diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0934e42b277e4..de144ee6104c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,6 +70,7 @@ jobs: HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} SCCACHE_BUCKET: rust-lang-ci-sccache2 + SCCACHE_REGION: us-west-1 CACHE_DOMAIN: ci-caches.rust-lang.org continue-on-error: ${{ matrix.continue_on_error || false }} strategy: @@ -173,6 +174,11 @@ jobs: - name: ensure the stable version number is correct run: src/ci/scripts/verify-stable-version-number.sh + # Show the environment just before we run the build + # This makes it easier to diagnose problems with the above install scripts. + - name: show the current environment + run: src/ci/scripts/dump-environment.sh + - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 diff --git a/.gitmodules b/.gitmodules index f9bd42edab3f4..97a0c0c54cf9f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,7 +29,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/19.1-2024-12-03 + branch = rustc/20.1-2025-02-13 shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book diff --git a/Cargo.lock b/Cargo.lock index 38a861727a9d3..4401489813a40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,19 +61,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "ammonia" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab99eae5ee58501ab236beb6f20f6ca39be615267b014899c89b2f0bc18a459" -dependencies = [ - "html5ever", - "maplit", - "once_cell", - "tendril", - "url", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -513,16 +500,6 @@ dependencies = [ "anstyle", "clap_lex", "strsim", - "terminal_size", -] - -[[package]] -name = "clap_complete" -version = "4.5.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0" -dependencies = [ - "clap", ] [[package]] @@ -1084,18 +1061,6 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" -[[package]] -name = "elasticlunr-rs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e83863a500656dfa214fee6682de9c5b9f03de6860fec531235ed2ae9f6571" -dependencies = [ - "regex", - "serde", - "serde_derive", - "serde_json", -] - [[package]] name = "elsa" version = "1.11.0" @@ -1159,13 +1124,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "error_index_generator" -version = "0.0.0" -dependencies = [ - "mdbook", -] - [[package]] name = "expect-test" version = "1.5.1" @@ -1517,22 +1475,6 @@ dependencies = [ "serde", ] -[[package]] -name = "handlebars" -version = "6.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6b224b95c1e668ac0270325ad563b2eef1469fbbb8959bc7c692c844b813d9" -dependencies = [ - "derive_builder", - "log", - "num-order", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror 2.0.11", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -2189,12 +2131,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "markup5ever" version = "0.12.1" @@ -2228,34 +2164,6 @@ dependencies = [ "digest", ] -[[package]] -name = "mdbook" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe1f98b8d66e537d2f0ba06e7dec4f44001deec539a2d18bfc102d6a86189148" -dependencies = [ - "ammonia", - "anyhow", - "chrono", - "clap", - "clap_complete", - "elasticlunr-rs", - "env_logger", - "handlebars", - "log", - "memchr", - "once_cell", - "opener", - "pulldown-cmark 0.10.3", - "regex", - "serde", - "serde_json", - "shlex", - "tempfile", - "toml 0.5.11", - "topological-sort", -] - [[package]] name = "measureme" version = "11.0.1" @@ -2303,9 +2211,9 @@ dependencies = [ [[package]] name = "minifier" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf47565b1430f5fe6c81d3afcb4b835271348d7eb35294a4d592e38dd09ea22" +checksum = "9bfdc64e2f805f3d12965f10522000bae36e88d2cfea44112331f467d4f4bf68" [[package]] name = "minimal-lexical" @@ -2483,21 +2391,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-modular" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" - -[[package]] -name = "num-order" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" -dependencies = [ - "num-modular", -] - [[package]] name = "num-rational" version = "0.4.2" @@ -2718,51 +2611,6 @@ dependencies = [ "libc", ] -[[package]] -name = "pest" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" -dependencies = [ - "memchr", - "thiserror 2.0.11", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.96", -] - -[[package]] -name = "pest_meta" -version = "2.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" -dependencies = [ - "once_cell", - "pest", - "sha2", -] - [[package]] name = "phf" version = "0.11.3" @@ -2903,9 +2751,9 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +checksum = "f58e5423e24c18cc840e1c98370b3993c6649cd1678b4d24318bcf0a083cbe88" dependencies = [ "cc", ] @@ -2921,18 +2769,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "pulldown-cmark" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" -dependencies = [ - "bitflags", - "memchr", - "pulldown-cmark-escape 0.10.1", - "unicase", -] - [[package]] name = "pulldown-cmark" version = "0.11.3" @@ -2941,16 +2777,10 @@ checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625" dependencies = [ "bitflags", "memchr", - "pulldown-cmark-escape 0.11.0", + "pulldown-cmark-escape", "unicase", ] -[[package]] -name = "pulldown-cmark-escape" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" - [[package]] name = "pulldown-cmark-escape" version = "0.11.0" @@ -3317,6 +3147,7 @@ dependencies = [ "rand 0.8.5", "rand_xoshiro", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3544,6 +3375,7 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_llvm", @@ -3586,6 +3418,7 @@ dependencies = [ "rustc_errors", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_hir_pretty", "rustc_incremental", @@ -3658,6 +3491,7 @@ dependencies = [ "rustc-stable-hash", "rustc_arena", "rustc_graphviz", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3768,6 +3602,7 @@ dependencies = [ "rustc_error_codes", "rustc_error_messages", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_lexer", @@ -3840,6 +3675,13 @@ version = "0.0.0" name = "rustc_graphviz" version = "0.0.0" +[[package]] +name = "rustc_hashes" +version = "0.0.0" +dependencies = [ + "rustc-stable-hash", +] + [[package]] name = "rustc_hir" version = "0.0.0" @@ -3849,6 +3691,7 @@ dependencies = [ "rustc_arena", "rustc_ast", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -3905,7 +3748,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -3937,6 +3779,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_fs_util", "rustc_graphviz", + "rustc_hashes", "rustc_hir", "rustc_macros", "rustc_middle", @@ -3970,7 +3813,6 @@ dependencies = [ name = "rustc_infer" version = "0.0.0" dependencies = [ - "rustc_ast_ir", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", @@ -4161,7 +4003,6 @@ dependencies = [ "rustc_apfloat", "rustc_arena", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_error_messages", @@ -4169,6 +4010,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_graphviz", + "rustc_hashes", "rustc_hir", "rustc_hir_pretty", "rustc_index", @@ -4290,7 +4132,6 @@ name = "rustc_next_trait_solver" version = "0.0.0" dependencies = [ "derive-where", - "rustc_ast_ir", "rustc_data_structures", "rustc_index", "rustc_macros", @@ -4405,6 +4246,7 @@ dependencies = [ "measureme", "rustc_data_structures", "rustc_errors", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_middle", @@ -4428,6 +4270,7 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_macros", @@ -4488,6 +4331,7 @@ name = "rustc_serialize" version = "0.0.0" dependencies = [ "indexmap", + "rustc_hashes", "rustc_macros", "smallvec", "tempfile", @@ -4508,6 +4352,7 @@ dependencies = [ "rustc_feature", "rustc_fluent_macro", "rustc_fs_util", + "rustc_hashes", "rustc_hir", "rustc_lint_defs", "rustc_macros", @@ -4549,6 +4394,7 @@ dependencies = [ "md-5", "rustc_arena", "rustc_data_structures", + "rustc_hashes", "rustc_index", "rustc_macros", "rustc_serialize", @@ -4568,6 +4414,7 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", + "rustc_hashes", "rustc_hir", "rustc_middle", "rustc_session", @@ -4604,7 +4451,6 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", - "rustc_ast_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -4643,7 +4489,6 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", - "rustc_ast_ir", "rustc_data_structures", "rustc_hir", "rustc_infer", @@ -4659,10 +4504,10 @@ version = "0.0.0" dependencies = [ "itertools", "rustc_abi", - "rustc_ast_ir", "rustc_data_structures", "rustc_errors", "rustc_fluent_macro", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_infer", @@ -5103,9 +4948,9 @@ dependencies = [ [[package]] name = "stacker" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" +checksum = "1d08feb8f695b465baed819b03c128dc23f57a694510ab1f06c77f763975685e" dependencies = [ "cc", "cfg-if", @@ -5289,16 +5134,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" -dependencies = [ - "rustix", - "windows-sys 0.59.0", -] - [[package]] name = "termize" version = "0.1.1" @@ -5539,12 +5374,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "topological-sort" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" - [[package]] name = "tracing" version = "0.1.37" @@ -5665,12 +5494,6 @@ dependencies = [ "regex-lite", ] -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - [[package]] name = "ui_test" version = "0.26.5" diff --git a/Cargo.toml b/Cargo.toml index 97e782d0df020..20a43aaaeeb37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "src/tools/clippy/clippy_dev", "src/tools/compiletest", "src/tools/run-make-support", - "src/tools/error_index_generator", "src/tools/linkchecker", "src/tools/lint-docs", "src/tools/miropt-test-tools", diff --git a/RELEASES.md b/RELEASES.md index f0def1a0e423a..038d7ca639f20 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -34,7 +34,8 @@ Libraries --------- - [Panics in the standard library now have a leading `library/` in their path](https://github.com/rust-lang/rust/pull/132390) - [`std::env::home_dir()` on Windows now ignores the non-standard `$HOME` environment variable](https://github.com/rust-lang/rust/pull/132515) - It will be un-deprecated in a subsequent release. + + It will be un-deprecated in a subsequent release. - [Add `AsyncFn*` to the prelude in all editions.](https://github.com/rust-lang/rust/pull/132611) @@ -98,15 +99,18 @@ Rustdoc Compatibility Notes ------------------- - [`rustc` no longer treats the `test` cfg as a well known check-cfg](https://github.com/rust-lang/rust/pull/131729), instead it is up to the build systems and users of `--check-cfg`[^check-cfg] to set it as a well known cfg using `--check-cfg=cfg(test)`. + This is done to enable build systems like Cargo to set it conditionally, as not all source files are suitable for unit tests. [Cargo (for now) unconditionally sets the `test` cfg as a well known cfg](https://github.com/rust-lang/cargo/pull/14963). -[^check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html + [^check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html - [Disable potentially incorrect type inference if there are trivial and non-trivial where-clauses](https://github.com/rust-lang/rust/pull/132325) - `std::env::home_dir()` has been deprecated for years, because it can give surprising results in some Windows configurations if the `HOME` environment variable is set (which is not the normal configuration on Windows). We had previously avoided changing its behavior, out of concern for compatibility with code depending on this non-standard configuration. Given how long this function has been deprecated, we're now fixing its behavior as a bugfix. A subsequent release will remove the deprecation for this function. - [Make `core::ffi::c_char` signedness more closely match that of the platform-default `char`](https://github.com/rust-lang/rust/pull/132975) + This changed `c_char` from an `i8` to `u8` or vice versa on many Tier 2 and 3 targets (mostly Arm and RISC-V embedded targets). The new definition may result in compilation failures but fixes compatibility issues with C. + The `libc` crate matches this change as of its 0.2.169 release. - [When compiling a nested `macro_rules` macro from an external crate, the content of the inner `macro_rules` is now built with the edition of the external crate, not the local crate.](https://github.com/rust-lang/rust/pull/133274) - [Increase `sparcv9-sun-solaris` and `x86_64-pc-solaris` Solaris baseline to 11.4.](https://github.com/rust-lang/rust/pull/133293) diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index d24b630516a7c..f4caa3ef769d5 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc-main" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc/src/main.rs b/compiler/rustc/src/main.rs index a55a63a7bf179..ca1bb59e59d60 100644 --- a/compiler/rustc/src/main.rs +++ b/compiler/rustc/src/main.rs @@ -65,7 +65,7 @@ fn main() { // linking, so we need to explicitly depend on the function. #[cfg(target_os = "macos")] { - extern "C" { + unsafe extern "C" { fn _rjem_je_zone_register(); } diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 1013f1d3958d8..86dc84e2016d6 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_abi" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -9,6 +9,7 @@ bitflags = "2.4.1" rand = { version = "0.8.4", default-features = false, optional = true } rand_xoshiro = { version = "0.6.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 9fb70b80c9efb..4529ab8058e9a 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -65,8 +65,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty: TyAbiInterface<'a, C> + Copy, { match self.backend_repr { - BackendRepr::Uninhabited => Err(Heterogeneous), - // The primitive for this algorithm. BackendRepr::Scalar(scalar) => { let kind = match scalar.primitive() { diff --git a/compiler/rustc_abi/src/callconv/reg.rs b/compiler/rustc_abi/src/callconv/reg.rs index 66f47c52c15d1..8cf140dbaad4e 100644 --- a/compiler/rustc_abi/src/callconv/reg.rs +++ b/compiler/rustc_abi/src/callconv/reg.rs @@ -57,7 +57,7 @@ impl Reg { 128 => dl.f128_align.abi, _ => panic!("unsupported float: {self:?}"), }, - RegKind::Vector => dl.vector_align(self.size).abi, + RegKind::Vector => dl.llvmlike_vector_align(self.size).abi, } } } diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index b8773f9ff38f6..3f83787ea3765 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -2,6 +2,7 @@ use std::fmt::{self, Write}; use std::ops::{Bound, Deref}; use std::{cmp, iter}; +use rustc_hashes::Hash64; use rustc_index::Idx; use tracing::debug; @@ -129,11 +130,12 @@ impl LayoutCalculator { }, backend_repr: BackendRepr::ScalarPair(a, b), largest_niche, + uninhabited: false, align, size, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed: combined_seed, + randomization_seed: Hash64::new(combined_seed), } } @@ -220,13 +222,14 @@ impl LayoutCalculator { LayoutData { variants: Variants::Empty, fields: FieldsShape::Primitive, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, } } @@ -307,10 +310,10 @@ impl LayoutCalculator { let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; - // If all the non-ZST fields have the same ABI and union ABI optimizations aren't - // disabled, we can use that common ABI for the union as a whole. + // If all the non-ZST fields have the same repr and union repr optimizations aren't + // disabled, we can use that common repr for the union as a whole. struct AbiMismatch; - let mut common_non_zst_abi_and_align = if repr.inhibits_union_abi_opt() { + let mut common_non_zst_repr_and_align = if repr.inhibits_union_abi_opt() { // Can't optimize Err(AbiMismatch) } else { @@ -334,14 +337,14 @@ impl LayoutCalculator { continue; } - if let Ok(common) = common_non_zst_abi_and_align { + if let Ok(common) = common_non_zst_repr_and_align { // Discard valid range information and allow undef let field_abi = field.backend_repr.to_union(); if let Some((common_abi, common_align)) = common { if common_abi != field_abi { // Different fields have different ABI: disable opt - common_non_zst_abi_and_align = Err(AbiMismatch); + common_non_zst_repr_and_align = Err(AbiMismatch); } else { // Fields with the same non-Aggregate ABI should also // have the same alignment @@ -354,7 +357,7 @@ impl LayoutCalculator { } } else { // First non-ZST field: record its ABI and alignment - common_non_zst_abi_and_align = Ok(Some((field_abi, field.align.abi))); + common_non_zst_repr_and_align = Ok(Some((field_abi, field.align.abi))); } } } @@ -373,16 +376,25 @@ impl LayoutCalculator { // If all non-ZST fields have the same ABI, we may forward that ABI // for the union as a whole, unless otherwise inhibited. - let abi = match common_non_zst_abi_and_align { + let backend_repr = match common_non_zst_repr_and_align { Err(AbiMismatch) | Ok(None) => BackendRepr::Memory { sized: true }, - Ok(Some((abi, _))) => { - if abi.inherent_align(dl).map(|a| a.abi) != Some(align.abi) { - // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt + Ok(Some((repr, _))) => match repr { + // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(_, _) + if repr.scalar_align(dl).unwrap() != align.abi => + { BackendRepr::Memory { sized: true } - } else { - abi } - } + // Vectors require at least element alignment, else disable the opt + BackendRepr::Vector { element, count: _ } if element.align(dl).abi > align.abi => { + BackendRepr::Memory { sized: true } + } + // the alignment tests passed and we can use this + BackendRepr::Scalar(..) + | BackendRepr::ScalarPair(..) + | BackendRepr::Vector { .. } + | BackendRepr::Memory { .. } => repr, + }, }; let Some(union_field_count) = NonZeroUsize::new(only_variant.len()) else { @@ -397,8 +409,9 @@ impl LayoutCalculator { Ok(LayoutData { variants: Variants::Single { index: only_variant_idx }, fields: FieldsShape::Union(union_field_count), - backend_repr: abi, + backend_repr, largest_niche: None, + uninhabited: false, align, size: size.align_to(align.abi), max_repr_align, @@ -446,7 +459,6 @@ impl LayoutCalculator { Scalar::Union { .. } => {} }; match &mut st.backend_repr { - BackendRepr::Uninhabited => {} BackendRepr::Scalar(scalar) => hide_niches(scalar), BackendRepr::ScalarPair(a, b) => { hide_niches(a); @@ -638,9 +650,8 @@ impl LayoutCalculator { let same_size = size == variant_layouts[largest_variant_index].size; let same_align = align == variant_layouts[largest_variant_index].align; - let abi = if variant_layouts.iter().all(|v| v.is_uninhabited()) { - BackendRepr::Uninhabited - } else if same_size && same_align && others_zst { + let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); + let abi = if same_size && same_align && others_zst { match variant_layouts[largest_variant_index].backend_repr { // When the total alignment and size match, we can use the // same ABI as the scalar variant with the reserved niche. @@ -682,6 +693,7 @@ impl LayoutCalculator { }, backend_repr: abi, largest_niche, + uninhabited, size, align, max_repr_align, @@ -852,9 +864,8 @@ impl LayoutCalculator { }; let mut abi = BackendRepr::Memory { sized: true }; - if layout_variants.iter().all(|v| v.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } else if tag.size(dl) == size { + let uninhabited = layout_variants.iter().all(|v| v.is_uninhabited()); + if tag.size(dl) == size { // Make sure we only use scalar layout when the enum is entirely its // own tag (i.e. it has no padding nor any non-ZST variant fields). abi = BackendRepr::Scalar(tag); @@ -994,6 +1005,7 @@ impl LayoutCalculator { memory_index: [0].into(), }, largest_niche, + uninhabited, backend_repr: abi, align, size, @@ -1058,7 +1070,7 @@ impl LayoutCalculator { // unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts. let field_seed = fields_excluding_tail .iter() - .fold(0u64, |acc, f| acc.wrapping_add(f.randomization_seed)); + .fold(Hash64::ZERO, |acc, f| acc.wrapping_add(f.randomization_seed)); if optimize_field_order && fields.len() > 1 { // If `-Z randomize-layout` was enabled for the type definition we can shuffle @@ -1072,7 +1084,7 @@ impl LayoutCalculator { // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field // ordering. let mut rng = rand_xoshiro::Xoshiro128StarStar::seed_from_u64( - field_seed.wrapping_add(repr.field_shuffle_seed), + field_seed.wrapping_add(repr.field_shuffle_seed).as_u64(), ); // Shuffle the ordering of the fields. @@ -1354,9 +1366,7 @@ impl LayoutCalculator { _ => {} } } - if fields.iter().any(|f| f.is_uninhabited()) { - abi = BackendRepr::Uninhabited; - } + let uninhabited = fields.iter().any(|f| f.is_uninhabited()); let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { @@ -1377,6 +1387,7 @@ impl LayoutCalculator { fields: FieldsShape::Arbitrary { offsets, memory_index }, backend_repr: abi, largest_niche, + uninhabited, align, size, max_repr_align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index da1c706d67cc4..81e4e255f3799 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -50,6 +50,7 @@ use std::str::FromStr; use bitflags::bitflags; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; +use rustc_hashes::Hash64; use rustc_index::{Idx, IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_Generic, Encodable_Generic, HashStable_Generic}; @@ -140,7 +141,7 @@ pub struct ReprOptions { /// hash without loss, but it does pay the price of being larger. /// Everything's a tradeoff, a 64-bit seed should be sufficient for our /// purposes (primarily `-Z randomize-layout`) - pub field_shuffle_seed: u64, + pub field_shuffle_seed: Hash64, } impl ReprOptions { @@ -328,19 +329,19 @@ impl TargetDataLayout { [p] if p.starts_with('P') => { dl.instruction_address_space = parse_address_space(&p[1..], "P")? } - ["a", ref a @ ..] => dl.aggregate_align = parse_align(a, "a")?, - ["f16", ref a @ ..] => dl.f16_align = parse_align(a, "f16")?, - ["f32", ref a @ ..] => dl.f32_align = parse_align(a, "f32")?, - ["f64", ref a @ ..] => dl.f64_align = parse_align(a, "f64")?, - ["f128", ref a @ ..] => dl.f128_align = parse_align(a, "f128")?, + ["a", a @ ..] => dl.aggregate_align = parse_align(a, "a")?, + ["f16", a @ ..] => dl.f16_align = parse_align(a, "f16")?, + ["f32", a @ ..] => dl.f32_align = parse_align(a, "f32")?, + ["f64", a @ ..] => dl.f64_align = parse_align(a, "f64")?, + ["f128", a @ ..] => dl.f128_align = parse_align(a, "f128")?, // FIXME(erikdesjardins): we should be parsing nonzero address spaces // this will require replacing TargetDataLayout::{pointer_size,pointer_align} // with e.g. `fn pointer_size_in(AddressSpace)` - [p @ "p", s, ref a @ ..] | [p @ "p0", s, ref a @ ..] => { + [p @ "p", s, a @ ..] | [p @ "p0", s, a @ ..] => { dl.pointer_size = parse_size(s, p)?; dl.pointer_align = parse_align(a, p)?; } - [s, ref a @ ..] if s.starts_with('i') => { + [s, a @ ..] if s.starts_with('i') => { let Ok(bits) = s[1..].parse::() else { parse_size(&s[1..], "i")?; // For the user error. continue; @@ -361,7 +362,7 @@ impl TargetDataLayout { dl.i128_align = a; } } - [s, ref a @ ..] if s.starts_with('v') => { + [s, a @ ..] if s.starts_with('v') => { let v_size = parse_size(&s[1..], "v")?; let a = parse_align(a, s)?; if let Some(v) = dl.vector_align.iter_mut().find(|v| v.0 == v_size) { @@ -407,16 +408,21 @@ impl TargetDataLayout { } } + /// psABI-mandated alignment for a vector type, if any #[inline] - pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { - for &(size, align) in &self.vector_align { - if size == vec_size { - return align; - } - } - // Default to natural alignment, which is what LLVM does. - // That is, use the size, rounded up to a power of 2. - AbiAndPrefAlign::new(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap()) + fn cabi_vector_align(&self, vec_size: Size) -> Option { + self.vector_align + .iter() + .find(|(size, _align)| *size == vec_size) + .map(|(_size, align)| *align) + } + + /// an alignment resembling the one LLVM would pick for a vector + #[inline] + pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { + self.cabi_vector_align(vec_size).unwrap_or(AbiAndPrefAlign::new( + Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(), + )) } } @@ -809,20 +815,19 @@ impl Align { self.bits().try_into().unwrap() } - /// Computes the best alignment possible for the given offset - /// (the largest power of two that the offset is a multiple of). + /// Obtain the greatest factor of `size` that is an alignment + /// (the largest power of two the Size is a multiple of). /// - /// N.B., for an offset of `0`, this happens to return `2^64`. + /// Note that all numbers are factors of 0 #[inline] - pub fn max_for_offset(offset: Size) -> Align { - Align { pow2: offset.bytes().trailing_zeros() as u8 } + pub fn max_aligned_factor(size: Size) -> Align { + Align { pow2: size.bytes().trailing_zeros() as u8 } } - /// Lower the alignment, if necessary, such that the given offset - /// is aligned to it (the offset is a multiple of the alignment). + /// Reduces Align to an aligned factor of `size`. #[inline] - pub fn restrict_for_offset(self, offset: Size) -> Align { - self.min(Align::max_for_offset(offset)) + pub fn restrict_for_offset(self, size: Size) -> Align { + self.min(Align::max_aligned_factor(size)) } } @@ -1344,7 +1349,7 @@ impl FieldsShape { /// Gets source indices of the fields by increasing offsets. #[inline] - pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator + '_ { + pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator { let mut inverse_small = [0u8; 64]; let mut inverse_big = IndexVec::new(); let use_small = self.count() <= inverse_small.len(); @@ -1403,7 +1408,6 @@ impl AddressSpace { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] pub enum BackendRepr { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -1422,10 +1426,9 @@ impl BackendRepr { #[inline] pub fn is_unsized(&self) -> bool { match *self { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) - | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { + false + } BackendRepr::Memory { sized } => !sized, } } @@ -1444,12 +1447,6 @@ impl BackendRepr { } } - /// Returns `true` if this is an uninhabited type - #[inline] - pub fn is_uninhabited(&self) -> bool { - matches!(*self, BackendRepr::Uninhabited) - } - /// Returns `true` if this is a scalar type #[inline] pub fn is_scalar(&self) -> bool { @@ -1462,37 +1459,38 @@ impl BackendRepr { matches!(*self, BackendRepr::Scalar(s) if s.is_bool()) } - /// Returns the fixed alignment of this ABI, if any is mandated. - pub fn inherent_align(&self, cx: &C) -> Option { - Some(match *self { - BackendRepr::Scalar(s) => s.align(cx), - BackendRepr::ScalarPair(s1, s2) => s1.align(cx).max(s2.align(cx)), - BackendRepr::Vector { element, count } => { - cx.data_layout().vector_align(element.size(cx) * count) - } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, - }) + /// The psABI alignment for a `Scalar` or `ScalarPair` + /// + /// `None` for other variants. + pub fn scalar_align(&self, cx: &C) -> Option { + match *self { + BackendRepr::Scalar(s) => Some(s.align(cx).abi), + BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi), + // The align of a Vector can vary in surprising ways + BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None, + } } - /// Returns the fixed size of this ABI, if any is mandated. - pub fn inherent_size(&self, cx: &C) -> Option { - Some(match *self { - BackendRepr::Scalar(s) => { - // No padding in scalars. - s.size(cx) - } + /// The psABI size for a `Scalar` or `ScalarPair` + /// + /// `None` for other variants + pub fn scalar_size(&self, cx: &C) -> Option { + match *self { + // No padding in scalars. + BackendRepr::Scalar(s) => Some(s.size(cx)), + // May have some padding between the pair. BackendRepr::ScalarPair(s1, s2) => { - // May have some padding between the pair. let field2_offset = s1.size(cx).align_to(s2.align(cx).abi); - (field2_offset + s2.size(cx)).align_to(self.inherent_align(cx)?.abi) + let size = (field2_offset + s2.size(cx)).align_to( + self.scalar_align(cx) + // We absolutely must have an answer here or everything is FUBAR. + .unwrap(), + ); + Some(size) } - BackendRepr::Vector { element, count } => { - // No padding in vectors, except possibly for trailing padding - // to make the size a multiple of align (e.g. for vectors of size 3). - (element.size(cx) * count).align_to(self.inherent_align(cx)?.abi) - } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => return None, - }) + // The size of a Vector can vary in surprising ways + BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => None, + } } /// Discard validity range information and allow undef. @@ -1505,9 +1503,7 @@ impl BackendRepr { BackendRepr::Vector { element, count } => { BackendRepr::Vector { element: element.to_union(), count } } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - BackendRepr::Memory { sized: true } - } + BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, } } @@ -1703,6 +1699,11 @@ pub struct LayoutData { /// The leaf scalar with the largest number of invalid values /// (i.e. outside of its `valid_range`), if it exists. pub largest_niche: Option, + /// Is this type known to be uninhabted? + /// + /// This is separate from BackendRepr because uninhabited return types can affect ABI, + /// especially in the case of by-pointer struct returns, which allocate stack even when unused. + pub uninhabited: bool, pub align: AbiAndPrefAlign, pub size: Size, @@ -1727,21 +1728,21 @@ pub struct LayoutData { /// transmuted to `Foo` we aim to create probalistically distinct seeds so that Foo can choose /// to reorder its fields based on that information. The current implementation is a conservative /// approximation of this goal. - pub randomization_seed: u64, + pub randomization_seed: Hash64, } impl LayoutData { /// Returns `true` if this is an aggregate type (including a ScalarPair!) pub fn is_aggregate(&self) -> bool { match self.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } /// Returns `true` if this is an uninhabited type pub fn is_uninhabited(&self) -> bool { - self.backend_repr.is_uninhabited() + self.uninhabited } pub fn scalar(cx: &C, scalar: Scalar) -> Self { @@ -1777,11 +1778,12 @@ impl LayoutData { fields: FieldsShape::Primitive, backend_repr: BackendRepr::Scalar(scalar), largest_niche, + uninhabited: false, size, align, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed, + randomization_seed: Hash64::new(randomization_seed), } } } @@ -1801,10 +1803,11 @@ where backend_repr, fields, largest_niche, + uninhabited, variants, max_repr_align, unadjusted_abi_align, - ref randomization_seed, + randomization_seed, } = self; f.debug_struct("Layout") .field("size", size) @@ -1812,6 +1815,7 @@ where .field("abi", backend_repr) .field("fields", fields) .field("largest_niche", largest_niche) + .field("uninhabited", uninhabited) .field("variants", variants) .field("max_repr_align", max_repr_align) .field("unadjusted_abi_align", unadjusted_abi_align) @@ -1876,7 +1880,6 @@ impl LayoutData { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. } => { false } - BackendRepr::Uninhabited => self.size.bytes() == 0, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } } diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index 382ab2b077547..bbcd8ea6d389d 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_arena" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 34c612dac692b..902287d032802 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 60f8c6e10481b..346edc87c86bc 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -203,10 +203,8 @@ impl HasTokens for Nonterminal { Nonterminal::NtStmt(stmt) => stmt.tokens(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(), Nonterminal::NtPat(pat) => pat.tokens(), - Nonterminal::NtTy(ty) => ty.tokens(), Nonterminal::NtMeta(attr_item) => attr_item.tokens(), Nonterminal::NtPath(path) => path.tokens(), - Nonterminal::NtVis(vis) => vis.tokens(), Nonterminal::NtBlock(block) => block.tokens(), } } @@ -216,10 +214,8 @@ impl HasTokens for Nonterminal { Nonterminal::NtStmt(stmt) => stmt.tokens_mut(), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(), Nonterminal::NtPat(pat) => pat.tokens_mut(), - Nonterminal::NtTy(ty) => ty.tokens_mut(), Nonterminal::NtMeta(attr_item) => attr_item.tokens_mut(), Nonterminal::NtPath(path) => path.tokens_mut(), - Nonterminal::NtVis(vis) => vis.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), } } diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index 70222f4acabe1..c8ec185ee5e29 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -17,7 +17,6 @@ use crate::{Ty, TyKind}; /// functions. The proper solution is to recognize and resolve this DAG of autodiff invocations, /// as it's already done in the C++ and Julia frontend of Enzyme. /// -/// (FIXME) remove *First variants. /// Documentation for using [reverse](https://enzyme.mit.edu/rust/rev.html) and /// [forward](https://enzyme.mit.edu/rust/fwd.html) mode is available online. #[derive(Clone, Copy, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index de9f049704a4f..40b29fdba2506 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -907,7 +907,6 @@ fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { }), token::NtPat(pat) => vis.visit_pat(pat), token::NtExpr(expr) => vis.visit_expr(expr), - token::NtTy(ty) => vis.visit_ty(ty), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); @@ -916,7 +915,6 @@ fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { visit_lazy_tts(vis, tokens); } token::NtPath(path) => vis.visit_path(path), - token::NtVis(visib) => vis.visit_vis(visib), } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 36a7b7d87892f..97d121909f8dd 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -84,7 +84,9 @@ pub enum MetaVarKind { // This field is needed for `Token::can_begin_string_literal`. can_begin_string_literal: bool, }, - Ty, + Ty { + is_path: bool, + }, Ident, Lifetime, Literal, @@ -104,7 +106,7 @@ impl fmt::Display for MetaVarKind { MetaVarKind::Pat(PatParam { inferred: false }) => sym::pat_param, MetaVarKind::Expr { kind: Expr2021 { inferred: true } | Expr, .. } => sym::expr, MetaVarKind::Expr { kind: Expr2021 { inferred: false }, .. } => sym::expr_2021, - MetaVarKind::Ty => sym::ty, + MetaVarKind::Ty { .. } => sym::ty, MetaVarKind::Ident => sym::ident, MetaVarKind::Lifetime => sym::lifetime, MetaVarKind::Literal => sym::literal, @@ -659,7 +661,6 @@ impl Token { | NtMeta(..) | NtPat(..) | NtPath(..) - | NtTy(..) ), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( MetaVarKind::Expr { .. } | @@ -667,7 +668,7 @@ impl Token { MetaVarKind::Meta | MetaVarKind::Pat(_) | MetaVarKind::Path | - MetaVarKind::Ty + MetaVarKind::Ty { .. } ))) => true, _ => false, } @@ -688,9 +689,9 @@ impl Token { Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path PathSep => true, // global path - Interpolated(ref nt) => matches!(&**nt, NtTy(..) | NtPath(..)), + Interpolated(ref nt) => matches!(&**nt, NtPath(..)), OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar( - MetaVarKind::Ty | + MetaVarKind::Ty { .. } | MetaVarKind::Path ))) => true, // For anonymous structs or unions, which only appear in specific positions @@ -969,6 +970,15 @@ impl Token { } } + /// Is this an invisible open delimiter at the start of a token sequence + /// from an expanded metavar? + pub fn is_metavar_seq(&self) -> Option { + match self.kind { + OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(kind))) => Some(kind), + _ => None, + } + } + pub fn glue(&self, joint: &Token) -> Option { let kind = match self.kind { Eq => match joint.kind { @@ -1067,12 +1077,10 @@ pub enum Nonterminal { NtStmt(P), NtPat(P), NtExpr(P), - NtTy(P), NtLiteral(P), /// Stuff inside brackets for attributes NtMeta(P), NtPath(P), - NtVis(P), } #[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)] @@ -1166,10 +1174,8 @@ impl Nonterminal { NtStmt(stmt) => stmt.span, NtPat(pat) => pat.span, NtExpr(expr) | NtLiteral(expr) => expr.span, - NtTy(ty) => ty.span, NtMeta(attr_item) => attr_item.span(), NtPath(path) => path.span, - NtVis(vis) => vis.span, } } @@ -1181,10 +1187,8 @@ impl Nonterminal { NtPat(..) => "pattern", NtExpr(..) => "expression", NtLiteral(..) => "literal", - NtTy(..) => "type", NtMeta(..) => "attribute", NtPath(..) => "path", - NtVis(..) => "visibility", } } } @@ -1207,11 +1211,9 @@ impl fmt::Debug for Nonterminal { NtStmt(..) => f.pad("NtStmt(..)"), NtPat(..) => f.pad("NtPat(..)"), NtExpr(..) => f.pad("NtExpr(..)"), - NtTy(..) => f.pad("NtTy(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), - NtVis(..) => f.pad("NtVis(..)"), } } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 50f10d083a041..1123ea3a449b6 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -469,10 +469,8 @@ impl TokenStream { } Nonterminal::NtStmt(stmt) => TokenStream::from_ast(stmt), Nonterminal::NtPat(pat) => TokenStream::from_ast(pat), - Nonterminal::NtTy(ty) => TokenStream::from_ast(ty), Nonterminal::NtMeta(attr) => TokenStream::from_ast(attr), Nonterminal::NtPath(path) => TokenStream::from_ast(path), - Nonterminal::NtVis(vis) => TokenStream::from_ast(vis), Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr), } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3242d4145959d..1cb32b56875c3 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -597,7 +597,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( visit_opt!(visitor, visit_ident, rename); } UseTreeKind::Glob => {} - UseTreeKind::Nested { ref items, span: _ } => { + UseTreeKind::Nested { items, span: _ } => { for &(ref nested_tree, nested_id) in items { try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); } diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index 1905574073f13..f54e9687d8c7f 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_ir" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index ff9d940ce9f28..9884e191ea7bd 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -1,3 +1,10 @@ +//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`. +//! +//! Don't depend on this crate directly; both of those crates should re-export +//! the functionality. Additionally, if you're in scope of `rustc_middle`, then +//! prefer imports via that too, to avoid needing to directly depend on (e.g.) +//! `rustc_type_ir` for a single import. + // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index ce95f4dfa1b82..3215ce6b0cb47 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_lowering" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] doctest = false diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 96c230ec243a2..cfd32fc066f41 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -1,13 +1,12 @@ use std::collections::hash_map::Entry; use std::fmt::Write; -use rustc_ast::ptr::P; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_session::parse::feature_err; -use rustc_span::{Span, kw, sym}; +use rustc_span::{Span, sym}; use rustc_target::asm; use super::LoweringContext; @@ -230,20 +229,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { tokens: None, }; - // Wrap the expression in an AnonConst. - let parent_def_id = self.current_hir_id_owner.def_id; - let node_id = self.next_node_id(); - self.create_def( - parent_def_id, - node_id, - kw::Empty, - DefKind::AnonConst, - *op_sp, - ); - let anon_const = AnonConst { id: node_id, value: P(expr) }; - hir::InlineAsmOperand::SymFn { - anon_const: self.lower_anon_const_to_anon_const(&anon_const), - } + hir::InlineAsmOperand::SymFn { expr: self.lower_expr(&expr) } } } InlineAsmOperand::Label { block } => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bc2db41546989..1d3db64b47ed9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -251,7 +251,12 @@ impl<'hir> LoweringContext<'_, 'hir> { .arena .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), }, - ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)), + ItemKind::GlobalAsm(asm) => { + let asm = self.lower_inline_asm(span, asm); + let fake_body = + self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); + hir::ItemKind::GlobalAsm { asm, fake_body } + } ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { // We lower // diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1c777111896dc..b865cbedbbb78 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -45,7 +45,6 @@ use std::sync::Arc; use rustc_ast::node_id::NodeMap; use rustc_ast::{self as ast, *}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -1821,11 +1820,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.new_named_lifetime_with_res(new_id, ident, res) } - fn lower_generic_params_mut<'s>( - &'s mut self, - params: &'s [GenericParam], + fn lower_generic_params_mut( + &mut self, + params: &[GenericParam], source: hir::GenericParamSource, - ) -> impl Iterator> + Captures<'a> + Captures<'s> { + ) -> impl Iterator> { params.iter().map(move |param| self.lower_generic_param(param, source)) } @@ -1986,11 +1985,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx)) } - fn lower_param_bounds_mut<'s>( - &'s mut self, - bounds: &'s [GenericBound], + fn lower_param_bounds_mut( + &mut self, + bounds: &[GenericBound], itctx: ImplTraitContext, - ) -> impl Iterator> + Captures<'s> + Captures<'a> { + ) -> impl Iterator> { bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx)) } diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index e4c227532085f..c738cb2aa2fd4 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_passes" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 0eb2043eaa356..6eb9bb1c0dafa 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -804,7 +804,14 @@ pub(crate) struct NegativeBoundWithParentheticalNotation { pub(crate) struct MatchArmWithNoBody { #[primary_span] pub span: Span, - #[suggestion(code = " => todo!(),", applicability = "has-placeholders")] + // We include the braces around `todo!()` so that a comma is optional, and we don't have to have + // any logic looking at the arm being replaced if there was a comma already or not for the + // resulting code to be correct. + #[suggestion( + code = " => {{ todo!() }}", + applicability = "has-placeholders", + style = "verbose" + )] pub suggestion: Span, } diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index f290fedcd8b9a..2634dd1fdf93e 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_ast_pretty" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0bf5de3ef8985..44e956dc37f3e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -424,20 +424,23 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.ann_post(ident) } - fn strsep( + fn strsep<'x, T: 'x, F, I>( &mut self, sep: &'static str, space_before: bool, b: Breaks, - elts: &[T], + elts: I, mut op: F, ) where F: FnMut(&mut Self, &T), + I: IntoIterator, { + let mut it = elts.into_iter(); + self.rbox(0, b); - if let Some((first, rest)) = elts.split_first() { + if let Some(first) = it.next() { op(self, first); - for elt in rest { + for elt in it { if space_before { self.space(); } @@ -448,9 +451,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.end(); } - fn commasep(&mut self, b: Breaks, elts: &[T], op: F) + fn commasep<'x, T: 'x, F, I>(&mut self, b: Breaks, elts: I, op: F) where F: FnMut(&mut Self, &T), + I: IntoIterator, { self.strsep(",", false, b, elts, op) } diff --git a/compiler/rustc_attr_data_structures/Cargo.toml b/compiler/rustc_attr_data_structures/Cargo.toml index 2ee58f24470e9..19d0d5a306d6e 100644 --- a/compiler/rustc_attr_data_structures/Cargo.toml +++ b/compiler/rustc_attr_data_structures/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_attr_data_structures" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml index 7ccedf40c3fa9..f681e9397d9f1 100644 --- a/compiler/rustc_attr_parsing/Cargo.toml +++ b/compiler/rustc_attr_parsing/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_attr_parsing" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs index 471168ed4f56d..13d246b08a8f4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs +++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs @@ -4,25 +4,25 @@ use rustc_span::{Symbol, sym}; use crate::session_diagnostics; -pub fn allow_internal_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { +pub fn allow_internal_unstable( + sess: &Session, + attrs: &[impl AttributeExt], +) -> impl Iterator { allow_unstable(sess, attrs, sym::allow_internal_unstable) } -pub fn rustc_allow_const_fn_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator + 'a { +pub fn rustc_allow_const_fn_unstable( + sess: &Session, + attrs: &[impl AttributeExt], +) -> impl Iterator { allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable) } -fn allow_unstable<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], +fn allow_unstable( + sess: &Session, + attrs: &[impl AttributeExt], symbol: Symbol, -) -> impl Iterator + 'a { +) -> impl Iterator { let attrs = filter_by_name(attrs, symbol); let list = attrs .filter_map(move |attr| { diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index c35556dcf5bf2..cb0e145386b83 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_baked_icu_data" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 89154bf2c23c4..9e7d55180a233 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_borrowck" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 59c76cb7f2bbc..f33f2ab58e05f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -8,7 +8,6 @@ use std::ops::ControlFlow; use either::Either; use hir::{ClosureKind, Path}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, MultiSpan, struct_span_code_err}; @@ -18,12 +17,11 @@ use rustc_hir::intravisit::{Visitor, walk_block, walk_expr}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, LangItem, PatField}; use rustc_middle::bug; use rustc_middle::hir::nested_filter::OnlyBodies; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, FakeBorrowKind, FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, MutBorrowKind, - Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, - TerminatorKind, VarBindingForm, VarDebugInfoContents, + Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement, StatementKind, + Terminator, TerminatorKind, VarBindingForm, VarDebugInfoContents, }; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ @@ -386,8 +384,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { hir::intravisit::walk_pat(self, p); } } - let hir = self.infcx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) { + let tcx = self.infcx.tcx; + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) { let expr = body.value; let place = &self.move_data.move_paths[mpi].place; let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); @@ -396,13 +394,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { expr: None, pat: None, parent_pat: None, - tcx: self.infcx.tcx, + tcx, }; finder.visit_expr(expr); if let Some(span) = span && let Some(expr) = finder.expr { - for (_, expr) in hir.parent_iter(expr.hir_id) { + for (_, expr) in tcx.hir_parent_iter(expr.hir_id) { if let hir::Node::Expr(expr) = expr { if expr.span.contains(span) { // If the let binding occurs within the same loop, then that @@ -782,9 +780,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); - let mut visitor = ConditionVisitor { tcx: self.infcx.tcx, spans, name, errors: vec![] }; + let tcx = self.infcx.tcx; + let body = tcx.hir_body_owned_by(self.mir_def_id()); + let mut visitor = ConditionVisitor { tcx, spans, name, errors: vec![] }; visitor.visit_body(&body); let spans = visitor.spans; @@ -969,7 +967,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut parent = None; // The top-most loop where the moved expression could be moved to a new binding. let mut outer_most_loop: Option<&hir::Expr<'_>> = None; - for (_, node) in tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in tcx.hir_parent_iter(expr.hir_id) { let e = match node { hir::Node::Expr(e) => e, hir::Node::LetStmt(hir::LetStmt { els: Some(els), .. }) => { @@ -1021,8 +1019,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } let loop_count: usize = tcx - .hir() - .parent_iter(expr.hir_id) + .hir_parent_iter(expr.hir_id) .map(|(_, node)| match node { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Loop(..), .. }) => 1, _ => 0, @@ -1048,8 +1045,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .collect::>(); // All of the spans for the loops above the expression with the move error. let loop_spans: Vec<_> = tcx - .hir() - .parent_iter(expr.hir_id) + .hir_parent_iter(expr.hir_id) .filter_map(|(_, node)| match node { hir::Node::Expr(hir::Expr { span, kind: hir::ExprKind::Loop(..), .. }) => { Some(*span) @@ -1334,7 +1330,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } fn in_move_closure(&self, expr: &hir::Expr<'_>) -> bool { - for (_, node) in self.infcx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in self.infcx.tcx.hir_parent_iter(expr.hir_id) { if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) = node && let hir::CaptureBy::Value { .. } = closure.capture_clause { @@ -2118,7 +2114,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { issued_span: Span, ) { let tcx = self.infcx.tcx; - let hir = tcx.hir(); let has_split_at_mut = |ty: Ty<'tcx>| { let ty = ty.peel_refs(); @@ -2171,7 +2166,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; - let Some(object) = hir.parent_id_iter(index1.hir_id).find_map(|id| { + let Some(object) = tcx.hir_parent_id_iter(index1.hir_id).find_map(|id| { if let hir::Node::Expr(expr) = tcx.hir_node(id) && let hir::ExprKind::Index(obj, ..) = expr.kind { @@ -2189,7 +2184,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; - let Some(swap_call) = hir.parent_id_iter(object.hir_id).find_map(|id| { + let Some(swap_call) = tcx.hir_parent_id_iter(object.hir_id).find_map(|id| { if let hir::Node::Expr(call) = tcx.hir_node(id) && let hir::ExprKind::Call(callee, ..) = call.kind && let hir::ExprKind::Path(qpath) = callee.kind @@ -2443,7 +2438,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; let tcx = self.infcx.tcx; - let hir = tcx.hir(); // Get the type of the local that we are trying to borrow let local = borrowed_place.local; @@ -2522,7 +2516,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // 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)| { + params.iter().zip(tcx.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() }) @@ -2622,7 +2616,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let hir::Pat { kind: hir::PatKind::Binding(_, hir_id, _ident, _), .. } = local.pat && let Some(init) = local.init - && let hir::Expr { + && let &hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { kind: hir::ClosureKind::Closure, @@ -3535,10 +3529,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { location: Location, mpi: MovePathIndex, ) -> (Vec, Vec) { - fn predecessor_locations<'a, 'tcx>( - body: &'a mir::Body<'tcx>, + fn predecessor_locations<'tcx>( + body: &mir::Body<'tcx>, location: Location, - ) -> impl Iterator + Captures<'tcx> + 'a { + ) -> impl Iterator { if location.statement_index == 0 { let predecessors = body.basic_blocks.predecessors()[location.block].to_vec(); Either::Left(predecessors.into_iter().map(move |bb| body.terminator_loc(bb))) @@ -4178,7 +4172,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!("annotate_fn_sig: did={:?} sig={:?}", did, sig); let is_closure = self.infcx.tcx.is_closure_like(did.to_def_id()); let fn_hir_id = self.infcx.tcx.local_def_id_to_hir_id(did); - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(fn_hir_id)?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(fn_hir_id)?; // We need to work out which arguments to highlight. We do this by looking // at the return type, where there are three cases: diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index a88b27f24767e..f77dda0d386aa 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -117,7 +117,7 @@ impl<'tcx> BorrowExplanation<'tcx> { let local_decl = &body.local_decls[dropped_local]; if let &LocalInfo::IfThenRescopeTemp { if_then } = local_decl.local_info() - && let Some((_, hir::Node::Expr(expr))) = tcx.hir().parent_iter(if_then).next() + && let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(if_then).next() && let hir::ExprKind::If(cond, conseq, alt) = expr.kind && let hir::ExprKind::Let(&hir::LetExpr { span: _, @@ -262,7 +262,7 @@ impl<'tcx> BorrowExplanation<'tcx> { fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) { if let hir::ExprKind::If(cond, _conseq, _alt) | hir::ExprKind::Loop( - hir::Block { + &hir::Block { expr: Some(&hir::Expr { kind: hir::ExprKind::If(cond, _conseq, _alt), @@ -522,7 +522,7 @@ fn suggest_rewrite_if_let( ); if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() { let needs_block = if let Some(hir::Node::Expr(expr)) = - alt.and_then(|alt| tcx.hir().parent_iter(alt.hir_id).next()).map(|(_, node)| node) + alt.and_then(|alt| tcx.hir_parent_iter(alt.hir_id).next()).map(|(_, node)| node) { matches!(expr.kind, hir::ExprKind::If(..)) } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index 26a090f5579ce..96f48840468e5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; @@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { let block_data = &self.body[p.block]; - match self.def_use(p, block_data.visitable(p.statement_index)) { + let mut visitor = DefUseVisitor { + body: self.body, + tcx: self.tcx, + region_vid: self.region_vid, + def_use_result: None, + }; + + let is_statement = p.statement_index < block_data.statements.len(); + + if is_statement { + visitor.visit_statement(&block_data.statements[p.statement_index], p); + } else { + visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p); + } + + match visitor.def_use_result { Some(DefUseResult::Def) => {} Some(DefUseResult::UseLive { local }) => { @@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { } None => { - if p.statement_index < block_data.statements.len() { + if is_statement { queue.push_back(p.successor_within_block()); } else { queue.extend( @@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { None } - - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option { - let mut visitor = DefUseVisitor { - body: self.body, - tcx: self.tcx, - region_vid: self.region_vid, - def_use_result: None, - }; - - thing.apply(location, &mut visitor); - - visitor.def_use_result - } } struct DefUseVisitor<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 07ea369c5c7f2..d1f238331d56f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -13,10 +13,9 @@ use rustc_infer::infer::{ }; use rustc_infer::traits::SelectionError; use rustc_middle::bug; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo, - LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, + LocalKind, Location, Operand, Place, PlaceRef, PlaceTy, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, find_self_call, }; use rustc_middle::ty::print::Print; @@ -1127,7 +1126,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id); let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind; debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr); - if let hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { + if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr { for (captured_place, place) in self.infcx.tcx.closure_captures(def_id).iter().zip(places) { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 38f22473edfac..5e83d2ffa97a1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -388,7 +388,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // Search for an appropriate place for the structured `.clone()` suggestion to be applied. // If we encounter a statement before the borrow error, we insert a statement there. - for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) { + for (_, node) in tcx.hir_parent_iter(closure_expr.hir_id) { if let Node::Stmt(stmt) = node { let padding = tcx .sess @@ -777,12 +777,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } let Some(pat_span) = pat_span else { return }; - let hir = self.infcx.tcx.hir(); - let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) else { return }; + let tcx = self.infcx.tcx; + let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) else { return }; let typeck_results = self.infcx.tcx.typeck(self.mir_def_id()); let mut finder = BindingFinder { typeck_results, - tcx: self.infcx.tcx, + tcx, pat_span, binding_spans, found_pat: false, diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fc782ce642497..be4a7736b1c20 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -404,7 +404,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { pat.kind { if upvar_ident.name == kw::SelfLower { - for (_, node) in self.infcx.tcx.hir().parent_iter(upvar_hir_id) { + for (_, node) in self.infcx.tcx.hir_parent_iter(upvar_hir_id) { if let Some(fn_decl) = node.fn_decl() { if !matches!( fn_decl.implicit_self, @@ -648,10 +648,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); let Some(local_def_id) = def_id.as_local() else { return }; - let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return }; + let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) else { return }; let mut v = SuggestIndexOperatorAlternativeVisitor { assign_span: span, @@ -749,7 +748,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)` let def_id = self.body.source.def_id(); if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value() && let node = self.infcx.tcx.hir_node(hir_id) && let hir::Node::LetStmt(hir::LetStmt { @@ -856,7 +855,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { use hir::ExprKind::{AddrOf, Block, Call, MethodCall}; use hir::{BorrowKind, Expr}; - let hir_map = self.infcx.tcx.hir(); + let tcx = self.infcx.tcx; struct Finder { span: Span, } @@ -871,7 +870,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } } - if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id()) + if let Some(body) = tcx.hir_maybe_body_owned_by(self.mir_def_id()) && let Block(block, _) = body.value.kind { // `span` corresponds to the expression being iterated, find the `for`-loop desugared @@ -884,17 +883,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { MethodCall(path_segment, _, _, span) => { // We have `for _ in iter.read_only_iter()`, try to // suggest `for _ in iter.mutable_iter()` instead. - let opt_suggestions = self - .infcx - .tcx + let opt_suggestions = tcx .typeck(path_segment.hir_id.owner.def_id) .type_dependent_def_id(expr.hir_id) - .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) - .map(|def_id| self.infcx.tcx.associated_items(def_id)) + .and_then(|def_id| tcx.impl_of_method(def_id)) + .map(|def_id| tcx.associated_items(def_id)) .map(|assoc_items| { assoc_items .in_definition_order() - .map(|assoc_item_def| assoc_item_def.ident(self.infcx.tcx)) + .map(|assoc_item_def| assoc_item_def.ident(tcx)) .filter(|&ident| { let original_method_ident = path_segment.ident; original_method_ident != ident @@ -937,12 +934,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { err.span_label(sp, format!("cannot {act}")); let tcx = self.infcx.tcx; - let hir = tcx.hir(); let closure_id = self.mir_hir_id(); let closure_span = tcx.def_span(self.mir_def_id()); let fn_call_id = tcx.parent_hir_id(closure_id); let node = tcx.hir_node(fn_call_id); - let def_id = hir.enclosing_body_owner(fn_call_id); + let def_id = tcx.hir_enclosing_body_owner(fn_call_id); let mut look_at_return = true; // If the HIR node is a function or method call gets the def ID @@ -1020,10 +1016,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } } - if look_at_return && hir.get_fn_id_for_return_block(closure_id).is_some() { + if look_at_return && tcx.hir_get_fn_id_for_return_block(closure_id).is_some() { // ...otherwise we are probably in the tail expression of the function, point at the // return type. - match tcx.hir_node_by_def_id(hir.get_parent_item(fn_call_id).def_id) { + match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(fn_call_id).def_id) { hir::Node::Item(hir::Item { ident, kind: hir::ItemKind::Fn { sig, .. }, .. }) @@ -1275,7 +1271,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { }) => { let def_id = self.body.source.def_id(); let hir_id = if let Some(local_def_id) = def_id.as_local() - && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id) + && let Some(body) = self.infcx.tcx.hir_maybe_body_owned_by(local_def_id) { BindingFinder { span: err_label_span }.visit_body(&body).break_value() } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d3c91cbdee9cf..55b6367f35ff8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1169,8 +1169,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { #[allow(rustc::diagnostic_outside_of_impl)] fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) { - let map = self.infcx.tcx.hir(); - let body = map.body_owned_by(self.mir_def_id()); + let body = self.infcx.tcx.hir_body_owned_by(self.mir_def_id()); let expr = &body.value.peel_blocks(); let mut closure_span = None::; match expr.kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index ccd13badad742..be28f84debd90 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -424,7 +424,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &self, argument_index: usize, ) -> Option<&hir::Ty<'tcx>> { - let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(self.mir_hir_id())?; + let fn_decl = self.infcx.tcx.hir_fn_decl_by_hir_id(self.mir_hir_id())?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like @@ -671,7 +671,6 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { #[instrument(level = "trace", skip(self))] fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option { let tcx = self.infcx.tcx; - let hir = tcx.hir(); let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); @@ -682,7 +681,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { let mir_hir_id = self.mir_hir_id(); let (return_span, mir_description, hir_ty) = match tcx.hir_node(mir_hir_id) { - hir::Node::Expr(hir::Expr { + hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl, kind, fn_decl_span, .. }), .. }) => { @@ -711,7 +710,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async fn should be in fn") @@ -741,7 +740,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from gen fn should be in fn") @@ -768,7 +767,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir::CoroutineSource::Fn, )) => { let parent_item = - tcx.hir_node_by_def_id(hir.get_parent_item(mir_hir_id).def_id); + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id); let output = &parent_item .fn_decl() .expect("coroutine lowered from async gen fn should be in fn") @@ -874,7 +873,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { .name; let yield_span = match tcx.hir_node(self.mir_hir_id()) { - hir::Node::Expr(hir::Expr { + hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. }) => tcx.sess.source_map().end_point(fn_decl_span), diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 53cf4f34ae794..a98984a4b4c7a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -33,7 +33,6 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::{ InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::fold::fold_regions; @@ -188,7 +187,7 @@ fn do_mir_borrowck<'tcx>( .iterate_to_fixpoint(tcx, body, Some("borrowck")) .into_results_cursor(body); - let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); + let locals_are_invalidated_at_exit = tcx.hir_body_owner_kind(def).is_fn_or_closure(); let borrow_set = BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &move_data); // Compute non-lexical lifetimes. diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index a0adf471fd31f..bdd0f6fe11e0f 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -1,7 +1,6 @@ use std::hash::Hash; use std::ops::Index; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::ty::{self, Ty}; @@ -147,9 +146,7 @@ impl<'tcx, R> MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - pub(crate) fn all_indices( - &self, - ) -> impl Iterator + Captures<'tcx> + '_ { + pub(crate) fn all_indices(&self) -> impl Iterator { self.constraints.indices() } @@ -159,7 +156,7 @@ where pub(crate) fn indices( &self, member_region_vid: R, - ) -> impl Iterator + Captures<'tcx> + '_ { + ) -> impl Iterator { let mut next = self.first_constraints.get(&member_region_vid).cloned(); std::iter::from_fn(move || -> Option { if let Some(current) = next { diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index 5f9fa3612b8d1..aa64a7c4e2a68 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -226,7 +226,7 @@ fn emit_polonius_mir<'tcx>( regioncx, closure_region_requirements, borrow_set, - pass_where.clone(), + pass_where, out, )?; diff --git a/compiler/rustc_borrowck/src/polonius/loan_liveness.rs b/compiler/rustc_borrowck/src/polonius/loan_liveness.rs index 768c12a97a64e..5cd265e0db92d 100644 --- a/compiler/rustc_borrowck/src/polonius/loan_liveness.rs +++ b/compiler/rustc_borrowck/src/polonius/loan_liveness.rs @@ -175,7 +175,7 @@ impl LocalizedConstraintGraph { } /// Returns the outgoing edges of a given node, not its transitive closure. - fn outgoing_edges(&self, node: LocalizedNode) -> impl Iterator + use<'_> { + fn outgoing_edges(&self, node: LocalizedNode) -> impl Iterator { // The outgoing edges are: // - the physical edges present at this node, // - the materialized logical edges that exist virtually at all points for this node's diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d2268c4779d63..a00fce08c9bac 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -576,9 +576,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns an iterator over all the outlives constraints. - pub(crate) fn outlives_constraints( - &self, - ) -> impl Iterator> + '_ { + pub(crate) fn outlives_constraints(&self) -> impl Iterator> { self.constraints.outlives().iter().copied() } @@ -615,10 +613,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.region_value_str(scc) } - pub(crate) fn placeholders_contained_in<'a>( - &'a self, + pub(crate) fn placeholders_contained_in( + &self, r: RegionVid, - ) -> impl Iterator + 'a { + ) -> impl Iterator { let scc = self.constraint_sccs.scc(r); self.scc_values.placeholders_contained_in(scc) } @@ -1267,6 +1265,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { let sub_region_scc = self.constraint_sccs.scc(sub_region); let sup_region_scc = self.constraint_sccs.scc(sup_region); + if sub_region_scc == sup_region_scc { + debug!("{sup_region:?}: {sub_region:?} holds trivially; they are in the same SCC"); + return true; + } + // If we are checking that `'sup: 'sub`, and `'sub` contains // some placeholder that `'sup` cannot name, then this is only // true if `'sup` outlives static. diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index d0cfe572d0876..b2ed8a3582796 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -20,10 +20,7 @@ pub(crate) struct ReverseSccGraph { impl ReverseSccGraph { /// Find all universal regions that are required to outlive the given SCC. - pub(super) fn upper_bounds<'a>( - &'a self, - scc0: ConstraintSccIndex, - ) -> impl Iterator + 'a { + pub(super) fn upper_bounds(&self, scc0: ConstraintSccIndex) -> impl Iterator { let mut duplicates = FxIndexSet::default(); graph::depth_first_search(&self.graph, scc0) .flat_map(move |scc1| { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index f1bcb353dc61c..d9ac5b5cb132a 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -88,7 +88,7 @@ impl LivenessValues { } /// Iterate through each region that has a value in this set. - pub(crate) fn regions(&self) -> impl Iterator + '_ { + pub(crate) fn regions(&self) -> impl Iterator { self.points.as_ref().expect("use with_specific_points").rows() } @@ -96,7 +96,7 @@ impl LivenessValues { // We are passing query instability implications to the caller. #[rustc_lint_query_instability] #[allow(rustc::potential_query_instability)] - pub(crate) fn live_regions_unordered(&self) -> impl Iterator + '_ { + pub(crate) fn live_regions_unordered(&self) -> impl Iterator { self.live_regions.as_ref().unwrap().iter().copied() } @@ -143,7 +143,7 @@ impl LivenessValues { } /// Returns an iterator of all the points where `region` is live. - fn live_points(&self, region: RegionVid) -> impl Iterator + '_ { + fn live_points(&self, region: RegionVid) -> impl Iterator { let Some(points) = &self.points else { unreachable!( "Should be using LivenessValues::with_specific_points to ask whether live at a location" @@ -340,7 +340,7 @@ impl RegionValues { } /// Returns the locations contained within a given region `r`. - pub(crate) fn locations_outlived_by<'a>(&'a self, r: N) -> impl Iterator + 'a { + pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator { self.points.row(r).into_iter().flat_map(move |set| { set.iter() .take_while(move |&p| self.location_map.point_in_range(p)) @@ -349,18 +349,15 @@ impl RegionValues { } /// Returns just the universal regions that are contained in a given region's value. - pub(crate) fn universal_regions_outlived_by<'a>( - &'a self, - r: N, - ) -> impl Iterator + 'a { + pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator { self.free_regions.row(r).into_iter().flat_map(|set| set.iter()) } /// Returns all the elements contained in a given region's value. - pub(crate) fn placeholders_contained_in<'a>( - &'a self, + pub(crate) fn placeholders_contained_in( + &self, r: N, - ) -> impl Iterator + 'a { + ) -> impl Iterator { self.placeholders .row(r) .into_iter() @@ -369,10 +366,7 @@ impl RegionValues { } /// Returns all the elements contained in a given region's value. - pub(crate) fn elements_contained_in<'a>( - &'a self, - r: N, - ) -> impl Iterator + 'a { + pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); let free_regions_iter = diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index efbae1e153537..eaac633b512d6 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -172,7 +172,7 @@ impl UniversalRegionRelations<'_> { } /// Returns the _non-transitive_ set of known `outlives` constraints between free regions. - pub(crate) fn known_outlives(&self) -> impl Iterator + '_ { + pub(crate) fn known_outlives(&self) -> impl Iterator { self.outlives.base_edges() } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index 6182b68f6f411..9591da83708b7 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -54,7 +54,7 @@ rustc_index::newtype_index! { fn appearances_iter( first: Option, appearances: &Appearances, -) -> impl Iterator + '_ { +) -> impl Iterator { AppearancesIter { appearances, current: first } } @@ -107,17 +107,17 @@ impl LocalUseMap { local_use_map } - pub(crate) fn defs(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn defs(&self, local: Local) -> impl Iterator { appearances_iter(self.first_def_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - pub(crate) fn uses(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn uses(&self, local: Local) -> impl Iterator { appearances_iter(self.first_use_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } - pub(crate) fn drops(&self, local: Local) -> impl Iterator + '_ { + pub(crate) fn drops(&self, local: Local) -> impl Iterator { appearances_iter(self.first_drop_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 62d49a62744e7..12e8be41614bd 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -3,7 +3,8 @@ use rustc_index::bit_set::DenseBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::for_liveness; -use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; +use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, HasLocalDecls, Local, Location}; +use rustc_middle::span_bug; use rustc_middle::traits::query::DropckOutlivesResult; use rustc_middle::ty::relate::Relate; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; @@ -11,7 +12,10 @@ use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex}; use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex}; -use rustc_span::DUMMY_SP; +use rustc_span::{DUMMY_SP, Span}; +use rustc_trait_selection::error_reporting::InferCtxtErrorExt; +use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::traits::query::dropck_outlives; use rustc_trait_selection::traits::query::type_op::{DropckOutlives, TypeOp, TypeOpOutput}; use tracing::debug; @@ -162,9 +166,10 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> { fn dropck_boring_locals(&mut self, boring_locals: Vec) { for local in boring_locals { let local_ty = self.cx.body.local_decls[local].ty; + let local_span = self.cx.body.local_decls[local].source_info.span; let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({ let typeck = &self.cx.typeck; - move || LivenessContext::compute_drop_data(typeck, local_ty) + move || LivenessContext::compute_drop_data(typeck, local_ty, local_span) }); drop_data.dropck_result.report_overflows( @@ -522,9 +527,10 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { values::pretty_print_points(self.location_map, live_at.iter()), ); + let local_span = self.body.local_decls()[dropped_local].source_info.span; let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({ let typeck = &self.typeck; - move || Self::compute_drop_data(typeck, dropped_ty) + move || Self::compute_drop_data(typeck, dropped_ty, local_span) }); if let Some(data) = &drop_data.region_constraint_data { @@ -589,19 +595,50 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { } } - fn compute_drop_data(typeck: &TypeChecker<'_, 'tcx>, dropped_ty: Ty<'tcx>) -> DropData<'tcx> { - debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); + fn compute_drop_data( + typeck: &TypeChecker<'_, 'tcx>, + dropped_ty: Ty<'tcx>, + span: Span, + ) -> DropData<'tcx> { + debug!("compute_drop_data(dropped_ty={:?})", dropped_ty); + + let op = typeck.infcx.param_env.and(DropckOutlives { dropped_ty }); - match typeck - .infcx - .param_env - .and(DropckOutlives { dropped_ty }) - .fully_perform(typeck.infcx, DUMMY_SP) - { + match op.fully_perform(typeck.infcx, DUMMY_SP) { Ok(TypeOpOutput { output, constraints, .. }) => { DropData { dropck_result: output, region_constraint_data: constraints } } - Err(_) => DropData { dropck_result: Default::default(), region_constraint_data: None }, + Err(_) => { + // We don't run dropck on HIR, and dropck looks inside fields of + // types, so there's no guarantee that it succeeds. We also + // can't rely on the the `ErrorGuaranteed` from `fully_perform` here + // because it comes from delay_span_bug. + // + // Do this inside of a probe because we don't particularly care (or want) + // any region side-effects of this operation in our infcx. + typeck.infcx.probe(|_| { + let ocx = ObligationCtxt::new_with_diagnostics(&typeck.infcx); + let errors = match dropck_outlives::compute_dropck_outlives_with_errors( + &ocx, op, span, + ) { + Ok(_) => ocx.select_all_or_error(), + Err(e) => { + if e.is_empty() { + ocx.select_all_or_error() + } else { + e + } + } + }; + + if !errors.is_empty() { + typeck.infcx.err_ctxt().report_fulfillment_errors(errors); + } else { + span_bug!(span, "Rerunning drop data query produced no error."); + } + }); + DropData { dropck_result: Default::default(), region_constraint_data: None } + } } } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 93081919ec79d..bd0d98028ae88 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -19,7 +19,6 @@ use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; use rustc_infer::traits::PredicateObligations; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; @@ -457,38 +456,38 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { self.super_local_decl(local, local_decl); - if let Some(user_ty) = &local_decl.user_ty { - for (user_ty, span) in user_ty.projections_and_spans() { - let ty = if !local_decl.is_nonref_binding() { - // If we have a binding of the form `let ref x: T = ..` - // then remove the outermost reference so we can check the - // type annotation for the remaining type. - if let ty::Ref(_, rty, _) = local_decl.ty.kind() { - *rty - } else { - bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); - } - } else { - local_decl.ty - }; + for user_ty in + local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) + { + let span = self.typeck.user_type_annotations[user_ty.base].span; + + let ty = if local_decl.is_nonref_binding() { + local_decl.ty + } else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() { + // If we have a binding of the form `let ref x: T = ..` + // then remove the outermost reference so we can check the + // type annotation for the remaining type. + rty + } else { + bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty); + }; - if let Err(terr) = self.typeck.relate_type_and_user_type( - ty, - ty::Invariant, - user_ty, - Locations::All(*span), - ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), - ) { - span_mirbug!( - self, - local, - "bad user type on variable {:?}: {:?} != {:?} ({:?})", - local, - local_decl.ty, - local_decl.user_ty, - terr, - ); - } + if let Err(terr) = self.typeck.relate_type_and_user_type( + ty, + ty::Invariant, + user_ty, + Locations::All(span), + ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration), + ) { + span_mirbug!( + self, + local, + "bad user type on variable {:?}: {:?} != {:?} ({:?})", + local, + local_decl.ty, + local_decl.user_ty, + terr, + ); } } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index eb0079a3883f0..cfac9b36832fd 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -21,6 +21,7 @@ use std::iter; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::Diag; use rustc_hir::BodyOwnerKind; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_index::IndexVec; @@ -125,6 +126,11 @@ pub(crate) enum DefiningTy<'tcx> { /// The MIR represents an inline const. The signature has no inputs and a /// single return value found via `InlineConstArgs::ty`. InlineConst(DefId, GenericArgsRef<'tcx>), + + // Fake body for a global asm. Not particularly useful or interesting, + // but we need it so we can properly store the typeck results of the asm + // operands, which aren't associated with a body otherwise. + GlobalAsm(DefId), } impl<'tcx> DefiningTy<'tcx> { @@ -137,9 +143,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(), DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(), DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(), - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => { - ty::List::empty() - } + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => ty::List::empty(), } } @@ -151,7 +158,10 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::Closure(..) | DefiningTy::CoroutineClosure(..) | DefiningTy::Coroutine(..) => 1, - DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0, + DefiningTy::FnDef(..) + | DefiningTy::Const(..) + | DefiningTy::InlineConst(..) + | DefiningTy::GlobalAsm(_) => 0, } } @@ -170,7 +180,8 @@ impl<'tcx> DefiningTy<'tcx> { | DefiningTy::Coroutine(def_id, ..) | DefiningTy::FnDef(def_id, ..) | DefiningTy::Const(def_id, ..) - | DefiningTy::InlineConst(def_id, ..) => def_id, + | DefiningTy::InlineConst(def_id, ..) + | DefiningTy::GlobalAsm(def_id) => def_id, } } } @@ -307,7 +318,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Returns an iterator over all the RegionVids corresponding to /// universally quantified free regions. - pub(crate) fn universal_regions_iter(&self) -> impl Iterator { + pub(crate) fn universal_regions_iter(&self) -> impl Iterator + 'static { (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } @@ -331,9 +342,9 @@ impl<'tcx> UniversalRegions<'tcx> { } /// Gets an iterator over all the early-bound regions that have names. - pub(crate) fn named_universal_regions_iter<'s>( - &'s self, - ) -> impl Iterator, ty::RegionVid)> + 's { + pub(crate) fn named_universal_regions_iter( + &self, + ) -> impl Iterator, ty::RegionVid)> { self.indices.indices.iter().map(|(&r, &v)| (r, v)) } @@ -410,6 +421,7 @@ impl<'tcx> UniversalRegions<'tcx> { tcx.def_path_str_with_args(def_id, args), )); } + DefiningTy::GlobalAsm(_) => unreachable!(), } } @@ -576,7 +588,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; 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) { + match tcx.hir_body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { let defining_ty = tcx.type_of(self.mir_def).instantiate_identity(); @@ -603,7 +615,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id { + if self.mir_def.to_def_id() == typeck_root_def_id + // Do not ICE when checking default_field_values consts with lifetimes (#135649) + && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id)) + { let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args); DefiningTy::Const(self.mir_def.to_def_id(), args) @@ -629,6 +644,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::InlineConst(self.mir_def.to_def_id(), args) } } + + BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()), } } @@ -662,6 +679,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args, + + DefiningTy::GlobalAsm(_) => ty::List::empty(), }; let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); @@ -798,6 +817,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let ty = args.as_inline_const().ty(); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } + + DefiningTy::GlobalAsm(def_id) => { + ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()])) + } }; // FIXME(#129952): We probably want a more principled approach here. diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index b50cb35b8e983..f29be2ee81855 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_builtin_macros" version = "0.0.0" -edition = "2021" +edition = "2024" [lints.rust] diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 24c54edd705a1..8d7ac6de8010b 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -242,6 +242,7 @@ mod llvm_enzyme { defaultness: ast::Defaultness::Final, sig: d_sig, generics: Generics::default(), + contract: None, body: Some(d_body), }); let mut rustc_ad_attr = diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 1a3f4d2d44908..6933ca09349a1 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -19,16 +19,12 @@ pub fn inject( let edition = sess.psess.edition; // the first name in this list is the crate name of the crate with the prelude - let names: &[Symbol] = if attr::contains_name(pre_configured_attrs, sym::no_core) { + let name: Symbol = if attr::contains_name(pre_configured_attrs, sym::no_core) { return 0; } else if attr::contains_name(pre_configured_attrs, sym::no_std) { - if attr::contains_name(pre_configured_attrs, sym::compiler_builtins) { - &[sym::core] - } else { - &[sym::core, sym::compiler_builtins] - } + sym::core } else { - &[sym::std] + sym::std }; let expn_id = resolver.expansion_for_ast_pass( @@ -43,36 +39,16 @@ pub fn inject( let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features); let cx = ExtCtxt::new(sess, ecfg, resolver, None); - // .rev() to preserve ordering above in combination with insert(0, ...) - for &name in names.iter().rev() { - let ident_span = if edition >= Edition2018 { span } else { call_site }; - let item = if name == sym::compiler_builtins { - // compiler_builtins is a private implementation detail. We only - // need to insert it into the crate graph for linking and should not - // expose any of its public API. - // - // FIXME(#113634) We should inject this during post-processing like - // we do for the panic runtime, profiler runtime, etc. - cx.item( - span, - Ident::new(kw::Underscore, ident_span), - thin_vec![], - ast::ItemKind::ExternCrate(Some(name)), - ) - } else { - cx.item( - span, - Ident::new(name, ident_span), - thin_vec![cx.attr_word(sym::macro_use, span)], - ast::ItemKind::ExternCrate(None), - ) - }; - krate.items.insert(0, item); - } + let ident_span = if edition >= Edition2018 { span } else { call_site }; - // The crates have been injected, the assumption is that the first one is - // the one with the prelude. - let name = names[0]; + let item = cx.item( + span, + Ident::new(name, ident_span), + thin_vec![cx.attr_word(sym::macro_use, span)], + ast::ItemKind::ExternCrate(None), + ); + + krate.items.insert(0, item); let root = (edition == Edition2015).then_some(kw::PathRoot); @@ -88,6 +64,7 @@ pub fn inject( .map(|&symbol| Ident::new(symbol, span)) .collect(); + // Inject the relevant crate's prelude. let use_item = cx.item( span, Ident::empty(), diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index e3a9512dda9c6..364a6a035ab88 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -15,9 +15,9 @@ index 7165c3e48af..968552ad435 100644 edition = "2021" [dependencies] - core = { path = "../core" } --compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std', 'no-f16-f128'] } + core = { path = "../core", public = true } +-compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/compiler/rustc_codegen_cranelift/src/abi/comments.rs b/compiler/rustc_codegen_cranelift/src/abi/comments.rs index 521a250ab82cc..c74efeb59f3fc 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/comments.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/comments.rs @@ -65,7 +65,7 @@ pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { if fx.clif_comments.enabled() { fx.add_global_comment(String::new()); fx.add_global_comment( - "kind local ty size align (abi,pref)".to_string(), + "kind local ty size align (abi)".to_string(), ); } } @@ -84,14 +84,13 @@ pub(super) fn add_local_place_comments<'tcx>( let (kind, extra) = place.debug_comment(); fx.add_global_comment(format!( - "{:<5} {:5} {:30} {:4}b {}, {}{}{}", + "{:<5} {:5} {:30} {:4}b {}{}{}", kind, format!("{:?}", local), format!("{:?}", ty), size.bytes(), align.abi.bytes(), - align.pref.bytes(), - if extra.is_empty() { "" } else { " " }, + if extra.is_empty() { "" } else { " " }, extra, )); } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 425b2adf32a37..bcc70f4567fbd 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -272,7 +272,7 @@ fn data_id_for_static( .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) .unwrap() .align - .pref + .abi .bytes(); let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 54745b0d8c104..9ea92c300f898 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -16,7 +16,7 @@ use crate::prelude::*; pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) { let item = tcx.hir_item(item_id); - if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind { + if let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind { let is_x86 = matches!(tcx.sess.asm_arch.unwrap(), InlineAsmArch::X86 | InlineAsmArch::X86_64); @@ -55,7 +55,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, } } } - InlineAsmOperand::SymFn { anon_const } => { + InlineAsmOperand::SymFn { expr } => { if cfg!(not(feature = "inline_asm_sym")) { tcx.dcx().span_err( item.span, @@ -63,7 +63,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + let ty = tcx.typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { &ty::FnDef(def_id, args) => Instance::new(def_id, args), _ => span_bug!(op_sp, "asm sym is not a function"), diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 26f14532b458e..4d9bed8652cbd 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -340,14 +340,10 @@ fn codegen_float_intrinsic_call<'tcx>( sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), - sym::rintf32 => ("rintf", 1, fx.tcx.types.f32, types::F32), - sym::rintf64 => ("rint", 1, fx.tcx.types.f64, types::F64), + sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32), + sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64), sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), - sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32), - sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64), - sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32), - sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), @@ -399,8 +395,8 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::ceilf64 | sym::truncf32 | sym::truncf64 - | sym::nearbyintf32 - | sym::nearbyintf64 + | sym::round_ties_even_f32 + | sym::round_ties_even_f64 | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { @@ -408,7 +404,9 @@ fn codegen_float_intrinsic_call<'tcx>( sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), - sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]), + sym::round_ties_even_f32 | sym::round_ties_even_f64 => { + fx.bcx.ins().nearest(args[0]) + } sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), _ => unreachable!(), }; diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index a9b8e1bd39353..1b3f86c8405de 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -638,9 +638,7 @@ impl<'tcx> CPlace<'tcx> { } CPlaceInner::Addr(_, Some(_)) => bug!("Can't write value to unsized place {:?}", self), CPlaceInner::Addr(to_ptr, None) => { - if dst_layout.size == Size::ZERO - || dst_layout.backend_repr == BackendRepr::Uninhabited - { + if dst_layout.size == Size::ZERO { return; } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index b8e37b604801f..c8b7616e64509 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -989,10 +989,14 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { OperandValue::Ref(place.val) } else if place.layout.is_gcc_immediate() { let load = self.load(place.layout.gcc_type(self), place.val.llval, place.val.align); - if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { - scalar_load_metadata(self, load, scalar); - } - OperandValue::Immediate(self.to_immediate(load, place.layout)) + OperandValue::Immediate( + if let abi::BackendRepr::Scalar(ref scalar) = place.layout.backend_repr { + scalar_load_metadata(self, load, scalar); + self.to_immediate_scalar(load, *scalar) + } else { + load + }, + ) } else if let abi::BackendRepr::ScalarPair(ref a, ref b) = place.layout.backend_repr { let b_offset = a.size(self).align_to(b.align(self).abi); @@ -1694,7 +1698,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { if scalar.is_bool() { - return self.trunc(val, self.cx().type_i1()); + return self.unchecked_utrunc(val, self.cx().type_i1()); } val } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index a1123fafe2f30..f8672c0729998 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -9,7 +9,7 @@ use gccjit::FunctionType; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; -use rustc_abi::HasDataLayout; +use rustc_abi::{BackendRepr, HasDataLayout}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; @@ -84,14 +84,11 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::ceilf64 => "ceil", sym::truncf32 => "truncf", sym::truncf64 => "trunc", - sym::rintf32 => "rintf", - sym::rintf64 => "rint", - sym::nearbyintf32 => "nearbyintf", - sym::nearbyintf64 => "nearbyint", + // We match the LLVM backend and lower this to `rint`. + sym::round_ties_even_f32 => "rintf", + sym::round_ties_even_f64 => "rint", sym::roundf32 => "roundf", sym::roundf64 => "round", - sym::roundevenf32 => "roundevenf", - sym::roundevenf64 => "roundeven", sym::abort => "abort", _ => return None, }; @@ -181,14 +178,19 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc sym::volatile_load | sym::unaligned_volatile_load => { let tp_ty = fn_args.type_at(0); let ptr = args[0].immediate(); + let layout = self.layout_of(tp_ty); let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode { let gcc_ty = ty.gcc_type(self); self.volatile_load(gcc_ty, ptr) } else { - self.volatile_load(self.layout_of(tp_ty).gcc_type(self), ptr) + self.volatile_load(layout.gcc_type(self), ptr) }; // TODO(antoyo): set alignment. - self.to_immediate(load, self.layout_of(tp_ty)) + if let BackendRepr::Scalar(scalar) = layout.backend_repr { + self.to_immediate_scalar(load, scalar) + } else { + load + } } sym::volatile_store => { let dst = args[0].deref(self.cx()); @@ -310,7 +312,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 8b8b54753e7fd..bac4fc51300a2 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -84,7 +84,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( false, ); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} + BackendRepr::Memory { .. } => {} } let name = match *layout.ty.kind() { @@ -179,19 +179,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_gcc_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 94f21ac5f5742..d3ce7c5a1130f 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_llvm" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] test = false @@ -25,6 +25,7 @@ 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_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_llvm = { path = "../rustc_llvm" } diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 399d7ffea8e6d..17f2e7ca9f702 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -1,3 +1,4 @@ +codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable codegen_llvm_autodiff_without_lto = using the autodiff feature requires using fat-lto codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 28f423efc2141..8c75125e009b9 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -2,19 +2,18 @@ use std::borrow::Borrow; use std::cmp; use libc::c_uint; -use rustc_abi as abi; -pub(crate) use rustc_abi::ExternAbi; -use rustc_abi::{HasDataLayout, Primitive, Reg, RegKind, Size}; +use rustc_abi::{BackendRepr, HasDataLayout, Primitive, Reg, RegKind, Size}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; -pub(crate) use rustc_middle::ty::layout::{WIDE_PTR_ADDR, WIDE_PTR_EXTRA}; use rustc_middle::{bug, ty}; use rustc_session::config; -pub(crate) use rustc_target::callconv::*; +use rustc_target::callconv::{ + ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, Conv, FnAbi, PassMode, +}; use rustc_target::spec::SanitizerSet; use smallvec::SmallVec; @@ -458,7 +457,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { match &self.ret.mode { PassMode::Direct(attrs) => { attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn); - if let abi::BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr { + if let BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr { apply_range_attr(llvm::AttributePlace::ReturnValue, scalar); } } @@ -499,7 +498,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } PassMode::Direct(attrs) => { let i = apply(attrs); - if let abi::BackendRepr::Scalar(scalar) = arg.layout.backend_repr { + if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar); } } @@ -514,9 +513,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { PassMode::Pair(a, b) => { let i = apply(a); let ii = apply(b); - if let abi::BackendRepr::ScalarPair(scalar_a, scalar_b) = - arg.layout.backend_repr - { + if let BackendRepr::ScalarPair(scalar_a, scalar_b) = arg.layout.backend_repr { apply_range_attr(llvm::AttributePlace::Argument(i), scalar_a); apply_range_attr(llvm::AttributePlace::Argument(ii), scalar_b); } @@ -576,7 +573,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } if bx.cx.sess().opts.optimize != config::OptLevel::No && llvm_util::get_version() < (19, 0, 0) - && let abi::BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr + && let BackendRepr::Scalar(scalar) = self.ret.layout.backend_repr && matches!(scalar.primitive(), Primitive::Int(..)) // If the value is a boolean, the range is 0..2 and that ultimately // become 0..0 when the type becomes i1, which would be rejected diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 7262fce491191..99906ea7bce39 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -362,8 +362,8 @@ fn fat_lto( ptr as *const *const libc::c_char, symbols_below_threshold.len() as libc::size_t, ); - save_temp_bitcode(cgcx, &module, "lto.after-restriction"); } + save_temp_bitcode(cgcx, &module, "lto.after-restriction"); } Ok(LtoModuleCodegen::Fat(module)) @@ -586,6 +586,42 @@ fn thin_lto( } } +fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen) { + for &val in ad { + match val { + config::AutoDiff::PrintModBefore => { + unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; + } + config::AutoDiff::PrintPerf => { + llvm::set_print_perf(true); + } + config::AutoDiff::PrintAA => { + llvm::set_print_activity(true); + } + config::AutoDiff::PrintTA => { + llvm::set_print_type(true); + } + config::AutoDiff::Inline => { + llvm::set_inline(true); + } + config::AutoDiff::LooseTypes => { + llvm::set_loose_types(false); + } + config::AutoDiff::PrintSteps => { + llvm::set_print(true); + } + // We handle this below + config::AutoDiff::PrintModAfter => {} + // This is required and already checked + config::AutoDiff::Enable => {} + } + } + // This helps with handling enums for now. + llvm::set_strict_aliasing(false); + // FIXME(ZuseZ4): Test this, since it was added a long time ago. + llvm::set_rust_rules(true); +} + pub(crate) fn run_pass_manager( cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>, @@ -604,34 +640,37 @@ pub(crate) fn run_pass_manager( let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO }; let opt_level = config.opt_level.unwrap_or(config::OptLevel::No); - // If this rustc version was build with enzyme/autodiff enabled, and if users applied the - // `#[autodiff]` macro at least once, then we will later call llvm_optimize a second time. - debug!("running llvm pm opt pipeline"); + // The PostAD behavior is the same that we would have if no autodiff was used. + // It will run the default optimization pipeline. If AD is enabled we select + // the DuringAD stage, which will disable vectorization and loop unrolling, and + // schedule two autodiff optimization + differentiation passes. + // We then run the llvm_optimize function a second time, to optimize the code which we generated + // in the enzyme differentiation pass. + let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable); + let stage = + if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }; + + if enable_ad { + enable_autodiff_settings(&config.autodiff, module); + } + unsafe { - write::llvm_optimize( - cgcx, - dcx, - module, - config, - opt_level, - opt_stage, - write::AutodiffStage::DuringAD, - )?; + write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; } - // FIXME(ZuseZ4): Make this more granular - if cfg!(llvm_enzyme) && !thin { + + if cfg!(llvm_enzyme) && enable_ad { + let opt_stage = llvm::OptStage::FatLTO; + let stage = write::AutodiffStage::PostAD; unsafe { - write::llvm_optimize( - cgcx, - dcx, - module, - config, - opt_level, - llvm::OptStage::FatLTO, - write::AutodiffStage::PostAD, - )?; + write::llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, stage)?; + } + + // This is the final IR, so people should be able to inspect the optimized autodiff output. + if config.autodiff.contains(&config::AutoDiff::PrintModAfter) { + unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; } } + debug!("lto done"); Ok(()) } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 9fa10e960680b..b67890c046572 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -564,19 +564,16 @@ pub(crate) unsafe fn llvm_optimize( // FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting // differentiated. + let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; let unroll_loops; let vectorize_slp; let vectorize_loop; - let run_enzyme = cfg!(llvm_enzyme) && autodiff_stage == AutodiffStage::DuringAD; // When we build rustc with enzyme/autodiff support, we want to postpone size-increasing // optimizations until after differentiation. Our pipeline is thus: (opt + enzyme), (full opt). // We therefore have two calls to llvm_optimize, if autodiff is used. - // - // FIXME(ZuseZ4): Before shipping on nightly, - // we should make this more granular, or at least check that the user has at least one autodiff - // call in their code, to justify altering the compilation pipeline. - if cfg!(llvm_enzyme) && autodiff_stage != AutodiffStage::PostAD { + if consider_ad && autodiff_stage != AutodiffStage::PostAD { unroll_loops = false; vectorize_slp = false; vectorize_loop = false; @@ -706,10 +703,8 @@ pub(crate) unsafe fn optimize( // If we know that we will later run AD, then we disable vectorization and loop unrolling. // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). - // FIXME(ZuseZ4): Make this more granular, only set PreAD if we actually have autodiff - // usages, not just if we build rustc with autodiff support. - let autodiff_stage = - if cfg!(llvm_enzyme) { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; + let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; return unsafe { llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage, autodiff_stage) }; diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 57f09b1fa2fd2..677a9cd3e90ea 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -4,7 +4,7 @@ use std::{iter, ptr}; pub(crate) mod autodiff; -use libc::{c_char, c_uint}; +use libc::{c_char, c_uint, size_t}; use rustc_abi as abi; use rustc_abi::{Align, Size, WrappingRange}; use rustc_codegen_ssa::MemFlags; @@ -29,13 +29,15 @@ use smallvec::SmallVec; use tracing::{debug, instrument}; use crate::abi::FnAbiLlvmExt; -use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, SimpleCx}; -use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True}; +use crate::llvm::{ + self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, GEPNoWrapFlags, Metadata, True, +}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; +use crate::{attributes, llvm_util}; #[must_use] pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { @@ -333,6 +335,50 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn switch_with_weights( + &mut self, + v: Self::Value, + else_llbb: Self::BasicBlock, + else_is_cold: bool, + cases: impl ExactSizeIterator, + ) { + if self.cx.sess().opts.optimize == rustc_session::config::OptLevel::No { + self.switch(v, else_llbb, cases.map(|(val, dest, _)| (val, dest))); + return; + } + + let id_str = "branch_weights"; + let id = unsafe { + llvm::LLVMMDStringInContext2(self.cx.llcx, id_str.as_ptr().cast(), id_str.len()) + }; + + // For switch instructions with 2 targets, the `llvm.expect` intrinsic is used. + // This function handles switch instructions with more than 2 targets and it needs to + // emit branch weights metadata instead of using the intrinsic. + // The values 1 and 2000 are the same as the values used by the `llvm.expect` intrinsic. + let cold_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(1)) }; + let hot_weight = unsafe { llvm::LLVMValueAsMetadata(self.cx.const_u32(2000)) }; + let weight = + |is_cold: bool| -> &Metadata { if is_cold { cold_weight } else { hot_weight } }; + + let mut md: SmallVec<[&Metadata; 16]> = SmallVec::with_capacity(cases.len() + 2); + md.push(id); + md.push(weight(else_is_cold)); + + let switch = + unsafe { llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint) }; + for (on_val, dest, is_cold) in cases { + let on_val = self.const_uint_big(self.val_ty(v), on_val); + unsafe { llvm::LLVMAddCase(switch, on_val, dest) } + md.push(weight(is_cold)); + } + + unsafe { + let md_node = llvm::LLVMMDNodeInContext2(self.cx.llcx, md.as_ptr(), md.len() as size_t); + self.cx.set_metadata(switch, llvm::MD_prof, md_node); + } + } + fn invoke( &mut self, llty: &'ll Type, @@ -562,7 +608,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value { if scalar.is_bool() { - return self.trunc(val, self.cx().type_i1()); + return self.unchecked_utrunc(val, self.cx().type_i1()); } val } @@ -702,10 +748,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let load = self.load(llty, place.val.llval, place.val.align); if let abi::BackendRepr::Scalar(scalar) = place.layout.backend_repr { scalar_load_metadata(self, load, scalar, place.layout, Size::ZERO); + self.to_immediate_scalar(load, scalar) + } else { + load } - load }); - OperandValue::Immediate(self.to_immediate(llval, place.layout)) + OperandValue::Immediate(llval) } else if let abi::BackendRepr::ScalarPair(a, b) = place.layout.backend_repr { let b_offset = a.size(self).align_to(b.align(self).abi); @@ -864,13 +912,14 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn gep(&mut self, ty: &'ll Type, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value { unsafe { - llvm::LLVMBuildGEP2( + llvm::LLVMBuildGEPWithNoWrapFlags( self.llbuilder, ty, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED, + GEPNoWrapFlags::default(), ) } } @@ -882,13 +931,33 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { indices: &[&'ll Value], ) -> &'ll Value { unsafe { - llvm::LLVMBuildInBoundsGEP2( + llvm::LLVMBuildGEPWithNoWrapFlags( self.llbuilder, ty, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED, + GEPNoWrapFlags::InBounds, + ) + } + } + + fn inbounds_nuw_gep( + &mut self, + ty: &'ll Type, + ptr: &'ll Value, + indices: &[&'ll Value], + ) -> &'ll Value { + unsafe { + llvm::LLVMBuildGEPWithNoWrapFlags( + self.llbuilder, + ty, + ptr, + indices.as_ptr(), + indices.len() as c_uint, + UNNAMED, + GEPNoWrapFlags::InBounds | GEPNoWrapFlags::NUW, ) } } @@ -898,6 +967,34 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) } } + fn unchecked_utrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + debug_assert_ne!(self.val_ty(val), dest_ty); + + let trunc = self.trunc(val, dest_ty); + if llvm_util::get_version() >= (19, 0, 0) { + unsafe { + if llvm::LLVMIsAInstruction(trunc).is_some() { + llvm::LLVMSetNUW(trunc, True); + } + } + } + trunc + } + + fn unchecked_strunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + debug_assert_ne!(self.val_ty(val), dest_ty); + + let trunc = self.trunc(val, dest_ty); + if llvm_util::get_version() >= (19, 0, 0) { + unsafe { + if llvm::LLVMIsAInstruction(trunc).is_some() { + llvm::LLVMSetNSW(trunc, True); + } + } + } + trunc + } + fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED) } } diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index b2c1088e3fc02..2c7899975e3ee 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -10,7 +10,7 @@ use crate::back::write::llvm_err; use crate::builder::SBuilder; use crate::context::SimpleCx; use crate::declare::declare_simple_fn; -use crate::errors::LlvmError; +use crate::errors::{AutoDiffWithoutEnable, LlvmError}; use crate::llvm::AttributePlace::Function; use crate::llvm::{Metadata, True}; use crate::value::Value; @@ -46,9 +46,6 @@ fn generate_enzyme_call<'ll>( let output = attrs.ret_activity; // We have to pick the name depending on whether we want forward or reverse mode autodiff. - // FIXME(ZuseZ4): The new pass based approach should not need the {Forward/Reverse}First method anymore, since - // it will handle higher-order derivatives correctly automatically (in theory). Currently - // higher-order derivatives fail, so we should debug that before adjusting this code. let mut ad_name: String = match attrs.mode { DiffMode::Forward => "__enzyme_fwddiff", DiffMode::Reverse => "__enzyme_autodiff", @@ -291,6 +288,14 @@ pub(crate) fn differentiate<'ll>( let diag_handler = cgcx.create_dcx(); let cx = SimpleCx { llmod: module.module_llvm.llmod(), llcx: module.module_llvm.llcx }; + // First of all, did the user try to use autodiff without using the -Zautodiff=Enable flag? + if !diff_items.is_empty() + && !cgcx.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) + { + let dcx = cgcx.create_dcx(); + return Err(dcx.handle().emit_almost_fatal(AutoDiffWithoutEnable)); + } + // Before dumping the module, we want all the TypeTrees to become part of the module. for item in diff_items.iter() { let name = item.source.clone(); diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index aa9a0f34f55e9..ea9ab5c02bd6c 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -66,9 +66,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t // LLVM will prefix the name with `__imp_`. Ideally, we'd like the // existing logic below to set the Storage Class, but it has an // exemption for MinGW for backwards compatibility. - unsafe { - llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(llfn); llfn } else { cx.declare_fn(sym, fn_abi, Some(instance)) @@ -99,65 +97,61 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t // has been applied to the definition (wherever that definition may be). llvm::set_linkage(llfn, llvm::Linkage::ExternalLinkage); - unsafe { - let is_generic = instance.args.non_erasable_generics().next().is_some(); - - let is_hidden = if is_generic { - // This is a monomorphization of a generic function. - if !(cx.tcx.sess.opts.share_generics() - || tcx.codegen_fn_attrs(instance_def_id).inline - == rustc_attr_parsing::InlineAttr::Never) - { - // When not sharing generics, all instances are in the same - // crate and have hidden visibility. - true - } else { - if let Some(instance_def_id) = instance_def_id.as_local() { - // This is a monomorphization of a generic function - // defined in the current crate. It is hidden if: - // - the definition is unreachable for downstream - // crates, or - // - the current crate does not re-export generics - // (because the crate is a C library or executable) - cx.tcx.is_unreachable_local_definition(instance_def_id) - || !cx.tcx.local_crate_exports_generics() - } else { - // This is a monomorphization of a generic function - // defined in an upstream crate. It is hidden if: - // - it is instantiated in this crate, and - // - the current crate does not re-export generics - instance.upstream_monomorphization(tcx).is_none() - && !cx.tcx.local_crate_exports_generics() - } - } - } else { - // This is a non-generic function. It is hidden if: - // - it is instantiated in the local crate, and - // - it is defined an upstream crate (non-local), or - // - it is not reachable - cx.tcx.is_codegened_item(instance_def_id) - && (!instance_def_id.is_local() - || !cx.tcx.is_reachable_non_generic(instance_def_id)) - }; - if is_hidden { - llvm::set_visibility(llfn, llvm::Visibility::Hidden); - } + let is_generic = instance.args.non_erasable_generics().next().is_some(); - // MinGW: For backward compatibility we rely on the linker to decide whether it - // should use dllimport for functions. - if cx.use_dll_storage_attrs - && let Some(library) = tcx.native_library(instance_def_id) - && library.kind.is_dllimport() - && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") + let is_hidden = if is_generic { + // This is a monomorphization of a generic function. + if !(cx.tcx.sess.opts.share_generics() + || tcx.codegen_fn_attrs(instance_def_id).inline + == rustc_attr_parsing::InlineAttr::Never) { - llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); + // When not sharing generics, all instances are in the same + // crate and have hidden visibility. + true + } else { + if let Some(instance_def_id) = instance_def_id.as_local() { + // This is a monomorphization of a generic function + // defined in the current crate. It is hidden if: + // - the definition is unreachable for downstream + // crates, or + // - the current crate does not re-export generics + // (because the crate is a C library or executable) + cx.tcx.is_unreachable_local_definition(instance_def_id) + || !cx.tcx.local_crate_exports_generics() + } else { + // This is a monomorphization of a generic function + // defined in an upstream crate. It is hidden if: + // - it is instantiated in this crate, and + // - the current crate does not re-export generics + instance.upstream_monomorphization(tcx).is_none() + && !cx.tcx.local_crate_exports_generics() + } } + } else { + // This is a non-generic function. It is hidden if: + // - it is instantiated in the local crate, and + // - it is defined an upstream crate (non-local), or + // - it is not reachable + cx.tcx.is_codegened_item(instance_def_id) + && (!instance_def_id.is_local() + || !cx.tcx.is_reachable_non_generic(instance_def_id)) + }; + if is_hidden { + llvm::set_visibility(llfn, llvm::Visibility::Hidden); + } - if cx.should_assume_dso_local(llfn, true) { - llvm::LLVMRustSetDSOLocal(llfn, true); - } + // MinGW: For backward compatibility we rely on the linker to decide whether it + // should use dllimport for functions. + if cx.use_dll_storage_attrs + && let Some(library) = tcx.native_library(instance_def_id) + && library.kind.is_dllimport() + && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc") + { + llvm::set_dllimport_storage_class(llfn); } + cx.assume_dso_local(llfn, true); + llfn }; diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 78b3a7f85417b..f17d98fa242b7 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -7,7 +7,8 @@ use rustc_abi::{AddressSpace, HasDataLayout}; use rustc_ast::Mutability; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash128; use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 4a5491ec7a18c..330e8a8f4069d 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -336,12 +336,7 @@ impl<'ll> CodegenCx<'ll, '_> { llvm::set_thread_local_mode(g, self.tls_model); } - let dso_local = self.should_assume_dso_local(g, true); - if dso_local { - unsafe { - llvm::LLVMRustSetDSOLocal(g, true); - } - } + let dso_local = self.assume_dso_local(g, true); if !def_id.is_local() { let needs_dll_storage_attr = self.use_dll_storage_attrs @@ -375,9 +370,7 @@ impl<'ll> CodegenCx<'ll, '_> { // is actually present in the current crate. We can find out via the // is_codegened_item query. if !self.tcx.is_codegened_item(def_id) { - unsafe { - llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(g); } } } @@ -387,9 +380,7 @@ impl<'ll> CodegenCx<'ll, '_> { && library.kind.is_dllimport() { // For foreign (native) libs we know the exact storage type to use. - unsafe { - llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); - } + llvm::set_dllimport_storage_class(g); } self.instances.borrow_mut().insert(instance, g); @@ -460,9 +451,7 @@ impl<'ll> CodegenCx<'ll, '_> { set_global_alignment(self, g, alloc.align); llvm::set_initializer(g, v); - if self.should_assume_dso_local(g, true) { - llvm::LLVMRustSetDSOLocal(g, true); - } + self.assume_dso_local(g, true); // Forward the allocation's mutability (picked by the const interner) to LLVM. if alloc.mutability.is_not() { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 54c5d445f66bd..4ffe551df09b5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -87,7 +87,7 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>( pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); + attr::contains_name(cx.tcx.hir_krate_attrs(), sym::omit_gdb_pretty_printer_section); // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create // ODR violations at link time, this section will not be emitted for rlibs since diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 59c3fe635d070..98d59f5a8ae06 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -11,7 +11,9 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; -use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf, TyAndLayout}; +use rustc_middle::ty::layout::{ + HasTypingEnv, LayoutOf, TyAndLayout, WIDE_PTR_ADDR, WIDE_PTR_EXTRA, +}; use rustc_middle::ty::{ self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; @@ -34,12 +36,12 @@ use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::dwarf_const; use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; +use crate::llvm; use crate::llvm::debuginfo::{ DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind, DebugNameTableKind, }; use crate::value::Value; -use crate::{abi, llvm}; impl PartialEq for llvm::Metadata { fn eq(&self, other: &Self) -> bool { @@ -211,16 +213,16 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( }; let layout = cx.layout_of(layout_type); - let addr_field = layout.field(cx, abi::WIDE_PTR_ADDR); - let extra_field = layout.field(cx, abi::WIDE_PTR_EXTRA); + let addr_field = layout.field(cx, WIDE_PTR_ADDR); + let extra_field = layout.field(cx, WIDE_PTR_EXTRA); let (addr_field_name, extra_field_name) = match wide_pointer_kind { WidePtrKind::Dyn => ("pointer", "vtable"), WidePtrKind::Slice => ("data_ptr", "length"), }; - assert_eq!(abi::WIDE_PTR_ADDR, 0); - assert_eq!(abi::WIDE_PTR_EXTRA, 1); + assert_eq!(WIDE_PTR_ADDR, 0); + assert_eq!(WIDE_PTR_EXTRA, 1); // The data pointer type is a regular, thin pointer, regardless of whether this // is a slice or a trait object. @@ -242,7 +244,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( owner, addr_field_name, (addr_field.size, addr_field.align.abi), - layout.fields.offset(abi::WIDE_PTR_ADDR), + layout.fields.offset(WIDE_PTR_ADDR), DIFlags::FlagZero, data_ptr_type_di_node, None, @@ -252,7 +254,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( owner, extra_field_name, (extra_field.size, extra_field.align.abi), - layout.fields.offset(abi::WIDE_PTR_EXTRA), + layout.fields.offset(WIDE_PTR_EXTRA), DIFlags::FlagZero, type_di_node(cx, extra_field.ty), None, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 17f2d5f4e731f..10819a53b1df8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -22,6 +22,7 @@ use rustc_session::config::{self, DebugInfo}; use rustc_span::{ BytePos, Pos, SourceFile, SourceFileAndLine, SourceFileHash, Span, StableSourceFileId, Symbol, }; +use rustc_target::callconv::FnAbi; use rustc_target::spec::DebuginfoKind; use smallvec::SmallVec; use tracing::debug; @@ -29,7 +30,6 @@ use tracing::debug; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node}; use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; -use crate::abi::FnAbi; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index cebceef1b93f8..e79662ebc6472 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -16,10 +16,11 @@ use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods; use rustc_data_structures::fx::FxIndexSet; use rustc_middle::ty::{Instance, Ty}; use rustc_sanitizers::{cfi, kcfi}; +use rustc_target::callconv::FnAbi; use smallvec::SmallVec; use tracing::debug; -use crate::abi::{FnAbi, FnAbiLlvmExt}; +use crate::abi::FnAbiLlvmExt; use crate::common::AsCCharPtr; use crate::context::{CodegenCx, SimpleCx}; use crate::llvm::AttributePlace::Function; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 97f4925616595..4c5a78ca74fe4 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -92,9 +92,12 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { #[derive(Diagnostic)] #[diag(codegen_llvm_autodiff_without_lto)] -#[note] pub(crate) struct AutoDiffWithoutLTO; +#[derive(Diagnostic)] +#[diag(codegen_llvm_autodiff_without_enable)] +pub(crate) struct AutoDiffWithoutEnable; + #[derive(Diagnostic)] #[diag(codegen_llvm_lto_disallowed)] pub(crate) struct LtoDisallowed; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 8b97688590456..dfbb5bc1731df 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1,7 +1,7 @@ use std::assert_matches::assert_matches; use std::cmp::Ordering; -use rustc_abi::{self as abi, Align, Float, HasDataLayout, Primitive, Size}; +use rustc_abi::{Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size}; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization}; @@ -14,10 +14,11 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; +use rustc_target::callconv::{FnAbi, PassMode}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use tracing::debug; -use crate::abi::{ExternAbi, FnAbi, FnAbiLlvmExt, LlvmType, PassMode}; +use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::builder::Builder; use crate::context::CodegenCx; use crate::llvm::{self, Metadata}; @@ -126,15 +127,14 @@ fn get_simple_intrinsic<'ll>( sym::truncf64 => "llvm.trunc.f64", sym::truncf128 => "llvm.trunc.f128", - sym::rintf16 => "llvm.rint.f16", - sym::rintf32 => "llvm.rint.f32", - sym::rintf64 => "llvm.rint.f64", - sym::rintf128 => "llvm.rint.f128", - - sym::nearbyintf16 => "llvm.nearbyint.f16", - sym::nearbyintf32 => "llvm.nearbyint.f32", - sym::nearbyintf64 => "llvm.nearbyint.f64", - sym::nearbyintf128 => "llvm.nearbyint.f128", + // We could use any of `rint`, `nearbyint`, or `roundeven` + // for this -- they are all identical in semantics when + // assuming the default FP environment. + // `rint` is what we used for $forever. + sym::round_ties_even_f16 => "llvm.rint.f16", + sym::round_ties_even_f32 => "llvm.rint.f32", + sym::round_ties_even_f64 => "llvm.rint.f64", + sym::round_ties_even_f128 => "llvm.rint.f128", sym::roundf16 => "llvm.round.f16", sym::roundf32 => "llvm.round.f32", @@ -143,11 +143,6 @@ fn get_simple_intrinsic<'ll>( sym::ptr_mask => "llvm.ptrmask", - sym::roundevenf16 => "llvm.roundeven.f16", - sym::roundevenf32 => "llvm.roundeven.f32", - sym::roundevenf64 => "llvm.roundeven.f64", - sym::roundevenf128 => "llvm.roundeven.f128", - _ => return None, }; Some(cx.get_intrinsic(llvm_name)) @@ -257,7 +252,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::va_arg => { match fn_abi.ret.layout.backend_repr { - abi::BackendRepr::Scalar(scalar) => { + BackendRepr::Scalar(scalar) => { match scalar.primitive() { Primitive::Int(..) => { if self.cx().size_of(ret_ty).bytes() < 4 { @@ -470,12 +465,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } sym::raw_eq => { - use abi::BackendRepr::*; + use BackendRepr::*; let tp_ty = fn_args.type_at(0); let layout = self.layout_of(tp_ty).layout; let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - Uninhabited | Vector { .. } => false, + Vector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), @@ -582,8 +577,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } let llret_ty = if ret_ty.is_simd() - && let abi::BackendRepr::Memory { .. } = - self.layout_of(ret_ty).layout.backend_repr + && let BackendRepr::Memory { .. } = self.layout_of(ret_ty).layout.backend_repr { let (size, elem_ty) = ret_ty.simd_size_and_type(self.tcx()); let elem_ll_ty = match elem_ty.kind() { diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 39bac13a9680c..3c2c6964a3d79 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -7,7 +7,7 @@ use super::ffi::{BasicBlock, Metadata, Module, Type, Value}; use crate::llvm::Bool; #[link(name = "llvm-wrapper", kind = "static")] -extern "C" { +unsafe extern "C" { // Enzyme pub(crate) fn LLVMRustHasMetadata(I: &Value, KindID: c_uint) -> bool; pub(crate) fn LLVMRustEraseInstUntilInclusive(BB: &BasicBlock, I: &Value); @@ -18,7 +18,7 @@ extern "C" { pub(crate) fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool; } -extern "C" { +unsafe extern "C" { // Enzyme pub(crate) fn LLVMDumpModule(M: &Module); pub(crate) fn LLVMDumpValue(V: &Value); @@ -35,3 +35,97 @@ pub enum LLVMRustVerifierFailureAction { LLVMPrintMessageAction = 1, LLVMReturnStatusAction = 2, } + +#[cfg(llvm_enzyme)] +pub use self::Enzyme_AD::*; + +#[cfg(llvm_enzyme)] +pub mod Enzyme_AD { + use libc::c_void; + extern "C" { + pub fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); + } + extern "C" { + static mut EnzymePrintPerf: c_void; + static mut EnzymePrintActivity: c_void; + static mut EnzymePrintType: c_void; + static mut EnzymePrint: c_void; + static mut EnzymeStrictAliasing: c_void; + static mut looseTypeAnalysis: c_void; + static mut EnzymeInline: c_void; + static mut RustTypeRules: c_void; + } + pub fn set_print_perf(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8); + } + } + pub fn set_print_activity(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8); + } + } + pub fn set_print_type(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8); + } + } + pub fn set_print(print: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8); + } + } + pub fn set_strict_aliasing(strict: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8); + } + } + pub fn set_loose_types(loose: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8); + } + } + pub fn set_inline(val: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8); + } + } + pub fn set_rust_rules(val: bool) { + unsafe { + EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8); + } + } +} + +#[cfg(not(llvm_enzyme))] +pub use self::Fallback_AD::*; + +#[cfg(not(llvm_enzyme))] +pub mod Fallback_AD { + #![allow(unused_variables)] + + pub fn set_inline(val: bool) { + unimplemented!() + } + pub fn set_print_perf(print: bool) { + unimplemented!() + } + pub fn set_print_activity(print: bool) { + unimplemented!() + } + pub fn set_print_type(print: bool) { + unimplemented!() + } + pub fn set_print(print: bool) { + unimplemented!() + } + pub fn set_strict_aliasing(strict: bool) { + unimplemented!() + } + pub fn set_loose_types(loose: bool) { + unimplemented!() + } + pub fn set_rust_rules(val: bool) { + unimplemented!() + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3b0187b9d37b1..da91e6edbcfb8 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -954,6 +954,17 @@ bitflags! { } } +// These values **must** match with LLVMGEPNoWrapFlags +bitflags! { + #[repr(transparent)] + #[derive(Default)] + pub struct GEPNoWrapFlags : c_uint { + const InBounds = 1 << 0; + const NUSW = 1 << 1; + const NUW = 1 << 2; + } +} + unsafe extern "C" { pub type ModuleBuffer; } @@ -1454,21 +1465,14 @@ unsafe extern "C" { pub(crate) fn LLVMBuildStore<'a>(B: &Builder<'a>, Val: &'a Value, Ptr: &'a Value) -> &'a Value; - pub(crate) fn LLVMBuildGEP2<'a>( - B: &Builder<'a>, - Ty: &'a Type, - Pointer: &'a Value, - Indices: *const &'a Value, - NumIndices: c_uint, - Name: *const c_char, - ) -> &'a Value; - pub(crate) fn LLVMBuildInBoundsGEP2<'a>( + pub(crate) fn LLVMBuildGEPWithNoWrapFlags<'a>( B: &Builder<'a>, Ty: &'a Type, Pointer: &'a Value, Indices: *const &'a Value, NumIndices: c_uint, Name: *const c_char, + Flags: GEPNoWrapFlags, ) -> &'a Value; // Casts diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index efc9cf2ef691b..5ec934241314c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -403,3 +403,15 @@ pub(crate) fn add_module_flag_str( ); } } + +pub(crate) fn set_dllimport_storage_class<'ll>(v: &'ll Value) { + unsafe { + LLVMSetDLLStorageClass(v, DLLStorageClass::DllImport); + } +} + +pub(crate) fn set_dso_local<'ll>(v: &'ll Value) { + unsafe { + LLVMRustSetDSOLocal(v, true); + } +} diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 70edee21bd63a..a64627eaf5986 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -38,11 +38,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::set_linkage(g, base::linkage_to_llvm(linkage)); llvm::set_visibility(g, base::visibility_to_llvm(visibility)); - unsafe { - if self.should_assume_dso_local(g, false) { - llvm::LLVMRustSetDSOLocal(g, true); - } - } + self.assume_dso_local(g, false); self.instances.borrow_mut().insert(instance, g); } @@ -79,9 +75,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { debug!("predefine_fn: instance = {:?}", instance); - if self.should_assume_dso_local(lldecl, false) { - unsafe { llvm::LLVMRustSetDSOLocal(lldecl, true) }; - } + self.assume_dso_local(lldecl, false); self.instances.borrow_mut().insert(instance, lldecl); } @@ -90,11 +84,16 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { impl CodegenCx<'_, '_> { /// Whether a definition or declaration can be assumed to be local to a group of /// libraries that form a single DSO or executable. - pub(crate) fn should_assume_dso_local( - &self, - llval: &llvm::Value, - is_declaration: bool, - ) -> bool { + /// Marks the local as DSO if so. + pub(crate) fn assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { + let assume = self.should_assume_dso_local(llval, is_declaration); + if assume { + llvm::set_dso_local(llval); + } + assume + } + + fn should_assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { let linkage = llvm::get_linkage(llval); let visibility = llvm::get_visibility(llval); diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index b0b6da869da68..ba01fbff38539 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -23,7 +23,7 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} + BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } let name = match layout.ty.kind() { @@ -172,19 +172,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => true, - BackendRepr::ScalarPair(..) | BackendRepr::Uninhabited | BackendRepr::Memory { .. } => { - false - } + BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } fn is_llvm_scalar_pair(&self) -> bool { match self.backend_repr { BackendRepr::ScalarPair(..) => true, - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } - | BackendRepr::Memory { .. } => false, + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } | BackendRepr::Memory { .. } => { + false + } } } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 2afc1efc1b34d..83d847f2d155a 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_codegen_ssa" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -25,6 +25,7 @@ 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_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_incremental = { path = "../rustc_incremental" } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 105a4cb81f0d1..4c07645026943 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -244,22 +244,17 @@ pub fn each_linked_rlib( fmts } else { - for combination in info.dependency_formats.iter().combinations(2) { - let (ty1, list1) = &combination[0]; - let (ty2, list2) = &combination[1]; - if list1 != list2 { - return Err(errors::LinkRlibError::IncompatibleDependencyFormats { - ty1: format!("{ty1:?}"), - ty2: format!("{ty2:?}"), - list1: format!("{list1:?}"), - list2: format!("{list2:?}"), - }); - } - } - if info.dependency_formats.is_empty() { - return Err(errors::LinkRlibError::MissingFormat); + let mut dep_formats = info.dependency_formats.iter(); + let (ty1, list1) = dep_formats.next().ok_or(errors::LinkRlibError::MissingFormat)?; + if let Some((ty2, list2)) = dep_formats.find(|(_, list2)| list1 != *list2) { + return Err(errors::LinkRlibError::IncompatibleDependencyFormats { + ty1: format!("{ty1:?}"), + ty2: format!("{ty2:?}"), + list1: format!("{list1:?}"), + list2: format!("{list2:?}"), + }); } - info.dependency_formats.first().unwrap().1 + list1 }; let used_dep_crates = info.used_crates.iter(); @@ -626,10 +621,9 @@ fn link_staticlib( let mut all_rust_dylibs = vec![]; for &cnum in crates { - match fmts.get(cnum) { - Some(&Linkage::Dynamic) => {} - _ => continue, - } + let Some(Linkage::Dynamic) = fmts.get(cnum) else { + continue; + }; let crate_name = codegen_results.crate_info.crate_name[&cnum]; let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; if let Some((path, _)) = &used_crate_source.dylib { @@ -1990,6 +1984,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) if let Some(args) = sess.target.pre_link_args.get(&flavor) { cmd.verbatim_args(args.iter().map(Deref::deref)); } + cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args); } @@ -2518,6 +2513,12 @@ fn add_order_independent_options( "--target-cpu", &codegen_results.crate_info.target_cpu, ]); + if codegen_results.crate_info.target_features.len() > 0 { + cmd.link_arg(&format!( + "--target-feature={}", + &codegen_results.crate_info.target_features.join(",") + )); + } } else if flavor == LinkerFlavor::Ptx { cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]); } else if flavor == LinkerFlavor::Bpf { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e3ace01c1eb54..8900405c1b8f8 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -153,6 +153,7 @@ pub(crate) fn get_linker<'a>( hinted_static: None, is_ld: cc == Cc::No, is_gnu: flavor.is_gnu(), + uses_lld: flavor.uses_lld(), }) as Box, LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box, LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box, @@ -361,6 +362,7 @@ struct GccLinker<'a> { // Link as ld is_ld: bool, is_gnu: bool, + uses_lld: bool, } impl<'a> GccLinker<'a> { @@ -552,6 +554,7 @@ impl<'a> Linker for GccLinker<'a> { self.link_args(&["--entry", "_initialize"]); } } + // VxWorks compiler driver introduced `--static-crt` flag specifically for rustc, // it switches linking for libc and similar system libraries to static without using // any `#[link]` attributes in the `libc` crate, see #72782 for details. @@ -567,6 +570,15 @@ impl<'a> Linker for GccLinker<'a> { { self.cc_arg("--static-crt"); } + + // avr-none doesn't have default ISA, users must specify which specific + // CPU (well, microcontroller) they are targetting using `-Ctarget-cpu`. + // + // Currently this makes sense only when using avr-gcc as a linker, since + // it brings a couple of hand-written important intrinsics from libgcc. + if self.sess.target.arch == "avr" && !self.uses_lld { + self.verbatim_arg(format!("-mmcu={}", self.target_cpu)); + } } fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool) { diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index d70413b8a4741..236507ac0cd28 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -252,15 +252,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option return None, }; - let binary_format = if sess.target.is_like_osx { - BinaryFormat::MachO - } else if sess.target.is_like_windows { - BinaryFormat::Coff - } else if sess.target.is_like_aix { - BinaryFormat::Xcoff - } else { - BinaryFormat::Elf - }; + let binary_format = sess.target.binary_format.to_object(); let mut file = write::Object::new(binary_format, architecture, endianness); file.set_sub_architecture(sub_architecture); diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 12ee872d53141..459f4329d6e92 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -183,11 +183,11 @@ fn exported_symbols_provider_local( }); let mut symbols: Vec<_> = - sorted.iter().map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)).collect(); + sorted.iter().map(|&(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)).collect(); // Export TLS shims if !tcx.sess.target.dll_tls_export { - symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| { + symbols.extend(sorted.iter().filter_map(|&(&def_id, &info)| { tcx.needs_thread_local_shim(def_id).then(|| { ( ExportedSymbol::ThreadLocalShim(def_id), diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index f029c08a80821..f008bd12ed8fe 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -405,7 +405,8 @@ fn generate_lto_work( B::run_fat_lto(cgcx, needs_fat_lto, import_only_modules).unwrap_or_else(|e| e.raise()); if cgcx.lto == Lto::Fat && !autodiff.is_empty() { let config = cgcx.config(ModuleKind::Regular); - module = unsafe { module.autodiff(cgcx, autodiff, config).unwrap() }; + module = + unsafe { module.autodiff(cgcx, autodiff, config).unwrap_or_else(|e| e.raise()) }; } // We are adding a single work item, so the cost doesn't matter. vec![(WorkItem::LTO(module), 0)] @@ -572,10 +573,10 @@ fn produce_final_output_artifacts( }; let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { - if compiled_modules.modules.len() == 1 { + if let [module] = &compiled_modules.modules[..] { // 1) Only one codegen unit. In this case it's no difficulty // to copy `foo.0.x` to `foo.x`. - let module_name = Some(&compiled_modules.modules[0].name[..]); + let module_name = Some(&module.name[..]); let path = crate_output.temp_path(output_type, module_name); let output = crate_output.path(output_type); if !output_type.is_text_output() && output.is_tty() { @@ -707,8 +708,8 @@ fn produce_final_output_artifacts( } if sess.opts.json_artifact_notifications { - if compiled_modules.modules.len() == 1 { - compiled_modules.modules[0].for_each_output(|_path, ty| { + if let [module] = &compiled_modules.modules[..] { + module.for_each_output(|_path, ty| { if sess.opts.output_types.contains_key(&ty) { let descr = ty.shorthand(); // for single cgu file is renamed to drop cgu specific suffix @@ -864,7 +865,7 @@ pub(crate) fn compute_per_cgu_lto_type( // require LTO so the request for LTO is always unconditionally // passed down to the backend, but we don't actually want to do // anything about it yet until we've got a final product. - let is_rlib = sess_crate_types.len() == 1 && sess_crate_types[0] == CrateType::Rlib; + let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]); match sess_lto { Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, @@ -1537,8 +1538,9 @@ fn start_executing_work( // Spin up what work we can, only doing this while we've got available // parallelism slots and work left to spawn. if codegen_state != Aborted { - while !work_items.is_empty() && running_with_own_token < tokens.len() { - let (item, _) = work_items.pop().unwrap(); + while running_with_own_token < tokens.len() + && let Some((item, _)) = work_items.pop() + { spawn_work( &cgcx, &mut llvm_start_time, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index e800492dad02f..40238f4b4915a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -24,7 +24,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::Session; -use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; +use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_span::{DUMMY_SP, Symbol, sym}; use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; @@ -364,13 +364,7 @@ pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let rhs_sz = bx.cx().int_width(rhs_llty); let lhs_sz = bx.cx().int_width(lhs_llty); if lhs_sz < rhs_sz { - if is_unchecked && bx.sess().opts.optimize != OptLevel::No { - // FIXME: Use `trunc nuw` once that's available - let inrange = bx.icmp(IntPredicate::IntULE, rhs, mask); - bx.assume(inrange); - } - - bx.trunc(rhs, lhs_llty) + if is_unchecked { bx.unchecked_utrunc(rhs, lhs_llty) } else { bx.trunc(rhs, lhs_llty) } } else if lhs_sz > rhs_sz { // We zero-extend even if the RHS is signed. So e.g. `(x: i32) << -1i8` will zero-extend the // RHS to `255i32`. But then we mask the shift amount to be within the size of the LHS @@ -921,6 +915,7 @@ impl CrateInfo { let n_crates = crates.len(); let mut info = CrateInfo { target_cpu, + target_features: tcx.global_backend_features(()).clone(), crate_types, exported_symbols, linked_symbols, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 3e9dfcea58b8b..97bc84c0b698b 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use rustc_abi::ExternAbi; -use rustc_ast::attr::list_contains_name; use rustc_ast::expand::autodiff_attrs::{ AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, }; @@ -377,24 +376,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let segments = set.path.segments.iter().map(|x| x.ident.name).collect::>(); match segments.as_slice() { - [sym::arm, sym::a32] | [sym::arm, sym::t32] => { - if !tcx.sess.target.has_thumb_interworking { - struct_span_code_err!( - tcx.dcx(), - attr.span, - E0779, - "target does not support `#[instruction_set]`" - ) - .emit(); - None - } else if segments[1] == sym::a32 { - Some(InstructionSetAttr::ArmA32) - } else if segments[1] == sym::t32 { - Some(InstructionSetAttr::ArmT32) - } else { - unreachable!() - } + [sym::arm, sym::a32 | sym::t32] + if !tcx.sess.target.has_thumb_interworking => + { + struct_span_code_err!( + tcx.dcx(), + attr.span, + E0779, + "target does not support `#[instruction_set]`" + ) + .emit(); + None } + [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), + [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), _ => { struct_span_code_err!( tcx.dcx(), @@ -435,7 +430,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some((sym::align, literal)) = item.singleton_lit_list() { rustc_attr_parsing::parse_alignment(&literal.kind) - .map_err(|msg| { + .inspect_err(|msg| { struct_span_code_err!( tcx.dcx(), literal.span, @@ -536,25 +531,27 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } if attr.is_word() { - InlineAttr::Hint - } else if let Some(ref items) = attr.meta_item_list() { - inline_span = Some(attr.span); - if items.len() != 1 { - struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); - InlineAttr::None - } else if list_contains_name(items, sym::always) { - InlineAttr::Always - } else if list_contains_name(items, sym::never) { - InlineAttr::Never - } else { - struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .with_help("valid inline arguments are `always` and `never`") - .emit(); + return InlineAttr::Hint; + } + let Some(ref items) = attr.meta_item_list() else { + return ia; + }; - InlineAttr::None - } + inline_span = Some(attr.span); + let [item] = &items[..] else { + struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit(); + return InlineAttr::None; + }; + if item.has_name(sym::always) { + InlineAttr::Always + } else if item.has_name(sym::never) { + InlineAttr::Never } else { - ia + struct_span_code_err!(tcx.dcx(), item.span(), E0535, "invalid argument") + .with_help("valid inline arguments are `always` and `never`") + .emit(); + + InlineAttr::None } }); codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| { @@ -586,23 +583,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); if attr.is_word() { err(attr.span, "expected one argument"); - ia - } else if let Some(ref items) = attr.meta_item_list() { - inline_span = Some(attr.span); - if items.len() != 1 { - err(attr.span, "expected one argument"); - OptimizeAttr::Default - } else if list_contains_name(items, sym::size) { - OptimizeAttr::Size - } else if list_contains_name(items, sym::speed) { - OptimizeAttr::Speed - } else if list_contains_name(items, sym::none) { - OptimizeAttr::DoNotOptimize - } else { - err(items[0].span(), "invalid argument"); - OptimizeAttr::Default - } + return ia; + } + let Some(ref items) = attr.meta_item_list() else { + return OptimizeAttr::Default; + }; + + inline_span = Some(attr.span); + let [item] = &items[..] else { + err(attr.span, "expected one argument"); + return OptimizeAttr::Default; + }; + if item.has_name(sym::size) { + OptimizeAttr::Size + } else if item.has_name(sym::speed) { + OptimizeAttr::Speed + } else if item.has_name(sym::none) { + OptimizeAttr::DoNotOptimize } else { + err(item.span(), "invalid argument"); OptimizeAttr::Default } }); @@ -644,25 +643,20 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // llvm/llvm-project#70563). if !codegen_fn_attrs.target_features.is_empty() && matches!(codegen_fn_attrs.inline, InlineAttr::Always) + && let Some(span) = inline_span { - if let Some(span) = inline_span { - tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`"); - } + tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`"); } - if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() { - if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) { - let hir_id = tcx.local_def_id_to_hir_id(did); - tcx.node_span_lint( - lint::builtin::INLINE_NO_SANITIZE, - hir_id, - no_sanitize_span, - |lint| { - lint.primary_message("`no_sanitize` will have no effect after inlining"); - lint.span_note(inline_span, "inlining requested here"); - }, - ) - } + if !codegen_fn_attrs.no_sanitize.is_empty() + && codegen_fn_attrs.inline.always() + && let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) + { + let hir_id = tcx.local_def_id_to_hir_id(did); + tcx.node_span_lint(lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, |lint| { + lint.primary_message("`no_sanitize` will have no effect after inlining"); + lint.span_note(inline_span, "inlining requested here"); + }) } // Weak lang items have the same semantics as "std internal" symbols in the @@ -692,10 +686,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { // Any linkage to LLVM intrinsics for now forcibly marks them all as never // unwinds since LLVM sometimes can't handle codegen which `invoke`s // intrinsic functions. - if let Some(name) = &codegen_fn_attrs.link_name { - if name.as_str().starts_with("llvm.") { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } + if let Some(name) = &codegen_fn_attrs.link_name + && name.as_str().starts_with("llvm.") + { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; } if let Some(features) = check_tied_features( @@ -756,18 +750,13 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option { use rustc_ast::{LitIntType, LitKind, MetaItemLit}; - let meta_item_list = attr.meta_item_list(); - let meta_item_list = meta_item_list.as_deref(); - let sole_meta_list = match meta_item_list { - Some([item]) => item.lit(), - Some(_) => { - tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span }); - return None; - } - _ => None, + let meta_item_list = attr.meta_item_list()?; + let [sole_meta_list] = &meta_item_list[..] else { + tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span }); + return None; }; if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) = - sole_meta_list + sole_meta_list.lit() { // According to the table at // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the @@ -894,7 +883,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { let [mode, input_activities @ .., ret_activity] = &list[..] else { span_bug!(attr.span, "rustc_autodiff attribute must contain mode and activities"); }; - let mode = if let MetaItemInner::MetaItem(MetaItem { path: ref p1, .. }) = mode { + let mode = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = mode { p1.segments.first().unwrap().ident } else { span_bug!(attr.span, "rustc_autodiff attribute must contain mode"); @@ -910,7 +899,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { }; // First read the ret symbol from the attribute - let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: ref p1, .. }) = ret_activity { + let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity { p1.segments.first().unwrap().ident } else { span_bug!(attr.span, "rustc_autodiff attribute must contain the return activity"); @@ -924,7 +913,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { // Now parse all the intermediate (input) activities let mut arg_activities: Vec = vec![]; for arg in input_activities { - let arg_symbol = if let MetaItemInner::MetaItem(MetaItem { path: ref p2, .. }) = arg { + let arg_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p2, .. }) = arg { match p2.segments.first() { Some(x) => x.ident, None => { diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 53953b089c613..84703a0a15692 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -15,7 +15,8 @@ use std::fmt::Write; use rustc_abi::Integer; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Mutability}; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 428a45975f1ec..9d2ac219d592c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -190,6 +190,7 @@ impl From<&cstore::NativeLib> for NativeLib { #[derive(Debug, Encodable, Decodable)] pub struct CrateInfo { pub target_cpu: String, + pub target_features: Vec, pub crate_types: Vec, pub exported_symbols: UnordMap>, pub linked_symbols: FxIndexMap>, @@ -230,6 +231,7 @@ pub fn provide(providers: &mut Providers) { crate::base::provide(providers); crate::target_features::provide(providers); crate::codegen_attrs::provide(providers); + providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![]; } /// Checks if the given filename ends with the `.rcgu.o` extension that `rustc` diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 4630ed48c520e..1e52c6394635b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -4,9 +4,7 @@ use rustc_abi::{BackendRepr, ExternAbi, HasDataLayout, Reg, WrappingRange}; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; -use rustc_middle::mir::{ - self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason, -}; +use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty}; @@ -429,11 +427,34 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let cmp = bx.icmp(IntPredicate::IntEQ, discr_value, llval); bx.cond_br(cmp, ll1, ll2); } else { - bx.switch( - discr_value, - helper.llbb_with_cleanup(self, targets.otherwise()), - target_iter.map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))), - ); + let otherwise = targets.otherwise(); + let otherwise_cold = self.cold_blocks[otherwise]; + let otherwise_unreachable = self.mir[otherwise].is_empty_unreachable(); + let cold_count = targets.iter().filter(|(_, target)| self.cold_blocks[*target]).count(); + let none_cold = cold_count == 0; + let all_cold = cold_count == targets.iter().len(); + if (none_cold && (!otherwise_cold || otherwise_unreachable)) + || (all_cold && (otherwise_cold || otherwise_unreachable)) + { + // All targets have the same weight, + // or `otherwise` is unreachable and it's the only target with a different weight. + bx.switch( + discr_value, + helper.llbb_with_cleanup(self, targets.otherwise()), + target_iter + .map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))), + ); + } else { + // Targets have different weights + bx.switch_with_weights( + discr_value, + helper.llbb_with_cleanup(self, targets.otherwise()), + otherwise_cold, + target_iter.map(|(value, target)| { + (value, helper.llbb_with_cleanup(self, target), self.cold_blocks[target]) + }), + ); + } } } @@ -699,14 +720,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Put together the arguments to the panic entry point. let (lang_item, args) = match msg { - AssertKind::BoundsCheck { ref len, ref index } => { + AssertKind::BoundsCheck { len, index } => { let len = self.codegen_operand(bx, len).immediate(); let index = self.codegen_operand(bx, index).immediate(); // It's `fn panic_bounds_check(index: usize, len: usize)`, // and `#[track_caller]` adds an implicit third argument. (LangItem::PanicBoundsCheck, vec![index, len, location]) } - AssertKind::MisalignedPointerDereference { ref required, ref found } => { + AssertKind::MisalignedPointerDereference { required, found } => { let required = self.codegen_operand(bx, required).immediate(); let found = self.codegen_operand(bx, found).immediate(); // It's `fn panic_misaligned_pointer_dereference(required: usize, found: usize)`, @@ -919,7 +940,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &fn_abi.ret, &mut llargs, Some(intrinsic), - target, ); let dest = match ret_dest { _ if fn_abi.ret.is_indirect() => llargs[0], @@ -975,23 +995,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let mut llargs = Vec::with_capacity(arg_count); - let destination = target.as_ref().map(|&target| { - ( - self.make_return_dest( - bx, - destination, - &fn_abi.ret, - &mut llargs, - None, - Some(target), - ), - target, - ) - }); + + // We still need to call `make_return_dest` even if there's no `target`, since + // `fn_abi.ret` could be `PassMode::Indirect`, even if it is uninhabited, + // and `make_return_dest` adds the return-place indirect pointer to `llargs`. + let return_dest = self.make_return_dest(bx, destination, &fn_abi.ret, &mut llargs, None); + let destination = target.map(|target| (return_dest, target)); // Split the rust-call tupled arguments off. - let (first_args, untuple) = if abi == ExternAbi::RustCall && !args.is_empty() { - let (tup, args) = args.split_last().unwrap(); + let (first_args, untuple) = if abi == ExternAbi::RustCall + && let Some((tup, args)) = args.split_last() + { (args, Some(tup)) } else { (args, None) @@ -1017,7 +1031,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(bx, idx); + op = op.extract_field(self, bx, idx); } // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its @@ -1049,7 +1063,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (idx, _) = op.layout.non_1zst_field(bx).expect( "not exactly one non-1-ZST field in a `DispatchFromDyn` type", ); - op = op.extract_field(bx, idx); + op = op.extract_field(self, bx, idx); } // Make sure that we've actually unwrapped the rcvr down @@ -1549,9 +1563,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if scalar.is_bool() { bx.range_metadata(llval, WrappingRange { start: 0, end: 1 }); } + // We store bools as `i8` so we need to truncate to `i1`. + llval = bx.to_immediate_scalar(llval, scalar); } - // We store bools as `i8` so we need to truncate to `i1`. - llval = bx.to_immediate(llval, arg.layout); } } @@ -1581,7 +1595,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { // If the tuple is immediate, the elements are as well. for i in 0..tuple.layout.fields.count() { - let op = tuple.extract_field(bx, i); + let op = tuple.extract_field(self, bx, i); self.codegen_argument(bx, op, llargs, &args[i]); } } @@ -1790,11 +1804,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_ret: &ArgAbi<'tcx, Ty<'tcx>>, llargs: &mut Vec, intrinsic: Option, - target: Option, ) -> ReturnDest<'tcx, Bx::Value> { - if target.is_none() { - return ReturnDest::Nothing; - } // If the return is ignored, we can just return a do-nothing `ReturnDest`. if fn_ret.is_ignore() { return ReturnDest::Nothing; diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 3a896071bc6b8..ba28720afecdd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -502,14 +502,25 @@ fn find_cold_blocks<'tcx>( for (bb, bb_data) in traversal::postorder(mir) { let terminator = bb_data.terminator(); - // If a BB ends with a call to a cold function, mark it as cold. - if let mir::TerminatorKind::Call { ref func, .. } = terminator.kind - && let ty::FnDef(def_id, ..) = *func.ty(local_decls, tcx).kind() - && let attrs = tcx.codegen_fn_attrs(def_id) - && attrs.flags.contains(CodegenFnAttrFlags::COLD) - { - cold_blocks[bb] = true; - continue; + match terminator.kind { + // If a BB ends with a call to a cold function, mark it as cold. + mir::TerminatorKind::Call { ref func, .. } + | mir::TerminatorKind::TailCall { ref func, .. } + if let ty::FnDef(def_id, ..) = *func.ty(local_decls, tcx).kind() + && let attrs = tcx.codegen_fn_attrs(def_id) + && attrs.flags.contains(CodegenFnAttrFlags::COLD) => + { + cold_blocks[bb] = true; + continue; + } + + // If a BB ends with an `unreachable`, also mark it as cold. + mir::TerminatorKind::Unreachable => { + cold_blocks[bb] = true; + continue; + } + + _ => {} } // If all successors of a BB are cold and there's at least one of them, mark this BB as cold diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index eb0711dbb32ff..0593fb420c306 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::sym; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; -use rustc_target::spec::WasmCAbi; +use rustc_target::spec::{BinaryFormat, WasmCAbi}; use crate::common; use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods}; @@ -104,27 +104,6 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } -enum AsmBinaryFormat { - Elf, - Macho, - Coff, - Wasm, -} - -impl AsmBinaryFormat { - fn from_target(target: &rustc_target::spec::Target) -> Self { - if target.is_like_windows { - Self::Coff - } else if target.is_like_osx { - Self::Macho - } else if target.is_like_wasm { - Self::Wasm - } else { - Self::Elf - } - } -} - fn prefix_and_suffix<'tcx>( tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, @@ -134,7 +113,7 @@ fn prefix_and_suffix<'tcx>( ) -> (String, String) { use std::fmt::Write; - let asm_binary_format = AsmBinaryFormat::from_target(&tcx.sess.target); + let asm_binary_format = &tcx.sess.target.binary_format; let is_arm = tcx.sess.target.arch == "arm"; let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode); @@ -178,10 +157,13 @@ fn prefix_and_suffix<'tcx>( } Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => { match asm_binary_format { - AsmBinaryFormat::Elf | AsmBinaryFormat::Coff | AsmBinaryFormat::Wasm => { + BinaryFormat::Elf + | BinaryFormat::Coff + | BinaryFormat::Wasm + | BinaryFormat::Xcoff => { writeln!(w, ".weak {asm_name}")?; } - AsmBinaryFormat::Macho => { + BinaryFormat::MachO => { writeln!(w, ".globl {asm_name}")?; writeln!(w, ".weak_definition {asm_name}")?; } @@ -207,7 +189,7 @@ fn prefix_and_suffix<'tcx>( let mut begin = String::new(); let mut end = String::new(); match asm_binary_format { - AsmBinaryFormat::Elf => { + BinaryFormat::Elf | BinaryFormat::Xcoff => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); let progbits = match is_arm { @@ -239,7 +221,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Macho => { + BinaryFormat::MachO => { let section = link_section.unwrap_or("__TEXT,__text".to_string()); writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap(); writeln!(begin, ".balign {align}").unwrap(); @@ -255,7 +237,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Coff => { + BinaryFormat::Coff => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); writeln!(begin, ".pushsection {},\"xr\"", section).unwrap(); writeln!(begin, ".balign {align}").unwrap(); @@ -272,7 +254,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end, "{}", arch_suffix).unwrap(); } } - AsmBinaryFormat::Wasm => { + BinaryFormat::Wasm => { let section = link_section.unwrap_or(format!(".text.{asm_name}")); writeln!(begin, ".section {section},\"\",@").unwrap(); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 9ca7d4f8f0047..461cf1b8acdaf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -1,15 +1,14 @@ -use std::assert_matches::assert_matches; use std::fmt; use arrayvec::ArrayVec; use either::Either; use rustc_abi as abi; use rustc_abi::{Align, BackendRepr, Size}; -use rustc_middle::bug; use rustc_middle::mir::interpret::{Pointer, Scalar, alloc_range}; use rustc_middle::mir::{self, ConstValue}; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; +use rustc_middle::{bug, span_bug}; use tracing::debug; use super::place::{PlaceRef, PlaceValue}; @@ -352,79 +351,83 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { pub(crate) fn extract_field>( &self, + fx: &mut FunctionCx<'a, 'tcx, Bx>, bx: &mut Bx, i: usize, ) -> Self { let field = self.layout.field(bx.cx(), i); let offset = self.layout.fields.offset(i); - let mut val = match (self.val, self.layout.backend_repr) { - // If the field is ZST, it has no data. - _ if field.is_zst() => OperandValue::ZeroSized, - - // Newtype of a scalar, scalar pair or vector. - (OperandValue::Immediate(_) | OperandValue::Pair(..), _) - if field.size == self.layout.size => + if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) { + if let BackendRepr::Vector { count, .. } = self.layout.backend_repr + && let BackendRepr::Memory { sized: true } = field.backend_repr + && count.is_power_of_two() { - assert_eq!(offset.bytes(), 0); - self.val + assert_eq!(field.size, self.layout.size); + // This is being deprecated, but for now stdarch still needs it for + // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); + let place = PlaceRef::alloca(bx, field); + self.val.store(bx, place.val.with_type(self.layout)); + return bx.load_operand(place); + } else { + // Part of https://github.com/rust-lang/compiler-team/issues/838 + bug!("Non-ref type {self:?} cannot project to ref field type {field:?}"); } + } - // Extract a scalar component from a pair. - (OperandValue::Pair(a_llval, b_llval), BackendRepr::ScalarPair(a, b)) => { - if offset.bytes() == 0 { - assert_eq!(field.size, a.size(bx.cx())); - OperandValue::Immediate(a_llval) - } else { - assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi)); - assert_eq!(field.size, b.size(bx.cx())); - OperandValue::Immediate(b_llval) + let val = if field.is_zst() { + OperandValue::ZeroSized + } else if field.size == self.layout.size { + assert_eq!(offset.bytes(), 0); + fx.codegen_transmute_operand(bx, *self, field).unwrap_or_else(|| { + bug!( + "Expected `codegen_transmute_operand` to handle equal-size \ + field {i:?} projection from {self:?} to {field:?}" + ) + }) + } else { + let (in_scalar, imm) = match (self.val, self.layout.backend_repr) { + // Extract a scalar component from a pair. + (OperandValue::Pair(a_llval, b_llval), BackendRepr::ScalarPair(a, b)) => { + if offset.bytes() == 0 { + assert_eq!(field.size, a.size(bx.cx())); + (Some(a), a_llval) + } else { + assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi)); + assert_eq!(field.size, b.size(bx.cx())); + (Some(b), b_llval) + } } - } - - // `#[repr(simd)]` types are also immediate. - (OperandValue::Immediate(llval), BackendRepr::Vector { .. }) => { - OperandValue::Immediate(bx.extract_element(llval, bx.cx().const_usize(i as u64))) - } - _ => bug!("OperandRef::extract_field({:?}): not applicable", self), + _ => { + span_bug!(fx.mir.span, "OperandRef::extract_field({:?}): not applicable", self) + } + }; + OperandValue::Immediate(match field.backend_repr { + BackendRepr::Vector { .. } => imm, + BackendRepr::Scalar(out_scalar) => { + let Some(in_scalar) = in_scalar else { + span_bug!( + fx.mir.span, + "OperandRef::extract_field({:?}): missing input scalar for output scalar", + self + ) + }; + if in_scalar != out_scalar { + // If the backend and backend_immediate types might differ, + // flip back to the backend type then to the new immediate. + // This avoids nop truncations, but still handles things like + // Bools in union fields needs to be truncated. + let backend = bx.from_immediate(imm); + bx.to_immediate_scalar(backend, out_scalar) + } else { + imm + } + } + BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } => bug!(), + }) }; - match (&mut val, field.backend_repr) { - (OperandValue::ZeroSized, _) => {} - ( - OperandValue::Immediate(llval), - BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) | BackendRepr::Vector { .. }, - ) => { - // Bools in union fields needs to be truncated. - *llval = bx.to_immediate(*llval, field); - } - (OperandValue::Pair(a, b), BackendRepr::ScalarPair(a_abi, b_abi)) => { - // Bools in union fields needs to be truncated. - *a = bx.to_immediate_scalar(*a, a_abi); - *b = bx.to_immediate_scalar(*b, b_abi); - } - // Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]); - (OperandValue::Immediate(llval), BackendRepr::Memory { sized: true }) => { - assert_matches!(self.layout.backend_repr, BackendRepr::Vector { .. }); - - let llfield_ty = bx.cx().backend_type(field); - - // Can't bitcast an aggregate, so round trip through memory. - let llptr = bx.alloca(field.size, field.align.abi); - bx.store(*llval, llptr, field.align.abi); - *llval = bx.load(llfield_ty, llptr, field.align.abi); - } - ( - OperandValue::Immediate(_), - BackendRepr::Uninhabited | BackendRepr::Memory { sized: false }, - ) => { - bug!() - } - (OperandValue::Pair(..), _) => bug!(), - (OperandValue::Ref(..), _) => bug!(), - } - OperandRef { val, layout: field } } } @@ -581,13 +584,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Moves out of scalar and scalar pair fields are trivial. for elem in place_ref.projection.iter() { match elem { - mir::ProjectionElem::Field(ref f, _) => { + mir::ProjectionElem::Field(f, _) => { assert!( !o.layout.ty.is_any_ptr(), "Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \ but tried to access field {f:?} of pointer {o:?}", ); - o = o.extract_field(bx, f.index()); + o = o.extract_field(self, bx, f.index()); } mir::ProjectionElem::Index(_) | mir::ProjectionElem::ConstantIndex { .. } => { diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index eb4270ffe8096..edd09b9c3c5fd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -1,7 +1,7 @@ use rustc_abi::Primitive::{Int, Pointer}; use rustc_abi::{Align, BackendRepr, FieldsShape, Size, TagEncoding, VariantIdx, Variants}; +use rustc_middle::mir::PlaceTy; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, mir}; @@ -423,7 +423,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout.size }; - let llval = bx.inbounds_gep(bx.cx().backend_type(layout), self.val.llval, &[llindex]); + let llval = bx.inbounds_nuw_gep(bx.cx().backend_type(layout), self.val.llval, &[llindex]); let align = self.val.align.restrict_for_offset(offset); PlaceValue::new_sized(llval, align).with_type(layout) } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 4c5b183cfe92a..1eebe04225bef 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// /// Returns `None` for cases that can't work in that framework, such as for /// `Immediate`->`Ref` that needs an `alloc` to get the location. - fn codegen_transmute_operand( + pub(crate) fn codegen_transmute_operand( &mut self, bx: &mut Bx, operand: OperandRef<'tcx, Bx::Value>, @@ -260,6 +260,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(source_place_val) => { assert_eq!(source_place_val.llextra, None); assert_matches!(operand_kind, OperandValueKind::Ref); + // The existing alignment is part of `source_place_val`, + // so that alignment will be used, not `cast`'s. Some(bx.load_operand(source_place_val.with_type(cast)).val) } OperandValue::ZeroSized => { @@ -664,9 +666,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lhs.layout.ty, ), - (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => { - self.codegen_scalar_binop(bx, op, lhs_val, rhs_val, lhs.layout.ty) - } + (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => self + .codegen_scalar_binop( + bx, + op, + lhs_val, + rhs_val, + lhs.layout.ty, + rhs.layout.ty, + ), _ => bug!(), }; @@ -887,10 +895,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { op: mir::BinOp, lhs: Bx::Value, rhs: Bx::Value, - input_ty: Ty<'tcx>, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, ) -> Bx::Value { - let is_float = input_ty.is_floating_point(); - let is_signed = input_ty.is_signed(); + let is_float = lhs_ty.is_floating_point(); + let is_signed = lhs_ty.is_signed(); match op { mir::BinOp::Add => { if is_float { @@ -956,9 +965,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::BinOp::BitAnd => bx.and(lhs, rhs), mir::BinOp::BitXor => bx.xor(lhs, rhs), mir::BinOp::Offset => { - let pointee_type = input_ty + let pointee_type = lhs_ty .builtin_deref(true) - .unwrap_or_else(|| bug!("deref of non-pointer {:?}", input_ty)); + .unwrap_or_else(|| bug!("deref of non-pointer {:?}", lhs_ty)); let pointee_layout = bx.cx().layout_of(pointee_type); if pointee_layout.is_zst() { // `Offset` works in terms of the size of pointee, @@ -966,7 +975,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lhs } else { let llty = bx.cx().backend_type(pointee_layout); - bx.inbounds_gep(llty, lhs, &[rhs]) + if !rhs_ty.is_signed() { + bx.inbounds_nuw_gep(llty, lhs, &[rhs]) + } else { + bx.inbounds_gep(llty, lhs, &[rhs]) + } } } mir::BinOp::Shl | mir::BinOp::ShlUnchecked => { diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs index 5f95b6615bd30..f6af889fd6ecb 100644 --- a/compiler/rustc_codegen_ssa/src/mono_item.rs +++ b/compiler/rustc_codegen_ssa/src/mono_item.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } MonoItem::GlobalAsm(item_id) => { let item = cx.tcx().hir_item(item_id); - if let hir::ItemKind::GlobalAsm(asm) = item.kind { + if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind { let operands: Vec<_> = asm .operands .iter() @@ -71,11 +71,8 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { } } } - hir::InlineAsmOperand::SymFn { ref anon_const } => { - let ty = cx - .tcx() - .typeck_body(anon_const.body) - .node_type(anon_const.hir_id); + hir::InlineAsmOperand::SymFn { expr } => { + let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr); let instance = match ty.kind() { &ty::FnDef(def_id, args) => Instance::new(def_id, args), _ => span_bug!(*op_sp, "asm sym is not a function"), diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 2c843e2f5e460..99fd6b6510ffe 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -1,7 +1,7 @@ use std::assert_matches::assert_matches; use std::ops::Deref; -use rustc_abi::{Align, BackendRepr, Scalar, Size, WrappingRange}; +use rustc_abi::{Align, Scalar, Size, WrappingRange}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::{Instance, Ty}; @@ -110,6 +110,20 @@ pub trait BuilderMethods<'a, 'tcx>: else_llbb: Self::BasicBlock, cases: impl ExactSizeIterator, ); + + // This is like `switch()`, but every case has a bool flag indicating whether it's cold. + // + // Default implementation throws away the cold flags and calls `switch()`. + fn switch_with_weights( + &mut self, + v: Self::Value, + else_llbb: Self::BasicBlock, + _else_is_cold: bool, + cases: impl ExactSizeIterator, + ) { + self.switch(v, else_llbb, cases.map(|(val, bb, _)| (val, bb))) + } + fn invoke( &mut self, llty: Self::Type, @@ -209,13 +223,6 @@ pub trait BuilderMethods<'a, 'tcx>: ) -> (Self::Value, Self::Value); fn from_immediate(&mut self, val: Self::Value) -> Self::Value; - fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value { - if let BackendRepr::Scalar(scalar) = layout.backend_repr { - self.to_immediate_scalar(val, scalar) - } else { - val - } - } fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; @@ -318,6 +325,14 @@ pub trait BuilderMethods<'a, 'tcx>: ptr: Self::Value, indices: &[Self::Value], ) -> Self::Value; + fn inbounds_nuw_gep( + &mut self, + ty: Self::Type, + ptr: Self::Value, + indices: &[Self::Value], + ) -> Self::Value { + self.inbounds_gep(ty, ptr, indices) + } fn ptradd(&mut self, ptr: Self::Value, offset: Self::Value) -> Self::Value { self.gep(self.cx().type_i8(), ptr, &[offset]) } @@ -326,6 +341,17 @@ pub trait BuilderMethods<'a, 'tcx>: } fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; + /// Produces the same value as [`Self::trunc`] (and defaults to that), + /// but is UB unless the *zero*-extending the result can reproduce `val`. + fn unchecked_utrunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value { + self.trunc(val, dest_ty) + } + /// Produces the same value as [`Self::trunc`] (and defaults to that), + /// but is UB unless the *sign*-extending the result can reproduce `val`. + fn unchecked_strunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value { + self.trunc(val, dest_ty) + } + fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 7717cd2c69664..a0cc2c65e6e03 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_const_eval" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index bfa0a0319c344..52e000858b4c7 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -31,7 +31,7 @@ pub struct ConstCx<'mir, 'tcx> { impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self { let typing_env = body.typing_env(tcx); - let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local()); + let const_kind = tcx.hir_body_const_context(body.source.def_id().expect_local()); ConstCx { body, tcx, typing_env, const_kind } } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 82e0a6e6666f3..4db862afd9f6d 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -502,12 +502,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { RemainderByZero(op) => RemainderByZero(eval_to_int(op)?), ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind), ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind), - MisalignedPointerDereference { ref required, ref found } => { - MisalignedPointerDereference { - required: eval_to_int(required)?, - found: eval_to_int(found)?, - } - } + MisalignedPointerDereference { required, found } => MisalignedPointerDereference { + required: eval_to_int(required)?, + found: eval_to_int(found)?, + }, NullPointerDereference => NullPointerDereference, }; Err(ConstEvalErrKind::AssertFailure(err)).into() diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index b53c1505f6b18..7b706334ed85e 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -430,10 +430,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; let erased_trait_ref = ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref); - assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env( - erased_trait_ref, - self.tcx.instantiate_bound_regions_with_erased(b) - ))); + assert_eq!( + data_b.principal().map(|b| { + self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b) + }), + Some(erased_trait_ref), + ); } else { // In this case codegen would keep using the old vtable. We don't want to do // that as it has the wrong trait. The reason codegen can do this is that diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 66a75113652f1..c1948e9f31f10 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -4,9 +4,6 @@ use either::{Left, Right}; use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout}; use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::infer::at::ToTrace; -use rustc_infer::traits::ObligationCause; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ @@ -17,8 +14,7 @@ use rustc_middle::{mir, span_bug}; use rustc_session::Limit; use rustc_span::Span; use rustc_target::callconv::FnAbi; -use rustc_trait_selection::traits::ObligationCtxt; -use tracing::{debug, instrument, trace}; +use tracing::{debug, trace}; use super::{ Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine, @@ -320,40 +316,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - /// Check if the two things are equal in the current param_env, using an infcx to get proper - /// equality checks. - #[instrument(level = "trace", skip(self), ret)] - pub(super) fn eq_in_param_env(&self, a: T, b: T) -> bool - where - T: PartialEq + TypeFoldable> + ToTrace<'tcx>, - { - // Fast path: compare directly. - if a == b { - return true; - } - // Slow path: spin up an inference context to check if these traits are sufficiently equal. - let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); - let ocx = ObligationCtxt::new(&infcx); - let cause = ObligationCause::dummy_with_span(self.cur_span()); - // equate the two trait refs after normalization - let a = ocx.normalize(&cause, param_env, a); - let b = ocx.normalize(&cause, param_env, b); - - if let Err(terr) = ocx.eq(&cause, param_env, a, b) { - trace!(?terr); - return false; - } - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - trace!(?errors); - return false; - } - - // All good. - true - } - /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a /// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic, /// and is primarily intended for the panic machinery. diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index e14cc1dad3634..43631330f89bf 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -61,8 +61,8 @@ impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> { /// already mutable (as a sanity check). /// /// Returns an iterator over all relocations referred to by this allocation. -fn intern_shallow<'rt, 'tcx, T, M: CompileTimeMachine<'tcx, T>>( - ecx: &'rt mut InterpCx<'tcx, M>, +fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>( + ecx: &mut InterpCx<'tcx, M>, alloc_id: AllocId, mutability: Mutability, ) -> Result + 'tcx, ()> { diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 5d905cff1f216..36da9037e43d9 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -385,7 +385,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { (Immediate::Uninit, _) => Immediate::Uninit, // If the field is uninhabited, we can forget the data (can happen in ConstProp). // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that - // has an `Uninhabited` variant, which means this case is possible. + // has an uninhabited variant, which means this case is possible. _ if layout.is_uninhabited() => Immediate::Uninit, // the field contains no information, can be left uninit // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST) diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 4cfaacebfcd0e..a5029eea5a796 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -86,21 +86,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type }); } + // This checks whether there is a subtyping relation between the predicates in either direction. + // For example: + // - casting between `dyn for<'a> Trait` and `dyn Trait` is OK + // - casting between `dyn Trait fn(&'a u8)>` and either of the above is UB for (a_pred, b_pred) in std::iter::zip(sorted_vtable, sorted_expected) { - let is_eq = match (a_pred.skip_binder(), b_pred.skip_binder()) { - ( - ty::ExistentialPredicate::Trait(a_data), - ty::ExistentialPredicate::Trait(b_data), - ) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)), + let a_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, a_pred); + let b_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b_pred); - ( - ty::ExistentialPredicate::Projection(a_data), - ty::ExistentialPredicate::Projection(b_data), - ) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)), - - _ => false, - }; - if !is_eq { + if a_pred != b_pred { throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type }); } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 0ac34f4633b57..40dec0cb39e7b 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1264,21 +1264,20 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, } } - // *After* all of this, check the ABI. We need to check the ABI to handle - // types like `NonNull` where the `Scalar` info is more restrictive than what - // the fields say (`rustc_layout_scalar_valid_range_start`). - // But in most cases, this will just propagate what the fields say, - // and then we want the error to point at the field -- so, first recurse, - // then check ABI. + // *After* all of this, check further information stored in the layout. We need to check + // this to handle types like `NonNull` where the `Scalar` info is more restrictive than what + // the fields say (`rustc_layout_scalar_valid_range_start`). But in most cases, this will + // just propagate what the fields say, and then we want the error to point at the field -- + // so, we first recurse, then we do this check. // // FIXME: We could avoid some redundant checks here. For newtypes wrapping // scalars, we do the same check on every "level" (e.g., first we check // MyNewtype and then the scalar in there). + if val.layout.is_uninhabited() { + let ty = val.layout.ty; + throw_validation_failure!(self.path, UninhabitedVal { ty }); + } match val.layout.backend_repr { - BackendRepr::Uninhabited => { - let ty = val.layout.ty; - throw_validation_failure!(self.path, UninhabitedVal { ty }); - } BackendRepr::Scalar(scalar_layout) => { if !scalar_layout.is_uninit_valid() { // There is something to check here. diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 79baf91c3ce64..6426bca2332d4 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -111,13 +111,15 @@ fn check_validity_requirement_lax<'tcx>( }; // Check the ABI. - let valid = match this.backend_repr { - BackendRepr::Uninhabited => false, // definitely UB - BackendRepr::Scalar(s) => scalar_allows_raw_init(s), - BackendRepr::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), - BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), - BackendRepr::Memory { .. } => true, // Fields are checked below. - }; + let valid = !this.is_uninhabited() // definitely UB if uninhabited + && match this.backend_repr { + BackendRepr::Scalar(s) => scalar_allows_raw_init(s), + BackendRepr::ScalarPair(s1, s2) => { + scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2) + } + BackendRepr::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), + BackendRepr::Memory { .. } => true, // Fields are checked below. + }; if !valid { // This is definitely not okay. return Ok(false); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index a8f83ca13e267..bdf5494f2107b 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_data_structures" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -18,6 +18,7 @@ rustc-rayon = { version = "0.5.1", features = ["indexmap"] } rustc-stable-hash = { version = "0.1.0", features = ["nightly"] } rustc_arena = { path = "../rustc_arena" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", package = "rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index 16c66824c5ba1..c7c0d0ab0725d 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,10 +1,9 @@ use std::hash::{Hash, Hasher}; +use rustc_hashes::Hash64; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use crate::stable_hasher::{ - FromStableHash, Hash64, StableHasherHash, impl_stable_traits_for_trivial_type, -}; +use crate::stable_hasher::{FromStableHash, StableHasherHash, impl_stable_traits_for_trivial_type}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs index 292a33d56469a..d423d8acefd0a 100644 --- a/compiler/rustc_data_structures/src/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs @@ -4,31 +4,6 @@ //! green/native threading. This is just a bare-bones enough solution for //! librustdoc, it is not production quality at all. -#[cfg(bootstrap)] -cfg_match! { - cfg(target_os = "linux") => { - mod linux; - use linux as imp; - } - cfg(target_os = "redox") => { - mod linux; - use linux as imp; - } - cfg(unix) => { - mod unix; - use unix as imp; - } - cfg(windows) => { - mod windows; - use self::windows as imp; - } - _ => { - mod unsupported; - use unsupported as imp; - } -} - -#[cfg(not(bootstrap))] cfg_match! { target_os = "linux" => { mod linux; diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs index 7724e9347d822..a80365938b96c 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs @@ -193,11 +193,11 @@ impl Graph { AdjacentEdges { graph: self, direction, next: first_edge } } - pub fn successor_nodes(&self, source: NodeIndex) -> impl Iterator + '_ { + pub fn successor_nodes(&self, source: NodeIndex) -> impl Iterator { self.outgoing_edges(source).targets() } - pub fn predecessor_nodes(&self, target: NodeIndex) -> impl Iterator + '_ { + pub fn predecessor_nodes(&self, target: NodeIndex) -> impl Iterator { self.incoming_edges(target).sources() } @@ -255,11 +255,11 @@ pub struct AdjacentEdges<'g, N, E> { } impl<'g, N: Debug, E: Debug> AdjacentEdges<'g, N, E> { - fn targets(self) -> impl Iterator + 'g { + fn targets(self) -> impl Iterator { self.map(|(_, edge)| edge.target) } - fn sources(self) -> impl Iterator + 'g { + fn sources(self) -> impl Iterator { self.map(|(_, edge)| edge.source) } } diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 93f6192b10b03..e7c4ea3daae45 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -133,7 +133,7 @@ impl Sccs { /// meaning that if `S1 -> S2`, we will visit `S2` first and `S1` after. /// This is convenient when the edges represent dependencies: when you visit /// `S1`, the value for `S2` will already have been computed. - pub fn all_sccs(&self) -> impl Iterator { + pub fn all_sccs(&self) -> impl Iterator + 'static { (0..self.scc_data.len()).map(S::new) } diff --git a/compiler/rustc_data_structures/src/intern.rs b/compiler/rustc_data_structures/src/intern.rs index 850b052f564b7..8079212fac551 100644 --- a/compiler/rustc_data_structures/src/intern.rs +++ b/compiler/rustc_data_structures/src/intern.rs @@ -92,7 +92,10 @@ impl<'a, T: Ord> Ord for Interned<'a, T> { } } -impl<'a, T> Hash for Interned<'a, T> { +impl<'a, T> Hash for Interned<'a, T> +where + T: Hash, +{ #[inline] fn hash(&self, s: &mut H) { // Pointer hashing is sufficient, due to the uniqueness constraint. diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 6ef73debadd50..66d3834d85784 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -84,7 +84,6 @@ pub mod vec_cache; pub mod work_queue; mod atomic_ref; -mod hashes; /// This calls the passed function while ensuring it won't be inlined into the caller. #[inline(never)] diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 18e98e6c39fa9..39db551adfb84 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -860,69 +860,6 @@ fn get_thread_id() -> u32 { } // Memory reporting -#[cfg(bootstrap)] -cfg_match! { - cfg(windows) => { - pub fn get_resident_set_size() -> Option { - use std::mem; - - use windows::{ - Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, - Win32::System::Threading::GetCurrentProcess, - }; - - let mut pmc = PROCESS_MEMORY_COUNTERS::default(); - let pmc_size = mem::size_of_val(&pmc); - unsafe { - K32GetProcessMemoryInfo( - GetCurrentProcess(), - &mut pmc, - pmc_size as u32, - ) - } - .ok() - .ok()?; - - Some(pmc.WorkingSetSize) - } - } - cfg(target_os = "macos") => { - pub fn get_resident_set_size() -> Option { - use libc::{c_int, c_void, getpid, proc_pidinfo, proc_taskinfo, PROC_PIDTASKINFO}; - use std::mem; - const PROC_TASKINFO_SIZE: c_int = mem::size_of::() as c_int; - - unsafe { - let mut info: proc_taskinfo = mem::zeroed(); - let info_ptr = &mut info as *mut proc_taskinfo as *mut c_void; - let pid = getpid() as c_int; - let ret = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, info_ptr, PROC_TASKINFO_SIZE); - if ret == PROC_TASKINFO_SIZE { - Some(info.pti_resident_size as usize) - } else { - None - } - } - } - } - cfg(unix) => { - pub fn get_resident_set_size() -> Option { - let field = 1; - let contents = fs::read("/proc/self/statm").ok()?; - let contents = String::from_utf8(contents).ok()?; - let s = contents.split_whitespace().nth(field)?; - let npages = s.parse::().ok()?; - Some(npages * 4096) - } - } - _ => { - pub fn get_resident_set_size() -> Option { - None - } - } -} - -#[cfg(not(bootstrap))] cfg_match! { windows => { pub fn get_resident_set_size() -> Option { diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index e9a5fb5197548..1654867739f0d 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -84,7 +84,7 @@ impl SortedIndexMultiMap { /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. #[inline] - pub fn get_by_key(&self, key: K) -> impl Iterator + '_ { + pub fn get_by_key(&self, key: K) -> impl Iterator { self.get_by_key_enumerated(key).map(|(_, v)| v) } @@ -94,7 +94,7 @@ impl SortedIndexMultiMap { /// If there are multiple items that are equivalent to `key`, they will be yielded in /// insertion order. #[inline] - pub fn get_by_key_enumerated(&self, key: K) -> impl Iterator + '_ { + pub fn get_by_key_enumerated(&self, key: K) -> impl Iterator { let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key); self.idx_sorted_by_item_key[lower_bound..].iter().map_while(move |&i| { let (k, v) = &self.items[i]; diff --git a/compiler/rustc_data_structures/src/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs index def7a7112fb3f..ea4d2f1feacc0 100644 --- a/compiler/rustc_data_structures/src/sorted_map/tests.rs +++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs @@ -24,7 +24,7 @@ fn test_sorted_index_multi_map() { // `get_by_key` returns items in insertion order. let twos: Vec<_> = set.get_by_key_enumerated(2).collect(); let idxs: Vec = twos.iter().map(|(i, _)| *i).collect(); - let values: Vec = twos.iter().map(|(_, &v)| v).collect(); + let values: Vec = twos.iter().map(|&(_, &v)| v).collect(); assert_eq!(idxs, vec![0, 2, 4]); assert_eq!(values, vec![0, 1, 2]); diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index 3200249a2dc4c..827c82fa46a11 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -165,7 +165,7 @@ impl SsoHashMap { /// Clears the map, returning all key-value pairs as an iterator. Keeps the /// allocated memory for reuse. - pub fn drain(&mut self) -> impl Iterator + '_ { + pub fn drain(&mut self) -> impl Iterator { match self { SsoHashMap::Array(array) => Either::Left(array.drain(..)), SsoHashMap::Map(map) => Either::Right(map.drain()), diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs index a4b40138933de..e3fa1cbf4cc57 100644 --- a/compiler/rustc_data_structures/src/sso/set.rs +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -80,7 +80,7 @@ impl SsoHashSet { /// Clears the set, returning all elements in an iterator. #[inline] - pub fn drain(&mut self) -> impl Iterator + '_ { + pub fn drain(&mut self) -> impl Iterator { self.map.drain().map(entry_to_key) } } diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 9cd0cc499ca32..ffbe54d620612 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -10,12 +10,11 @@ use smallvec::SmallVec; #[cfg(test)] mod tests; +use rustc_hashes::{Hash64, Hash128}; pub use rustc_stable_hash::{ FromStableHash, SipHasher128Hash as StableHasherHash, StableSipHasher128 as StableHasher, }; -pub use crate::hashes::{Hash64, Hash128}; - /// Something that implements `HashStable` can be hashed in a way that is /// stable across multiple compilation sessions. /// diff --git a/compiler/rustc_data_structures/src/stack.rs b/compiler/rustc_data_structures/src/stack.rs index 102b364091154..3d6d000348324 100644 --- a/compiler/rustc_data_structures/src/stack.rs +++ b/compiler/rustc_data_structures/src/stack.rs @@ -17,18 +17,6 @@ const STACK_PER_RECURSION: usize = 16 * 1024 * 1024; // 16MB /// /// Should not be sprinkled around carelessly, as it causes a little bit of overhead. #[inline] -#[cfg(not(miri))] pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f) } - -/// Grows the stack on demand to prevent stack overflow. Call this in strategic locations -/// to "break up" recursive calls. E.g. almost any call to `visit_expr` or equivalent can benefit -/// from this. -/// -/// Should not be sprinkled around carelessly, as it causes a little bit of overhead. -#[cfg(miri)] -#[inline] -pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { - f() -} diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs index 21ec5cf6c13bf..afbb0cef9f956 100644 --- a/compiler/rustc_data_structures/src/sync/vec.rs +++ b/compiler/rustc_data_structures/src/sync/vec.rs @@ -45,14 +45,14 @@ impl AppendOnlyVec { self.vec.read().get(i).copied() } - pub fn iter_enumerated(&self) -> impl Iterator + '_ { + pub fn iter_enumerated(&self) -> impl Iterator { (0..) .map(|i| (i, self.get(i))) .take_while(|(_, o)| o.is_some()) .filter_map(|(i, o)| Some((i, o?))) } - pub fn iter(&self) -> impl Iterator + '_ { + pub fn iter(&self) -> impl Iterator { (0..).map(|i| self.get(i)).take_while(|o| o.is_some()).flatten() } } diff --git a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs index b1bdee18d6d43..9c1e4cefa6923 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/tests.rs @@ -1,7 +1,8 @@ use std::ptr; +use rustc_hashes::Hash128; + use super::*; -use crate::hashes::Hash128; use crate::stable_hasher::{HashStable, StableHasher}; /// A tag type used in [`TaggedRef`] tests. diff --git a/compiler/rustc_data_structures/src/transitive_relation.rs b/compiler/rustc_data_structures/src/transitive_relation.rs index e81ebb9a4be22..33ac279f3e0ae 100644 --- a/compiler/rustc_data_structures/src/transitive_relation.rs +++ b/compiler/rustc_data_structures/src/transitive_relation.rs @@ -363,7 +363,7 @@ impl TransitiveRelation { /// Lists all the base edges in the graph: the initial _non-transitive_ set of element /// relations, which will be later used as the basis for the transitive closure computation. - pub fn base_edges(&self) -> impl Iterator + '_ { + pub fn base_edges(&self) -> impl Iterator { self.edges .iter() .map(move |edge| (self.elements[edge.source.0], self.elements[edge.target.0])) diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index ae9712ad66d83..e3ee83512952a 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_driver" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] crate-type = ["dylib"] diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 0b45e5786e83d..8593d1faba264 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_driver_impl" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 093ee659bb42a..828a14e707c50 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -164,8 +164,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { if let pprust_hir::AnnNode::Expr(expr) = node { let typeck_results = self.maybe_typeck_results.get().or_else(|| { self.tcx - .hir() - .maybe_body_owned_by(expr.hir_id.owner.def_id) + .hir_maybe_body_owned_by(expr.hir_id.owner.def_id) .map(|body_id| self.tcx.typeck_body(body_id.id())) }); @@ -317,7 +316,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { rustc_hir_analysis::check_crate(tcx); tcx.dcx().abort_if_errors(); debug!("pretty printing THIR tree"); - for did in tcx.hir().body_owners() { + for did in tcx.hir_body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, thir_tree(tcx, did)); } out @@ -328,7 +327,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { rustc_hir_analysis::check_crate(tcx); tcx.dcx().abort_if_errors(); debug!("pretty printing THIR flat"); - for did in tcx.hir().body_owners() { + for did in tcx.hir_body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, thir_flat(tcx, did)); } out diff --git a/compiler/rustc_driver_impl/src/signal_handler.rs b/compiler/rustc_driver_impl/src/signal_handler.rs index 08b7d937661fb..e7bc57c9749b5 100644 --- a/compiler/rustc_driver_impl/src/signal_handler.rs +++ b/compiler/rustc_driver_impl/src/signal_handler.rs @@ -6,6 +6,15 @@ use std::{fmt, mem, ptr, slice}; use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE}; +/// Signals that represent that we have a bug, and our prompt termination has +/// been ordered. +#[rustfmt::skip] +const KILL_SIGNALS: [(libc::c_int, &str); 3] = [ + (libc::SIGILL, "SIGILL"), + (libc::SIGBUS, "SIGBUS"), + (libc::SIGSEGV, "SIGSEGV") +]; + unsafe extern "C" { fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int); } @@ -39,8 +48,19 @@ macro raw_errln($tokens:tt) { /// # Safety /// /// Caller must ensure that this function is not re-entered. -unsafe extern "C" fn print_stack_trace(_: libc::c_int) { +unsafe extern "C" fn print_stack_trace(signum: libc::c_int) { const MAX_FRAMES: usize = 256; + + let signame = { + let mut signame = ""; + for sig in KILL_SIGNALS { + if sig.0 == signum { + signame = sig.1; + } + } + signame + }; + let stack = unsafe { // Reserve data segment so we don't have to malloc in a signal handler, which might fail // in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking @@ -54,7 +74,8 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) { }; // Just a stack trace is cryptic. Explain what we're doing. - raw_errln!("error: rustc interrupted by SIGSEGV, printing backtrace\n"); + raw_errln!("error: rustc interrupted by {signame}, printing backtrace\n"); + let mut written = 1; let mut consumed = 0; // Begin elaborating return addrs into symbols and writing them directly to stderr @@ -94,7 +115,7 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) { written += rem.len() + 1; let random_depth = || 8 * 16; // chosen by random diceroll (2d20) - if cyclic || stack.len() > random_depth() { + if (cyclic || stack.len() > random_depth()) && signum == libc::SIGSEGV { // technically speculation, but assert it with confidence anyway. // rustc only arrived in this signal handler because bad things happened // and this message is for explaining it's not the programmer's fault @@ -106,17 +127,22 @@ unsafe extern "C" fn print_stack_trace(_: libc::c_int) { written += 1; } raw_errln!("note: we would appreciate a report at https://github.com/rust-lang/rust"); - // get the current stack size WITHOUT blocking and double it - let new_size = STACK_SIZE.get().copied().unwrap_or(DEFAULT_STACK_SIZE) * 2; - raw_errln!("help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}"); - written += 2; + written += 1; + if signum == libc::SIGSEGV { + // get the current stack size WITHOUT blocking and double it + let new_size = STACK_SIZE.get().copied().unwrap_or(DEFAULT_STACK_SIZE) * 2; + raw_errln!( + "help: you can increase rustc's stack size by setting RUST_MIN_STACK={new_size}" + ); + written += 1; + } if written > 24 { - // We probably just scrolled the earlier "we got SIGSEGV" message off the terminal - raw_errln!("note: backtrace dumped due to SIGSEGV! resuming signal"); + // We probably just scrolled the earlier "interrupted by {signame}" message off the terminal + raw_errln!("note: backtrace dumped due to {signame}! resuming signal"); }; } -/// When SIGSEGV is delivered to the process, print a stack trace and then exit. +/// When one of the KILL signals is delivered to the process, print a stack trace and then exit. pub(super) fn install() { unsafe { let alt_stack_size: usize = min_sigstack_size() + 64 * 1024; @@ -129,7 +155,9 @@ pub(super) fn install() { sa.sa_sigaction = print_stack_trace as libc::sighandler_t; sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; libc::sigemptyset(&mut sa.sa_mask); - libc::sigaction(libc::SIGSEGV, &sa, ptr::null_mut()); + for (signum, _signame) in KILL_SIGNALS { + libc::sigaction(signum, &sa, ptr::null_mut()); + } } } diff --git a/compiler/rustc_error_codes/Cargo.toml b/compiler/rustc_error_codes/Cargo.toml index de668b81b7e07..55b4e89905126 100644 --- a/compiler/rustc_error_codes/Cargo.toml +++ b/compiler/rustc_error_codes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_error_codes" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_error_codes/src/error_codes/E0803.md b/compiler/rustc_error_codes/src/error_codes/E0803.md new file mode 100644 index 0000000000000..4c022688a2ded --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0803.md @@ -0,0 +1,46 @@ +A trait implementation returns a reference without an +explicit lifetime linking it to `self`. +It commonly arises in generic trait implementations +requiring explicit lifetime bounds. + +Erroneous code example: + +```compile_fail,E0803 +trait DataAccess { + fn get_ref(&self) -> T; +} + +struct Container<'a> { + value: &'a f64, +} + +// Attempting to implement reference return +impl<'a> DataAccess<&f64> for Container<'a> { + fn get_ref(&self) -> &f64 { // Error: Lifetime mismatch + self.value + } +} +``` + +The trait method returns &f64 requiring an independent lifetime +The struct Container<'a> carries lifetime parameter 'a +The compiler cannot verify if the returned reference satisfies 'a constraints +Solution +Explicitly bind lifetimes to clarify constraints: +``` +// Modified trait with explicit lifetime binding +trait DataAccess<'a, T> { + fn get_ref(&'a self) -> T; +} + +struct Container<'a> { + value: &'a f64, +} + +// Correct implementation (bound lifetimes) +impl<'a> DataAccess<'a, &'a f64> for Container<'a> { + fn get_ref(&'a self) -> &'a f64 { + self.value + } +} +``` diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index e970b16f61064..098ca42be2b44 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -546,6 +546,7 @@ E0799: 0799, E0800: 0800, E0801: 0801, E0802: 0802, +E0803: 0803, ); ) } diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 6974c12f994b1..578af7fc51d40 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_error_messages" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index fbb6a1cc47559..c1d8cd9bb9ed2 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_errors" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -14,6 +14,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 634afacf53900..f7f842393084b 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2216,12 +2216,7 @@ impl HumanEmitter { if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add = show_code_change { - for mut part in parts { - // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the - // suggestion and snippet to look as if we just suggested to add - // `"b"`, which is typically much easier for the user to understand. - part.trim_trivial_replacements(sm); - + for part in parts { let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) { snippet } else { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8ff5dc1259697..ceed0cd94fc91 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -58,19 +58,20 @@ pub use emitter::ColorConfig; use emitter::{DynEmitter, Emitter, is_case_difference, is_different}; use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{DynSend, Lock}; pub use rustc_error_messages::{ DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, fallback_fluent_bundle, fluent_bundle, }; +use rustc_hashes::Hash128; use rustc_lint_defs::LintExpectationId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; use rustc_span::source_map::SourceMap; -use rustc_span::{DUMMY_SP, Loc, Span}; +use rustc_span::{BytePos, DUMMY_SP, Loc, Span}; pub use snippet::Style; // Used by external projects such as `rust-gpu`. // See https://github.com/rust-lang/rust/pull/115393. @@ -236,10 +237,9 @@ impl SubstitutionPart { /// it with "abx" is, since the "c" character is lost. pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool { self.is_replacement(sm) - && !sm.span_to_snippet(self.span).is_ok_and(|snippet| { - self.snippet.trim_start().starts_with(snippet.trim_start()) - || self.snippet.trim_end().ends_with(snippet.trim_end()) - }) + && !sm + .span_to_snippet(self.span) + .is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some()) } fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool { @@ -256,16 +256,40 @@ impl SubstitutionPart { let Ok(snippet) = sm.span_to_snippet(self.span) else { return; }; - if self.snippet.starts_with(&snippet) { - self.span = self.span.shrink_to_hi(); - self.snippet = self.snippet[snippet.len()..].to_string(); - } else if self.snippet.ends_with(&snippet) { - self.span = self.span.shrink_to_lo(); - self.snippet = self.snippet[..self.snippet.len() - snippet.len()].to_string(); + + if let Some((prefix, substr, suffix)) = as_substr(&snippet, &self.snippet) { + self.span = Span::new( + self.span.lo() + BytePos(prefix as u32), + self.span.hi() - BytePos(suffix as u32), + self.span.ctxt(), + self.span.parent(), + ); + self.snippet = substr.to_string(); } } } +/// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect +/// the case where a substring of the suggestion is "sandwiched" in the original, like +/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length +/// of the suffix. +fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> { + let common_prefix = original + .chars() + .zip(suggestion.chars()) + .take_while(|(c1, c2)| c1 == c2) + .map(|(c, _)| c.len_utf8()) + .sum(); + let original = &original[common_prefix..]; + let suggestion = &suggestion[common_prefix..]; + if suggestion.ends_with(original) { + let common_suffix = original.len(); + Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix)) + } else { + None + } +} + impl CodeSuggestion { /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. @@ -379,7 +403,12 @@ impl CodeSuggestion { // or deleted code in order to point at the correct column *after* substitution. let mut acc = 0; let mut only_capitalization = false; - for part in &substitution.parts { + for part in &mut substitution.parts { + // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the + // suggestion and snippet to look as if we just suggested to add + // `"b"`, which is typically much easier for the user to understand. + part.trim_trivial_replacements(sm); + only_capitalization |= is_case_difference(sm, &part.snippet, part.span); let cur_lo = sm.lookup_char_pos(part.span.lo()); if prev_hi.line == cur_lo.line { diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index eb93972387d40..33bada106ca79 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_expand" version = "0.0.0" -edition = "2021" +edition = "2024" build = false [lib] diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 595c8c3279f41..7fe9fa7937d9f 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -1,10 +1,13 @@ use std::mem; use std::sync::Arc; -use rustc_ast::ExprKind; use rustc_ast::mut_visit::{self, MutVisitor}; -use rustc_ast::token::{self, Delimiter, IdentIsRaw, Lit, LitKind, Nonterminal, Token, TokenKind}; +use rustc_ast::token::{ + self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Nonterminal, Token, + TokenKind, +}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; +use rustc_ast::{ExprKind, TyKind}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize}; use rustc_parse::lexer::nfc_normalize; @@ -255,7 +258,7 @@ pub(super) fn transcribe<'a>( } // Replace the meta-var with the matched token tree from the invocation. - mbe::TokenTree::MetaVar(mut sp, mut original_ident) => { + &mbe::TokenTree::MetaVar(mut sp, mut original_ident) => { // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. // @@ -274,6 +277,33 @@ pub(super) fn transcribe<'a>( // some of the unnecessary whitespace. let ident = MacroRulesNormalizedIdent::new(original_ident); if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { + // We wrap the tokens in invisible delimiters, unless they are already wrapped + // in invisible delimiters with the same `MetaVarKind`. Because some proc + // macros can't multiple layers of invisible delimiters of the same + // `MetaVarKind`. This loses some span info, though it hopefully won't matter. + let mut mk_delimited = |mv_kind, mut stream: TokenStream| { + if stream.len() == 1 { + let tree = stream.iter().next().unwrap(); + if let TokenTree::Delimited(_, _, delim, inner) = tree + && let Delimiter::Invisible(InvisibleOrigin::MetaVar(mvk)) = delim + && mv_kind == *mvk + { + stream = inner.clone(); + } + } + + // Emit as a token stream within `Delimiter::Invisible` to maintain + // parsing priorities. + marker.visit_span(&mut sp); + // Both the open delim and close delim get the same span, which covers the + // `$foo` in the decl macro RHS. + TokenTree::Delimited( + DelimSpan::from_single(sp), + DelimSpacing::new(Spacing::Alone, Spacing::Alone), + Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)), + stream, + ) + }; let tt = match cur_matched { MatchedSingle(ParseNtResult::Tt(tt)) => { // `tt`s are emitted into the output stream directly as "raw tokens", @@ -292,6 +322,13 @@ pub(super) fn transcribe<'a>( let kind = token::NtLifetime(*ident, *is_raw); TokenTree::token_alone(kind, sp) } + MatchedSingle(ParseNtResult::Ty(ty)) => { + let is_path = matches!(&ty.kind, TyKind::Path(None, _path)); + mk_delimited(MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty)) + } + MatchedSingle(ParseNtResult::Vis(vis)) => { + mk_delimited(MetaVarKind::Vis, TokenStream::from_ast(vis)) + } MatchedSingle(ParseNtResult::Nt(nt)) => { // Other variables are emitted into the output stream as groups with // `Delimiter::Invisible` to maintain parsing priorities. @@ -339,7 +376,7 @@ pub(super) fn transcribe<'a>( // We will produce all of the results of the inside of the `Delimited` and then we will // jump back out of the Delimited, pop the result_stack and add the new results back to // the previous results (from outside the Delimited). - mbe::TokenTree::Delimited(mut span, spacing, delimited) => { + &mbe::TokenTree::Delimited(mut span, ref spacing, ref delimited) => { mut_visit::visit_delim_span(&mut marker, &mut span); stack.push(Frame::new_delimited(delimited, span, *spacing)); result_stack.push(mem::take(&mut result)); diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index dca0516f9f3b3..a6cdeaee176f1 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -31,7 +31,7 @@ impl pm::bridge::server::MessagePipe for MessagePipe { } } -fn exec_strategy(ecx: &ExtCtxt<'_>) -> impl pm::bridge::server::ExecutionStrategy { +fn exec_strategy(ecx: &ExtCtxt<'_>) -> impl pm::bridge::server::ExecutionStrategy + 'static { pm::bridge::server::MaybeCrossThread::>::new( ecx.sess.opts.unstable_opts.proc_macro_execution_strategy == ProcMacroExecutionStrategy::CrossThread, diff --git a/compiler/rustc_feature/Cargo.toml b/compiler/rustc_feature/Cargo.toml index 77de7fabd4f92..a5ae06473cbe3 100644 --- a/compiler/rustc_feature/Cargo.toml +++ b/compiler/rustc_feature/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_feature" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 2dfb0c8e04093..d50fe8c6a3e6b 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -387,7 +387,7 @@ declare_features! ( /// Allows `#[target_feature(...)]`. (accepted, target_feature, "1.27.0", None), /// Allows the use of `#[target_feature]` on safe functions. - (accepted, target_feature_11, "CURRENT_RUSTC_VERSION", Some(69098)), + (accepted, target_feature_11, "1.86.0", Some(69098)), /// Allows `fn main()` with return types which implements `Termination` (RFC 1937). (accepted, termination_trait, "1.26.0", Some(43301)), /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). @@ -401,7 +401,7 @@ declare_features! ( (accepted, track_caller, "1.46.0", Some(47809)), /// Allows dyn upcasting trait objects via supertraits. /// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`. - (accepted, trait_upcasting, "CURRENT_RUSTC_VERSION", Some(65991)), + (accepted, trait_upcasting, "1.86.0", Some(65991)), /// Allows #[repr(transparent)] on univariant enums (RFC 2645). (accepted, transparent_enums, "1.42.0", Some(60405)), /// Allows indexing tuples. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 8eb9bf1582902..b2ada8fe61ef0 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -743,7 +743,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_autodiff, Normal, template!(Word, List: r#""...""#), DuplicatesOk, - EncodeCrossCrate::No, INTERNAL_UNSTABLE + EncodeCrossCrate::Yes, INTERNAL_UNSTABLE ), // ========================================================================== diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 2fb0c8e43448a..60e7788f2c05d 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -135,6 +135,8 @@ declare_features! ( Some("removed as it caused some confusion and discussion was inactive for years")), /// Lazily evaluate constants. This allows constants to depend on type parameters. (removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")), + /// Changes `impl Trait` to capture all lifetimes in scope. + (removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")), /// Allows using the `#[link_args]` attribute. (removed, link_args, "1.53.0", Some(29596), Some("removed in favor of using `-C link-arg=ARG` on command line, \ diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e852f239aa27c..fe643e9a7d1d8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -203,7 +203,7 @@ declare_features! ( /// Allows using anonymous lifetimes in argument-position impl-trait. (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None), /// Allows access to the emscripten_wasm_eh config, used by panic_unwind and unwind - (internal, cfg_emscripten_wasm_eh, "CURRENT_RUSTC_VERSION", None), + (internal, cfg_emscripten_wasm_eh, "1.86.0", None), /// Allows identifying the `compiler_builtins` crate. (internal, compiler_builtins, "1.13.0", None), /// Allows writing custom MIR @@ -214,8 +214,6 @@ declare_features! ( (internal, intrinsics, "1.0.0", None), /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. (internal, lang_items, "1.0.0", None), - /// Changes `impl Trait` to capture all lifetimes in scope. - (unstable, lifetime_capture_rules_2024, "1.76.0", None), /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406 (internal, link_cfg, "1.14.0", None), /// Allows using `?Trait` trait bounds in more contexts. @@ -360,7 +358,7 @@ declare_features! ( /// Allows `extern "C-cmse-nonsecure-call" fn()`. (unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391)), /// Allows `extern "gpu-kernel" fn()`. - (unstable, abi_gpu_kernel, "CURRENT_RUSTC_VERSION", Some(135467)), + (unstable, abi_gpu_kernel, "1.86.0", Some(135467)), /// Allows `extern "msp430-interrupt" fn()`. (unstable, abi_msp430_interrupt, "1.16.0", Some(38487)), /// Allows `extern "ptx-*" fn()`. @@ -404,7 +402,7 @@ declare_features! ( /// Allows the use of `#[cfg()]`. (unstable, cfg_boolean_literals, "1.83.0", Some(131204)), /// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled. - (unstable, cfg_contract_checks, "CURRENT_RUSTC_VERSION", Some(128044)), + (unstable, cfg_contract_checks, "1.86.0", Some(128044)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. (unstable, cfg_overflow_checks, "1.71.0", Some(111466)), /// Provides the relocation model information as cfg entry @@ -448,9 +446,9 @@ declare_features! ( /// Allows the `?` operator in const contexts. (unstable, const_try, "1.56.0", Some(74935)), /// Allows use of contracts attributes. - (incomplete, contracts, "CURRENT_RUSTC_VERSION", Some(128044)), + (incomplete, contracts, "1.86.0", Some(128044)), /// Allows access to internal machinery used to implement contracts. - (internal, contracts_internals, "CURRENT_RUSTC_VERSION", Some(128044)), + (internal, contracts_internals, "1.86.0", Some(128044)), /// Allows coroutines to be cloned. (unstable, coroutine_clone, "1.65.0", Some(95360)), /// Allows defining coroutines. @@ -491,7 +489,7 @@ declare_features! ( /// for functions with varargs. (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), /// Allows using `system` as a calling convention with varargs. - (unstable, extern_system_varargs, "CURRENT_RUSTC_VERSION", Some(136946)), + (unstable, extern_system_varargs, "1.86.0", Some(136946)), /// Allows defining `extern type`s. (unstable, extern_types, "1.23.0", Some(43467)), /// Allow using 128-bit (quad precision) floating point numbers. @@ -519,7 +517,7 @@ declare_features! ( /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), /// Allows any generic constants being used as pattern type range ends - (incomplete, generic_pattern_types, "CURRENT_RUSTC_VERSION", Some(136574)), + (incomplete, generic_pattern_types, "1.86.0", Some(136574)), /// Allows registering static items globally, possibly across crates, to iterate over at runtime. (unstable, global_registration, "1.80.0", Some(125119)), /// Allows using guards in patterns. @@ -535,7 +533,7 @@ declare_features! ( /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)), /// Allows `use` associated functions from traits. - (unstable, import_trait_associated_functions, "CURRENT_RUSTC_VERSION", Some(134691)), + (unstable, import_trait_associated_functions, "1.86.0", Some(134691)), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995)), /// Allow anonymous constants from an inline `const` block in pattern position @@ -543,7 +541,7 @@ declare_features! ( /// Allows using `pointer` and `reference` in intra-doc links (unstable, intra_doc_pointers, "1.51.0", Some(80896)), // Allows using the `kl` and `widekl` target features and the associated intrinsics - (unstable, keylocker_x86, "CURRENT_RUSTC_VERSION", Some(134813)), + (unstable, keylocker_x86, "1.86.0", Some(134813)), // Allows setting the threshold for the `large_assignments` lint. (unstable, large_assignments, "1.52.0", Some(83518)), /// Allow to have type alias types for inter-crate use. @@ -584,7 +582,7 @@ declare_features! ( /// Allows diverging expressions to fall back to `!` rather than `()`. (unstable, never_type_fallback, "1.41.0", Some(65992)), /// Switch `..` syntax to use the new (`Copy + IntoIterator`) range types. - (unstable, new_range, "CURRENT_RUSTC_VERSION", Some(123741)), + (unstable, new_range, "1.86.0", Some(123741)), /// Allows `#![no_core]`. (unstable, no_core, "1.3.0", Some(29639)), /// Allows the use of `no_sanitize` attribute. @@ -636,7 +634,7 @@ declare_features! ( /// Allows string patterns to dereference values to match them. (unstable, string_deref_patterns, "1.67.0", Some(87121)), /// Allows subtrait items to shadow supertrait items. - (unstable, supertrait_item_shadowing, "CURRENT_RUSTC_VERSION", Some(89151)), + (unstable, supertrait_item_shadowing, "1.86.0", Some(89151)), /// Allows using `#[thread_local]` on `static` items. (unstable, thread_local, "1.0.0", Some(29594)), /// Allows defining `trait X = A + B;` alias items. diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml index eeceaa4691a2a..ce76b2745eaad 100644 --- a/compiler/rustc_fluent_macro/Cargo.toml +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_fluent_macro" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] proc-macro = true diff --git a/compiler/rustc_fs_util/Cargo.toml b/compiler/rustc_fs_util/Cargo.toml index 4b76200c06c53..baca3bc7d49eb 100644 --- a/compiler/rustc_fs_util/Cargo.toml +++ b/compiler/rustc_fs_util/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_fs_util" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_graphviz/Cargo.toml b/compiler/rustc_graphviz/Cargo.toml index 780004ae3fbc8..d84943760baeb 100644 --- a/compiler/rustc_graphviz/Cargo.toml +++ b/compiler/rustc_graphviz/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_graphviz" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_hashes/Cargo.toml b/compiler/rustc_hashes/Cargo.toml new file mode 100644 index 0000000000000..c7a273cff88c9 --- /dev/null +++ b/compiler/rustc_hashes/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rustc_hashes" +version = "0.0.0" +edition = "2024" + +[dependencies] +# tidy-alphabetical-start +rustc-stable-hash = { version = "0.1.0" } +# tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/src/hashes.rs b/compiler/rustc_hashes/src/lib.rs similarity index 79% rename from compiler/rustc_data_structures/src/hashes.rs rename to compiler/rustc_hashes/src/lib.rs index 8f4639fc2e666..3755caaaa2963 100644 --- a/compiler/rustc_data_structures/src/hashes.rs +++ b/compiler/rustc_hashes/src/lib.rs @@ -1,6 +1,8 @@ //! rustc encodes a lot of hashes. If hashes are stored as `u64` or `u128`, a `derive(Encodable)` //! will apply varint encoding to the hashes, which is less efficient than directly encoding the 8 -//! or 16 bytes of the hash. +//! or 16 bytes of the hash. And if that hash depends on the `StableCrateHash` (which most in rustc +//! do), the varint encoding will make the number of bytes encoded fluctuate between compiler +//! versions. //! //! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`. //! `Hash64` and `Hash128` expose some utility functions to encourage users to not extract the inner @@ -14,10 +16,9 @@ use std::fmt; use std::ops::BitXorAssign; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; - -use crate::stable_hasher::{FromStableHash, StableHasherHash}; +use rustc_stable_hash::{FromStableHash, SipHasher128Hash as StableHasherHash}; +/// A `u64` but encoded with a fixed size; for hashes this encoding is more compact than `u64`. #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] pub struct Hash64 { inner: u64, @@ -35,26 +36,17 @@ impl Hash64 { pub fn as_u64(self) -> u64 { self.inner } -} -impl BitXorAssign for Hash64 { #[inline] - fn bitxor_assign(&mut self, rhs: u64) { - self.inner ^= rhs; - } -} - -impl Encodable for Hash64 { - #[inline] - fn encode(&self, s: &mut S) { - s.emit_raw_bytes(&self.inner.to_le_bytes()); + pub fn wrapping_add(self, other: Self) -> Self { + Self { inner: self.inner.wrapping_add(other.inner) } } } -impl Decodable for Hash64 { +impl BitXorAssign for Hash64 { #[inline] - fn decode(d: &mut D) -> Self { - Self { inner: u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap()) } + fn bitxor_assign(&mut self, rhs: u64) { + self.inner ^= rhs; } } @@ -79,6 +71,7 @@ impl fmt::LowerHex for Hash64 { } } +/// A `u128` but encoded with a fixed size; for hashes this encoding is more compact than `u128`. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] pub struct Hash128 { inner: u128, @@ -95,6 +88,11 @@ impl std::hash::Hash for Hash128 { } impl Hash128 { + #[inline] + pub fn new(n: u128) -> Self { + Self { inner: n } + } + #[inline] pub fn truncate(self) -> Hash64 { Hash64 { inner: self.inner as u64 } @@ -111,20 +109,6 @@ impl Hash128 { } } -impl Encodable for Hash128 { - #[inline] - fn encode(&self, s: &mut S) { - s.emit_raw_bytes(&self.inner.to_le_bytes()); - } -} - -impl Decodable for Hash128 { - #[inline] - fn decode(d: &mut D) -> Self { - Self { inner: u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) } - } -} - impl FromStableHash for Hash128 { type Hash = StableHasherHash; diff --git a/compiler/rustc_hir/Cargo.toml b/compiler/rustc_hir/Cargo.toml index 5bfc4756ec6a7..98300fc40fbeb 100644 --- a/compiler/rustc_hir/Cargo.toml +++ b/compiler/rustc_hir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_hir" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -10,6 +10,7 @@ rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_hir/src/def_path_hash_map.rs b/compiler/rustc_hir/src/def_path_hash_map.rs index 9a6dee1e511df..35c6e57b87700 100644 --- a/compiler/rustc_hir/src/def_path_hash_map.rs +++ b/compiler/rustc_hir/src/def_path_hash_map.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_span::def_id::DefIndex; #[derive(Clone, Default)] diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index dc527240f742a..c4c309e77e194 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,8 +7,9 @@ use std::fmt::{self, Write}; use std::hash::Hash; -use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_span::{Symbol, kw, sym}; @@ -92,7 +93,7 @@ impl DefPathTable { pub fn enumerated_keys_and_path_hashes( &self, - ) -> impl Iterator + ExactSizeIterator + '_ { + ) -> impl Iterator + ExactSizeIterator { self.index_to_key .iter_enumerated() .map(move |(index, key)| (index, key, self.def_path_hash(index))) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index eafc60f9d72f7..61f64e62058fc 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1913,13 +1913,18 @@ pub enum BodyOwnerKind { /// Initializer of a `static` item. Static(Mutability), + + /// Fake body for a global asm to store its const-like value types. + GlobalAsm, } impl BodyOwnerKind { pub fn is_fn_or_closure(self) -> bool { match self { BodyOwnerKind::Fn | BodyOwnerKind::Closure => true, - BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) => false, + BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => { + false + } } } } @@ -3420,7 +3425,7 @@ pub enum InlineAsmOperand<'hir> { anon_const: &'hir AnonConst, }, SymFn { - anon_const: &'hir AnonConst, + expr: &'hir Expr<'hir>, }, SymStatic { path: QPath<'hir>, @@ -3848,7 +3853,7 @@ impl<'hir> Item<'hir> { expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]), ItemKind::ForeignMod { abi, items }, (*abi, items); - expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm; + expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm; expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>), ItemKind::TyAlias(ty, generics), (ty, generics); @@ -4015,7 +4020,15 @@ pub enum ItemKind<'hir> { /// An external module, e.g. `extern { .. }`. ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] }, /// Module-level inline assembly (from `global_asm!`). - GlobalAsm(&'hir InlineAsm<'hir>), + GlobalAsm { + asm: &'hir InlineAsm<'hir>, + /// A fake body which stores typeck results for the global asm's sym_fn + /// operands, which are represented as path expressions. This body contains + /// a single [`ExprKind::InlineAsm`] which points to the asm in the field + /// above, and which is typechecked like a inline asm expr just for the + /// typeck results. + fake_body: BodyId, + }, /// A type alias, e.g., `type Foo = Bar`. TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>), /// An enum definition, e.g., `enum Foo {C, D}`. @@ -4081,7 +4094,7 @@ impl ItemKind<'_> { ItemKind::Macro(..) => "macro", ItemKind::Mod(..) => "module", ItemKind::ForeignMod { .. } => "extern block", - ItemKind::GlobalAsm(..) => "global asm item", + ItemKind::GlobalAsm { .. } => "global asm item", ItemKind::TyAlias(..) => "type alias", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", @@ -4540,6 +4553,10 @@ impl<'hir> Node<'hir> { .. }) => Some((owner_id.def_id, *body)), + Node::Item(Item { + owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, .. + }) => Some((owner_id.def_id, *fake_body)), + Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => { Some((*def_id, *body)) } diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs index 300d44355303a..f75b9662132e8 100644 --- a/compiler/rustc_hir/src/hir/tests.rs +++ b/compiler/rustc_hir/src/hir/tests.rs @@ -9,11 +9,11 @@ macro_rules! define_tests { let unambig = $kind::$variant::<'_, ()> { $($init)* }; let unambig_to_ambig = unsafe { std::mem::transmute::<_, $kind<'_, AmbigArg>>(unambig) }; - assert!(matches!(&unambig_to_ambig, $kind::$variant { $($init)* })); + assert!(matches!(&unambig_to_ambig, &$kind::$variant { $($init)* })); let ambig_to_unambig = unsafe { std::mem::transmute::<_, $kind<'_, ()>>(unambig_to_ambig) }; - assert!(matches!(&ambig_to_unambig, $kind::$variant { $($init)* })); + assert!(matches!(&ambig_to_unambig, &$kind::$variant { $($init)* })); } )*}; } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 949f8daa4dcf2..d5fa7ec366b28 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -19,7 +19,7 @@ //! - Example: Examine each expression to look for its type and do some check or other. //! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to //! `nested_filter::OnlyBodies` (and implement `maybe_tcx`), and use -//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your +//! `tcx.hir_visit_all_item_likes_in_crate(&mut visitor)`. Within your //! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke //! `intravisit::walk_expr()` to keep walking the subparts). //! - Pro: Visitor methods for any kind of HIR node, not just item-like things. @@ -31,7 +31,7 @@ //! impl into scope while visiting the impl-items, and then back out again. //! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to //! `nested_filter::All` (and implement `maybe_tcx`). Walk your crate with -//! `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`. +//! `tcx.hir_walk_toplevel_module(visitor)`. //! - Pro: Visitor methods for any kind of HIR node, not just item-like things. //! - Pro: Preserves nesting information //! - Con: Does not integrate well into dependency tracking. @@ -193,7 +193,7 @@ use nested_filter::NestedFilter; /// (this is why the module is called `intravisit`, to distinguish it /// from the AST's `visit` module, which acts differently). If you /// simply want to visit all items in the crate in some order, you -/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment +/// should call `tcx.hir_visit_all_item_likes_in_crate`. Otherwise, see the comment /// on `visit_nested_item` for details on how to visit nested items. /// /// If you want to ensure that your code handles every variant @@ -573,9 +573,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_id(item.hir_id())); walk_list!(visitor, visit_foreign_item_ref, items); } - ItemKind::GlobalAsm(asm) => { + ItemKind::GlobalAsm { asm: _, fake_body } => { try_visit!(visitor.visit_id(item.hir_id())); - try_visit!(visitor.visit_inline_asm(asm, item.hir_id())); + // Visit the fake body, which contains the asm statement. + // Therefore we should not visit the asm statement again + // outside of the body, or some visitors won't have their + // typeck results set correctly. + try_visit!(visitor.visit_nested_body(fake_body)); } ItemKind::TyAlias(ref ty, ref generics) => { try_visit!(visitor.visit_id(item.hir_id())); @@ -593,9 +597,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: defaultness: _, polarity: _, defaultness_span: _, - ref generics, - ref of_trait, - ref self_ty, + generics, + of_trait, + self_ty, items, }) => { try_visit!(visitor.visit_id(item.hir_id())); @@ -1045,7 +1049,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>( } GenericParamKind::Const { ref ty, ref default, synthetic: _ } => { try_visit!(visitor.visit_ty_unambig(ty)); - if let Some(ref default) = default { + if let Some(default) = default { try_visit!(visitor.visit_const_param_default(param.hir_id, default)); } } @@ -1401,8 +1405,8 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>( try_visit!(visitor.visit_generic_args(constraint.gen_args)); match constraint.kind { AssocItemConstraintKind::Equality { ref term } => match term { - Term::Ty(ref ty) => try_visit!(visitor.visit_ty_unambig(ty)), - Term::Const(ref c) => try_visit!(visitor.visit_const_arg_unambig(c)), + Term::Ty(ty) => try_visit!(visitor.visit_ty_unambig(ty)), + Term::Const(c) => try_visit!(visitor.visit_const_arg_unambig(c)), }, AssocItemConstraintKind::Bound { bounds } => { walk_list!(visitor, visit_param_bound, bounds) @@ -1442,10 +1446,12 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>( try_visit!(visitor.visit_expr(in_expr)); visit_opt!(visitor, visit_expr, out_expr); } - InlineAsmOperand::Const { anon_const, .. } - | InlineAsmOperand::SymFn { anon_const, .. } => { + InlineAsmOperand::Const { anon_const, .. } => { try_visit!(visitor.visit_anon_const(anon_const)); } + InlineAsmOperand::SymFn { expr, .. } => { + try_visit!(visitor.visit_expr(expr)); + } InlineAsmOperand::SymStatic { path, .. } => { try_visit!(visitor.visit_qpath(path, id, *op_sp)); } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 34c0837b25a52..f5626937ec456 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -60,7 +60,7 @@ impl LanguageItems { self.reverse_items.get(&def_id).copied() } - pub fn iter(&self) -> impl Iterator + '_ { + pub fn iter(&self) -> impl Iterator { self.items .iter() .enumerate() diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index f3e8f059c9e3c..70e95a84e68cc 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -110,7 +110,7 @@ impl Target { ItemKind::Macro(..) => Target::MacroDef, ItemKind::Mod(..) => Target::Mod, ItemKind::ForeignMod { .. } => Target::ForeignMod, - ItemKind::GlobalAsm(..) => Target::GlobalAsm, + ItemKind::GlobalAsm { .. } => Target::GlobalAsm, ItemKind::TyAlias(..) => Target::TyAlias, ItemKind::Enum(..) => Target::Enum, ItemKind::Struct(..) => Target::Struct, diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index e0e63d183c63d..0837444ffdbe5 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -1,6 +1,6 @@ #![allow(rustc::symbol_intern_string_literal)] -use rustc_data_structures::stable_hasher::Hash64; +use rustc_hashes::Hash64; use rustc_span::def_id::{DefPathHash, StableCrateId}; use rustc_span::edition::Edition; use rustc_span::{Symbol, create_session_globals_then}; diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 196d7d99e933d..55a816a855af4 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_hir_analysis" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] test = false diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 5560d087e96f0..47d5976be09ef 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -387,6 +387,8 @@ hir_analysis_must_implement_not_function_span_note = required by this annotation hir_analysis_must_implement_one_of_attribute = the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args +hir_analysis_no_variant_named = no variant named `{$ident}` found for enum `{$ty}` + hir_analysis_not_supported_delegation = {$descr} .label = callee defined here diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs deleted file mode 100644 index 9b02651a8bdf5..0000000000000 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! Bounds are restrictions applied to some types after they've been lowered from the HIR to the -//! [`rustc_middle::ty`] form. - -use rustc_hir::LangItem; -use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; -use rustc_span::Span; - -/// Collects together a list of type bounds. These lists of bounds occur in many places -/// in Rust's syntax: -/// -/// ```text -/// trait Foo: Bar + Baz { } -/// ^^^^^^^^^ supertrait list bounding the `Self` type parameter -/// -/// fn foo() { } -/// ^^^^^^^^^ bounding the type parameter `T` -/// -/// impl dyn Bar + Baz -/// ^^^^^^^^^ bounding the type-erased dynamic type -/// ``` -/// -/// Our representation is a bit mixed here -- in some cases, we -/// include the self type (e.g., `trait_bounds`) but in others we do not -#[derive(Default, PartialEq, Eq, Clone, Debug)] -pub(crate) struct Bounds<'tcx> { - clauses: Vec<(ty::Clause<'tcx>, Span)>, -} - -impl<'tcx> Bounds<'tcx> { - pub(crate) fn push_region_bound( - &mut self, - tcx: TyCtxt<'tcx>, - region: ty::PolyTypeOutlivesPredicate<'tcx>, - span: Span, - ) { - self.clauses - .push((region.map_bound(|p| ty::ClauseKind::TypeOutlives(p)).upcast(tcx), span)); - } - - pub(crate) fn push_trait_bound( - &mut self, - tcx: TyCtxt<'tcx>, - bound_trait_ref: ty::PolyTraitRef<'tcx>, - span: Span, - polarity: ty::PredicatePolarity, - ) { - let clause = ( - bound_trait_ref - .map_bound(|trait_ref| { - ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) - }) - .upcast(tcx), - span, - ); - // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. - if tcx.is_lang_item(bound_trait_ref.def_id(), LangItem::Sized) { - self.clauses.insert(0, clause); - } else { - self.clauses.push(clause); - } - } - - pub(crate) fn push_projection_bound( - &mut self, - tcx: TyCtxt<'tcx>, - projection: ty::PolyProjectionPredicate<'tcx>, - span: Span, - ) { - self.clauses.push(( - projection.map_bound(|proj| ty::ClauseKind::Projection(proj)).upcast(tcx), - span, - )); - } - - pub(crate) fn push_sized(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) { - let sized_def_id = tcx.require_lang_item(LangItem::Sized, Some(span)); - let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [ty]); - // Preferable to put this obligation first, since we report better errors for sized ambiguity. - self.clauses.insert(0, (trait_ref.upcast(tcx), span)); - } - - /// Push a `const` or `~const` bound as a `HostEffect` predicate. - pub(crate) fn push_const_bound( - &mut self, - tcx: TyCtxt<'tcx>, - bound_trait_ref: ty::PolyTraitRef<'tcx>, - constness: ty::BoundConstness, - span: Span, - ) { - if tcx.is_const_trait(bound_trait_ref.def_id()) { - self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, constness), span)); - } else { - tcx.dcx().span_delayed_bug(span, "tried to lower {host:?} bound for non-const trait"); - } - } - - pub(crate) fn clauses(&self) -> impl Iterator, Span)> + '_ { - self.clauses.iter().cloned() - } -} diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index bc0fd4b705d06..3236e0a3644d9 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -15,7 +15,6 @@ use rustc_lint_defs::builtin::{ use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::span_bug; use rustc_middle::ty::error::TypeErrorToStringExt; use rustc_middle::ty::fold::{BottomUpFolder, fold_regions}; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; @@ -35,7 +34,6 @@ use {rustc_attr_parsing as attr, rustc_hir as hir}; use super::compare_impl_item::check_type_bounds; use super::*; -use crate::check::intrinsicck::InlineAsmCtxt; pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) { if !tcx.sess.target.is_abi_supported(abi) { @@ -482,9 +480,9 @@ fn best_definition_site_of_opaque<'tcx>( None } hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => { - let scope = tcx.hir().get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); + let scope = tcx.hir_get_defining_scope(tcx.local_def_id_to_hir_id(opaque_def_id)); let found = if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator) + tcx.hir_walk_toplevel_module(&mut locator) } else { match tcx.hir_node(scope) { Node::Item(it) => locator.visit_item(it), @@ -895,13 +893,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } - DefKind::GlobalAsm => { - let it = tcx.hir().expect_item(def_id); - let hir::ItemKind::GlobalAsm(asm) = it.kind else { - span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) - }; - InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, def_id); - } _ => {} } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 84d5ec4a1e5b0..c193aad2afd00 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -501,7 +501,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?; let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id); - let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); + let return_span = tcx.hir_fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); let cause = ObligationCause::new( return_span, impl_m_def_id, @@ -1033,8 +1033,7 @@ fn report_trait_method_mismatch<'tcx>( // argument pattern and type. let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn(); let span = tcx - .hir() - .body_param_names(body) + .hir_body_param_names(body) .zip(sig.decl.inputs.iter()) .map(|(param, ty)| param.span.to(ty.span)) .next() @@ -2105,18 +2104,21 @@ pub(super) fn check_type_bounds<'tcx>( ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; - let mut obligations: Vec<_> = tcx - .explicit_item_bounds(trait_ty.def_id) - .iter_instantiated_copied(tcx, rebased_args) - .map(|(concrete_ty_bound, span)| { - debug!(?concrete_ty_bound); - traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) - }) - .collect(); + let mut obligations: Vec<_> = util::elaborate( + tcx, + tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map( + |(concrete_ty_bound, span)| { + debug!(?concrete_ty_bound); + traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) + }, + ), + ) + .collect(); // Only in a const implementation do we need to check that the `~const` item bounds hold. if tcx.is_conditionally_const(impl_ty_def_id) { - obligations.extend( + obligations.extend(util::elaborate( + tcx, tcx.explicit_implied_const_bounds(trait_ty.def_id) .iter_instantiated_copied(tcx, rebased_args) .map(|(c, span)| { @@ -2127,7 +2129,7 @@ pub(super) fn check_type_bounds<'tcx>( c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe), ) }), - ); + )); } debug!(item_bounds=?obligations); @@ -2135,26 +2137,19 @@ pub(super) fn check_type_bounds<'tcx>( // to its definition type. This should be the param-env we use to *prove* the // predicate too, but we don't do that because of performance issues. // See . - let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args); - let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity(); let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref); - for mut obligation in util::elaborate(tcx, obligations) { - let normalized_predicate = if infcx.next_trait_solver() { - obligation.predicate.fold_with(&mut ReplaceTy { - tcx, - from: trait_projection_ty, - to: impl_identity_ty, - }) - } else { - ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate) - }; - debug!(?normalized_predicate); - obligation.predicate = normalized_predicate; - - ocx.register_obligation(obligation); + for obligation in &mut obligations { + match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) { + Ok(pred) => obligation.predicate = pred, + Err(e) => { + return Err(infcx.err_ctxt().report_fulfillment_errors(e)); + } + } } + // Check that all obligations are satisfied by the implementation's // version. + ocx.register_obligations(obligations); let errors = ocx.select_all_or_error(); if !errors.is_empty() { let reported = infcx.err_ctxt().report_fulfillment_errors(errors); @@ -2166,22 +2161,6 @@ pub(super) fn check_type_bounds<'tcx>( ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types) } -struct ReplaceTy<'tcx> { - tcx: TyCtxt<'tcx>, - from: Ty<'tcx>, - to: Ty<'tcx>, -} - -impl<'tcx> TypeFolder> for ReplaceTy<'tcx> { - fn cx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if self.from == ty { self.to } else { ty.super_fold_with(self) } - } -} - /// Install projection predicates that allow GATs to project to their own /// definition types. This is not allowed in general in cases of default /// associated types in trait definitions, or when specialization is involved, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 08e0e52a4925b..d468027602cf3 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -140,6 +140,10 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) - | sym::fmul_algebraic | sym::fdiv_algebraic | sym::frem_algebraic + | sym::round_ties_even_f16 + | sym::round_ties_even_f32 + | sym::round_ties_even_f64 + | sym::round_ties_even_f128 | sym::const_eval_select => hir::Safety::Safe, _ => hir::Safety::Unsafe, }; @@ -416,26 +420,16 @@ pub fn check_intrinsic_type( sym::truncf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::truncf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::rintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::rintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::rintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::rintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - - sym::nearbyintf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::nearbyintf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::nearbyintf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::nearbyintf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), + sym::round_ties_even_f16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), + sym::round_ties_even_f32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), + sym::round_ties_even_f64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), + sym::round_ties_even_f128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), sym::roundf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), sym::roundf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), sym::roundf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), sym::roundf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::roundevenf16 => (0, 0, vec![tcx.types.f16], tcx.types.f16), - sym::roundevenf32 => (0, 0, vec![tcx.types.f32], tcx.types.f32), - sym::roundevenf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64), - sym::roundevenf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128), - sym::volatile_load | sym::unaligned_volatile_load => { (1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], param(0)) } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 90e93bdbb5075..e1727fc48a833 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_middle::bug; -use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, sym}; @@ -16,10 +16,11 @@ use rustc_target::asm::{ use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx> { +pub struct InlineAsmCtxt<'a, 'tcx: 'a> { tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: Box) -> Ty<'tcx> + 'a>, + target_features: &'tcx FxIndexSet, + expr_ty: Box) -> Ty<'tcx> + 'a>, } enum NonAsmTypeReason<'tcx> { @@ -29,25 +30,24 @@ enum NonAsmTypeReason<'tcx> { } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new_global_asm(tcx: TyCtxt<'tcx>) -> Self { + pub fn new( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, + ) -> Self { InlineAsmCtxt { tcx, typing_env: ty::TypingEnv { typing_mode: ty::TypingMode::non_body_analysis(), param_env: ty::ParamEnv::empty(), }, - get_operand_ty: Box::new(|e| bug!("asm operand in global asm: {e:?}")), + target_features: tcx.asm_target_features(def_id), + expr_ty: Box::new(get_operand_ty), } } - // FIXME(#132279): This likely causes us to incorrectly handle opaque types in their - // defining scope. - pub fn new_in_fn( - tcx: TyCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - get_operand_ty: impl Fn(&'tcx hir::Expr<'tcx>) -> Ty<'tcx> + 'a, - ) -> Self { - InlineAsmCtxt { tcx, typing_env, get_operand_ty: Box::new(get_operand_ty) } + fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { + (self.expr_ty)(expr) } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` @@ -139,9 +139,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { template: &[InlineAsmTemplatePiece], is_input: bool, tied_input: Option<(&'tcx hir::Expr<'tcx>, Option)>, - target_features: &FxIndexSet, ) -> Option { - let ty = (self.get_operand_ty)(expr); + let ty = self.expr_ty(expr); if ty.has_non_region_infer() { bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); } @@ -229,7 +228,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some((in_expr, Some(in_asm_ty))) = tied_input { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; - let in_expr_ty = (self.get_operand_ty)(in_expr); + let in_expr_ty = self.expr_ty(in_expr); self.tcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) @@ -291,7 +290,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // (!). In that case we still need the earlier check to verify that the // register class is usable at all. if let Some(feature) = feature { - if !target_features.contains(feature) { + if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); self.tcx .dcx() @@ -351,14 +350,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Some(asm_ty) } - pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: LocalDefId) { - let target_features = self.tcx.asm_target_features(enclosing_id.to_def_id()); + pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { let Some(asm_arch) = self.tcx.sess.asm_arch else { self.tcx.dcx().delayed_bug("target architecture does not support asm"); return; }; let allow_experimental_reg = self.tcx.features().asm_experimental_reg(); - for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { + for (idx, &(op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for // the enabled features. @@ -381,12 +379,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Err(msg) = reg.validate( asm_arch, self.tcx.sess.relocation_model(), - target_features, + self.target_features, &self.tcx.sess.target, op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); continue; } } @@ -401,7 +399,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { { match feature { Some(feature) => { - if target_features.contains(&feature) { + if self.target_features.contains(&feature) { missing_required_features.clear(); break; } else { @@ -426,7 +424,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -440,7 +438,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.tcx.dcx().span_err(*op_sp, msg); + self.tcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -448,52 +446,21 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } } - match *op { + match op { hir::InlineAsmOperand::In { reg, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - true, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, true, None); } hir::InlineAsmOperand::Out { reg, late: _, expr } => { if let Some(expr) = expr { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } } hir::InlineAsmOperand::InOut { reg, late: _, expr } => { - self.check_asm_operand_type( - idx, - reg, - expr, - asm.template, - false, - None, - target_features, - ); + self.check_asm_operand_type(idx, reg, expr, asm.template, false, None); } hir::InlineAsmOperand::SplitInOut { reg, late: _, in_expr, out_expr } => { - let in_ty = self.check_asm_operand_type( - idx, - reg, - in_expr, - asm.template, - true, - None, - target_features, - ); + let in_ty = + self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None); if let Some(out_expr) = out_expr { self.check_asm_operand_type( idx, @@ -502,7 +469,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { asm.template, false, Some((in_expr, in_ty)), - target_features, ); } } @@ -514,11 +480,25 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); } // Typeck has checked that SymFn refers to a function. - hir::InlineAsmOperand::SymFn { anon_const } => { - debug_assert_matches!( - self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(), - ty::Error(_) | ty::FnDef(..) - ); + hir::InlineAsmOperand::SymFn { expr } => { + let ty = self.expr_ty(expr); + match ty.kind() { + ty::FnDef(..) => {} + ty::Error(_) => {} + _ => { + self.tcx + .dcx() + .struct_span_err(op_sp, "invalid `sym` operand") + .with_span_label( + expr.span, + format!("is {} `{}`", ty.kind().article(), ty), + ) + .with_help( + "`sym` operands must refer to either a function or a static", + ) + .emit(); + } + } } // AST lowering guarantees that SymStatic points to a static. hir::InlineAsmOperand::SymStatic { .. } => {} diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 7b3c3ea2bb46b..1c5455710db8a 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -127,7 +127,7 @@ fn get_owner_return_paths( def_id: LocalDefId, ) -> Option<(LocalDefId, ReturnsVisitor<'_>)> { let hir_id = tcx.local_def_id_to_hir_id(def_id); - let parent_id = tcx.hir().get_parent_item(hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(hir_id).def_id; tcx.hir_node_by_def_id(parent_id).body_id().map(|body_id| { let body = tcx.hir_body(body_id); let mut visitor = ReturnsVisitor::default(); diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index 88dd40ba28984..255f5fee52a80 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -844,7 +844,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { fn visit_body(&mut self, body: &hir::Body<'tcx>) { let body_id = body.id(); - let owner_id = self.tcx.hir().body_owner_def_id(body_id); + let owner_id = self.tcx.hir_body_owner_def_id(body_id); debug!( "visit_body(id={:?}, span={:?}, body.id={:?}, cx.parent={:?})", @@ -855,7 +855,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> { ); self.enter_body(body.value.hir_id, |this| { - if this.tcx.hir().body_owner_kind(owner_id).is_fn_or_closure() { + if this.tcx.hir_body_owner_kind(owner_id).is_fn_or_closure() { // The arguments and `self` are parented to the fn. this.cx.var_parent = this.cx.parent.take(); for param in body.params { @@ -924,7 +924,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree { return tcx.region_scope_tree(typeck_root_def_id); } - let scope_tree = if let Some(body) = tcx.hir().maybe_body_owned_by(def_id.expect_local()) { + let scope_tree = if let Some(body) = tcx.hir_maybe_body_owned_by(def_id.expect_local()) { let mut visitor = ScopeResolutionVisitor { tcx, scope_tree: ScopeTree::default(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 01b4a5649f14c..e6ea6eddcaaf3 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::query::Providers; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, @@ -143,33 +142,7 @@ where return Ok(()); } - let is_bevy = 'is_bevy: { - // We don't want to emit this for dependents of Bevy, for now. - // See #119956 - let is_bevy_paramset = |def: ty::AdtDef<'_>| { - let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did)); - adt_did.contains("ParamSet") - }; - for ty in assumed_wf_types.iter() { - match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - ty::Ref(_, ty, _) => match ty.kind() { - ty::Adt(def, _) => { - if is_bevy_paramset(*def) { - break 'is_bevy true; - } - } - _ => {} - }, - _ => {} - } - } - false - }; + let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break(); // If we have set `no_implied_bounds_compat`, then do not attempt compatibility. // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`, @@ -194,6 +167,31 @@ where } } +struct ContainsBevyParamSet<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> TypeVisitor> for ContainsBevyParamSet<'tcx> { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + // We only care to match `ParamSet` or `&ParamSet`. + match t.kind() { + ty::Adt(def, _) => { + if self.tcx.item_name(def.did()) == sym::ParamSet + && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs + { + return ControlFlow::Break(()); + } + } + ty::Ref(_, ty, _) => ty.visit_with(self)?, + _ => {} + } + + ControlFlow::Continue(()) + } +} + fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let node = tcx.hir_node_by_def_id(def_id); let mut res = match node { @@ -855,7 +853,7 @@ fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { /// In such cases, suggest using `Self` instead. fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) { let (trait_name, trait_def_id) = - match tcx.hir_node_by_def_id(tcx.hir().get_parent_item(item.hir_id()).def_id) { + match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) { hir::Node::Item(item) => match item.kind { hir::ItemKind::Trait(..) => (item.ident, item.owner_id), _ => return, @@ -1710,7 +1708,7 @@ fn check_sized_if_body<'tcx>( maybe_span: Option, ) { let tcx = wfcx.tcx(); - if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) { + if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) { let span = maybe_span.unwrap_or(body.value.span); wfcx.register_bound( diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 68b7b44c36d67..750c09887a1e5 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -13,11 +13,11 @@ pub(crate) fn provide(providers: &mut Providers) { fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { let mut used_trait_imports = UnordSet::::default(); - // FIXME: Use `tcx.hir().par_body_owners()` when we implement creating `DefId`s + // FIXME: Use `tcx.hir_par_body_owners()` when we implement creating `DefId`s // for anon constants during their parents' typeck. // Doing so at current will produce queries cycle errors because it may typeck // on anon constants directly. - for item_def_id in tcx.hir().body_owners() { + for item_def_id in tcx.hir_body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); used_trait_imports.extend_unord(imports.items().copied()); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 1805e2438afa5..c9a9180c5c9dc 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -113,7 +113,7 @@ impl<'tcx> InherentCollect<'tcx> { ty: Ty<'tcx>, ) -> Result<(), ErrorGuaranteed> { let items = self.tcx.associated_item_def_ids(impl_def_id); - if !self.tcx.hir().rustc_coherence_is_core() { + if !self.tcx.hir_rustc_coherence_is_core() { if self.tcx.features().rustc_attrs() { for &impl_item in items { if !self.tcx.has_attr(impl_item, sym::rustc_allow_incoherent_impl) { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 75ea207a06bb1..dd91d70b004bb 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -20,7 +20,6 @@ use std::ops::Bound; use rustc_abi::ExternAbi; use rustc_ast::Recovered; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_errors::{ @@ -469,7 +468,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> { let item = self .tcx .hir() - .expect_item(self.tcx.hir().get_parent_item(self.hir_id()).def_id); + .expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id); match &item.kind { hir::ItemKind::Enum(_, generics) | hir::ItemKind::Struct(_, generics) @@ -680,7 +679,7 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { | hir::ItemKind::Use(..) | hir::ItemKind::Macro(..) | hir::ItemKind::Mod(_) - | hir::ItemKind::GlobalAsm(_) => {} + | hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::ForeignMod { items, .. } => { for item in *items { let item = tcx.hir_foreign_item(item.id); @@ -1349,7 +1348,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn } Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { - let adt_def_id = tcx.hir().get_parent_item(hir_id).def_id.to_def_id(); + let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id(); let ty = tcx.type_of(adt_def_id).instantiate_identity(); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity()); // constructors for structs with `layout_scalar_valid_range` are unsafe to call @@ -1690,10 +1689,10 @@ fn polarity_of_impl( /// the lifetimes that are declared. For fns or methods, we have to /// screen out those that do not appear in any where-clauses etc using /// `resolve_lifetime::early_bound_lifetimes`. -fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>( +fn early_bound_lifetimes_from_generics<'a, 'tcx>( tcx: TyCtxt<'tcx>, generics: &'a hir::Generics<'a>, -) -> impl Iterator> + Captures<'tcx> { +) -> impl Iterator> { generics.params.iter().filter(move |param| match param.kind { GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id), _ => false, diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index c0902398a54ae..2cdd9a3a9348a 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -71,7 +71,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { | Node::Variant(_) | Node::Ctor(..) | Node::Field(_) => { - let parent_id = tcx.hir().get_parent_item(hir_id); + let parent_id = tcx.hir_get_parent_item(hir_id); Some(parent_id.to_def_id()) } // FIXME(#43408) always enable this once `lazy_normalization` is @@ -90,12 +90,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) { parent_did } else { - tcx.hir().get_parent_item(hir_id).to_def_id() + tcx.hir_get_parent_item(hir_id).to_def_id() }; debug!(?parent_did); let mut in_param_ty = false; - for (_parent, node) in tcx.hir().parent_iter(hir_id) { + for (_parent, node) in tcx.hir_parent_iter(hir_id) { if let Some(generics) = node.generics() { let mut visitor = AnonConstInParamTyDetector { in_param_ty: false, ct: hir_id }; @@ -189,8 +189,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // Exclude `GlobalAsm` here which cannot have generics. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { + hir::InlineAsmOperand::Const { anon_const } => { anon_const.hir_id == hir_id } _ => false, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 41c4cfbaa825d..1c1a246cc1519 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -13,7 +13,6 @@ use tracing::{debug, instrument}; use super::ItemCtxt; use super::predicates_of::assert_only_contains_predicates_from; -use crate::bounds::Bounds; use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter}; /// For associated types we include both bounds written on the type @@ -38,7 +37,7 @@ fn associated_type_bounds<'tcx>( ); let icx = ItemCtxt::new(tcx, assoc_item_def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Associated types are implicitly sized unless a `?Sized` bound is found match filter { @@ -68,7 +67,7 @@ fn associated_type_bounds<'tcx>( ) }); - let all_bounds = tcx.arena.alloc_from_iter(bounds.clauses().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter(bounds.into_iter().chain(bounds_from_parent)); debug!( "associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id.to_def_id()), @@ -327,7 +326,7 @@ fn opaque_type_bounds<'tcx>( ) -> &'tcx [(ty::Clause<'tcx>, Span)] { ty::print::with_reduced_queries!({ let icx = ItemCtxt::new(tcx, opaque_def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter); // Opaque types are implicitly sized unless a `?Sized` bound is found match filter { @@ -343,7 +342,7 @@ fn opaque_type_bounds<'tcx>( } debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.clauses()) + tcx.arena.alloc_slice(&bounds) }) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index d94383d6f3d88..5b511d270743b 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -13,7 +13,6 @@ use rustc_span::{DUMMY_SP, Ident, Span}; use tracing::{debug, instrument, trace}; use super::item_bounds::explicit_item_bounds_with_filter; -use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; use crate::delegation::inherit_predicates_for_delegation_item; @@ -178,7 +177,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // on a trait we must also consider the bounds that follow the trait's name, // like `trait Foo: A + B + C`. if let Some(self_bounds) = is_trait { - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds( tcx.types.self_param, self_bounds, @@ -186,7 +185,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen ty::List::empty(), PredicateFilter::All, ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); } // In default impls, we can assume that the self type implements @@ -209,7 +208,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen GenericParamKind::Lifetime { .. } => (), GenericParamKind::Type { .. } => { let param_ty = icx.lowerer().lower_ty_param(param.hir_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); // Params are implicitly sized unless a `?Sized` bound is found icx.lowerer().add_sized_bound( &mut bounds, @@ -219,7 +218,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen param.span, ); trace!(?bounds); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); trace!(?predicates); } hir::GenericParamKind::Const { .. } => { @@ -264,7 +263,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } } - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds( ty, bound_pred.bounds, @@ -272,7 +271,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen bound_vars, PredicateFilter::All, ); - predicates.extend(bounds.clauses()); + predicates.extend(bounds); } hir::WherePredicateKind::RegionPredicate(region_pred) => { @@ -383,8 +382,7 @@ fn const_evaluatable_predicates_of<'tcx>( fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool { let hir_id = tcx.local_def_id_to_hir_id(def); let (_, parent_node) = tcx - .hir() - .parent_iter(hir_id) + .hir_parent_iter(hir_id) .skip_while(|(_, n)| matches!(n, Node::ConstArg(..))) .next() .unwrap(); @@ -436,7 +434,7 @@ fn const_evaluatable_predicates_of<'tcx>( self_ty.instantiate_identity().visit_with(&mut collector); } - if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { + if let Some(_) = tcx.hir_fn_sig_by_hir_id(hir_id) { debug!("visit fn sig"); let fn_sig = tcx.fn_sig(def_id); let fn_sig = fn_sig.instantiate_identity(); @@ -627,7 +625,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let icx = ItemCtxt::new(tcx, trait_def_id); let self_param_ty = tcx.types.self_param; - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); let where_bounds_that_match = @@ -635,7 +633,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( // Combine the two lists to form the complete set of superbounds: let implied_bounds = - &*tcx.arena.alloc_from_iter(bounds.clauses().chain(where_bounds_that_match)); + &*tcx.arena.alloc_from_iter(bounds.into_iter().chain(where_bounds_that_match)); debug!(?implied_bounds); // Now require that immediate supertraits are lowered, which will, in @@ -826,7 +824,7 @@ pub(super) fn type_param_predicates<'tcx>( // `where T: Foo`. let param_id = tcx.local_def_id_to_hir_id(def_id); - let param_owner = tcx.hir().ty_param_owner(def_id); + let param_owner = tcx.hir_ty_param_owner(def_id); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { @@ -904,7 +902,7 @@ impl<'tcx> ItemCtxt<'tcx> { param_def_id: LocalDefId, filter: PredicateFilter, ) -> Vec<(ty::Clause<'tcx>, Span)> { - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); for predicate in hir_generics.predicates { let hir_id = predicate.hir_id; @@ -938,7 +936,7 @@ impl<'tcx> ItemCtxt<'tcx> { ); } - bounds.clauses().collect() + bounds } } @@ -1007,7 +1005,7 @@ pub(super) fn const_conditions<'tcx>( }; let icx = ItemCtxt::new(tcx, def_id); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); for pred in generics.predicates { match pred.kind { @@ -1027,12 +1025,12 @@ pub(super) fn const_conditions<'tcx>( } if let Some((def_id, supertraits)) = trait_def_id_and_supertraits { - bounds.push_const_bound( - tcx, - ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())), - ty::BoundConstness::Maybe, + // We've checked above that the trait is conditionally const. + bounds.push(( + ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())) + .to_host_effect_clause(tcx, ty::BoundConstness::Maybe), DUMMY_SP, - ); + )); icx.lowerer().lower_bounds( tcx.types.self_param, @@ -1045,7 +1043,7 @@ pub(super) fn const_conditions<'tcx>( ty::ConstConditions { parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()), - predicates: tcx.arena.alloc_from_iter(bounds.clauses().map(|(clause, span)| { + predicates: tcx.arena.alloc_from_iter(bounds.into_iter().map(|(clause, span)| { ( clause.kind().map_bound(|clause| match clause { ty::ClauseKind::HostEffect(ty::HostEffectPredicate { diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5a8a2f1fe28e0..6b61d317d3f50 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -160,7 +160,7 @@ enum Scope<'a> { impl<'a> Scope<'a> { // A helper for debugging scopes without printing parent scopes - fn debug_truncated(&'a self) -> impl fmt::Debug + 'a { + fn debug_truncated(&self) -> impl fmt::Debug { fmt::from_fn(move |f| match self { Self::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f .debug_struct("Binder") @@ -305,21 +305,15 @@ fn generic_param_def_as_bound_arg(param: &ty::GenericParamDef) -> ty::BoundVaria } /// Whether this opaque always captures lifetimes in scope. -/// Right now, this is all RPITIT and TAITs, and when `lifetime_capture_rules_2024` -/// is enabled. We don't check the span of the edition, since this is done -/// on a per-opaque basis to account for nested opaques. -fn opaque_captures_all_in_scope_lifetimes<'tcx>( - tcx: TyCtxt<'tcx>, - opaque: &'tcx hir::OpaqueTy<'tcx>, -) -> bool { +/// Right now, this is all RPITIT and TAITs, and when the opaque +/// is coming from a span corresponding to edition 2024. +fn opaque_captures_all_in_scope_lifetimes<'tcx>(opaque: &'tcx hir::OpaqueTy<'tcx>) -> bool { match opaque.origin { // if the opaque has the `use<...>` syntax, the user is telling us that they only want // to account for those lifetimes, so do not try to be clever. _ if opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) => false, hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => true, - _ if tcx.features().lifetime_capture_rules_2024() || opaque.span.at_least_rust_2024() => { - true - } + _ if opaque.span.at_least_rust_2024() => true, hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl, .. } => in_trait_or_impl.is_some(), } } @@ -519,8 +513,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) { let captures = RefCell::new(FxIndexMap::default()); - let capture_all_in_scope_lifetimes = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + let capture_all_in_scope_lifetimes = opaque_captures_all_in_scope_lifetimes(opaque); if capture_all_in_scope_lifetimes { let lifetime_ident = |def_id: LocalDefId| { let name = self.tcx.item_name(def_id.to_def_id()); @@ -630,7 +623,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Static(..) - | hir::ItemKind::GlobalAsm(..) => { + | hir::ItemKind::GlobalAsm { .. } => { // These sorts of items have no lifetime parameters at all. intravisit::walk_item(self, item); } @@ -1340,7 +1333,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }; def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { - let fn_id = self.tcx.hir().body_owner(body_id); + let fn_id = self.tcx.hir_body_owner(body_id); match self.tcx.hir_node(fn_id) { Node::Item(hir::Item { owner_id, kind: hir::ItemKind::Fn { .. }, .. }) | Node::TraitItem(hir::TraitItem { @@ -2166,10 +2159,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { /// Walk the generics of the item for a trait bound whose self type /// corresponds to the expected res, and return the trait def id. - fn for_each_trait_bound_on_res( - &self, - expected_res: Res, - ) -> impl Iterator + use<'tcx, '_> { + fn for_each_trait_bound_on_res(&self, expected_res: Res) -> impl Iterator { std::iter::from_coroutine( #[coroutine] move || { @@ -2265,7 +2255,7 @@ fn is_late_bound_map( tcx: TyCtxt<'_>, owner_id: hir::OwnerId, ) -> Option<&FxIndexSet> { - let sig = tcx.hir().fn_sig_by_hir_id(owner_id.into())?; + let sig = tcx.hir_fn_sig_by_hir_id(owner_id.into())?; let generics = tcx.hir_get_generics(owner_id.def_id)?; let mut late_bound = FxIndexSet::default(); @@ -2276,7 +2266,7 @@ fn is_late_bound_map( } let mut appears_in_output = - AllCollector { tcx, has_fully_capturing_opaque: false, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: false, regions: Default::default() }; intravisit::walk_fn_ret_ty(&mut appears_in_output, &sig.decl.output); if appears_in_output.has_fully_capturing_opaque { appears_in_output.regions.extend(generics.params.iter().map(|param| param.def_id)); @@ -2289,7 +2279,7 @@ fn is_late_bound_map( // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. let mut appears_in_where_clause = - AllCollector { tcx, has_fully_capturing_opaque: true, regions: Default::default() }; + AllCollector { has_fully_capturing_opaque: true, regions: Default::default() }; appears_in_where_clause.visit_generics(generics); debug!(?appears_in_where_clause.regions); @@ -2455,23 +2445,21 @@ fn is_late_bound_map( } } - struct AllCollector<'tcx> { - tcx: TyCtxt<'tcx>, + struct AllCollector { has_fully_capturing_opaque: bool, regions: FxHashSet, } - impl<'v> Visitor<'v> for AllCollector<'v> { - fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { + impl<'tcx> Visitor<'tcx> for AllCollector { + fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { if let hir::LifetimeName::Param(def_id) = lifetime_ref.res { self.regions.insert(def_id); } } - fn visit_opaque_ty(&mut self, opaque: &'v hir::OpaqueTy<'v>) { + fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { if !self.has_fully_capturing_opaque { - self.has_fully_capturing_opaque = - opaque_captures_all_in_scope_lifetimes(self.tcx, opaque); + self.has_fully_capturing_opaque = opaque_captures_all_in_scope_lifetimes(opaque); } intravisit::walk_opaque_ty(self, opaque); } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 293a095b41d0c..d564dc9699a88 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx let parent_node_id = tcx.parent_hir_id(hir_id); let parent_node = tcx.hir_node(parent_node_id); - let find_sym_fn = |&(op, op_sp)| match op { - hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => { - Some((anon_const, op_sp)) - } - _ => None, - }; - let find_const = |&(op, op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => { Some((anon_const, op_sp)) @@ -59,31 +52,7 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx // Anon consts outside the type system. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) => - { - let ty = tcx.typeck(def_id).node_type(hir_id); - - match ty.kind() { - ty::Error(_) => ty, - ty::FnDef(..) => ty, - _ => { - let guar = tcx - .dcx() - .struct_span_err(op_sp, "invalid `sym` operand") - .with_span_label( - tcx.def_span(anon_const.def_id), - format!("is {} `{}`", ty.kind().article(), ty), - ) - .with_help("`sym` operands must refer to either a function or a static") - .emit(); - - Ty::new_error(tcx, guar) - } - } - } - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. }) if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) => { let ty = tcx.typeck(def_id).node_type(hir_id); @@ -106,8 +75,8 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx } } } - Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) + 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) } // Sort of affects the type system, but only for the purpose of diagnostics // so no need for ConstArg. @@ -257,7 +226,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } } ImplItemKind::Type(ty) => { - if tcx.impl_trait_ref(tcx.hir().get_parent_item(hir_id)).is_none() { + if tcx.impl_trait_ref(tcx.hir_get_parent_item(hir_id)).is_none() { check_feature_inherent_assoc_ty(tcx, item.span); } @@ -313,12 +282,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_adt(tcx, def, args) } + ItemKind::GlobalAsm { .. } => tcx.typeck(def_id).node_type(hir_id), ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Macro(..) | ItemKind::Mod(..) | ItemKind::ForeignMod { .. } - | ItemKind::GlobalAsm(..) | ItemKind::ExternCrate(..) | ItemKind::Use(..) => { span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind); @@ -341,7 +310,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { VariantData::Unit(..) | VariantData::Struct { .. } => { - tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity() + tcx.type_of(tcx.hir_get_parent_item(hir_id)).instantiate_identity() } VariantData::Tuple(_, _, ctor) => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 88d4acbdd8dc6..399c4fbe55a9c 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -83,13 +83,13 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type( #[instrument(skip(tcx), level = "debug")] pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { let hir_id = tcx.local_def_id_to_hir_id(def_id); - let scope = tcx.hir().get_defining_scope(hir_id); + let scope = tcx.hir_get_defining_scope(hir_id); let mut locator = TaitConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] }; debug!(?scope); if scope == hir::CRATE_HIR_ID { - tcx.hir().walk_toplevel_module(&mut locator); + tcx.hir_walk_toplevel_module(&mut locator); } else { trace!("scope={:#?}", tcx.hir_node(scope)); match tcx.hir_node(scope) { diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 14ea10461cbea..1a0b0edb25703 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1417,6 +1417,15 @@ pub(crate) struct CrossCrateTraitsDefined { pub traits: String, } +#[derive(Diagnostic)] +#[diag(hir_analysis_no_variant_named, code = E0599)] +pub struct NoVariantNamed<'tcx> { + #[primary_span] + pub span: Span, + pub ident: Ident, + pub ty: Ty<'tcx>, +} + // FIXME(fmease): Deduplicate: #[derive(Diagnostic)] diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 681e8e36d589a..610b293a114e6 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -134,9 +134,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { // is from the 'of_trait' field of the enclosing impl let parent = self.tcx.parent_hir_node(self.path_segment.hir_id); - let parent_item = self.tcx.hir_node_by_def_id( - self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id, - ); + let parent_item = self + .tcx + .hir_node_by_def_id(self.tcx.hir_get_parent_item(self.path_segment.hir_id).def_id); // Get the HIR id of the trait ref let hir::Node::TraitRef(hir::TraitRef { hir_ref_id: trait_ref_id, .. }) = parent else { @@ -343,7 +343,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let mut ret = Vec::new(); let mut ty_id = None; - for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { + for (id, node) in self.tcx.hir_parent_iter(path_hir_id) { debug!(?id); if let hir::Node::Ty(_) = node { ty_id = Some(id); @@ -437,8 +437,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { ) -> String { let is_in_a_method_call = self .tcx - .hir() - .parent_iter(self.path_segment.hir_id) + .hir_parent_iter(self.path_segment.hir_id) .skip(1) .find_map(|(_, node)| match node { hir::Node::Expr(expr) => Some(expr), diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index ef6167907b5b2..dd346ed1f97a5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -8,7 +8,7 @@ use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; -use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt, Upcast}; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use rustc_trait_selection::traits; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; @@ -16,7 +16,6 @@ use smallvec::SmallVec; use tracing::{debug, instrument}; use super::errors::GenericsArgsErrExtend; -use crate::bounds::Bounds; use crate::errors; use crate::hir_ty_lowering::{ AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason, @@ -28,7 +27,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Doesn't add the bound if the HIR bounds contain any of `Sized`, `?Sized` or `!Sized`. pub(crate) fn add_sized_bound( &self, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, self_ty: Ty<'tcx>, hir_bounds: &'tcx [hir::GenericBound<'tcx>], self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, @@ -113,10 +112,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound { // There was in fact a `?Sized`, `!Sized` or explicit `Sized` bound; // we don't need to do anything. - } else if sized_def_id.is_some() { + } else if let Some(sized_def_id) = sized_def_id { // There was no `?Sized`, `!Sized` or explicit `Sized` bound; // add `Sized` if it's available. - bounds.push_sized(tcx, self_ty, span); + let trait_ref = ty::TraitRef::new(tcx, sized_def_id, [self_ty]); + // Preferable to put this obligation first, since we report better errors for sized ambiguity. + bounds.insert(0, (trait_ref.upcast(tcx), span)); } } @@ -146,7 +147,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, param_ty: Ty<'tcx>, hir_bounds: I, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, bound_vars: &'tcx ty::List, predicate_filter: PredicateFilter, ) where @@ -189,14 +190,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound); - bounds.push_region_bound( - self.tcx(), - ty::Binder::bind_with_vars( - ty::OutlivesPredicate(param_ty, region), - bound_vars, - ), - lifetime.ident.span, + let bound = ty::Binder::bind_with_vars( + ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region)), + bound_vars, ); + bounds.push((bound.upcast(self.tcx()), lifetime.ident.span)); } hir::GenericBound::Use(..) => { // We don't actually lower `use` into the type layer. @@ -219,7 +217,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, constraint: &hir::AssocItemConstraint<'tcx>, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, duplicates: &mut FxIndexMap, path_span: Span, predicate_filter: PredicateFilter, @@ -389,14 +387,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { PredicateFilter::All | PredicateFilter::SelfOnly | PredicateFilter::SelfAndAssociatedTypeBounds => { - bounds.push_projection_bound( - tcx, - projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + let bound = projection_term.map_bound(|projection_term| { + ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term, term, - }), - constraint.span, - ); + }) + }); + bounds.push((bound.upcast(tcx), constraint.span)); } // SelfTraitThatDefines is only interested in trait predicates. PredicateFilter::SelfTraitThatDefines(_) => {} @@ -739,8 +736,7 @@ fn check_assoc_const_binding_type<'tcx>( .map(|ty| crate::errors::TyOfAssocConstBindingNote { assoc_const, ty }); let enclosing_item_owner_id = tcx - .hir() - .parent_owner_iter(hir_id) + .hir_parent_owner_iter(hir_id) .find_map(|(owner_id, parent)| parent.generics().map(|_| owner_id)) .unwrap(); let generics = tcx.generics_of(enclosing_item_owner_id); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index a8b37fa505420..3eb4945ebf80e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; @@ -17,7 +17,6 @@ use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; use super::HirTyLowerer; -use crate::bounds::Bounds; use crate::hir_ty_lowering::{ GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason, }; @@ -36,7 +35,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let tcx = self.tcx(); let dummy_self = tcx.types.trait_object_dummy_self; - let mut user_written_bounds = Bounds::default(); + let mut user_written_bounds = Vec::new(); let mut potential_assoc_types = Vec::new(); for trait_bound in hir_bounds.iter() { if let hir::BoundPolarity::Maybe(_) = trait_bound.modifiers.polarity { @@ -59,16 +58,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - let (trait_bounds, mut projection_bounds) = - traits::expand_trait_aliases(tcx, user_written_bounds.clauses()); - let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = trait_bounds + let (elaborated_trait_bounds, elaborated_projection_bounds) = + traits::expand_trait_aliases(tcx, user_written_bounds.iter().copied()); + let (regular_traits, mut auto_traits): (Vec<_>, Vec<_>) = elaborated_trait_bounds .into_iter() .partition(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id())); // We don't support empty trait objects. if regular_traits.is_empty() && auto_traits.is_empty() { - let guar = - self.report_trait_object_with_no_traits_error(span, user_written_bounds.clauses()); + let guar = self.report_trait_object_with_no_traits_error( + span, + user_written_bounds.iter().copied(), + ); return Ty::new_error(tcx, guar); } // We don't support >1 principal @@ -84,7 +85,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Check that there are no gross dyn-compatibility violations; // most importantly, that the supertraits don't contain `Self`, // to avoid ICEs. - for (clause, span) in user_written_bounds.clauses() { + for (clause, span) in user_written_bounds { if let Some(trait_pred) = clause.as_trait_clause() { let violations = hir_ty_lowering_dyn_compatibility_violations(tcx, trait_pred.def_id()); @@ -102,29 +103,81 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + // Map the projection bounds onto a key that makes it easy to remove redundant + // bounds that are constrained by supertraits of the principal def id. + // + // Also make sure we detect conflicting bounds from expanding a trait alias and + // also specifying it manually, like: + // ``` + // type Alias = Trait; + // let _: &dyn Alias = /* ... */; + // ``` + let mut projection_bounds = FxIndexMap::default(); + for (proj, proj_span) in elaborated_projection_bounds { + let key = ( + proj.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + proj.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if let Some((old_proj, old_proj_span)) = + projection_bounds.insert(key, (proj, proj_span)) + && tcx.anonymize_bound_vars(proj) != tcx.anonymize_bound_vars(old_proj) + { + let item = tcx.item_name(proj.item_def_id()); + self.dcx() + .struct_span_err( + span, + format!( + "conflicting associated type bounds for `{item}` when \ + expanding trait alias" + ), + ) + .with_span_label( + old_proj_span, + format!("`{item}` is specified to be `{}` here", old_proj.term()), + ) + .with_span_label( + proj_span, + format!("`{item}` is specified to be `{}` here", proj.term()), + ) + .emit(); + } + } + let principal_trait = regular_traits.into_iter().next(); - let mut needed_associated_types = FxIndexSet::default(); - if let Some((principal_trait, spans)) = &principal_trait { - let pred: ty::Predicate<'tcx> = (*principal_trait).upcast(tcx); - for ClauseWithSupertraitSpan { pred, supertrait_span } in traits::elaborate( + let mut needed_associated_types = vec![]; + if let Some((principal_trait, ref spans)) = principal_trait { + let principal_trait = principal_trait.map_bound(|trait_pred| { + assert_eq!(trait_pred.polarity, ty::PredicatePolarity::Positive); + trait_pred.trait_ref + }); + + for ClauseWithSupertraitSpan { clause, supertrait_span } in traits::elaborate( tcx, - [ClauseWithSupertraitSpan::new(pred, *spans.last().unwrap())], + [ClauseWithSupertraitSpan::new( + ty::TraitRef::identity(tcx, principal_trait.def_id()).upcast(tcx), + *spans.last().unwrap(), + )], ) .filter_only_self() { - debug!("observing object predicate `{pred:?}`"); + let clause = clause.instantiate_supertrait(tcx, principal_trait); + debug!("observing object predicate `{clause:?}`"); - let bound_predicate = pred.kind(); + let bound_predicate = clause.kind(); match bound_predicate.skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { + ty::ClauseKind::Trait(pred) => { // FIXME(negative_bounds): Handle this correctly... let trait_ref = tcx.anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref)); needed_associated_types.extend( - tcx.associated_items(trait_ref.def_id()) + tcx.associated_items(pred.trait_ref.def_id) .in_definition_order() + // We only care about associated types. .filter(|item| item.kind == ty::AssocKind::Type) + // No RPITITs -- even with `async_fn_in_dyn_trait`, they are implicit. .filter(|item| !item.is_impl_trait_in_trait()) // If the associated type has a `where Self: Sized` bound, // we do not need to constrain the associated type. @@ -132,7 +185,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|item| (item.def_id, trait_ref)), ); } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { + ty::ClauseKind::Projection(pred) => { let pred = bound_predicate.rebind(pred); // A `Self` within the original bound will be instantiated with a // `trait_object_dummy_self`, so check for that. @@ -160,8 +213,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // `dyn MyTrait`, which is uglier but works. See // the discussion in #56288 for alternatives. if !references_self { - // Include projections defined on supertraits. - projection_bounds.push((pred, supertrait_span)); + let key = ( + pred.skip_binder().projection_term.def_id, + tcx.anonymize_bound_vars( + pred.map_bound(|proj| proj.projection_term.trait_ref(tcx)), + ), + ); + if !projection_bounds.contains_key(&key) { + projection_bounds.insert(key, (pred, supertrait_span)); + } } self.check_elaborated_projection_mentions_input_lifetimes( @@ -181,12 +241,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // types that we expect to be provided by the user, so the following loop // removes all the associated types that have a corresponding `Projection` // clause, either from expanding trait aliases or written by the user. - for &(projection_bound, span) in &projection_bounds { + for &(projection_bound, span) in projection_bounds.values() { let def_id = projection_bound.item_def_id(); - let trait_ref = tcx.anonymize_bound_vars( - projection_bound.map_bound(|p| p.projection_term.trait_ref(tcx)), - ); - needed_associated_types.swap_remove(&(def_id, trait_ref)); if tcx.generics_require_sized_self(def_id) { tcx.emit_node_span_lint( UNUSED_ASSOCIATED_TYPE_BOUNDS, @@ -197,9 +253,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + let mut missing_assoc_types = FxIndexSet::default(); + let projection_bounds: Vec<_> = needed_associated_types + .into_iter() + .filter_map(|key| { + if let Some(assoc) = projection_bounds.get(&key) { + Some(*assoc) + } else { + missing_assoc_types.insert(key); + None + } + }) + .collect(); + if let Err(guar) = self.check_for_required_assoc_tys( principal_trait.as_ref().map_or(smallvec![], |(_, spans)| spans.clone()), - needed_associated_types, + missing_assoc_types, potential_assoc_types, hir_bounds, ) { @@ -265,7 +334,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let existential_projections = projection_bounds.iter().map(|(bound, _)| { + let existential_projections = projection_bounds.into_iter().map(|(bound, _)| { bound.map_bound(|mut b| { assert_eq!(b.projection_term.self_ty(), dummy_self); @@ -290,12 +359,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) }); - let auto_trait_predicates = auto_traits.into_iter().map(|(trait_pred, _)| { - assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); - assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); + let mut auto_trait_predicates: Vec<_> = auto_traits + .into_iter() + .map(|(trait_pred, _)| { + assert_eq!(trait_pred.polarity(), ty::PredicatePolarity::Positive); + assert_eq!(trait_pred.self_ty().skip_binder(), dummy_self); - ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) - }); + ty::Binder::dummy(ty::ExistentialPredicate::AutoTrait(trait_pred.def_id())) + }) + .collect(); + auto_trait_predicates.dedup(); // N.b. principal, projections, auto traits // FIXME: This is actually wrong with multiple principals in regards to symbol mangling @@ -305,7 +378,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .chain(auto_trait_predicates) .collect::>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); - v.dedup(); let existential_predicates = tcx.mk_poly_existential_predicates(&v); // Use explicitly-specified region bound, unless the bound is missing. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index d2789cc0fd627..d644a1f224c7e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -223,7 +223,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // inside an opaque type while we're interested in the overarching type alias (TAIT). // FIXME: However, for trait aliases, this incorrectly returns the enclosing module... && let item_def_id = - tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id)) + tcx.hir_get_parent_item(tcx.local_def_id_to_hir_id(ty_param_def_id)) // FIXME: ...which obviously won't have any generics. && let Some(generics) = tcx.hir_get_generics(item_def_id.def_id) { @@ -979,7 +979,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { qself: &hir::Ty<'_>, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - if let Some((_, node)) = tcx.hir().parent_iter(qself.hir_id).skip(1).next() + if let Some((_, node)) = tcx.hir_parent_iter(qself.hir_id).skip(1).next() && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Path(hir::QPath::TypeRelative( @@ -1278,8 +1278,7 @@ pub fn prohibit_assoc_item_constraint( // Get the parent impl block based on the binding we have // and the trait DefId let impl_block = tcx - .hir() - .parent_iter(constraint.hir_id) + .hir_parent_iter(constraint.hir_id) .find_map(|(_, node)| node.impl_block_of_trait(def_id)); let type_with_constraints = diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index cc28b8780c61f..8d58a3bfbd3c5 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -70,7 +70,7 @@ fn generic_arg_mismatch_err( } Res::Def(DefKind::TyParam, src_def_id) => { if let Some(param_local_id) = param.def_id.as_local() { - let param_name = tcx.hir().ty_param_name(param_local_id); + let param_name = tcx.hir_ty_param_name(param_local_id); let param_type = tcx.type_of(param.def_id).instantiate_identity(); if param_type.is_suggestable(tcx, false) { err.span_suggestion( @@ -542,8 +542,7 @@ pub(crate) fn check_generic_arg_count( // ``` let parent_is_impl_block = cx .tcx() - .hir() - .parent_owner_iter(seg.hir_id) + .hir_parent_owner_iter(seg.hir_id) .next() .is_some_and(|(_, owner_node)| owner_node.is_impl_block()); if parent_is_impl_block { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 44f7a035a10fc..f5e075367f336 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -130,7 +130,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { diag: &mut Diag<'_, G>, ) { let tcx = self.tcx(); - let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait, generics, .. }), .. @@ -191,7 +191,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// Make sure that we are in the condition to suggest `impl Trait`. fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool { let tcx = self.tcx(); - let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; + let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; // FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0` // and suggest `Trait0`. // Functions are found in three different contexts. @@ -321,7 +321,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) { - let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id); + let mut parents = self.tcx().hir_parent_iter(self_ty.hir_id); if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next() && let Some(obj_ty) = constraint.ty() diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d5ccbdc11c825..750770178eef9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -49,11 +49,13 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::wf::object_region_bounds; use rustc_trait_selection::traits::{self, ObligationCtxt}; +use rustc_type_ir::Upcast; use tracing::{debug, instrument}; -use crate::bounds::Bounds; use crate::check::check_abi_fn_ptr; -use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType}; +use crate::errors::{ + AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed, +}; use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint}; use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args}; use crate::middle::resolve_bound_vars as rbv; @@ -217,7 +219,7 @@ impl AssocItemQSelf { fn to_string(&self, tcx: TyCtxt<'_>) -> String { match *self { Self::Trait(def_id) => tcx.def_path_str(def_id), - Self::TyParam(def_id, _) => tcx.hir().ty_param_name(def_id).to_string(), + Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(), Self::SelfTyAlias => kw::SelfUpper.to_string(), } } @@ -342,8 +344,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } rbv::ResolvedArg::EarlyBound(def_id) => { - let name = tcx.hir().ty_param_name(def_id); - let item_def_id = tcx.hir().ty_param_owner(def_id); + let name = tcx.hir_ty_param_name(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name }) @@ -691,7 +693,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constness: hir::BoundConstness, polarity: hir::BoundPolarity, self_ty: Ty<'tcx>, - bounds: &mut Bounds<'tcx>, + bounds: &mut Vec<(ty::Clause<'tcx>, Span)>, predicate_filter: PredicateFilter, ) -> GenericArgCountResult { let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); @@ -720,6 +722,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_vars, ); + debug!(?poly_trait_ref); + let polarity = match polarity { rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, @@ -741,6 +745,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } }; + // We deal with const conditions later. + match predicate_filter { + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfTraitThatDefines(..) + | PredicateFilter::SelfAndAssociatedTypeBounds => { + let bound = poly_trait_ref.map_bound(|trait_ref| { + ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity }) + }); + let bound = (bound.upcast(tcx), span); + // FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands. + if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) { + bounds.insert(0, bound); + } else { + bounds.push(bound); + } + } + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} + } + if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness && !self.tcx().is_const_trait(trait_def_id) { @@ -765,58 +789,53 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { suggestion_pre, suggestion, }); - } - - match predicate_filter { - // This is only concerned with trait predicates. - PredicateFilter::SelfTraitThatDefines(..) => { - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - } - PredicateFilter::All - | PredicateFilter::SelfOnly - | PredicateFilter::SelfAndAssociatedTypeBounds => { - debug!(?poly_trait_ref); - bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - - match constness { - hir::BoundConstness::Always(span) => { - if polarity == ty::PredicatePolarity::Positive { - bounds.push_const_bound( - tcx, - poly_trait_ref, - ty::BoundConstness::Const, - span, - ); + } else { + match predicate_filter { + // This is only concerned with trait predicates. + PredicateFilter::SelfTraitThatDefines(..) => {} + PredicateFilter::All + | PredicateFilter::SelfOnly + | PredicateFilter::SelfAndAssociatedTypeBounds => { + match constness { + hir::BoundConstness::Always(span) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push(( + poly_trait_ref + .to_host_effect_clause(tcx, ty::BoundConstness::Const), + span, + )); + } } + hir::BoundConstness::Maybe(_) => { + // We don't emit a const bound here, since that would mean that we + // unconditionally need to prove a `HostEffect` predicate, even when + // the predicates are being instantiated in a non-const context. This + // is instead handled in the `const_conditions` query. + } + hir::BoundConstness::Never => {} } - hir::BoundConstness::Maybe(_) => { - // We don't emit a const bound here, since that would mean that we - // unconditionally need to prove a `HostEffect` predicate, even when - // the predicates are being instantiated in a non-const context. This - // is instead handled in the `const_conditions` query. - } - hir::BoundConstness::Never => {} } - } - // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert - // `~const` bounds. All other predicates are handled in their respective queries. - // - // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering - // here because we only call this on self bounds, and deal with the recursive case - // in `lower_assoc_item_constraint`. - PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness { - hir::BoundConstness::Maybe(span) => { - if polarity == ty::PredicatePolarity::Positive { - bounds.push_const_bound( - tcx, - poly_trait_ref, - ty::BoundConstness::Maybe, - span, - ); + // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert + // `~const` bounds. All other predicates are handled in their respective queries. + // + // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering + // here because we only call this on self bounds, and deal with the recursive case + // in `lower_assoc_item_constraint`. + PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => { + match constness { + hir::BoundConstness::Maybe(span) => { + if polarity == ty::PredicatePolarity::Positive { + bounds.push(( + poly_trait_ref + .to_host_effect_clause(tcx, ty::BoundConstness::Maybe), + span, + )); + } + } + hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {} } } - hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {} - }, + } } let mut dup_constraints = FxIndexMap::default(); @@ -1188,14 +1207,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let msg = format!("expected type, found variant `{assoc_ident}`"); self.dcx().span_err(span, msg) } else if qself_ty.is_enum() { - let mut err = struct_span_code_err!( - self.dcx(), - assoc_ident.span, - E0599, - "no variant named `{}` found for enum `{}`", - assoc_ident, - qself_ty, - ); + let mut err = self.dcx().create_err(NoVariantNamed { + span: assoc_ident.span, + ident: assoc_ident, + ty: qself_ty, + }); let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT"); if let Some(variant_name) = find_best_match_for_name( @@ -1210,11 +1226,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { adt_def.variants().iter().find(|s| s.name == variant_name) { let mut suggestion = vec![(assoc_ident.span, variant_name.to_string())]; - if let hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Semi(ref expr), - .. + if let hir::Node::Stmt(&hir::Stmt { + kind: hir::StmtKind::Semi(expr), .. }) - | hir::Node::Expr(ref expr) = tcx.parent_hir_node(hir_ref_id) + | hir::Node::Expr(expr) = tcx.parent_hir_node(hir_ref_id) && let hir::ExprKind::Struct(..) = expr.kind { match variant.ctor { @@ -1657,8 +1672,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(item_def_id = ?def_id); // FIXME: document why/how this is different from `tcx.local_parent(def_id)` - let parent_def_id = - tcx.hir().get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id(); + let parent_def_id = tcx.hir_get_parent_item(tcx.local_def_id_to_hir_id(def_id)).to_def_id(); debug!(?parent_def_id); // If the trait in segment is the same as the trait defining the item, @@ -2053,10 +2067,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Ty::new_bound(tcx, debruijn, br) } Some(rbv::ResolvedArg::EarlyBound(def_id)) => { - let item_def_id = tcx.hir().ty_param_owner(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)) + Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id)) } Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), @@ -2382,7 +2396,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Impl trait in bindings lower as an infer var with additional // set of type bounds. let self_ty = self.ty_infer(None, hir_ty.span); - let mut bounds = Bounds::default(); + let mut bounds = Vec::new(); self.lower_bounds( self_ty, hir_bounds.iter(), @@ -2390,11 +2404,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ty::List::empty(), PredicateFilter::All, ); - self.register_trait_ascription_bounds( - bounds.clauses().collect(), - hir_ty.hir_id, - hir_ty.span, - ); + self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span); self_ty } // If we encounter a type relative path with RTN generics, then it must have diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index f5abcd234401b..0b1be8e4f7a99 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -22,8 +22,6 @@ fn diagnostic_hir_wf_check<'tcx>( tcx: TyCtxt<'tcx>, (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc), ) -> Option> { - let hir = tcx.hir(); - let def_id = match loc { WellFormedLoc::Ty(def_id) => def_id, WellFormedLoc::Param { function, param_idx: _ } => function, @@ -187,7 +185,7 @@ fn diagnostic_hir_wf_check<'tcx>( ref node => bug!("Unexpected node {:?}", node), }, WellFormedLoc::Param { function: _, param_idx } => { - let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap(); + let fn_decl = tcx.hir_fn_decl_by_hir_id(hir_id).unwrap(); // Get return type if param_idx as usize == fn_decl.inputs.len() { match fn_decl.output { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 8a529e9c686e0..bdfbd540e40a3 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -80,7 +80,6 @@ This API is completely unstable and subject to change. pub mod check; pub mod autoderef; -mod bounds; mod check_unused; mod coherence; mod collect; @@ -93,6 +92,7 @@ mod impl_wf_check; mod outlives; mod variance; +pub use errors::NoVariantNamed; use rustc_abi::ExternAbi; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -184,7 +184,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // what we are intending to discard, to help future type-based refactoring. type R = Result<(), ErrorGuaranteed>; - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { let _: R = tcx.ensure_ok().check_mod_type_wf(module); }); @@ -209,7 +209,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // Make sure we evaluate all static and (non-associated) const items, even if unused. // If any of these fail to evaluate, we do not want this crate to pass compilation. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); match def_kind { DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id), @@ -227,7 +227,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { // for anon constants during their parents' typeck. // Typeck all body owners in parallel will produce queries // cycle errors because it may typeck on anon constants directly. - tcx.hir().par_body_owners(|item_def_id| { + tcx.par_hir_body_owners(|item_def_id| { let def_kind = tcx.def_kind(item_def_id); if !matches!(def_kind, DefKind::AnonConst) { tcx.ensure_ok().typeck(item_def_id); @@ -251,7 +251,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> { // In case there are any projections, etc., find the "environment" // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. - let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id); + let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty) } @@ -262,6 +262,6 @@ pub fn lower_const_arg_for_rustdoc<'tcx>( hir_ct: &hir::ConstArg<'tcx>, feed: FeedConstTy, ) -> Const<'tcx> { - let env_def_id = tcx.hir().get_parent_item(hir_ct.hir_id); + let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id); collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed) } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c43917649de2e..32b05dcc569ef 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -37,7 +37,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau // parent of generics returned by `generics_of` // // In the above code we want the anon const to have predicates in its param env for `'b: 'a` - let item_def_id = tcx.hir().get_parent_item(id); + let item_def_id = tcx.hir_get_parent_item(id); // In the above code example we would be calling `inferred_outlives_of(Foo)` here tcx.inferred_outlives_of(item_def_id) } else { diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index 9af1fb8279e9f..f5d7dbd3f96e4 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_hir_pretty" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 34124a6aa11a3..167bed5f65029 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -18,7 +18,8 @@ use rustc_ast_pretty::pprust::state::MacHeader; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir::{ BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind, - HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TyPatKind, + HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, + TyPatKind, }; use rustc_span::source_map::SourceMap; use rustc_span::{FileName, Ident, Span, Symbol, kw}; @@ -692,7 +693,7 @@ impl<'a> State<'a> { } self.bclose(item.span); } - hir::ItemKind::GlobalAsm(asm) => { + hir::ItemKind::GlobalAsm { asm, .. } => { self.head("global_asm!"); self.print_inline_asm(asm); self.end() @@ -1431,10 +1432,10 @@ impl<'a> State<'a> { s.space(); s.print_anon_const(anon_const); } - hir::InlineAsmOperand::SymFn { ref anon_const } => { + hir::InlineAsmOperand::SymFn { ref expr } => { s.word("sym_fn"); s.space(); - s.print_anon_const(anon_const); + s.print_expr(expr); } hir::InlineAsmOperand::SymStatic { ref path, def_id: _ } => { s.word("sym_static"); @@ -1856,7 +1857,7 @@ impl<'a> State<'a> { self.word_space("="); match term { Term::Ty(ty) => self.print_type(ty), - Term::Const(ref c) => self.print_const_arg(c), + Term::Const(c) => self.print_const_arg(c), } } hir::AssocItemConstraintKind::Bound { bounds } => { @@ -2086,6 +2087,28 @@ impl<'a> State<'a> { self.print_pat(arg.pat); } + fn print_implicit_self(&mut self, implicit_self_kind: &hir::ImplicitSelfKind) { + match implicit_self_kind { + ImplicitSelfKind::Imm => { + self.word("self"); + } + ImplicitSelfKind::Mut => { + self.print_mutability(hir::Mutability::Mut, false); + self.word("self"); + } + ImplicitSelfKind::RefImm => { + self.word("&"); + self.word("self"); + } + ImplicitSelfKind::RefMut => { + self.word("&"); + self.print_mutability(hir::Mutability::Mut, false); + self.word("self"); + } + ImplicitSelfKind::None => unreachable!(), + } + } + fn print_arm(&mut self, arm: &hir::Arm<'_>) { // I have no idea why this check is necessary, but here it // is :( @@ -2151,27 +2174,33 @@ impl<'a> State<'a> { // Make sure we aren't supplied *both* `arg_names` and `body_id`. assert!(arg_names.is_empty() || body_id.is_none()); let mut i = 0; - let mut print_arg = |s: &mut Self| { - if let Some(arg_name) = arg_names.get(i) { - s.word(arg_name.to_string()); - s.word(":"); - s.space(); - } else if let Some(body_id) = body_id { - s.ann.nested(s, Nested::BodyParamPat(body_id, i)); - s.word(":"); - s.space(); + let mut print_arg = |s: &mut Self, ty: Option<&hir::Ty<'_>>| { + if i == 0 && decl.implicit_self.has_implicit_self() { + s.print_implicit_self(&decl.implicit_self); + } else { + if let Some(arg_name) = arg_names.get(i) { + s.word(arg_name.to_string()); + s.word(":"); + s.space(); + } else if let Some(body_id) = body_id { + s.ann.nested(s, Nested::BodyParamPat(body_id, i)); + s.word(":"); + s.space(); + } + if let Some(ty) = ty { + s.print_type(ty); + } } i += 1; }; self.commasep(Inconsistent, decl.inputs, |s, ty| { s.ibox(INDENT_UNIT); - print_arg(s); - s.print_type(ty); + print_arg(s, Some(ty)); s.end(); }); if decl.c_variadic { self.word(", "); - print_arg(self); + print_arg(self, None); self.word("..."); } self.pclose(); @@ -2284,7 +2313,9 @@ impl<'a> State<'a> { GenericBound::Use(args, _) => { self.word("use <"); - self.commasep(Inconsistent, args, |s, arg| s.print_precise_capturing_arg(*arg)); + self.commasep(Inconsistent, *args, |s, arg| { + s.print_precise_capturing_arg(*arg) + }); self.word(">"); } @@ -2300,10 +2331,23 @@ impl<'a> State<'a> { } fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) { - if !generic_params.is_empty() { + let is_lifetime_elided = |generic_param: &GenericParam<'_>| { + matches!( + generic_param.kind, + GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) } + ) + }; + + // We don't want to show elided lifetimes as they are compiler-inserted and not + // expressible in surface level Rust. + if !generic_params.is_empty() && !generic_params.iter().all(is_lifetime_elided) { self.word("<"); - self.commasep(Inconsistent, generic_params, |s, param| s.print_generic_param(param)); + self.commasep( + Inconsistent, + generic_params.iter().filter(|gp| !is_lifetime_elided(gp)), + |s, param| s.print_generic_param(param), + ); self.word(">"); } diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 1f5acaa58a972..f1afb7b712d59 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -1,14 +1,13 @@ [package] name = "rustc_hir_typeck" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 3d40c5ee80450..38319862334a8 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -213,10 +213,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arm_ty: Ty<'tcx>, prior_arm: Option<(Option, Ty<'tcx>, Span)>, ) { - let hir = self.tcx.hir(); - // First, check that we're actually in the tail of a function. - let Some(body) = hir.maybe_body_owned_by(self.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(self.body_id) else { return; }; let hir::ExprKind::Block(block, _) = body.value.kind else { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index bccde7822645b..d18869b6d90c3 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -346,8 +346,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; - let hir = self.tcx.hir(); - let fn_decl_span = if let hir::Node::Expr(hir::Expr { + let fn_decl_span = if let hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. }) = self.tcx.parent_hir_node(hir_id) @@ -368,11 +367,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }), .. }), - )) = hir.parent_iter(hir_id).nth(3) + )) = self.tcx.hir_parent_iter(hir_id).nth(3) { // Actually need to unwrap one more layer of HIR to get to // the _real_ closure... - if let hir::Node::Expr(hir::Expr { + if let hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. }) = self.tcx.parent_hir_node(parent_hir_id) @@ -860,7 +859,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let host = match self.tcx.hir().body_const_context(self.body_id) { + let host = match self.tcx.hir_body_const_context(self.body_id) { Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => { ty::BoundConstness::Const } diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 6fb5f6af0913a..dabae7b1d094c 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -35,12 +35,8 @@ pub(super) fn check_fn<'a, 'tcx>( params_can_be_unsized: bool, ) -> Option> { let fn_id = fcx.tcx.local_def_id_to_hir_id(fn_def_id); - let tcx = fcx.tcx; - let hir = tcx.hir(); - let declared_ret_ty = fn_sig.output(); - let ret_ty = fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars( declared_ret_ty, @@ -69,7 +65,7 @@ pub(super) fn check_fn<'a, 'tcx>( }); // Add formal parameters. - let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); + let inputs_hir = tcx.hir_fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs); let inputs_fn = fn_sig.inputs().iter().copied(); for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() { // We checked the root's signature during wfcheck, but not the child. diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index c8433d0cb5b16..a5108e7a0326d 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1752,7 +1752,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { return false; } let Some((_, hir::Node::Expr(expr))) = - fcx.tcx.hir().parent_iter(id).nth(1) + fcx.tcx.hir_parent_iter(id).nth(1) else { return false; }; @@ -1887,7 +1887,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let parent_id = fcx.tcx.parent_hir_id(block_or_return_id); let parent = fcx.tcx.hir_node(parent_id); if let Some(expr) = expression - && let hir::Node::Expr(hir::Expr { + && let hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent @@ -1909,7 +1909,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { found, block_or_return_id, ); - if let Some(cond_expr) = fcx.tcx.hir().get_if_cause(expr.hir_id) + if let Some(cond_expr) = fcx.tcx.hir_get_if_cause(expr.hir_id) && expected.is_unit() && !pointing_at_return_type // If the block is from an external macro or try (`?`) desugaring, then @@ -1943,7 +1943,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if due_to_block && let Some(expr) = expression && let Some(parent_fn_decl) = - fcx.tcx.hir().fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) + fcx.tcx.hir_fn_decl_by_hir_id(fcx.tcx.local_def_id_to_hir_id(fcx.body_id)) { fcx.suggest_missing_break_or_return_expr( &mut err, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 2f7f914802331..85131f6195f83 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -156,7 +156,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && segment.ident.name.as_str() == name && let Res::Local(hir_id) = path.res && let Some((_, hir::Node::Expr(match_expr))) = - self.tcx.hir().parent_iter(hir_id).nth(2) + self.tcx.hir_parent_iter(hir_id).nth(2) && let hir::ExprKind::Match(scrutinee, _, _) = match_expr.kind && let hir::ExprKind::Tup(exprs) = scrutinee.kind && let hir::ExprKind::AddrOf(_, _, macro_arg) = exprs[idx].kind @@ -293,8 +293,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, source: TypeMismatchSource<'tcx>, ) -> bool { - let hir = self.tcx.hir(); - let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; @@ -334,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut expr_finder = FindExprs { hir_id: local_hir_id, uses: init.into_iter().collect() }; - let body = hir.body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); expr_finder.visit_expr(body.value); // Replaces all of the variables in the given type with a fresh inference variable. @@ -579,9 +577,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut parent; 'outer: loop { // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement. - let (hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. }) - | hir::Node::Block(hir::Block { expr: Some(&ref p), .. }) - | hir::Node::Expr(&ref p)) = self.tcx.hir_node(parent_id) + let (hir::Node::Stmt(&hir::Stmt { kind: hir::StmtKind::Semi(p), .. }) + | hir::Node::Block(&hir::Block { expr: Some(p), .. }) + | hir::Node::Expr(p)) = self.tcx.hir_node(parent_id) else { break; }; @@ -595,13 +593,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { loop { // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to. let parent = match self.tcx.hir_node(parent_id) { - hir::Node::Expr(&ref parent) => { + hir::Node::Expr(parent) => { parent_id = self.tcx.parent_hir_id(parent.hir_id); parent } hir::Node::Stmt(hir::Stmt { hir_id, - kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent), + kind: hir::StmtKind::Semi(parent) | hir::StmtKind::Expr(parent), .. }) => { parent_id = self.tcx.parent_hir_id(*hir_id); @@ -843,7 +841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The pattern we have is an fn argument. && let hir::Node::Param(hir::Param { ty_span, .. }) = self.tcx.parent_hir_node(pat.hir_id) - && let item = self.tcx.hir().get_parent_item(pat.hir_id) + && let item = self.tcx.hir_get_parent_item(pat.hir_id) && let item = self.tcx.hir_owner_node(item) && let Some(fn_decl) = item.fn_decl() diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index a41ad94f95e2f..0c71ef4655c5c 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -19,6 +19,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; +use rustc_hir_analysis::NoVariantNamed; use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _}; use rustc_infer::infer; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; @@ -1129,7 +1130,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { statement_kind: kind, }; - let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id); + let encl_item_id = self.tcx.hir_get_parent_item(expr.hir_id); if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { .. }, @@ -1150,13 +1151,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We are inside a function body, so reporting "return statement // outside of function body" needs an explanation. - let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id); + let encl_body_owner_id = self.tcx.hir_enclosing_body_owner(expr.hir_id); // If this didn't hold, we would not have to report an error in // the first place. assert_ne!(encl_item_id.def_id, encl_body_owner_id); - let encl_body = self.tcx.hir().body_owned_by(encl_body_owner_id); + let encl_body = self.tcx.hir_body_owned_by(encl_body_owner_id); err.encl_body_span = Some(encl_body.value.span); err.encl_fn_span = Some(*encl_fn_span); @@ -1278,7 +1279,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if our original expression is a child of the condition of a while loop. // If it is, then we have a situation like `while Some(0) = value.get(0) {`, // where `while let` was more likely intended. - if self.tcx.hir().parent_id_iter(original_expr_id).any(|id| id == expr.hir_id) { + if self.tcx.hir_parent_id_iter(original_expr_id).any(|id| id == expr.hir_id) { then(expr); } break; @@ -1773,7 +1774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn suggest_array_len(&self, expr: &'tcx hir::Expr<'tcx>, array_len: u64) { - let parent_node = self.tcx.hir().parent_iter(expr.hir_id).find(|(_, node)| { + let parent_node = self.tcx.hir_parent_iter(expr.hir_id).find(|(_, node)| { !matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::AddrOf(..), .. })) }); let Some((_, hir::Node::LetStmt(hir::LetStmt { ty: Some(ty), .. }))) = parent_node else { @@ -3229,7 +3230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None => return, }; let param_span = self.tcx.hir().span(param_hir_id); - let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local()); + let param_name = self.tcx.hir_ty_param_name(param_def_id.expect_local()); err.span_label(param_span, format!("type parameter '{param_name}' declared here")); } @@ -3762,7 +3763,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut diverge = asm.asm_macro.diverges(asm.options); for (op, _op_sp) in asm.operands { - match op { + match *op { hir::InlineAsmOperand::In { expr, .. } => { self.check_expr_asm_operand(expr, true); } @@ -3777,10 +3778,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_expr_asm_operand(out_expr, false); } } + hir::InlineAsmOperand::SymFn { expr } => { + self.check_expr(expr); + } // `AnonConst`s have their own body and is type-checked separately. // As they don't flow into the type system we don't need them to // be well-formed. - hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymFn { .. } => {} + hir::InlineAsmOperand::Const { .. } => {} hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Label { block } => { let previous_diverges = self.diverges.get(); @@ -3837,15 +3841,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter_enumerated() .find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident) else { - type_error_struct!( - self.dcx(), - ident.span, - container, - E0599, - "no variant named `{ident}` found for enum `{container}`", - ) - .with_span_label(field.span, "variant not found") - .emit(); + self.dcx() + .create_err(NoVariantNamed { span: ident.span, ident, ty: container }) + .with_span_label(field.span, "variant not found") + .emit_unless(container.references_error()); break; }; let Some(&subfield) = fields.next() else { diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 860e619be7187..9b85b2aeec6e9 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -1001,11 +1001,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx let closure_def_id = closure_expr.def_id; // For purposes of this function, coroutine and closures are equivalent. let body_owner_is_closure = matches!( - tcx.hir().body_owner_kind(self.cx.body_owner_def_id()), + tcx.hir_body_owner_kind(self.cx.body_owner_def_id()), hir::BodyOwnerKind::Closure ); - // If we have a nested closure, we want to include the fake reads present in the nested closure. + // If we have a nested closure, we want to include the fake reads present in the nested + // closure. if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) { for (fake_read, cause, hir_id) in fake_reads.iter() { match fake_read.base { diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ce6f7420e5baf..759b5d9550c05 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -503,7 +503,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit); if unit_errors.is_empty() && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) - && let [ref mut never_error, ..] = never_errors.as_mut_slice() + && let [never_error, ..] = never_errors.as_mut_slice() { self.adjust_fulfillment_error_for_expr_obligation(never_error); let sugg = self.try_to_suggest_annotations(diverging_vids, coercions); @@ -573,7 +573,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { coercions: &VecGraph, ) -> errors::SuggestAnnotations { let body = - self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + self.tcx.hir_maybe_body_owned_by(self.body_id).expect("body id must have an owner"); // For each diverging var, look through the HIR for a place to give it // a type annotation. We do this per var because we only really need one // suggestion to influence a var to be `()`. @@ -764,7 +764,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, body_id: LocalDefId, ) -> UnordMap { - let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir_maybe_body_owned_by(body_id).expect("body id must have an owner"); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ff41a080d6290..2d7d80e39bc31 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -856,7 +856,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>)> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. - self.tcx.hir().get_fn_id_for_return_block(blk_id).and_then(|item_id| { + self.tcx.hir_get_fn_id_for_return_block(blk_id).and_then(|item_id| { match self.tcx.hir_node(item_id) { Node::Item(&hir::Item { kind: hir::ItemKind::Fn { sig, .. }, owner_id, .. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c0af5ea7bbffd..120a43576e814 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -100,8 +100,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut deferred_asm_checks = self.deferred_asm_checks.borrow_mut(); debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { - let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id); - let get_operand_ty = |expr| { + let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); + let expr_ty = |expr: &hir::Expr<'tcx>| { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); if ty.has_non_region_infer() { @@ -110,12 +110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.erase_regions(ty) } }; - InlineAsmCtxt::new_in_fn( - self.tcx, - self.infcx.typing_env(self.param_env), - get_operand_ty, - ) - .check_asm(asm, enclosing_id); + InlineAsmCtxt::new(self.tcx, enclosing_id, expr_ty).check_asm(asm); } } @@ -2052,7 +2047,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn parent_item_span(&self, id: HirId) -> Option { - let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id); + let node = self.tcx.hir_node_by_def_id(self.tcx.hir_get_parent_item(id).def_id); match node { Node::Item(&hir::Item { kind: hir::ItemKind::Fn { body: body_id, .. }, .. }) | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => { @@ -2179,7 +2174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let mut block_num = 0; let mut found_semi = false; - for (hir_id, node) in self.tcx.hir().parent_iter(binding_hir_id) { + for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) { // Don't proceed into parent bodies if hir_id.owner != binding_hir_id.owner { break; @@ -2521,7 +2516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Try to find earlier invocations of this closure to find if the type mismatch // is because of inference. If we find one, point at them. let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] }; - let parent_def_id = self.tcx.hir().get_parent_item(call_expr.hir_id).def_id; + let parent_def_id = self.tcx.hir_get_parent_item(call_expr.hir_id).def_id; match self.tcx.hir_node_by_def_id(parent_def_id) { hir::Node::Item(item) => call_finder.visit_item(item), hir::Node::TraitItem(item) => call_finder.visit_trait_item(item), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index b77e6de52ff1c..42236ac6d8087 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -290,7 +290,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> { _: Ident, ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { let tcx = self.tcx; - let item_def_id = tcx.hir().ty_param_owner(def_id); + let item_def_id = tcx.hir_ty_param_owner(def_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id.to_def_id()]; // HACK(eddyb) should get the original `Span`. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 05c76b3c56818..f9fc121593637 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut tuple_indexes = Vec::new(); let mut expr_id = expr.hir_id; - for (parent_id, node) in self.tcx.hir().parent_iter(expr.hir_id) { + for (parent_id, node) in self.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Expr(&Expr { kind: ExprKind::Tup(subs), .. }) => { tuple_indexes.push( @@ -565,7 +565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { found: Ty<'tcx>, ) -> bool { // Do not suggest `Box::new` in const context. - if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() { + if self.tcx.hir_is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() { return false; } if self.may_coerce(Ty::new_box(self.tcx, found), expected) { @@ -645,7 +645,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> bool { // Handle #68197. - if self.tcx.hir().is_inside_const_context(expr.hir_id) { + if self.tcx.hir_is_inside_const_context(expr.hir_id) { // Do not suggest `Box::new` in const context. return false; } @@ -1084,8 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let in_loop = self.is_loop(id) || self .tcx - .hir() - .parent_iter(id) + .hir_parent_iter(id) .take_while(|(_, node)| { // look at parents until we find the first body owner node.body_id().is_none() @@ -1095,8 +1094,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let in_local_statement = self.is_local_statement(id) || self .tcx - .hir() - .parent_iter(id) + .hir_parent_iter(id) .any(|(parent_id, _)| self.is_local_statement(parent_id)); if in_loop && in_local_statement { @@ -1111,7 +1109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - let scope = self.tcx.hir().parent_iter(id).find(|(_, node)| { + let scope = self.tcx.hir_parent_iter(id).find(|(_, node)| { matches!( node, Node::Expr(Expr { kind: ExprKind::Closure(..), .. }) @@ -1168,7 +1166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // -------------^^^^^^^- // Don't add semicolon `;` at the end of `dbg!(x)` expr fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool { - for (_, node) in tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in tcx.hir_parent_iter(expr.hir_id) { match node { hir::Node::Block(block) => { if let Some(ret) = block.expr @@ -1411,8 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let hir = self.tcx.hir(); - let cond_parent = hir.parent_iter(expr.hir_id).find(|(_, node)| { + let cond_parent = self.tcx.hir_parent_iter(expr.hir_id).find(|(_, node)| { !matches!(node, hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, _, _), .. }) if op.node == hir::BinOpKind::And) }); // Don't suggest: @@ -1811,7 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "`{expected_ty}` does not implement `Clone`, so `{found_ty}` was cloned instead" ), ); - let owner = self.tcx.hir().enclosing_body_owner(expr.hir_id); + let owner = self.tcx.hir_enclosing_body_owner(expr.hir_id); if let ty::Param(param) = expected_ty.kind() && let Some(generics) = self.tcx.hir_get_generics(owner) { @@ -2048,11 +2045,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, ) -> bool { - let map = self.tcx.hir(); let returned = matches!( self.tcx.parent_hir_node(expr.hir_id), hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) - ) || map.get_fn_id_for_return_block(expr.hir_id).is_some(); + ) || self.tcx.hir_get_fn_id_for_return_block(expr.hir_id).is_some(); if returned && let ty::Adt(e, args_e) = expected.kind() && let ty::Adt(f, args_f) = found.kind() @@ -2094,9 +2090,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'tcx>, expected: Ty<'tcx>, ) -> bool { - let hir = self.tcx.hir(); + let tcx = self.tcx; let enclosing_scope = - hir.get_enclosing_scope(expr.hir_id).map(|hir_id| self.tcx.hir_node(hir_id)); + tcx.hir_get_enclosing_scope(expr.hir_id).map(|hir_id| tcx.hir_node(hir_id)); // Get tail expr of the enclosing block or body let tail_expr = if let Some(Node::Block(hir::Block { expr, .. })) = enclosing_scope @@ -2104,8 +2100,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { *expr } else { - let body_def_id = hir.enclosing_body_owner(expr.hir_id); - let body = hir.body_owned_by(body_def_id); + let body_def_id = tcx.hir_enclosing_body_owner(expr.hir_id); + let body = tcx.hir_body_owned_by(body_def_id); // Get tail expr of the body match body.value.kind { @@ -2147,7 +2143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ("consider returning a value here", format!("`{expected}` value")) }; - let src_map = self.tcx.sess.source_map(); + let src_map = tcx.sess.source_map(); let suggestion = if src_map.is_multiline(expr.span) { let indentation = src_map.indentation_before(span).unwrap_or_else(String::new); format!("\n{indentation}/* {suggestion} */") @@ -3097,7 +3093,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |expr: &hir::Expr<'_>| matches!(expr.kind, hir::ExprKind::Unary(hir::UnOp::Neg, ..)); let is_uint = |ty: Ty<'_>| matches!(ty.kind(), ty::Uint(..)); - let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id); + let in_const_context = self.tcx.hir_is_inside_const_context(expr.hir_id); let suggest_fallible_into_or_lhs_from = |err: &mut Diag<'_>, exp_to_found_is_fallible: bool| { @@ -3141,7 +3137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let suggest_to_change_suffix_or_into = |err: &mut Diag<'_>, found_to_exp_is_fallible: bool, exp_to_found_is_fallible: bool| { - let exp_is_lhs = expected_ty_expr.is_some_and(|e| self.tcx.hir().is_lhs(e.hir_id)); + let exp_is_lhs = expected_ty_expr.is_some_and(|e| self.tcx.hir_is_lhs(e.hir_id)); if exp_is_lhs { return; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 9d5184acb3ca7..0130ad775d9e7 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -133,7 +133,12 @@ fn typeck_with_inspect<'tcx>( } let mut fcx = FnCtxt::new(&root_ctxt, param_env, def_id); - if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { + if let hir::Node::Item(hir::Item { kind: hir::ItemKind::GlobalAsm { .. }, .. }) = node { + // Check the fake body of a global ASM. There's not much to do here except + // for visit the asm expr of the body. + let ty = fcx.check_expr(body.value); + fcx.write_ty(id, ty); + } else if let Some(hir::FnSig { header, decl, .. }) = node.fn_sig() { let fn_sig = if decl.output.is_suggestable_infer_ty().is_some() { // In the case that we're recovering `fn() -> W<_>` or some other return // type that has an infer in it, lower the type directly so that it'll @@ -277,12 +282,9 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Some(fcx.next_ty_var(span)) } Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. }) - | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => { + | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm { asm, .. }, span, .. }) => { asm.operands.iter().find_map(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } - if anon_const.hir_id == id => - { + hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => { Some(fcx.next_ty_var(span)) } _ => None, diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 8fb425ff0c94c..3b107fbf17394 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -11,7 +11,7 @@ use rustc_hir_analysis::hir_ty_lowering::{ }; use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk}; use rustc_lint::builtin::SUPERTRAIT_ITEM_SHADOWING_USAGE; -use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext}; +use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, }; @@ -136,7 +136,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { "confirm: self_ty={:?} method_sig_rcvr={:?} method_sig={:?} method_predicates={:?}", self_ty, method_sig_rcvr, method_sig, method_predicates ); - self.unify_receivers(self_ty, method_sig_rcvr, pick, all_args); + self.unify_receivers(self_ty, method_sig_rcvr, pick); let (method_sig, method_predicates) = self.normalize(self.span, (method_sig, method_predicates)); @@ -525,20 +525,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>, pick: &probe::Pick<'tcx>, - args: GenericArgsRef<'tcx>, ) { debug!( "unify_receivers: self_ty={:?} method_self_ty={:?} span={:?} pick={:?}", self_ty, method_self_ty, self.span, pick ); - let cause = self.cause( - self.self_expr.span, - ObligationCauseCode::UnifyReceiver(Box::new(UnifyReceiverContext { - assoc_item: pick.item, - param_env: self.param_env, - args, - })), - ); + let cause = self.cause(self.self_expr.span, ObligationCauseCode::Misc); match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index b3e48fd5bb592..f87e5b5202ab5 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -873,7 +873,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) { let principal = match self_ty.kind() { - ty::Dynamic(ref data, ..) => Some(data), + ty::Dynamic(data, ..) => Some(data), _ => None, } .and_then(|data| data.principal()) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1ca8b59db223c..8438a92219eae 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let hir::def::Res::Local(recv_id) = path.res && let Some(segment) = path.segments.first() { - let body = self.tcx.hir().body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); if let Node::Expr(call_expr) = self.tcx.parent_hir_node(rcvr.hir_id) { let mut let_visitor = LetVisitor { @@ -905,11 +905,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if self.impl_into_iterator_should_be_iterator(rcvr_ty, span, unsatisfied_predicates) { err.span_label(span, format!("`{rcvr_ty}` is not an iterator")); - err.multipart_suggestion_verbose( - "call `.into_iter()` first", - vec![(span.shrink_to_lo(), format!("into_iter()."))], - Applicability::MaybeIncorrect, - ); + if !span.in_external_macro(self.tcx.sess.source_map()) { + err.multipart_suggestion_verbose( + "call `.into_iter()` first", + vec![(span.shrink_to_lo(), format!("into_iter()."))], + Applicability::MaybeIncorrect, + ); + } return err.emit(); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in @@ -1586,10 +1588,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::QPath(ty) = source && let hir::Node::Expr(ref path_expr) = self.tcx.parent_hir_node(ty.hir_id) && let hir::ExprKind::Path(_) = path_expr.kind - && let hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Semi(ref parent), .. - }) - | hir::Node::Expr(ref parent) = self.tcx.parent_hir_node(path_expr.hir_id) + && let hir::Node::Stmt(&hir::Stmt { kind: hir::StmtKind::Semi(parent), .. }) + | hir::Node::Expr(parent) = self.tcx.parent_hir_node(path_expr.hir_id) { let replacement_span = if let hir::ExprKind::Call(..) | hir::ExprKind::Struct(..) = parent.kind { @@ -2390,7 +2390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { long_ty_path: &mut Option, ) -> Result<(), ErrorGuaranteed> { if let SelfSource::MethodCall(expr) = source { - for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) { + for (_, parent) in tcx.hir_parent_iter(expr.hir_id).take(5) { if let Node::Expr(parent_expr) = parent { let lang_item = match parent_expr.kind { ExprKind::Struct(qpath, _, _) => match *qpath { @@ -2599,7 +2599,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { seg1.ident.span, StashKey::CallAssocMethod, |err| { - let body = self.tcx.hir().body_owned_by(self.body_id); + let body = self.tcx.hir_body_owned_by(self.body_id); struct LetVisitor { ident_name: Symbol, } @@ -3149,8 +3149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut derives_grouped = Vec::<(String, Span, String)>::new(); for (self_name, self_span, trait_name) in derives.into_iter() { - if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut() - { + if let Some((last_self_name, _, last_trait_names)) = derives_grouped.last_mut() { if last_self_name == &self_name { last_trait_names.push_str(format!(", {trait_name}").as_str()); continue; @@ -3336,7 +3335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let accessible_sugg = sugg(accessible_candidates, true); let inaccessible_sugg = sugg(inaccessible_candidates, false); - let (module, _, _) = self.tcx.hir().get_module(scope); + let (module, _, _) = self.tcx.hir_get_module(scope); let span = module.spans.inject_use_span; handle_candidates(accessible_sugg, inaccessible_sugg, span); } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index cd07666ca6c5e..bd0848b991661 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -230,10 +230,19 @@ enum InheritedRefMatchRule { /// underlying type is not a reference type, the inherited reference will be consumed. EatInner, /// When the underlying type is a reference type, reference patterns consume both layers of - /// reference, i.e. they both reset the binding mode and consume the reference type. Reference - /// patterns are not permitted when there is no underlying reference type, i.e. they can't eat - /// only an inherited reference. This is the current stable Rust behavior. - EatBoth, + /// reference, i.e. they both reset the binding mode and consume the reference type. + EatBoth { + /// If `true`, an inherited reference will be considered when determining whether a reference + /// pattern matches a given type: + /// - If the underlying type is not a reference, a reference pattern may eat the inherited reference; + /// - If the underlying type is a reference, a reference pattern matches if it can eat either one + /// of the underlying and inherited references. E.g. a `&mut` pattern is allowed if either the + /// underlying type is `&mut` or the inherited reference is `&mut`. + /// If `false`, a reference pattern is only matched against the underlying type. + /// This is `false` for stable Rust and `true` for both the `ref_pat_eat_one_layer_2024` and + /// `ref_pat_eat_one_layer_2024_structural` feature gates. + consider_inherited_ref: bool, + }, } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -259,10 +268,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // Currently, matching against an inherited ref on edition 2024 is an error. // Use `EatBoth` as a fallback to be similar to stable Rust. - InheritedRefMatchRule::EatBoth + InheritedRefMatchRule::EatBoth { consider_inherited_ref: false } } } else { - InheritedRefMatchRule::EatBoth + InheritedRefMatchRule::EatBoth { + consider_inherited_ref: self.tcx.features().ref_pat_eat_one_layer_2024() + || self.tcx.features().ref_pat_eat_one_layer_2024_structural(), + } } } @@ -312,7 +324,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info; let path_res = match pat.kind { - PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref qpath), hir_id, span }) => { + PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => { Some(self.resolve_ty_and_res_fully_qualified_call(qpath, *hir_id, *span)) } _ => None, @@ -332,7 +344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Wild | PatKind::Err(_) => expected, // We allow any type here; we ensure that the type is uninhabited during match checking. PatKind::Never => expected, - PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref qpath), hir_id, span }) => { + PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), hir_id, span }) => { let ty = self.check_pat_path( *hir_id, pat.hir_id, @@ -835,20 +847,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - ident.span, + 't', // last char of `mut` def_br_mutbl, ); BindingMode(ByRef::No, Mutability::Mut) } } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => { + BindingMode(ByRef::Yes(user_br_mutbl), _) => { if let ByRef::Yes(def_br_mutbl) = def_br { // `ref`/`ref mut` overrides the binding mode on edition <= 2021 self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - ident.span, + match user_br_mutbl { + Mutability::Not => 'f', // last char of `ref` + Mutability::Mut => 't', // last char of `ref mut` + }, def_br_mutbl, ); } @@ -931,7 +946,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let var_ty = self.resolve_vars_if_possible(var_ty); let msg = format!("first introduced with type `{var_ty}` here"); err.span_label(hir.span(var_id), msg); - let in_match = hir.parent_iter(var_id).any(|(_, n)| { + let in_match = self.tcx.hir_parent_iter(var_id).any(|(_, n)| { matches!( n, hir::Node::Expr(hir::Expr { @@ -2371,6 +2386,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // NB: This assumes that `&` patterns can match against mutable // references (RFC 3627, Rule 5). If we implement a pattern typing // ruleset with Rule 4 but not Rule 5, we'll need to check that here. + // FIXME(ref_pat_eat_one_layer_2024_structural): If we already tried + // matching the real reference, the error message should explain that + // falling back to the inherited reference didn't work. This should be + // the same error as the old-Edition version below. debug_assert!(ref_pat_matches_mut_ref); self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); } @@ -2381,13 +2400,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return expected; } } - InheritedRefMatchRule::EatBoth => { + InheritedRefMatchRule::EatBoth { consider_inherited_ref: true } => { // Reset binding mode on old editions pat_info.binding_mode = ByRef::No; + + if let ty::Ref(_, inner_ty, _) = *expected.kind() { + // Consume both the inherited and inner references. + if pat_mutbl.is_mut() && inh_mut.is_mut() { + // As a special case, a `&mut` reference pattern will be able to match + // against a reference type of any mutability if the inherited ref is + // mutable. Since this allows us to match against a shared reference + // type, we refer to this as "falling back" to matching the inherited + // reference, though we consume the real reference as well. We handle + // this here to avoid adding this case to the common logic below. + self.check_pat(inner, inner_ty, pat_info); + return expected; + } else { + // Otherwise, use the common logic below for matching the inner + // reference type. + // FIXME(ref_pat_eat_one_layer_2024_structural): If this results in a + // mutability mismatch, the error message should explain that falling + // back to the inherited reference didn't work. This should be the same + // error as the Edition 2024 version above. + } + } else { + // The expected type isn't a reference type, so only match against the + // inherited reference. + if pat_mutbl > inh_mut { + // We can't match a lone inherited shared reference with `&mut`. + self.error_inherited_ref_mutability_mismatch(pat, pat_prefix_span); + } + + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } + } + InheritedRefMatchRule::EatBoth { consider_inherited_ref: false } => { + // Reset binding mode on stable Rust. This will be a type error below if + // `expected` is not a reference type. + pat_info.binding_mode = ByRef::No; self.add_rust_2024_migration_desugared_pat( pat_info.top_info.hir_id, pat, - inner.span, + match pat_mutbl { + Mutability::Not => '&', // last char of `&` + Mutability::Mut => 't', // last char of `&mut` + }, inh_mut, ) } @@ -2779,18 +2838,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat_id: HirId, subpat: &'tcx Pat<'tcx>, - cutoff_span: Span, + final_char: char, def_br_mutbl: Mutability, ) { // Try to trim the span we're labeling to just the `&` or binding mode that's an issue. - // If the subpattern's span is is from an expansion, the emitted label will not be trimmed. - let source_map = self.tcx.sess.source_map(); - let cutoff_span = source_map - .span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(') - .unwrap_or(cutoff_span); - // Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard - // error if the subpattern is of edition >= 2024. - let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt()); + let from_expansion = subpat.span.from_expansion(); + let trimmed_span = if from_expansion { + // If the subpattern is from an expansion, highlight the whole macro call instead. + subpat.span + } else { + let trimmed = self.tcx.sess.source_map().span_through_char(subpat.span, final_char); + // The edition of the trimmed span should be the same as `subpat.span`; this will be a + // a hard error if the subpattern is of edition >= 2024. We set it manually to be sure: + trimmed.with_ctxt(subpat.span.ctxt()) + }; let mut typeck_results = self.typeck_results.borrow_mut(); let mut table = typeck_results.rust_2024_migration_desugared_pats_mut(); @@ -2806,31 +2867,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !self.tcx.features().ref_pat_eat_one_layer_2024_structural(), }); + let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind { + info.bad_modifiers = true; + // If the user-provided binding modifier doesn't match the default binding mode, we'll + // need to suggest reference patterns, which can affect other bindings. + // For simplicity, we opt to suggest making the pattern fully explicit. + info.suggest_eliding_modes &= + user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not); + "binding modifier" + } else { + info.bad_ref_pats = true; + // For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll + // suggest adding them instead, which can affect the types assigned to bindings. + // As such, we opt to suggest making the pattern fully explicit. + info.suggest_eliding_modes = false; + "reference pattern" + }; // Only provide a detailed label if the problematic subpattern isn't from an expansion. // In the case that it's from a macro, we'll add a more detailed note in the emitter. - let from_expansion = subpat.span.from_expansion(); let primary_label = if from_expansion { + // We can't suggest eliding modifiers within expansions. + info.suggest_eliding_modes = false; // NB: This wording assumes the only expansions that can produce problematic reference // patterns and bindings are macros. If a desugaring or AST pass is added that can do // so, we may want to inspect the span's source callee or macro backtrace. "occurs within macro expansion".to_owned() } else { - let pat_kind = if let PatKind::Binding(user_bind_annot, _, _, _) = subpat.kind { - info.bad_modifiers |= true; - // If the user-provided binding modifier doesn't match the default binding mode, we'll - // need to suggest reference patterns, which can affect other bindings. - // For simplicity, we opt to suggest making the pattern fully explicit. - info.suggest_eliding_modes &= - user_bind_annot == BindingMode(ByRef::Yes(def_br_mutbl), Mutability::Not); - "binding modifier" - } else { - info.bad_ref_pats |= true; - // For simplicity, we don't try to suggest eliding reference patterns. Thus, we'll - // suggest adding them instead, which can affect the types assigned to bindings. - // As such, we opt to suggest making the pattern fully explicit. - info.suggest_eliding_modes = false; - "reference pattern" - }; let dbm_str = match def_br_mutbl { Mutability::Not => "ref", Mutability::Mut => "ref mut", diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 871d08137b34e..9a0b22470585f 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let args = self.resolve_vars_if_possible(args); let closure_def_id = closure_def_id.expect_local(); - assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id); + assert_eq!(self.tcx.hir_body_owner_def_id(body.id()), closure_def_id); let mut delegate = InferBorrowKind { closure_def_id, capture_information: Default::default(), @@ -1934,7 +1934,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( /// Returns the Span of where the value with the provided HirId would be dropped fn drop_location_span(tcx: TyCtxt<'_>, hir_id: HirId) -> Span { - let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap(); + let owner_id = tcx.hir_get_enclosing_scope(hir_id).unwrap(); let owner_node = tcx.hir_node(owner_id); let owner_span = match owner_node { diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index dbcf99157905a..3e9ce0e11e402 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, body: &'tcx hir::Body<'tcx>, ) -> &'tcx ty::TypeckResults<'tcx> { - let item_def_id = self.tcx.hir().body_owner_def_id(body.id()); + let item_def_id = self.tcx.hir_body_owner_def_id(body.id()); // This attribute causes us to dump some writeback information // in the form of errors, which is used for unit tests. @@ -48,13 +48,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for param in body.params { wbcx.visit_node_id(param.pat.span, param.hir_id); } - // Type only exists for constants and statics, not functions. - match self.tcx.hir().body_owner_kind(item_def_id) { - hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) => { + match self.tcx.hir_body_owner_kind(item_def_id) { + // Visit the type of a const or static, which is used during THIR building. + hir::BodyOwnerKind::Const { .. } + | hir::BodyOwnerKind::Static(_) + | hir::BodyOwnerKind::GlobalAsm => { let item_hir_id = self.tcx.local_def_id_to_hir_id(item_def_id); wbcx.visit_node_id(body.value.span, item_hir_id); } - hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (), + // For closures and consts, we already plan to visit liberated signatures. + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => {} } wbcx.visit_body(body); wbcx.visit_min_capture_map(); @@ -790,7 +793,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { self.fcx .err_ctxt() .emit_inference_failure_err( - self.fcx.tcx.hir().body_owner_def_id(self.body.id()), + self.fcx.tcx.hir_body_owner_def_id(self.body.id()), self.span.to_span(self.fcx.tcx), p.into(), TypeAnnotationNeeded::E0282, @@ -814,7 +817,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { // expect that types that show up in the typeck are fully // normalized. let mut value = if self.should_normalize { - let body_id = tcx.hir().body_owner_def_id(self.body.id()); + let body_id = tcx.hir_body_owner_def_id(self.body.id()); let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); let at = self.fcx.at(&cause, self.fcx.param_env); let universes = vec![None; outer_exclusive_binder(value).as_usize()]; diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 46a63b02e8469..4939bfb3a1cdd 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_incremental" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -12,6 +12,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index c2f9ebc5262a7..d4407559202f0 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -76,7 +76,7 @@ pub(crate) fn assert_dep_graph(tcx: TyCtxt<'_>) { let mut visitor = IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] }; visitor.process_attrs(CRATE_DEF_ID); - tcx.hir().visit_all_item_likes_in_crate(&mut visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut visitor); (visitor.if_this_changed, visitor.then_this_would_need) }; diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index a95599e7a860e..56858679af663 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -166,7 +166,7 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { } let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] }; - tcx.hir().walk_attributes(&mut all_attrs); + tcx.hir_walk_attributes(&mut all_attrs); // Note that we cannot use the existing "unused attribute"-infrastructure // here, since that is running before codegen. This is also the reason why @@ -261,7 +261,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { HirItem::ForeignMod { .. } => ("ItemForeignMod", LABELS_HIR_ONLY), // Module-level inline assembly (from global_asm!) - HirItem::GlobalAsm(..) => ("ItemGlobalAsm", LABELS_HIR_ONLY), + HirItem::GlobalAsm { .. } => ("ItemGlobalAsm", LABELS_HIR_ONLY), // A type alias, e.g., `type Foo = Bar` HirItem::TyAlias(..) => ("ItemTy", LABELS_HIR_ONLY), diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 7977bcc68911d..50e47533ab6ca 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::Hash64; use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap}; use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_serialize::Decodable; @@ -154,7 +155,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc, WorkPr sess.dcx().emit_warn(errors::CorruptFile { path: &path }); return LoadResult::DataOutOfDate; }; - let prev_commandline_args_hash = u64::decode(&mut decoder); + let prev_commandline_args_hash = Hash64::decode(&mut decoder); if prev_commandline_args_hash != expected_hash { if sess.opts.unstable_opts.incremental_info { diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index f27db7a5400ad..3d83a3c98daf8 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_index" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index f12df831cb503..6dc044a6d380d 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -723,7 +723,7 @@ impl ChunkedBitSet { match self.chunks.get(chunk_index) { Some(Zeros(_chunk_domain_size)) => ChunkIter::Zeros, Some(Ones(chunk_domain_size)) => ChunkIter::Ones(0..*chunk_domain_size as usize), - Some(Mixed(chunk_domain_size, _, ref words)) => { + Some(Mixed(chunk_domain_size, _, words)) => { let num_words = num_words(*chunk_domain_size as usize); ChunkIter::Mixed(BitIter::new(&words[0..num_words])) } @@ -752,11 +752,7 @@ impl BitRelations> for ChunkedBitSet { changed = true; } ( - Mixed( - self_chunk_domain_size, - ref mut self_chunk_count, - ref mut self_chunk_words, - ), + Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words), Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words), ) => { // First check if the operation would change @@ -836,11 +832,7 @@ impl BitRelations> for ChunkedBitSet { Mixed(*self_chunk_domain_size, self_chunk_count, Rc::new(self_chunk_words)); } ( - Mixed( - self_chunk_domain_size, - ref mut self_chunk_count, - ref mut self_chunk_words, - ), + Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words), Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words), ) => { // See [`>>::union`] for the explanation @@ -891,11 +883,7 @@ impl BitRelations> for ChunkedBitSet { *self_chunk = other_chunk.clone(); } ( - Mixed( - self_chunk_domain_size, - ref mut self_chunk_count, - ref mut self_chunk_words, - ), + Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words), Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words), ) => { // See [`>>::union`] for the explanation @@ -1678,7 +1666,7 @@ impl SparseBitMatrix { /// Iterates through all the columns set to true in a given row of /// the matrix. - pub fn iter(&self, row: R) -> impl Iterator + '_ { + pub fn iter(&self, row: R) -> impl Iterator { self.row(row).into_iter().flat_map(|r| r.iter()) } diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs index a3d87f59567fe..0225c5c4f329a 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -51,7 +51,7 @@ impl IntervalSet { self.map.clear(); } - pub fn iter(&self) -> impl Iterator + '_ + pub fn iter(&self) -> impl Iterator where I: Step, { @@ -59,7 +59,7 @@ impl IntervalSet { } /// Iterates through intervals stored in the set, in order. - pub fn iter_intervals(&self) -> impl Iterator> + '_ + pub fn iter_intervals(&self) -> impl Iterator> where I: Step, { diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 956d32c9a6943..4636f294f13bb 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -63,9 +63,7 @@ impl IndexSlice { } #[inline] - pub fn iter_enumerated( - &self, - ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { + pub fn iter_enumerated(&self) -> impl DoubleEndedIterator + ExactSizeIterator { self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } @@ -84,7 +82,7 @@ impl IndexSlice { #[inline] pub fn iter_enumerated_mut( &mut self, - ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { + ) -> impl DoubleEndedIterator + ExactSizeIterator { self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 1cb8bc861af98..7f3f3ead5f2af 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -132,7 +132,7 @@ impl IndexVec { } #[inline] - pub fn drain>(&mut self, range: R) -> impl Iterator + '_ { + pub fn drain>(&mut self, range: R) -> impl Iterator { self.raw.drain(range) } @@ -140,7 +140,7 @@ impl IndexVec { pub fn drain_enumerated>( &mut self, range: R, - ) -> impl Iterator + '_ { + ) -> impl Iterator { let begin = match range.start_bound() { std::ops::Bound::Included(i) => *i, std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(), diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index 98bc1b6a29bba..891e7ded61996 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_index_macros" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] proc-macro = true diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 6d1a2d3de9e35..08c0361488493 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -1,14 +1,13 @@ [package] name = "rustc_infer" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] doctest = false [dependencies] # tidy-alphabetical-start -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 23f63af778d07..8a61631c69c0b 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -10,7 +10,6 @@ use std::fmt::Debug; use std::iter; -use rustc_data_structures::captures::Captures; use rustc_index::{Idx, IndexVec}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::mir::ConstraintCategory; @@ -541,13 +540,13 @@ impl<'tcx> InferCtxt<'tcx> { /// Converts the region constraints resulting from a query into an /// iterator of obligations. - fn query_outlives_constraints_into_obligations<'a>( - &'a self, - cause: &'a ObligationCause<'tcx>, + fn query_outlives_constraints_into_obligations( + &self, + cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - uninstantiated_region_constraints: &'a [QueryOutlivesConstraint<'tcx>], - result_args: &'a CanonicalVarValues<'tcx>, - ) -> impl Iterator> + 'a + Captures<'tcx> { + uninstantiated_region_constraints: &[QueryOutlivesConstraint<'tcx>], + result_args: &CanonicalVarValues<'tcx>, + ) -> impl Iterator> { uninstantiated_region_constraints.iter().map(move |&constraint| { let predicate = instantiate_value(self.tcx, result_args, constraint); self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env) diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index 5452ba67497bc..8fa5361121c67 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -38,7 +38,7 @@ pub struct FreeRegionMap<'tcx> { } impl<'tcx> FreeRegionMap<'tcx> { - pub fn elements(&self) -> impl Iterator> + '_ { + pub fn elements(&self) -> impl Iterator> { self.relation.elements().copied() } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c2513a1af1988..537e8119adaf6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -15,7 +15,6 @@ use region_constraints::{ }; pub use relate::StructurallyRelateAliases; pub use relate::combine::PredicateEmittingRelation; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::undo_log::{Rollback, UndoLogs}; use rustc_data_structures::unify as ut; @@ -28,7 +27,6 @@ use rustc_middle::bug; use rustc_middle::infer::canonical::{CanonicalQueryInput, CanonicalVarValues}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::select; -pub use rustc_middle::ty::IntVarValue; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{ BoundVarReplacerDelegate, TypeFoldable, TypeFolder, TypeSuperFoldable, fold_regions, @@ -234,7 +232,7 @@ impl<'tcx> InferCtxtInner<'tcx> { // while looping through this. pub fn iter_opaque_types( &self, - ) -> impl Iterator, ty::OpaqueHiddenType<'tcx>)> + '_ { + ) -> impl Iterator, ty::OpaqueHiddenType<'tcx>)> { self.opaque_type_storage.opaque_types.iter().map(|(&k, &v)| (k, v)) } } @@ -950,7 +948,7 @@ impl<'tcx> InferCtxt<'tcx> { let inner = self.inner.borrow(); assert!(!UndoLogs::>::in_snapshot(&inner.undo_log)); let storage = inner.region_constraint_storage.as_ref().expect("regions already resolved"); - assert!(storage.data.is_empty()); + assert!(storage.data.is_empty(), "{:#?}", storage.data); // We clone instead of taking because borrowck still wants to use the // inference context after calling this for diagnostics and the new // trait solver. @@ -1296,9 +1294,7 @@ impl<'tcx> InferCtxt<'tcx> { /// The returned function is used in a fast path. If it returns `true` the variable is /// unchanged, `false` indicates that the status is unknown. #[inline] - pub fn is_ty_infer_var_definitely_unchanged<'a>( - &'a self, - ) -> (impl Fn(TyOrConstInferVar) -> bool + Captures<'tcx> + 'a) { + pub fn is_ty_infer_var_definitely_unchanged(&self) -> impl Fn(TyOrConstInferVar) -> bool { // This hoists the borrow/release out of the loop body. let inner = self.inner.try_borrow(); diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 1afe50e336da2..2a4544c1140d1 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -20,7 +20,7 @@ pub(crate) mod verify; #[instrument(level = "debug", skip(param_env), ret)] pub fn explicit_outlives_bounds<'tcx>( param_env: ty::ParamEnv<'tcx>, -) -> impl Iterator> + 'tcx { +) -> impl Iterator> { param_env .caller_bounds() .into_iter() diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 31f585c0c9edd..b346e193d0b84 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -1,8 +1,7 @@ use std::fmt; -use rustc_ast_ir::try_visit; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor, try_visit}; use rustc_middle::ty::{self, TyCtxt}; use crate::traits; diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 295a988d2da5d..9c9660cf50469 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_interface" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index ca4e556dcdb80..eed729a1777fc 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -24,8 +24,9 @@ pub(crate) struct CrateNameInvalid<'a> { pub struct FerrisIdentifier { #[primary_span] pub spans: Vec, - #[suggestion(code = "ferris", applicability = "maybe-incorrect")] + #[suggestion(code = "{ferris_fix}", applicability = "maybe-incorrect")] pub first_span: Span, + pub ferris_fix: &'static str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_interface/src/limits.rs b/compiler/rustc_interface/src/limits.rs index 3de513797e3ea..8f01edec09f33 100644 --- a/compiler/rustc_interface/src/limits.rs +++ b/compiler/rustc_interface/src/limits.rs @@ -20,21 +20,21 @@ use crate::errors::LimitInvalid; pub(crate) fn provide(providers: &mut Providers) { providers.limits = |tcx, ()| Limits { - recursion_limit: get_recursion_limit(tcx.hir().krate_attrs(), tcx.sess), + recursion_limit: get_recursion_limit(tcx.hir_krate_attrs(), tcx.sess), move_size_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::move_size_limit, Limit::new(tcx.sess.opts.unstable_opts.move_size_limit.unwrap_or(0)), ), type_length_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::type_length_limit, Limit::new(2usize.pow(24)), ), pattern_complexity_limit: get_limit( - tcx.hir().krate_attrs(), + tcx.hir_krate_attrs(), tcx.sess, sym::pattern_complexity_limit, Limit::unlimited(), diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d7d183e17edb8..553215ca0af02 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -171,13 +171,15 @@ fn configure_and_expand( new_path.push(path); } } - env::set_var( - "PATH", - &env::join_paths( - new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), - ) - .unwrap(), - ); + unsafe { + env::set_var( + "PATH", + &env::join_paths( + new_path.iter().filter(|p| env::join_paths(iter::once(p)).is_ok()), + ) + .unwrap(), + ); + } } // Create the config for macro expansion @@ -216,7 +218,9 @@ fn configure_and_expand( } if cfg!(windows) { - env::set_var("PATH", &old_path); + unsafe { + env::set_var("PATH", &old_path); + } } krate @@ -301,8 +305,41 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { for (ident, mut spans) in identifiers.drain(..) { spans.sort(); if ident == sym::ferris { + enum FerrisFix { + SnakeCase, + ScreamingSnakeCase, + PascalCase, + } + + impl FerrisFix { + const fn as_str(self) -> &'static str { + match self { + FerrisFix::SnakeCase => "ferris", + FerrisFix::ScreamingSnakeCase => "FERRIS", + FerrisFix::PascalCase => "Ferris", + } + } + } + let first_span = spans[0]; - sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span }); + let prev_source = sess.psess.source_map().span_to_prev_source(first_span); + let ferris_fix = prev_source + .map_or(FerrisFix::SnakeCase, |source| { + let mut source_before_ferris = source.trim_end().split_whitespace().rev(); + match source_before_ferris.next() { + Some("struct" | "trait" | "mod" | "union" | "type" | "enum") => { + FerrisFix::PascalCase + } + Some("const" | "static") => FerrisFix::ScreamingSnakeCase, + Some("mut") if source_before_ferris.next() == Some("static") => { + FerrisFix::ScreamingSnakeCase + } + _ => FerrisFix::SnakeCase, + } + }) + .as_str(); + + sess.dcx().emit_err(errors::FerrisIdentifier { spans, first_span, ferris_fix }); } else { sess.dcx().emit_err(errors::EmojiIdentifier { spans, ident }); } @@ -846,7 +883,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { CStore::from_tcx(tcx).report_unused_deps(tcx); }, { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_loops(module); tcx.ensure_ok().check_mod_attrs(module); tcx.ensure_ok().check_mod_naked_functions(module); @@ -871,7 +908,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { rustc_hir_analysis::check_crate(tcx); sess.time("MIR_coroutine_by_move_body", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { if tcx.needs_coroutine_by_move_body_def_id(def_id.to_def_id()) { tcx.ensure_done().coroutine_by_move_body_def_id(def_id); } @@ -885,7 +922,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.untracked().definitions.freeze(); sess.time("MIR_borrow_checking", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { // Run unsafety check because it's responsible for stealing and // deallocating THIR. tcx.ensure_ok().check_unsafety(def_id); @@ -893,21 +930,21 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { }); }); sess.time("MIR_effect_checking", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { tcx.ensure_ok().has_ffi_unwind_calls(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.hir_body_const_context(def_id).is_some() { tcx.ensure_ok().mir_drops_elaborated_and_const_checked(def_id); } }); }); sess.time("coroutine_obligations", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { if tcx.is_coroutine(def_id.to_def_id()) { tcx.ensure_ok().mir_coroutine_witnesses(def_id); tcx.ensure_ok().check_coroutine_obligations( @@ -931,7 +968,7 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { // that requires the optimized/ctfe MIR, coroutine bodies, or evaluating consts. if tcx.sess.opts.unstable_opts.validate_mir { sess.time("ensuring_final_MIR_is_computable", || { - tcx.hir().par_body_owners(|def_id| { + tcx.par_hir_body_owners(|def_id| { tcx.instance_mir(ty::InstanceKind::Item(def_id.into())); }); }); @@ -967,7 +1004,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { tcx.ensure_ok().check_private_in_public(()); }, { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_deathness(module) }); }, @@ -983,7 +1020,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) { }, { sess.time("privacy_checking_modules", || { - tcx.hir().par_for_each_module(|module| { + tcx.par_hir_for_each_module(|module| { tcx.ensure_ok().check_mod_privacy(module); }); }); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 233bfcb529710..aabd235bcabed 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -759,7 +759,7 @@ fn test_unstable_options_tracking_hash() { tracked!(allow_features, Some(vec![String::from("lang_items")])); tracked!(always_encode_mir, true); tracked!(assume_incomplete_release, true); - tracked!(autodiff, vec![AutoDiff::Print]); + tracked!(autodiff, vec![AutoDiff::Enable]); tracked!(binary_dep_depinfo, true); tracked!(box_noalias, false); tracked!( diff --git a/compiler/rustc_lexer/Cargo.toml b/compiler/rustc_lexer/Cargo.toml index 4b3492fdeda25..448a50faf458e 100644 --- a/compiler/rustc_lexer/Cargo.toml +++ b/compiler/rustc_lexer/Cargo.toml @@ -2,7 +2,7 @@ name = "rustc_lexer" version = "0.0.0" license = "MIT OR Apache-2.0" -edition = "2021" +edition = "2024" repository = "https://github.com/rust-lang/rust/" description = """ Rust lexer used by rustc. No stability guarantees are provided. diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index c63ab77decac9..bf18845a0830d 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -291,7 +291,7 @@ pub fn validate_raw_str(input: &str, prefix_len: u32) -> Result<(), RawStrError> } /// Creates an iterator that produces tokens from the input string. -pub fn tokenize(input: &str) -> impl Iterator + '_ { +pub fn tokenize(input: &str) -> impl Iterator { let mut cursor = Cursor::new(input); std::iter::from_fn(move || { let token = cursor.advance_token(); diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index cc5a90296332d..24e7b40c8a2d3 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_lint" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index dbe24c9cdf24c..679367634276d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -630,7 +630,8 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro .suggestion = use pat_param to preserve semantics -lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope +lint_out_of_scope_macro_calls = cannot find macro `{$path}` in the current scope when looking from {$location} + .label = not found from {$location} .help = import `macro_rules` with `use` to make it callable above its definition lint_overflowing_bin_hex = literal out of range for `{$ty}` diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index e449f1106131d..5e44583b2976b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -466,7 +466,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { MethodLateContext::TraitAutoImpl => {} // If the method is an impl for an item with docs_hidden, don't doc. MethodLateContext::PlainImpl => { - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()); + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()); let impl_ty = cx.tcx.type_of(parent).instantiate_identity(); let outerdef = match impl_ty.kind() { ty::Adt(def, _) => Some(def.did()), @@ -975,10 +975,8 @@ declare_lint! { /// ### Example /// /// ```rust - /// #[no_mangle] - /// fn foo(t: T) { - /// - /// } + /// #[unsafe(no_mangle)] + /// fn foo(t: T) {} /// ``` /// /// {{produces}} @@ -2909,7 +2907,13 @@ enum AsmLabelKind { impl<'tcx> LateLintPass<'tcx> for AsmLabels { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { if let hir::Expr { - kind: hir::ExprKind::InlineAsm(hir::InlineAsm { template_strs, options, .. }), + kind: + hir::ExprKind::InlineAsm(hir::InlineAsm { + asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, + template_strs, + options, + .. + }), .. } = expr { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c74158102c7a5..74663e6b4bbe1 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -139,9 +139,7 @@ impl LintStore { &self.lints } - pub fn get_lint_groups<'t>( - &'t self, - ) -> impl Iterator, bool)> + 't { + pub fn get_lint_groups(&self) -> impl Iterator, bool)> { self.lint_groups .iter() .filter(|(_, LintGroup { depr, .. })| { diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index f418d6d8753b4..ec8f84415759f 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -12,7 +12,7 @@ declare_lint! { /// for `dyn SubTrait` with a `dyn SuperTrait` type as the `Output` type. /// /// These implementations are "shadowed" by trait upcasting (stabilized since - /// CURRENT_RUSTC_VERSION). The `deref` functions is no longer called implicitly, which might + /// 1.86.0). The `deref` functions is no longer called implicitly, which might /// change behavior compared to previous rustc versions. /// /// ### Example diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 1ca2e4e74ea6f..7f098893f7de5 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -147,7 +147,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { let is_copy = cx.type_is_copy_modulo_regions(arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let let_underscore_ignore_sugg = || { - if let Some((_, node)) = cx.tcx.hir().parent_iter(expr.hir_id).nth(0) + if let Some((_, node)) = cx.tcx.hir_parent_iter(expr.hir_id).nth(0) && let Node::Stmt(stmt) = node && let StmtKind::Semi(e) = stmt.kind && e.hir_id == expr.hir_id diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index aeb5a03a4f7e3..40ca9e05d95d6 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -444,8 +444,8 @@ pub(super) fn decorate_lint( lints::InnerAttributeUnstable::CustomInnerAttribute } .decorate_lint(diag), - BuiltinLintDiag::OutOfScopeMacroCalls { path } => { - lints::OutOfScopeMacroCalls { path }.decorate_lint(diag) + BuiltinLintDiag::OutOfScopeMacroCalls { span, path, location } => { + lints::OutOfScopeMacroCalls { span, path, location }.decorate_lint(diag) } BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => { lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag) diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index 59390b7e4206c..757fc1f58bd51 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>( let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env()); let ocx = ObligationCtxt::new(&infcx); - let body_def_id = cx.tcx.hir().body_owner_def_id(body_id); + let body_def_id = cx.tcx.hir_body_owner_def_id(body_id); let cause = ObligationCause::new(span, body_def_id, rustc_infer::traits::ObligationCauseCode::Misc); diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 636779fe9b4cf..49c34d0edcc2a 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -35,12 +35,12 @@ declare_lint! { /// /// ```rust /// mod m { - /// extern "C" { + /// unsafe extern "C" { /// fn foo(); /// } /// } /// - /// extern "C" { + /// unsafe extern "C" { /// fn foo(_: u32); /// } /// ``` diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 869dab6799d02..c1aa95667da68 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -95,7 +95,7 @@ pub(crate) struct IfLetRescope { } fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { - let Some((_, hir::Node::Expr(expr))) = tcx.hir().parent_iter(hir_id).next() else { + let Some((_, hir::Node::Expr(expr))) = tcx.hir_parent_iter(hir_id).next() else { return false; }; let hir::ExprKind::If(_cond, _conseq, Some(alt)) = expr.kind else { return false }; @@ -103,7 +103,7 @@ fn expr_parent_is_else(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { } fn expr_parent_is_stmt(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { - let mut parents = tcx.hir().parent_iter(hir_id); + let mut parents = tcx.hir_parent_iter(hir_id); let stmt = match parents.next() { Some((_, hir::Node::Stmt(stmt))) => stmt, Some((_, hir::Node::Block(_) | hir::Node::Arm(_))) => return true, diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index d2956d94685f1..0b3af7d6aba98 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -86,8 +86,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust,compile_fail - /// # #![feature(lifetime_capture_rules_2024)] + /// ```rust,edition2024,compile_fail /// # #![deny(impl_trait_redundant_captures)] /// fn test<'a>(x: &'a i32) -> impl Sized + use<'a> { x } /// ``` @@ -268,8 +267,7 @@ where && parent == self.parent_def_id { let opaque_span = self.tcx.def_span(opaque_def_id); - let new_capture_rules = opaque_span.at_least_rust_2024() - || self.tcx.features().lifetime_capture_rules_2024(); + let new_capture_rules = opaque_span.at_least_rust_2024(); if !new_capture_rules && !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..))) { diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index ddc9ae1594f90..1f999bbea5fe7 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -497,7 +497,7 @@ impl Diagnostics { return; }; - for (hir_id, _parent) in cx.tcx.hir().parent_iter(current_id) { + for (hir_id, _parent) in cx.tcx.hir_parent_iter(current_id) { if let Some(owner_did) = hir_id.as_owner() && cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics) { @@ -512,7 +512,7 @@ impl Diagnostics { // // Otherwise, emit a `DIAGNOSTIC_OUTSIDE_OF_IMPL` lint. let mut is_inside_appropriate_impl = false; - for (_hir_id, parent) in cx.tcx.hir().parent_iter(current_id) { + for (_hir_id, parent) in cx.tcx.hir_parent_iter(current_id) { debug!(?parent); if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent && let Impl { of_trait: Some(of_trait), .. } = impl_ diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index f17570e4a81fa..d22515d62d60e 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -379,7 +379,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>( ) { let mut cx = LateContextAndPass { context, pass }; - let (module, _span, hir_id) = tcx.hir().get_module(module_def_id); + let (module, _span, hir_id) = tcx.hir_get_module(module_def_id); cx.with_lint_attrs(hir_id, |cx| { // There is no module lint that will have the crate itself as an item, so check it here. @@ -445,7 +445,7 @@ fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( // Since the root module isn't visited as an item (because it isn't an // item), warn for it here. lint_callback!(cx, check_crate,); - tcx.hir().walk_toplevel_module(cx); + tcx.hir_walk_toplevel_module(cx); lint_callback!(cx, check_crate_post,); }) } @@ -462,7 +462,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) { || { tcx.sess.time("module_lints", || { // Run per-module lints - tcx.hir().par_for_each_module(|module| tcx.ensure_ok().lint_mod(module)); + tcx.par_hir_for_each_module(|module| tcx.ensure_ok().lint_mod(module)); }); }, ); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7e13205bbf1e9..4ede9b4408798 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -144,7 +144,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { let mut visitor = LintLevelMaximum { tcx, dont_need_to_run }; visitor.process_opts(); - tcx.hir().walk_attributes(&mut visitor); + tcx.hir_walk_attributes(&mut visitor); visitor.dont_need_to_run } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index c8de5e877531e..ded50d98db5e3 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -21,7 +21,6 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(array_windows)] @@ -641,6 +640,7 @@ fn register_internals(store: &mut LintStore) { LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO), LintId::of(USAGE_OF_QUALIFIED_TY), LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT), + LintId::of(USAGE_OF_TYPE_IR_INHERENT), LintId::of(BAD_OPT_ACCESS), LintId::of(SPAN_USE_EQ_CTXT), ], diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 368d36bfdd0b2..0058630957291 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3108,7 +3108,10 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { #[diag(lint_out_of_scope_macro_calls)] #[help] pub(crate) struct OutOfScopeMacroCalls { + #[label] + pub span: Span, pub path: String, + pub location: String, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 2f9cf98848e94..66e207a451ef0 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -183,7 +183,7 @@ impl EarlyLintPass for NonAsciiIdents { #[allow(rustc::potential_query_instability)] let mut symbols: Vec<_> = symbols.iter().collect(); symbols.sort_by_key(|k| k.1); - for (symbol, &sp) in symbols.iter() { + for &(ref symbol, &sp) in symbols.iter() { let symbol_str = symbol.as_str(); if symbol_str.is_ascii() { continue; @@ -242,7 +242,7 @@ impl EarlyLintPass for NonAsciiIdents { UnordMap::with_capacity(symbols.len()); let mut skeleton_buf = String::new(); - for (&symbol, &sp) in symbols.iter() { + for &(&symbol, &sp) in symbols.iter() { use unicode_security::confusable_detection::skeleton; let symbol_str = symbol.as_str(); @@ -298,7 +298,7 @@ impl EarlyLintPass for NonAsciiIdents { script_states.insert(latin_augmented_script_set, ScriptSetUsage::Verified); let mut has_suspicious = false; - for (symbol, &sp) in symbols.iter() { + for &(ref symbol, &sp) in symbols.iter() { let symbol_str = symbol.as_str(); for ch in symbol_str.chars() { if ch.is_ascii() { diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 5636f80d60020..bc35e2f0538d0 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -344,7 +344,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name) .and_then(|attr| { if let AttrKind::Normal(n) = &attr.kind - && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: ref lit }, .. } = + && let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: lit }, .. } = n.as_ref() && let ast::LitKind::Str(name, ..) = lit.kind { diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index 7cc35e20fcb64..571cab934fd6a 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter { // we should just suggest removing the `.into_iter()` or changing it to `.iter()` // to disambiguate if we want to iterate by-value or by-ref. let sub = if let Some((_, hir::Node::Expr(parent_expr))) = - cx.tcx.hir().parent_iter(expr.hir_id).nth(1) + cx.tcx.hir_parent_iter(expr.hir_id).nth(1) && let hir::ExprKind::Match(arg, [_], hir::MatchSource::ForLoopDesugar) = &parent_expr.kind && let hir::ExprKind::Call(path, [_]) = &arg.kind diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 68b1f435a4cf7..cb83d405cc3ed 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -696,7 +696,7 @@ declare_lint! { /// ### Example /// /// ```rust - /// extern "C" { + /// unsafe extern "C" { /// static STATIC: String; /// } /// ``` @@ -1587,7 +1587,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } impl<'a, 'b, 'tcx> ty::visit::TypeVisitor> for FnPtrFinder<'a, 'b, 'tcx> { - type Result = ControlFlow>; + type Result = (); fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let ty::FnPtr(_, hdr) = ty.kind() @@ -1740,7 +1740,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions { hir::ItemKind::Impl(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::ForeignMod { .. } | hir::ItemKind::Mod(..) | hir::ItemKind::Macro(..) @@ -1791,7 +1791,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { let t = cx.tcx.type_of(it.owner_id).instantiate_identity(); let ty = cx.tcx.erase_regions(t); let Ok(layout) = cx.layout_of(ty) else { return }; - let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, ref variants, .. } = + let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, variants, .. } = &layout.variants else { return; diff --git a/compiler/rustc_lint/src/unqualified_local_imports.rs b/compiler/rustc_lint/src/unqualified_local_imports.rs index b27398a950c81..50c5119285f7c 100644 --- a/compiler/rustc_lint/src/unqualified_local_imports.rs +++ b/compiler/rustc_lint/src/unqualified_local_imports.rs @@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for UnqualifiedLocalImports { return; } - let encl_item_id = cx.tcx.hir().get_parent_item(item.hir_id()); + let encl_item_id = cx.tcx.hir_get_parent_item(item.hir_id()); let encl_item = cx.tcx.hir_node_by_def_id(encl_item_id.def_id); if encl_item.fn_kind().is_some() { // `use` in a method -- don't lint, that leads to too many undesirable lints diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index 450885e71647f..9ab350daf69d7 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_lint_defs" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 10bf4ec77ed93..97850a2afc11e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2780,7 +2780,7 @@ declare_lint! { /// /// ```rust /// enum Void {} - /// extern { + /// unsafe extern { /// static EXTERN: Void; /// } /// ``` @@ -4011,7 +4011,7 @@ declare_lint! { /// ```rust /// #![warn(ffi_unwind_calls)] /// - /// extern "C-unwind" { + /// unsafe extern "C-unwind" { /// fn foo(); /// } /// @@ -4755,7 +4755,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,edition2021 /// #![warn(missing_unsafe_on_extern)] /// #![allow(dead_code)] /// @@ -4792,7 +4792,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,edition2021 /// #![warn(unsafe_attr_outside_unsafe)] /// /// #[no_mangle] diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7ffe4e4e4901c..ff3dae08ffc96 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -134,8 +134,8 @@ impl LintExpectationId { } pub fn set_lint_index(&mut self, new_lint_index: Option) { - let (LintExpectationId::Unstable { ref mut lint_index, .. } - | LintExpectationId::Stable { ref mut lint_index, .. }) = self; + let (LintExpectationId::Unstable { lint_index, .. } + | LintExpectationId::Stable { lint_index, .. }) = self; *lint_index = new_lint_index } @@ -819,7 +819,9 @@ pub enum BuiltinLintDiag { is_macro: bool, }, OutOfScopeMacroCalls { + span: Span, path: String, + location: String, }, UnexpectedBuiltinCfg { cfg: String, diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 2168a0df9ec87..4f3ce77efc441 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_llvm" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 48806888b43df..3d1f3b2cd4dd4 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -51,9 +51,13 @@ fn detect_llvm_link() -> (&'static str, &'static str) { fn restore_library_path() { let key = tracked_env_var_os("REAL_LIBRARY_PATH_VAR").expect("REAL_LIBRARY_PATH_VAR"); if let Some(env) = tracked_env_var_os("REAL_LIBRARY_PATH") { - env::set_var(&key, env); + unsafe { + env::set_var(&key, env); + } } else { - env::remove_var(&key); + unsafe { + env::remove_var(&key); + } } } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index a6b2384f2d7b2..9ce4abdb432e8 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -22,6 +22,7 @@ #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Program.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Target/TargetMachine.h" @@ -472,16 +473,19 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); auto Arg0 = std::string(ArgsCstrBuff); buffer_offset = Arg0.size() + 1; - auto ArgsCppStr = std::string(ArgsCstrBuff + buffer_offset, - ArgsCstrBuffLen - buffer_offset); - auto i = 0; - while (i != std::string::npos) { - i = ArgsCppStr.find('\0', i + 1); - if (i != std::string::npos) - ArgsCppStr.replace(i, 1, " "); + + std::string CommandlineArgs; + raw_string_ostream OS(CommandlineArgs); + ListSeparator LS(" "); + for (StringRef Arg : split(StringRef(ArgsCstrBuff + buffer_offset, + ArgsCstrBuffLen - buffer_offset), + '\0')) { + OS << LS; + sys::printArg(OS, Arg, /*Quote=*/true); } + OS.flush(); Options.MCOptions.Argv0 = Arg0; - Options.MCOptions.CommandlineArgs = ArgsCppStr; + Options.MCOptions.CommandlineArgs = CommandlineArgs; #else int buffer_offset = 0; assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0'); @@ -688,9 +692,12 @@ struct LLVMRustSanitizerOptions { bool SanitizeKernelAddressRecover; }; -// This symbol won't be available or used when Enzyme is not enabled +// This symbol won't be available or used when Enzyme is not enabled. +// Always set AugmentPassBuilder to true, since it registers optimizations which +// will improve the performance for Enzyme. #ifdef ENZYME -extern "C" void registerEnzyme(llvm::PassBuilder &PB); +extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB, + /* augmentPassBuilder */ bool); #endif extern "C" LLVMRustResult LLVMRustOptimize( @@ -1019,7 +1026,7 @@ extern "C" LLVMRustResult LLVMRustOptimize( // now load "-enzyme" pass: #ifdef ENZYME if (RunEnzyme) { - registerEnzyme(PB); + registerEnzymeAndPassPipeline(PB, true); if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) { std::string ErrMsg = toString(std::move(Err)); LLVMRustSetLastError(ErrMsg.c_str()); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b8cef6a7e250e..aea2a8dd09787 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1767,6 +1767,24 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS))); } +#if LLVM_VERSION_LT(19, 0) +enum { + LLVMGEPFlagInBounds = (1 << 0), + LLVMGEPFlagNUSW = (1 << 1), + LLVMGEPFlagNUW = (1 << 2), +}; +extern "C" LLVMValueRef +LLVMBuildGEPWithNoWrapFlags(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Pointer, LLVMValueRef *Indices, + unsigned NumIndices, const char *Name, + unsigned NoWrapFlags) { + if (NoWrapFlags & LLVMGEPFlagInBounds) + return LLVMBuildInBoundsGEP2(B, Ty, Pointer, Indices, NumIndices, Name); + else + return LLVMBuildGEP2(B, Ty, Pointer, Indices, NumIndices, Name); +} +#endif + // Transfers ownership of DiagnosticHandler unique_ptr to the caller. extern "C" DiagnosticHandler * LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) { diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index fe399bc77e32a..30f6e9ba8053f 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_log" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index d8d2bef496404..f9d3b75835907 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_macros" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] proc-macro = true diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 612a36ba9aa57..060799e981d46 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -760,8 +760,8 @@ impl SubdiagnosticVariant { } ( "applicability", - SubdiagnosticKind::Suggestion { ref mut applicability, .. } - | SubdiagnosticKind::MultipartSuggestion { ref mut applicability, .. }, + SubdiagnosticKind::Suggestion { applicability, .. } + | SubdiagnosticKind::MultipartSuggestion { applicability, .. }, ) => { let value = get_string!(); let value = Applicability::from_str(&value.value()).unwrap_or_else(|()| { diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 527ca26c0eb10..a7906d50d0f2d 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -36,12 +36,12 @@ pub(super) fn type_visitable_derive( s.add_bounds(synstructure::AddBounds::Generics); let body_visit = s.each(|bind| { quote! { - match ::rustc_ast_ir::visit::VisitorResult::branch( + match ::rustc_middle::ty::visit::VisitorResult::branch( ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { - return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + return ::rustc_middle::ty::visit::VisitorResult::from_residual(r); }, } } @@ -56,7 +56,7 @@ pub(super) fn type_visitable_derive( __visitor: &mut __V ) -> __V::Result { match *self { #body_visit } - <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + <__V::Result as ::rustc_middle::ty::visit::VisitorResult>::output() } }, ) diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 0b9fdbbd3da8d..a8821640f048e 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_metadata" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 6fc84b06647f5..df0a25712cca4 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -47,6 +47,9 @@ metadata_crate_dep_rustc_driver = metadata_crate_location_unknown_type = extern location for {$crate_name} is of an unknown type: {$path} +metadata_crate_not_compiler_builtins = + the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]` + metadata_crate_not_panic_runtime = the crate `{$crate_name}` is not a panic runtime diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index c2dda21bb72e6..12503ffd1a67f 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -32,7 +32,7 @@ use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_span::edition::Edition; -use rustc_span::{DUMMY_SP, Ident, STDLIB_STABLE_CRATES, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; use rustc_target::spec::{PanicStrategy, Target, TargetTuple}; use tracing::{debug, info, trace}; @@ -147,6 +147,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { writeln!(fmt, " cnum: {cnum}")?; writeln!(fmt, " hash: {}", data.hash())?; writeln!(fmt, " reqd: {:?}", data.dep_kind())?; + writeln!(fmt, " priv: {:?}", data.is_private_dep())?; let CrateSource { dylib, rlib, rmeta } = data.source(); if let Some(dylib) = dylib { writeln!(fmt, " dylib: {}", dylib.0.display())?; @@ -162,6 +163,53 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { } } +/// Reason that a crate is being sourced as a dependency. +#[derive(Clone, Copy)] +enum CrateOrigin<'a> { + /// This crate was a dependency of another crate. + IndirectDependency { + /// Where this dependency was included from. + dep_root: &'a CratePaths, + /// True if the parent is private, meaning the dependent should also be private. + parent_private: bool, + /// Dependency info about this crate. + dep: &'a CrateDep, + }, + /// Injected by `rustc`. + Injected, + /// Provided by `extern crate foo` or as part of the extern prelude. + Extern, +} + +impl<'a> CrateOrigin<'a> { + /// Return the dependency root, if any. + fn dep_root(&self) -> Option<&'a CratePaths> { + match self { + CrateOrigin::IndirectDependency { dep_root, .. } => Some(dep_root), + _ => None, + } + } + + /// Return dependency information, if any. + fn dep(&self) -> Option<&'a CrateDep> { + match self { + CrateOrigin::IndirectDependency { dep, .. } => Some(dep), + _ => None, + } + } + + /// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the + /// dependency is not private, `None` if it could not be determined. + fn private_dep(&self) -> Option { + match self { + CrateOrigin::IndirectDependency { parent_private, dep, .. } => { + Some(dep.is_private || *parent_private) + } + _ => None, + } + } +} + impl CStore { pub fn from_tcx(tcx: TyCtxt<'_>) -> FreezeReadGuard<'_, CStore> { FreezeReadGuard::map(tcx.untracked().cstore.read(), |cstore| { @@ -497,25 +545,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { &self, name: Symbol, private_dep: Option, - dep_root: Option<&CratePaths>, + origin: CrateOrigin<'_>, ) -> bool { - // Standard library crates are never private. - if STDLIB_STABLE_CRATES.contains(&name) { - tracing::info!("returning false for {name} is private"); - return false; - } - - let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep); - - // Any descendants of `std` should be private. These crates are usually not marked - // private in metadata, so we ignore that field. - if extern_private.is_none() - && let Some(dep) = dep_root - && STDLIB_STABLE_CRATES.contains(&dep.name) - { + if matches!(origin, CrateOrigin::Injected) { return true; } + let extern_private = self.sess.opts.externs.get(name.as_str()).map(|e| e.is_private_dep); match (extern_private, private_dep) { // Explicit non-private via `--extern`, explicit non-private from metadata, or // unspecified with default to public. @@ -528,7 +564,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn register_crate( &mut self, host_lib: Option, - dep_root: Option<&CratePaths>, + origin: CrateOrigin<'_>, lib: Library, dep_kind: CrateDepKind, name: Symbol, @@ -540,7 +576,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { let Library { source, metadata } = lib; let crate_root = metadata.get_root(); let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); - let private_dep = self.is_private_dep(name, private_dep, dep_root); + let private_dep = self.is_private_dep(name, private_dep, origin); // Claim this crate number and cache it let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?; @@ -556,14 +592,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Maintain a reference to the top most crate. // Stash paths for top-most crate locally if necessary. let crate_paths; - let dep_root = if let Some(dep_root) = dep_root { + let dep_root = if let Some(dep_root) = origin.dep_root() { dep_root } else { crate_paths = CratePaths::new(crate_root.name(), source.clone()); &crate_paths }; - let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?; + let cnum_map = + self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind, private_dep)?; let raw_proc_macros = if crate_root.is_proc_macro_crate() { let temp_root; @@ -664,17 +701,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { name: Symbol, span: Span, dep_kind: CrateDepKind, + origin: CrateOrigin<'_>, ) -> Option { self.used_extern_options.insert(name); - match self.maybe_resolve_crate(name, dep_kind, None) { + match self.maybe_resolve_crate(name, dep_kind, origin) { Ok(cnum) => { self.cstore.set_used_recursively(cnum); Some(cnum) } Err(err) => { debug!("failed to resolve crate {} {:?}", name, dep_kind); - let missing_core = - self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err(); + let missing_core = self + .maybe_resolve_crate(sym::core, CrateDepKind::Explicit, CrateOrigin::Extern) + .is_err(); err.report(self.sess, span, missing_core); None } @@ -685,20 +724,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { &'b mut self, name: Symbol, mut dep_kind: CrateDepKind, - dep_of: Option<(&'b CratePaths, &'b CrateDep)>, + origin: CrateOrigin<'b>, ) -> Result { info!("resolving crate `{}`", name); if !name.as_str().is_ascii() { return Err(CrateError::NonAsciiName(name)); } - let dep_root = dep_of.map(|d| d.0); - let dep = dep_of.map(|d| d.1); + let dep_root = origin.dep_root(); + let dep = origin.dep(); let hash = dep.map(|d| d.hash); let host_hash = dep.map(|d| d.host_hash).flatten(); let extra_filename = dep.map(|d| &d.extra_filename[..]); let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate }; - let private_dep = dep.map(|d| d.is_private); + let private_dep = origin.private_dep(); let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) { (LoadResult::Previous(cnum), None) @@ -731,12 +770,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { match result { (LoadResult::Previous(cnum), None) => { - info!("library for `{}` was loaded previously", name); + info!("library for `{}` was loaded previously, cnum {cnum}", name); // When `private_dep` is none, it indicates the directly dependent crate. If it is // not specified by `--extern` on command line parameters, it may be // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to // `public-dependency` here. - let private_dep = self.is_private_dep(name, private_dep, dep_root); + let private_dep = self.is_private_dep(name, private_dep, origin); let data = self.cstore.get_crate_data_mut(cnum); if data.is_proc_macro_crate() { dep_kind = CrateDepKind::MacrosOnly; @@ -747,7 +786,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } (LoadResult::Loaded(library), host_library) => { info!("register newly loaded library for `{}`", name); - self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep) + self.register_crate(host_library, origin, library, dep_kind, name, private_dep) } _ => panic!(), } @@ -762,29 +801,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // against a hash, we could load a crate which has the same hash // as an already loaded crate. If this is the case prevent // duplicates by just using the first crate. - // - // Note that we only do this for target triple crates, though, as we - // don't want to match a host crate against an equivalent target one - // already loaded. let root = library.metadata.get_root(); - // FIXME: why is this condition necessary? It was adding in #33625 but I - // don't know why and the original author doesn't remember ... - let can_reuse_cratenum = - locator.tuple == self.sess.opts.target_triple || locator.is_proc_macro; - Ok(Some(if can_reuse_cratenum { - let mut result = LoadResult::Loaded(library); - for (cnum, data) in self.cstore.iter_crate_data() { - if data.name() == root.name() && root.hash() == data.hash() { - assert!(locator.hash.is_none()); - info!("load success, going to previous cnum: {}", cnum); - result = LoadResult::Previous(cnum); - break; - } + let mut result = LoadResult::Loaded(library); + for (cnum, data) in self.cstore.iter_crate_data() { + if data.name() == root.name() && root.hash() == data.hash() { + assert!(locator.hash.is_none()); + info!("load success, going to previous cnum: {}", cnum); + result = LoadResult::Previous(cnum); + break; } - result - } else { - LoadResult::Loaded(library) - })) + } + Ok(Some(result)) } /// Go through the crate metadata and load any crates that it references. @@ -795,6 +822,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { metadata: &MetadataBlob, krate: CrateNum, dep_kind: CrateDepKind, + parent_is_private: bool, ) -> Result { debug!( "resolving deps of external crate `{}` with dep root `{}`", @@ -813,17 +841,26 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { crate_num_map.push(krate); for dep in deps { info!( - "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`", + "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}` private {}", crate_root.name(), dep.name, dep.hash, - dep.extra_filename + dep.extra_filename, + dep.is_private, ); let dep_kind = match dep_kind { CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly, _ => dep.kind, }; - let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?; + let cnum = self.maybe_resolve_crate( + dep.name, + dep_kind, + CrateOrigin::IndirectDependency { + dep_root, + parent_private: parent_is_private, + dep: &dep, + }, + )?; crate_num_map.push(cnum); } @@ -917,7 +954,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { }; info!("panic runtime not found -- loading {}", name); - let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { + let Some(cnum) = + self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected) + else { return; }; let data = self.cstore.get_crate_data(cnum); @@ -946,7 +985,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { info!("loading profiler"); let name = Symbol::intern(&self.sess.opts.unstable_opts.profiler_runtime); - let Some(cnum) = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit) else { + let Some(cnum) = + self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, CrateOrigin::Injected) + else { return; }; let data = self.cstore.get_crate_data(cnum); @@ -1059,12 +1100,54 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { if entry.force { let name_interned = Symbol::intern(name); if !self.used_extern_options.contains(&name_interned) { - self.resolve_crate(name_interned, DUMMY_SP, CrateDepKind::Explicit); + self.resolve_crate( + name_interned, + DUMMY_SP, + CrateDepKind::Explicit, + CrateOrigin::Extern, + ); } } } } + /// Inject the `compiler_builtins` crate if it is not already in the graph. + fn inject_compiler_builtins(&mut self, krate: &ast::Crate) { + // `compiler_builtins` does not get extern builtins, nor do `#![no_core]` crates + if attr::contains_name(&krate.attrs, sym::compiler_builtins) + || attr::contains_name(&krate.attrs, sym::no_core) + { + info!("`compiler_builtins` unneeded"); + return; + } + + // If a `#![compiler_builtins]` crate already exists, avoid injecting it twice. This is + // the common case since usually it appears as a dependency of `std` or `alloc`. + for (cnum, cmeta) in self.cstore.iter_crate_data() { + if cmeta.is_compiler_builtins() { + info!("`compiler_builtins` already exists (cnum = {cnum}); skipping injection"); + return; + } + } + + // `compiler_builtins` is not yet in the graph; inject it. Error on resolution failure. + let Some(cnum) = self.resolve_crate( + sym::compiler_builtins, + krate.spans.inner_span.shrink_to_lo(), + CrateDepKind::Explicit, + CrateOrigin::Injected, + ) else { + info!("`compiler_builtins` not resolved"); + return; + }; + + // Sanity check that the loaded crate is `#![compiler_builtins]` + let cmeta = self.cstore.get_crate_data(cnum); + if !cmeta.is_compiler_builtins() { + self.dcx().emit_err(errors::CrateNotCompilerBuiltins { crate_name: cmeta.name() }); + } + } + fn inject_dependency_if( &mut self, krate: CrateNum, @@ -1174,6 +1257,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn postprocess(&mut self, krate: &ast::Crate) { + self.inject_compiler_builtins(krate); self.inject_forced_externs(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -1185,6 +1269,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { info!("{:?}", CrateDump(self.cstore)); } + /// Process an `extern crate foo` AST node. pub fn process_extern_crate( &mut self, item: &ast::Item, @@ -1210,7 +1295,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { CrateDepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind)?; + let cnum = self.resolve_crate(name, item.span, dep_kind, CrateOrigin::Extern)?; let path_len = definitions.def_path(def_id).data.len(); self.cstore.update_extern_crate( @@ -1229,7 +1314,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option { - let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?; + let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit, CrateOrigin::Extern)?; self.cstore.update_extern_crate( cnum, @@ -1246,7 +1331,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option { - self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok() + self.maybe_resolve_crate(name, CrateDepKind::Explicit, CrateOrigin::Extern).ok() } } diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index a77f9bc623b5b..2ad6389c0b4ac 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -332,6 +332,12 @@ pub struct CrateNotPanicRuntime { pub crate_name: Symbol, } +#[derive(Diagnostic)] +#[diag(metadata_crate_not_compiler_builtins)] +pub struct CrateNotCompilerBuiltins { + pub crate_name: Symbol, +} + #[derive(Diagnostic)] #[diag(metadata_no_panic_strategy)] pub struct NoPanicStrategy { diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 2ddabeb49f70d..3f3e58384cbf4 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -260,7 +260,7 @@ pub(crate) struct CrateLocator<'a> { crate_rejections: CrateRejections, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub(crate) struct CratePaths { pub(crate) name: Symbol, source: CrateSource, @@ -272,7 +272,7 @@ impl CratePaths { } } -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq)] pub(crate) enum CrateFlavor { Rlib, Rmeta, @@ -893,13 +893,13 @@ fn get_flavor_from_path(path: &Path) -> CrateFlavor { // ------------------------------------------ Error reporting ------------------------------------- -#[derive(Clone)] +#[derive(Clone, Debug)] struct CrateMismatch { path: PathBuf, got: String, } -#[derive(Clone, Default)] +#[derive(Clone, Debug, Default)] struct CrateRejections { via_hash: Vec, via_triple: Vec, @@ -912,6 +912,7 @@ struct CrateRejections { /// Candidate rejection reasons collected during crate search. /// If no candidate is accepted, then these reasons are presented to the user, /// otherwise they are ignored. +#[derive(Debug)] pub(crate) struct CombinedLocatorError { crate_name: Symbol, dep_root: Option, @@ -921,6 +922,7 @@ pub(crate) struct CombinedLocatorError { crate_rejections: CrateRejections, } +#[derive(Debug)] pub(crate) enum CrateError { NonAsciiName(Symbol), ExternLocationNotExist(Symbol, PathBuf), diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index e8dcda875e67a..591c8ed50d57a 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -8,7 +8,6 @@ use std::{io, iter, mem}; pub(super) use cstore_impl::provide; use proc_macro::bridge::client::ProcMacro; use rustc_ast as ast; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::owned_slice::OwnedSlice; @@ -963,14 +962,14 @@ impl CrateRoot { pub(crate) fn decode_crate_deps<'a>( &self, metadata: &'a MetadataBlob, - ) -> impl ExactSizeIterator + Captures<'a> { + ) -> impl ExactSizeIterator { self.crate_deps.decode(metadata) } pub(crate) fn decode_target_modifiers<'a>( &self, metadata: &'a MetadataBlob, - ) -> impl ExactSizeIterator + Captures<'a> { + ) -> impl ExactSizeIterator { self.target_modifiers.decode(metadata) } } @@ -1276,7 +1275,7 @@ impl<'a> CrateMetadataRef<'a> { self, id: DefIndex, sess: &'a Session, - ) -> impl Iterator + 'a { + ) -> impl Iterator { iter::from_coroutine( #[coroutine] move || { @@ -1326,10 +1325,7 @@ impl<'a> CrateMetadataRef<'a> { .is_some_and(|ident| ident.name == kw::SelfLower) } - fn get_associated_item_or_field_def_ids( - self, - id: DefIndex, - ) -> impl Iterator + 'a { + fn get_associated_item_or_field_def_ids(self, id: DefIndex) -> impl Iterator { self.root .tables .associated_item_or_field_def_ids @@ -1380,7 +1376,7 @@ impl<'a> CrateMetadataRef<'a> { self, id: DefIndex, sess: &'a Session, - ) -> impl Iterator + 'a { + ) -> impl Iterator { self.root .tables .attributes @@ -1417,12 +1413,12 @@ impl<'a> CrateMetadataRef<'a> { } /// Decodes all traits in the crate (for rustdoc and rustc diagnostics). - fn get_traits(self) -> impl Iterator + 'a { + fn get_traits(self) -> impl Iterator { self.root.traits.decode(self).map(move |index| self.local_def_id(index)) } /// Decodes all trait impls in the crate (for rustdoc). - fn get_trait_impls(self) -> impl Iterator + 'a { + fn get_trait_impls(self) -> impl Iterator { self.cdata.trait_impls.values().flat_map(move |impls| { impls.decode(self).map(move |(impl_index, _)| self.local_def_id(impl_index)) }) @@ -1463,7 +1459,7 @@ impl<'a> CrateMetadataRef<'a> { } } - fn get_native_libraries(self, sess: &'a Session) -> impl Iterator + 'a { + fn get_native_libraries(self, sess: &'a Session) -> impl Iterator { self.root.native_libraries.decode((self, sess)) } @@ -1476,7 +1472,7 @@ impl<'a> CrateMetadataRef<'a> { .decode((self, sess)) } - fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator + 'a { + fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator { self.root.foreign_modules.decode((self, sess)) } @@ -1816,7 +1812,7 @@ impl<'a> CrateMetadataRef<'a> { .decode(self) } - fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator + 'a { + fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator { self.root .tables .doc_link_traits_in_scope @@ -1887,7 +1883,7 @@ impl CrateMetadata { cdata } - pub(crate) fn dependencies(&self) -> impl Iterator + '_ { + pub(crate) fn dependencies(&self) -> impl Iterator { self.dependencies.iter().copied() } @@ -1936,6 +1932,10 @@ impl CrateMetadata { self.root.needs_panic_runtime } + pub(crate) fn is_private_dep(&self) -> bool { + self.private_dep + } + pub(crate) fn is_panic_runtime(&self) -> bool { self.root.panic_runtime } @@ -1944,6 +1944,10 @@ impl CrateMetadata { self.root.profiler_runtime } + pub(crate) fn is_compiler_builtins(&self) -> bool { + self.root.compiler_builtins + } + pub(crate) fn needs_allocator(&self) -> bool { self.root.needs_allocator } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1ac2f6e81e58d..88a88847e6b8b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -696,7 +696,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers()); let root = stat!("final", || { - let attrs = tcx.hir().krate_attrs(); + let attrs = tcx.hir_krate_attrs(); self.lazy(CrateRoot { header: CrateHeader { name: tcx.crate_name(LOCAL_CRATE), @@ -1763,7 +1763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_const(tcx.def_kind(def_id)) { let qualifs = tcx.mir_const_qualif(def_id); record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs); - let body = tcx.hir().maybe_body_owned_by(def_id); + let body = tcx.hir_maybe_body_owned_by(def_id); if let Some(body) = body { let const_data = rendered_const(self.tcx, &body, def_id); record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data); diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index de722e62043cd..aebd2181f31e1 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_middle" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -14,7 +14,6 @@ rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links @@ -22,6 +21,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index dcfa81dab2526..0b3c0be1a4e1a 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -37,9 +37,6 @@ middle_autodiff_unsafe_inner_const_ref = reading from a `Duplicated` const {$ty} middle_bounds_check = index out of bounds: the length is {$len} but the index is {$index} -middle_cannot_be_normalized = - unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized - middle_conflict_types = this expression supplies two conflicting concrete types for the same opaque type @@ -52,9 +49,6 @@ middle_const_eval_non_int = middle_const_not_used_in_type_alias = const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias -middle_cycle = - a cycle occurred during layout computation - middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note -> [true] : {$note} *[other] {""} @@ -78,9 +72,23 @@ middle_erroneous_constant = erroneous constant encountered middle_failed_writing_file = failed to write file {$path}: {$error}" +middle_layout_cycle = + a cycle occurred during layout computation + +middle_layout_normalization_failure = + unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized + middle_layout_references_error = the type has an unknown layout +middle_layout_size_overflow = + values of the type `{$ty}` are too big for the target architecture + +middle_layout_too_generic = the type `{$ty}` does not have a fixed layout + +middle_layout_unknown = + the type `{$ty}` has an unknown layout + middle_opaque_hidden_type_mismatch = concrete type differs from previous defining opaque type use .label = expected `{$self_ty}`, got `{$other_ty}` @@ -98,16 +106,8 @@ middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute -middle_too_generic = `{$ty}` does not have a fixed size - middle_type_length_limit = reached the type-length limit while instantiating `{$shrunk}` -middle_unknown_layout = - the type `{$ty}` has an unknown layout - middle_unsupported_union = we don't support unions yet: '{$ty_name}' -middle_values_too_big = - values of the type `{$ty}` are too big for the target architecture - middle_written_to_path = the full type name has been written to '{$path}' diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index c53e3d54cc491..be8a3403ba956 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -132,19 +132,19 @@ impl fmt::Debug for CustomSubdiagnostic<'_> { #[derive(Diagnostic)] pub enum LayoutError<'tcx> { - #[diag(middle_unknown_layout)] + #[diag(middle_layout_unknown)] Unknown { ty: Ty<'tcx> }, - #[diag(middle_too_generic)] + #[diag(middle_layout_too_generic)] TooGeneric { ty: Ty<'tcx> }, - #[diag(middle_values_too_big)] + #[diag(middle_layout_size_overflow)] Overflow { ty: Ty<'tcx> }, - #[diag(middle_cannot_be_normalized)] + #[diag(middle_layout_normalization_failure)] NormalizationFailure { ty: Ty<'tcx>, failure_ty: String }, - #[diag(middle_cycle)] + #[diag(middle_layout_cycle)] Cycle, #[diag(middle_layout_references_error)] diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index b44f14315d753..fad8c7dcbcbcb 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -28,22 +28,22 @@ pub struct Map<'hir> { } /// An iterator that walks up the ancestor tree of a given `HirId`. -/// Constructed using `tcx.hir().parent_iter(hir_id)`. -struct ParentHirIterator<'hir> { +/// Constructed using `tcx.hir_parent_iter(hir_id)`. +struct ParentHirIterator<'tcx> { current_id: HirId, - map: Map<'hir>, + tcx: TyCtxt<'tcx>, // Cache the current value of `hir_owner_nodes` to avoid repeatedly calling the same query for // the same owner, which will uselessly record many times the same query dependency. - current_owner_nodes: Option<&'hir OwnerNodes<'hir>>, + current_owner_nodes: Option<&'tcx OwnerNodes<'tcx>>, } -impl<'hir> ParentHirIterator<'hir> { - fn new(map: Map<'hir>, current_id: HirId) -> ParentHirIterator<'hir> { - ParentHirIterator { current_id, map, current_owner_nodes: None } +impl<'tcx> ParentHirIterator<'tcx> { + fn new(tcx: TyCtxt<'tcx>, current_id: HirId) -> ParentHirIterator<'tcx> { + ParentHirIterator { current_id, tcx, current_owner_nodes: None } } } -impl<'hir> Iterator for ParentHirIterator<'hir> { +impl<'tcx> Iterator for ParentHirIterator<'tcx> { type Item = HirId; fn next(&mut self) -> Option { @@ -56,10 +56,10 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { let parent_id = if local_id == ItemLocalId::ZERO { // We go from an owner to its parent, so clear the cache. self.current_owner_nodes = None; - self.map.tcx.hir_owner_parent(owner) + self.tcx.hir_owner_parent(owner) } else { let owner_nodes = - self.current_owner_nodes.get_or_insert_with(|| self.map.tcx.hir_owner_nodes(owner)); + self.current_owner_nodes.get_or_insert_with(|| self.tcx.hir_owner_nodes(owner)); let parent_local_id = owner_nodes.nodes[local_id].parent; // HIR indexing should have checked that. debug_assert_ne!(parent_local_id, local_id); @@ -74,33 +74,33 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { } /// An iterator that walks up the ancestor tree of a given `HirId`. -/// Constructed using `tcx.hir().parent_owner_iter(hir_id)`. -pub struct ParentOwnerIterator<'hir> { +/// Constructed using `tcx.hir_parent_owner_iter(hir_id)`. +pub struct ParentOwnerIterator<'tcx> { current_id: HirId, - map: Map<'hir>, + tcx: TyCtxt<'tcx>, } -impl<'hir> Iterator for ParentOwnerIterator<'hir> { - type Item = (OwnerId, OwnerNode<'hir>); +impl<'tcx> Iterator for ParentOwnerIterator<'tcx> { + type Item = (OwnerId, OwnerNode<'tcx>); fn next(&mut self) -> Option { if self.current_id.local_id.index() != 0 { self.current_id.local_id = ItemLocalId::ZERO; - let node = self.map.tcx.hir_owner_node(self.current_id.owner); + let node = self.tcx.hir_owner_node(self.current_id.owner); return Some((self.current_id.owner, node)); } if self.current_id == CRATE_HIR_ID { return None; } - let parent_id = self.map.tcx.hir_def_key(self.current_id.owner.def_id).parent; + let parent_id = self.tcx.hir_def_key(self.current_id.owner.def_id).parent; let parent_id = parent_id.map_or(CRATE_OWNER_ID, |local_def_index| { let def_id = LocalDefId { local_def_index }; - self.map.tcx.local_def_id_to_hir_id(def_id).owner + self.tcx.local_def_id_to_hir_id(def_id).owner }); self.current_id = HirId::make_owner(parent_id.def_id); - let node = self.map.tcx.hir_owner_node(self.current_id.owner); + let node = self.tcx.hir_owner_node(self.current_id.owner); Some((self.current_id.owner, node)) } } @@ -146,7 +146,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `HirId` of the parent HIR node of node with this `hir_id`. /// Returns the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`. /// - /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`]. + /// If calling repeatedly and iterating over parents, prefer [`TyCtxt::hir_parent_iter`]. pub fn parent_hir_id(self, hir_id: HirId) -> HirId { let HirId { owner, local_id } = hir_id; if local_id == ItemLocalId::ZERO { @@ -174,15 +174,12 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn hir_free_items(self) -> impl Iterator + 'tcx { + pub fn hir_free_items(self) -> impl Iterator { self.hir_crate_items(()).free_items.iter().copied() } #[inline] - pub fn hir_module_free_items( - self, - module: LocalModDefId, - ) -> impl Iterator + 'tcx { + pub fn hir_module_free_items(self, module: LocalModDefId) -> impl Iterator { self.hir_module_items(module).free_items() } @@ -229,64 +226,62 @@ impl<'tcx> TyCtxt<'tcx> { pub fn hir_body(self, id: BodyId) -> &'tcx Body<'tcx> { self.hir_owner_nodes(id.hir_id.owner).bodies[&id.hir_id.local_id] } -} -impl<'hir> Map<'hir> { #[track_caller] - pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> { - self.tcx.hir_node(hir_id).fn_decl() + pub fn hir_fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'tcx FnDecl<'tcx>> { + self.hir_node(hir_id).fn_decl() } #[track_caller] - pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> { - self.tcx.hir_node(hir_id).fn_sig() + pub fn hir_fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'tcx FnSig<'tcx>> { + self.hir_node(hir_id).fn_sig() } #[track_caller] - pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { - for (_, node) in self.parent_iter(hir_id) { + pub fn hir_enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { + for (_, node) in self.hir_parent_iter(hir_id) { if let Some((def_id, _)) = node.associated_body() { return def_id; } } - bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id); + bug!("no `hir_enclosing_body_owner` for hir_id `{}`", hir_id); } /// Returns the `HirId` that corresponds to the definition of /// which this is the body of, i.e., a `fn`, `const` or `static` /// item (possibly associated), a closure, or a `hir::AnonConst`. - pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId { - let parent = self.tcx.parent_hir_id(hir_id); - assert_eq!(self.tcx.hir_node(parent).body_id().unwrap().hir_id, hir_id, "{hir_id:?}"); + pub fn hir_body_owner(self, BodyId { hir_id }: BodyId) -> HirId { + let parent = self.parent_hir_id(hir_id); + assert_eq!(self.hir_node(parent).body_id().unwrap().hir_id, hir_id, "{hir_id:?}"); parent } - pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { - self.tcx.parent_hir_node(hir_id).associated_body().unwrap().0 + pub fn hir_body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId { + self.parent_hir_node(hir_id).associated_body().unwrap().0 } /// Given a `LocalDefId`, returns the `BodyId` associated with it, /// if the node is a body owner, otherwise returns `None`. - pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> { - Some(self.tcx.hir_body(self.tcx.hir_node_by_def_id(id).body_id()?)) + pub fn hir_maybe_body_owned_by(self, id: LocalDefId) -> Option<&'tcx Body<'tcx>> { + Some(self.hir_body(self.hir_node_by_def_id(id).body_id()?)) } /// Given a body owner's id, returns the `BodyId` associated with it. #[track_caller] - pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> { - self.maybe_body_owned_by(id).unwrap_or_else(|| { - let hir_id = self.tcx.local_def_id_to_hir_id(id); + pub fn hir_body_owned_by(self, id: LocalDefId) -> &'tcx Body<'tcx> { + self.hir_maybe_body_owned_by(id).unwrap_or_else(|| { + let hir_id = self.local_def_id_to_hir_id(id); span_bug!( - self.span(hir_id), + self.hir().span(hir_id), "body_owned_by: {} has no associated body", - self.node_to_string(hir_id) + self.hir().node_to_string(hir_id) ); }) } - pub fn body_param_names(self, id: BodyId) -> impl Iterator + 'hir { - self.tcx.hir_body(id).params.iter().map(|arg| match arg.pat.kind { + pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator { + self.hir_body(id).params.iter().map(|arg| match arg.pat.kind { PatKind::Binding(_, _, ident, _) => ident, _ => Ident::empty(), }) @@ -295,9 +290,9 @@ impl<'hir> Map<'hir> { /// Returns the `BodyOwnerKind` of this `LocalDefId`. /// /// Panics if `LocalDefId` does not have an associated body. - pub fn body_owner_kind(self, def_id: impl Into) -> BodyOwnerKind { + pub fn hir_body_owner_kind(self, def_id: impl Into) -> BodyOwnerKind { let def_id = def_id.into(); - match self.tcx.def_kind(def_id) { + match self.def_kind(def_id) { DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => { BodyOwnerKind::Const { inline: false } } @@ -307,6 +302,7 @@ impl<'hir> Map<'hir> { DefKind::Static { safety: _, mutability, nested: false } => { BodyOwnerKind::Static(mutability) } + DefKind::GlobalAsm => BodyOwnerKind::GlobalAsm, dk => bug!("{:?} is not a body node: {:?}", def_id, dk), } } @@ -318,18 +314,18 @@ impl<'hir> Map<'hir> { /// This should only be used for determining the context of a body, a return /// value of `Some` does not always suggest that the owner of the body is `const`, /// just that it has to be checked as if it were. - pub fn body_const_context(self, def_id: impl Into) -> Option { + pub fn hir_body_const_context(self, def_id: impl Into) -> Option { let def_id = def_id.into(); - let ccx = match self.body_owner_kind(def_id) { + let ccx = match self.hir_body_owner_kind(def_id) { BodyOwnerKind::Const { inline } => ConstContext::Const { inline }, BodyOwnerKind::Static(mutability) => ConstContext::Static(mutability), - BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None, - BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn(def_id) => { + BodyOwnerKind::Fn if self.is_constructor(def_id) => return None, + BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.is_const_fn(def_id) => { ConstContext::ConstFn } - BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn, - BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None, + BodyOwnerKind::Fn if self.is_const_default_method(def_id) => ConstContext::ConstFn, + BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None, }; Some(ccx) @@ -339,55 +335,55 @@ impl<'hir> Map<'hir> { /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir().krate().body_ids.iter()`. #[inline] - pub fn body_owners(self) -> impl Iterator + 'hir { - self.tcx.hir_crate_items(()).body_owners.iter().copied() + pub fn hir_body_owners(self) -> impl Iterator { + self.hir_crate_items(()).body_owners.iter().copied() } #[inline] - pub fn par_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { - par_for_each_in(&self.tcx.hir_crate_items(()).body_owners[..], |&def_id| f(def_id)); + pub fn par_hir_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) { + par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&def_id| f(def_id)); } - pub fn ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { - let def_kind = self.tcx.def_kind(def_id); + pub fn hir_ty_param_owner(self, def_id: LocalDefId) -> LocalDefId { + let def_kind = self.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => def_id, DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { - self.tcx.local_parent(def_id) + self.local_parent(def_id) } _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } - pub fn ty_param_name(self, def_id: LocalDefId) -> Symbol { - let def_kind = self.tcx.def_kind(def_id); + pub fn hir_ty_param_name(self, def_id: LocalDefId) -> Symbol { + let def_kind = self.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper, DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { - self.tcx.item_name(def_id.to_def_id()) + self.item_name(def_id.to_def_id()) } _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind), } } - pub fn trait_impls(self, trait_did: DefId) -> &'hir [LocalDefId] { - self.tcx.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) + pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] { + self.all_local_trait_impls(()).get(&trait_did).map_or(&[], |xs| &xs[..]) } /// Gets the attributes on the crate. This is preferable to /// invoking `krate.attrs` because it registers a tighter /// dep-graph access. - pub fn krate_attrs(self) -> &'hir [Attribute] { - self.attrs(CRATE_HIR_ID) + pub fn hir_krate_attrs(self) -> &'tcx [Attribute] { + self.hir().attrs(CRATE_HIR_ID) } - pub fn rustc_coherence_is_core(self) -> bool { - self.krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) + pub fn hir_rustc_coherence_is_core(self) -> bool { + self.hir_krate_attrs().iter().any(|attr| attr.has_name(sym::rustc_coherence_is_core)) } - pub fn get_module(self, module: LocalModDefId) -> (&'hir Mod<'hir>, Span, HirId) { + pub fn hir_get_module(self, module: LocalModDefId) -> (&'tcx Mod<'tcx>, Span, HirId) { let hir_id = HirId::make_owner(module.to_local_def_id()); - match self.tcx.hir_owner_node(hir_id.owner) { + match self.hir_owner_node(hir_id.owner) { OwnerNode::Item(&Item { span, kind: ItemKind::Mod(m), .. }) => (m, span, hir_id), OwnerNode::Crate(item) => (item, item.spans.inner_span, hir_id), node => panic!("not a module: {node:?}"), @@ -395,20 +391,20 @@ impl<'hir> Map<'hir> { } /// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`. - pub fn walk_toplevel_module(self, visitor: &mut V) -> V::Result + pub fn hir_walk_toplevel_module(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let (top_mod, span, hir_id) = self.get_module(LocalModDefId::CRATE_DEF_ID); + let (top_mod, span, hir_id) = self.hir_get_module(LocalModDefId::CRATE_DEF_ID); visitor.visit_mod(top_mod, span, hir_id) } /// Walks the attributes in a crate. - pub fn walk_attributes(self, visitor: &mut V) -> V::Result + pub fn hir_walk_attributes(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let krate = self.tcx.hir_crate(()); + let krate = self.hir_crate(()); for info in krate.owners.iter() { if let MaybeOwner::Owner(info) = info { for attrs in info.attrs.map.values() { @@ -422,84 +418,80 @@ impl<'hir> Map<'hir> { /// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you /// need to process every item-like, and don't care about visiting nested items in a particular /// order then this method is the best choice. If you do care about this nesting, you should - /// use the `tcx.hir().walk_toplevel_module`. + /// use the `tcx.hir_walk_toplevel_module`. /// /// Note that this function will access HIR for all the item-likes in the crate. If you only /// need to access some of them, it is usually better to manually loop on the iterators /// provided by `tcx.hir_crate_items(())`. /// /// Please see the notes in `intravisit.rs` for more information. - pub fn visit_all_item_likes_in_crate(self, visitor: &mut V) -> V::Result + pub fn hir_visit_all_item_likes_in_crate(self, visitor: &mut V) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let krate = self.tcx.hir_crate_items(()); - walk_list!(visitor, visit_item, krate.free_items().map(|id| self.tcx.hir_item(id))); + let krate = self.hir_crate_items(()); + walk_list!(visitor, visit_item, krate.free_items().map(|id| self.hir_item(id))); walk_list!( visitor, visit_trait_item, - krate.trait_items().map(|id| self.tcx.hir_trait_item(id)) - ); - walk_list!( - visitor, - visit_impl_item, - krate.impl_items().map(|id| self.tcx.hir_impl_item(id)) + krate.trait_items().map(|id| self.hir_trait_item(id)) ); + walk_list!(visitor, visit_impl_item, krate.impl_items().map(|id| self.hir_impl_item(id))); walk_list!( visitor, visit_foreign_item, - krate.foreign_items().map(|id| self.tcx.hir_foreign_item(id)) + krate.foreign_items().map(|id| self.hir_foreign_item(id)) ); V::Result::output() } /// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to /// item-likes in a single module. - pub fn visit_item_likes_in_module(self, module: LocalModDefId, visitor: &mut V) -> V::Result + pub fn hir_visit_item_likes_in_module( + self, + module: LocalModDefId, + visitor: &mut V, + ) -> V::Result where - V: Visitor<'hir>, + V: Visitor<'tcx>, { - let module = self.tcx.hir_module_items(module); - walk_list!(visitor, visit_item, module.free_items().map(|id| self.tcx.hir_item(id))); + let module = self.hir_module_items(module); + walk_list!(visitor, visit_item, module.free_items().map(|id| self.hir_item(id))); walk_list!( visitor, visit_trait_item, - module.trait_items().map(|id| self.tcx.hir_trait_item(id)) - ); - walk_list!( - visitor, - visit_impl_item, - module.impl_items().map(|id| self.tcx.hir_impl_item(id)) + module.trait_items().map(|id| self.hir_trait_item(id)) ); + walk_list!(visitor, visit_impl_item, module.impl_items().map(|id| self.hir_impl_item(id))); walk_list!( visitor, visit_foreign_item, - module.foreign_items().map(|id| self.tcx.hir_foreign_item(id)) + module.foreign_items().map(|id| self.hir_foreign_item(id)) ); V::Result::output() } - pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) { - let crate_items = self.tcx.hir_crate_items(()); + pub fn hir_for_each_module(self, mut f: impl FnMut(LocalModDefId)) { + let crate_items = self.hir_crate_items(()); for module in crate_items.submodules.iter() { f(LocalModDefId::new_unchecked(module.def_id)) } } #[inline] - pub fn par_for_each_module(self, f: impl Fn(LocalModDefId) + DynSend + DynSync) { - let crate_items = self.tcx.hir_crate_items(()); + pub fn par_hir_for_each_module(self, f: impl Fn(LocalModDefId) + DynSend + DynSync) { + let crate_items = self.hir_crate_items(()); par_for_each_in(&crate_items.submodules[..], |module| { f(LocalModDefId::new_unchecked(module.def_id)) }) } #[inline] - pub fn try_par_for_each_module( + pub fn try_par_hir_for_each_module( self, f: impl Fn(LocalModDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { - let crate_items = self.tcx.hir_crate_items(()); + let crate_items = self.hir_crate_items(()); try_par_for_each_in(&crate_items.submodules[..], |module| { f(LocalModDefId::new_unchecked(module.def_id)) }) @@ -508,27 +500,27 @@ impl<'hir> Map<'hir> { /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] - pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator + 'hir { + pub fn hir_parent_id_iter(self, current_id: HirId) -> impl Iterator { ParentHirIterator::new(self, current_id) } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] - pub fn parent_iter(self, current_id: HirId) -> impl Iterator)> { - self.parent_id_iter(current_id).map(move |id| (id, self.tcx.hir_node(id))) + pub fn hir_parent_iter(self, current_id: HirId) -> impl Iterator)> { + self.hir_parent_id_iter(current_id).map(move |id| (id, self.hir_node(id))) } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] - pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> { - ParentOwnerIterator { current_id, map: self } + pub fn hir_parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'tcx> { + ParentOwnerIterator { current_id, tcx: self } } /// Checks if the node is left-hand side of an assignment. - pub fn is_lhs(self, id: HirId) -> bool { - match self.tcx.parent_hir_node(id) { + pub fn hir_is_lhs(self, id: HirId) -> bool { + match self.parent_hir_node(id) { Node::Expr(expr) => match expr.kind { ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id, _ => false, @@ -539,8 +531,8 @@ impl<'hir> Map<'hir> { /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. /// Used exclusively for diagnostics, to avoid suggestion function calls. - pub fn is_inside_const_context(self, hir_id: HirId) -> bool { - self.body_const_context(self.enclosing_body_owner(hir_id)).is_some() + pub fn hir_is_inside_const_context(self, hir_id: HirId) -> bool { + self.hir_body_const_context(self.hir_enclosing_body_owner(hir_id)).is_some() } /// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is @@ -565,11 +557,11 @@ impl<'hir> Map<'hir> { /// false /// } /// ``` - pub fn get_fn_id_for_return_block(self, id: HirId) -> Option { - let enclosing_body_owner = self.tcx.local_def_id_to_hir_id(self.enclosing_body_owner(id)); + pub fn hir_get_fn_id_for_return_block(self, id: HirId) -> Option { + let enclosing_body_owner = self.local_def_id_to_hir_id(self.hir_enclosing_body_owner(id)); // Return `None` if the `id` expression is not the returned value of the enclosing body - let mut iter = [id].into_iter().chain(self.parent_id_iter(id)).peekable(); + let mut iter = [id].into_iter().chain(self.hir_parent_id_iter(id)).peekable(); while let Some(cur_id) = iter.next() { if enclosing_body_owner == cur_id { break; @@ -577,14 +569,16 @@ impl<'hir> Map<'hir> { // A return statement is always the value returned from the enclosing body regardless of // what the parent expressions are. - if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = self.tcx.hir_node(cur_id) { + if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = self.hir_node(cur_id) { break; } - // If the current expression's value doesnt get used as the parent expressions value then return `None` + // If the current expression's value doesnt get used as the parent expressions value + // then return `None` if let Some(&parent_id) = iter.peek() { - match self.tcx.hir_node(parent_id) { - // The current node is not the tail expression of the block expression parent expr. + match self.hir_node(parent_id) { + // The current node is not the tail expression of the block expression parent + // expr. Node::Block(Block { expr: Some(e), .. }) if cur_id != e.hir_id => return None, Node::Block(Block { expr: Some(e), .. }) if matches!(e.kind, ExprKind::If(_, _, None)) => @@ -592,7 +586,8 @@ impl<'hir> Map<'hir> { return None; } - // The current expression's value does not pass up through these parent expressions + // The current expression's value does not pass up through these parent + // expressions. Node::Block(Block { expr: None, .. }) | Node::Expr(Expr { kind: ExprKind::Loop(..), .. }) | Node::LetStmt(..) => return None, @@ -609,11 +604,11 @@ impl<'hir> Map<'hir> { /// parent item is in this map. The "parent item" is the closest parent node /// in the HIR which is recorded by the map and is an item, either an item /// in a module, trait, or impl. - pub fn get_parent_item(self, hir_id: HirId) -> OwnerId { + pub fn hir_get_parent_item(self, hir_id: HirId) -> OwnerId { if hir_id.local_id != ItemLocalId::ZERO { // If this is a child of a HIR owner, return the owner. hir_id.owner - } else if let Some((def_id, _node)) = self.parent_owner_iter(hir_id).next() { + } else if let Some((def_id, _node)) = self.hir_parent_owner_iter(hir_id).next() { def_id } else { CRATE_OWNER_ID @@ -625,8 +620,8 @@ impl<'hir> Map<'hir> { /// /// Used by error reporting when there's a type error in an if or match arm caused by the /// expression needing to be unit. - pub fn get_if_cause(self, hir_id: HirId) -> Option<&'hir Expr<'hir>> { - for (_, node) in self.parent_iter(hir_id) { + pub fn hir_get_if_cause(self, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> { + for (_, node) in self.hir_parent_iter(hir_id) { match node { Node::Item(_) | Node::ForeignItem(_) @@ -643,8 +638,8 @@ impl<'hir> Map<'hir> { } /// Returns the nearest enclosing scope. A scope is roughly an item or block. - pub fn get_enclosing_scope(self, hir_id: HirId) -> Option { - for (hir_id, node) in self.parent_iter(hir_id) { + pub fn hir_get_enclosing_scope(self, hir_id: HirId) -> Option { + for (hir_id, node) in self.hir_parent_iter(hir_id) { if let Node::Item(Item { kind: ItemKind::Fn { .. } @@ -670,18 +665,20 @@ impl<'hir> Map<'hir> { } /// Returns the defining scope for an opaque type definition. - pub fn get_defining_scope(self, id: HirId) -> HirId { + pub fn hir_get_defining_scope(self, id: HirId) -> HirId { let mut scope = id; loop { - scope = self.get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID); - if scope == CRATE_HIR_ID || !matches!(self.tcx.hir_node(scope), Node::Block(_)) { + scope = self.hir_get_enclosing_scope(scope).unwrap_or(CRATE_HIR_ID); + if scope == CRATE_HIR_ID || !matches!(self.hir_node(scope), Node::Block(_)) { return scope; } } } +} +impl<'hir> Map<'hir> { pub fn get_foreign_abi(self, hir_id: HirId) -> ExternAbi { - let parent = self.get_parent_item(hir_id); + let parent = self.tcx.hir_get_parent_item(hir_id); if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = self.tcx.hir_owner_node(parent) { @@ -1167,7 +1164,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { ItemKind::Macro(..) => "macro", ItemKind::Mod(..) => "mod", ItemKind::ForeignMod { .. } => "foreign mod", - ItemKind::GlobalAsm(..) => "global asm", + ItemKind::GlobalAsm { .. } => "global asm", ItemKind::TyAlias(..) => "ty", ItemKind::Enum(..) => "enum", ItemKind::Struct(..) => "struct", @@ -1249,7 +1246,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { let mut collector = ItemCollector::new(tcx, false); - let (hir_mod, span, hir_id) = tcx.hir().get_module(module_id); + let (hir_mod, span, hir_id) = tcx.hir_get_module(module_id); collector.visit_mod(hir_mod, span, hir_id); let ItemCollector { @@ -1282,7 +1279,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { // module item (the former starts at the crate root) but only // the former needs to collect it. ItemCollector does not do this for us. collector.submodules.push(CRATE_OWNER_ID); - tcx.hir().walk_toplevel_module(&mut collector); + tcx.hir_walk_toplevel_module(&mut collector); let ItemCollector { submodules, diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0d2acf96d08f1..6071a58367ed1 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -40,25 +40,25 @@ impl ModuleItems { /// include foreign items. If you want to e.g. get all functions, use `definitions()` below. /// /// However, this does include the `impl` blocks themselves. - pub fn free_items(&self) -> impl Iterator + '_ { + pub fn free_items(&self) -> impl Iterator { self.free_items.iter().copied() } - pub fn trait_items(&self) -> impl Iterator + '_ { + pub fn trait_items(&self) -> impl Iterator { self.trait_items.iter().copied() } /// Returns all items that are associated with some `impl` block (both inherent and trait impl /// blocks). - pub fn impl_items(&self) -> impl Iterator + '_ { + pub fn impl_items(&self) -> impl Iterator { self.impl_items.iter().copied() } - pub fn foreign_items(&self) -> impl Iterator + '_ { + pub fn foreign_items(&self) -> impl Iterator { self.foreign_items.iter().copied() } - pub fn owners(&self) -> impl Iterator + '_ { + pub fn owners(&self) -> impl Iterator { self.free_items .iter() .map(|id| id.owner_id) @@ -67,15 +67,15 @@ impl ModuleItems { .chain(self.foreign_items.iter().map(|id| id.owner_id)) } - pub fn opaques(&self) -> impl Iterator + '_ { + pub fn opaques(&self) -> impl Iterator { self.opaques.iter().copied() } - pub fn nested_bodies(&self) -> impl Iterator + '_ { + pub fn nested_bodies(&self) -> impl Iterator { self.nested_bodies.iter().copied() } - pub fn definitions(&self) -> impl Iterator + '_ { + pub fn definitions(&self) -> impl Iterator { self.owners().map(|id| id.def_id) } @@ -213,7 +213,7 @@ pub fn provide(providers: &mut Providers) { providers.fn_arg_names = |tcx, def_id| { let hir = tcx.hir(); if let Some(body_id) = tcx.hir_node_by_def_id(def_id).body_id() { - tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) + tcx.arena.alloc_from_iter(tcx.hir_body_param_names(body_id)) } else if let Node::TraitItem(&TraitItem { kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), .. diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 66b701523b71f..316ad80eb9857 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -97,7 +97,7 @@ impl<'tcx> Place<'tcx> { /// The types are in the reverse order that they are applied. So if /// `x: &*const u32` and the `Place` is `**x`, then the types returned are ///`*const u32` then `&*const u32`. - pub fn deref_tys(&self) -> impl Iterator> + '_ { + pub fn deref_tys(&self) -> impl Iterator> { self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| { if ProjectionKind::Deref == proj.kind { Some(self.ty_before_projection(index)) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 95128a5d903bb..93a7227d65ee3 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -29,7 +29,6 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(allocator_api)] diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index ab711aca573e5..88bf17070b9c5 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -131,7 +131,7 @@ impl ShallowLintLevelMap { let mut owner = start.owner; let mut specs = &self.specs; - for parent in tcx.hir().parent_id_iter(start) { + for parent in tcx.hir_parent_id_iter(start) { if parent.owner != owner { owner = parent.owner; specs = &tcx.shallow_lint_levels_on(owner).specs; diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index b3064d8fe25cb..b5f3a0e1482a9 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -83,7 +83,7 @@ macro_rules! TrivialTypeTraversalImpls { _: &mut F) -> F::Result { - ::output() + ::output() } } )+ diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 9f71971ea08b1..4587dcaddc487 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -25,7 +25,7 @@ pub mod lib_features { self.stability .to_sorted_stable_ord() .iter() - .map(|(&sym, &(stab, _))| (sym, stab)) + .map(|&(&sym, &(stab, _))| (sym, stab)) .collect() } } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 93bbf6d7fa4ff..2260cad41b97c 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -373,7 +373,7 @@ impl<'tcx> TyCtxt<'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { - let parent_def_id = self.hir().get_parent_item(id); + let parent_def_id = self.hir_get_parent_item(id); let skip = self .lookup_deprecation_entry(parent_def_id.to_def_id()) .is_some_and(|parent_depr| parent_depr.same_origin(&depr_entry)); diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index c32cf5f825334..171542d1279c7 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -20,7 +20,22 @@ pub struct BasicBlocks<'tcx> { // Typically 95%+ of basic blocks have 4 or fewer predecessors. type Predecessors = IndexVec>; -type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option; 1]>>; +/// Each `(target, switch)` entry in the map contains a list of switch values +/// that lead to a `target` block from a `switch` block. +/// +/// Note: this type is currently never instantiated, because it's only used for +/// `BasicBlocks::switch_sources`, which is only called by backwards analyses +/// that do `SwitchInt` handling, and we don't have any of those, not even in +/// tests. See #95120 and #94576. +type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[SwitchTargetValue; 1]>>; + +#[derive(Debug, Clone, Copy)] +pub enum SwitchTargetValue { + // A normal switch value. + Normal(u128), + // The final "otherwise" fallback value. + Otherwise, +} #[derive(Clone, Default, Debug)] struct Cache { @@ -64,14 +79,14 @@ impl<'tcx> BasicBlocks<'tcx> { #[inline] pub fn reverse_postorder(&self) -> &[BasicBlock] { self.cache.reverse_postorder.get_or_init(|| { - let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, ()).collect(); + let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, None).collect(); rpo.reverse(); rpo }) } - /// `switch_sources()[&(target, switch)]` returns a list of switch - /// values that lead to a `target` block from a `switch` block. + /// Returns info about switch values that lead from one block to another + /// block. See `SwitchSources`. #[inline] pub fn switch_sources(&self) -> &SwitchSources { self.cache.switch_sources.get_or_init(|| { @@ -82,9 +97,15 @@ impl<'tcx> BasicBlocks<'tcx> { }) = &data.terminator { for (value, target) in targets.iter() { - switch_sources.entry((target, bb)).or_default().push(Some(value)); + switch_sources + .entry((target, bb)) + .or_default() + .push(SwitchTargetValue::Normal(value)); } - switch_sources.entry((targets.otherwise(), bb)).or_default().push(None); + switch_sources + .entry((targets.otherwise(), bb)) + .or_default() + .push(SwitchTargetValue::Otherwise); } } switch_sources diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 78196b0536190..2f13f9635785a 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -121,7 +121,7 @@ impl ProvenanceMap { } /// Yields all the provenances stored in this map. - pub fn provenances(&self) -> impl Iterator + '_ { + pub fn provenances(&self) -> impl Iterator { let bytes = self.bytes.iter().flat_map(|b| b.values()); self.ptrs.values().chain(bytes).copied() } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 8861e31b0991c..743812e3a20a7 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -5,7 +5,6 @@ use std::{convert, fmt, mem, ops}; use either::Either; use rustc_abi::{Align, Size, VariantIdx, WrappingRange}; -use rustc_ast_ir::Mutability; use rustc_data_structures::sync::Lock; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg}; use rustc_macros::{HashStable, TyDecodable, TyEncodable}; @@ -16,7 +15,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar}; use crate::error; use crate::mir::{ConstAlloc, ConstValue}; -use crate::ty::{self, Ty, TyCtxt, ValTree, layout, tls}; +use crate::ty::{self, Mutability, Ty, TyCtxt, ValTree, layout, tls}; #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] pub enum ErrorHandled { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 795cfcef2d36d..cf90df1b198b8 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -4,15 +4,14 @@ use std::borrow::Cow; use std::fmt::{self, Debug, Formatter}; +use std::iter; use std::ops::{Index, IndexMut}; -use std::{iter, mem}; -pub use basic_blocks::BasicBlocks; +pub use basic_blocks::{BasicBlocks, SwitchTargetValue}; use either::Either; use polonius_engine::Atom; use rustc_abi::{FieldIdx, VariantIdx}; pub use rustc_ast::Mutability; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg}; @@ -30,9 +29,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use tracing::{debug, trace}; pub use self::query::*; -use self::visit::TyContext; use crate::mir::interpret::{AllocRange, Scalar}; -use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; @@ -53,7 +50,6 @@ pub mod pretty; mod query; mod statement; mod syntax; -pub mod tcx; mod terminator; pub mod traversal; @@ -100,24 +96,17 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> { } impl MirPhase { - /// Gets the index of the current MirPhase within the set of all `MirPhase`s. - /// - /// FIXME(JakobDegen): Return a `(usize, usize)` instead. - pub fn phase_index(&self) -> usize { - const BUILT_PHASE_COUNT: usize = 1; - const ANALYSIS_PHASE_COUNT: usize = 2; - match self { - MirPhase::Built => 1, - MirPhase::Analysis(analysis_phase) => { - 1 + BUILT_PHASE_COUNT + (*analysis_phase as usize) - } - MirPhase::Runtime(runtime_phase) => { - 1 + BUILT_PHASE_COUNT + ANALYSIS_PHASE_COUNT + (*runtime_phase as usize) - } + /// Gets the (dialect, phase) index of the current `MirPhase`. Both numbers + /// are 1-indexed. + pub fn index(&self) -> (usize, usize) { + match *self { + MirPhase::Built => (1, 1), + MirPhase::Analysis(analysis_phase) => (2, 1 + analysis_phase as usize), + MirPhase::Runtime(runtime_phase) => (3, 1 + runtime_phase as usize), } } - /// Parses an `MirPhase` from a pair of strings. Panics if this isn't possible for any reason. + /// Parses a `MirPhase` from a pair of strings. Panics if this isn't possible for any reason. pub fn parse(dialect: String, phase: Option) -> Self { match &*dialect.to_ascii_lowercase() { "built" => { @@ -482,7 +471,7 @@ impl<'tcx> Body<'tcx> { /// Returns an iterator over all user-declared mutable locals. #[inline] - pub fn mut_vars_iter<'a>(&'a self) -> impl Iterator + Captures<'tcx> + 'a { + pub fn mut_vars_iter(&self) -> impl Iterator { (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); let decl = &self.local_decls[local]; @@ -492,9 +481,7 @@ impl<'tcx> Body<'tcx> { /// Returns an iterator over all user-declared mutable arguments and locals. #[inline] - pub fn mut_vars_and_args_iter<'a>( - &'a self, - ) -> impl Iterator + Captures<'tcx> + 'a { + pub fn mut_vars_and_args_iter(&self) -> impl Iterator { (1..self.local_decls.len()).filter_map(move |index| { let local = Local::new(index); let decl = &self.local_decls[local]; @@ -524,7 +511,7 @@ impl<'tcx> Body<'tcx> { } #[inline] - pub fn drain_vars_and_temps<'a>(&'a mut self) -> impl Iterator> + 'a { + pub fn drain_vars_and_temps(&mut self) -> impl Iterator> { self.local_decls.drain(self.arg_count + 1..) } @@ -541,17 +528,6 @@ impl<'tcx> Body<'tcx> { } } - pub fn span_for_ty_context(&self, ty_context: TyContext) -> Span { - match ty_context { - TyContext::UserTy(span) => span, - TyContext::ReturnTy(source_info) - | TyContext::LocalDecl { source_info, .. } - | TyContext::YieldTy(source_info) - | TyContext::ResumeTy(source_info) => source_info.span, - TyContext::Location(loc) => self.source_info(loc).span, - } - } - /// Returns the return type; it always return first element from `local_decls` array. #[inline] pub fn return_ty(&self) -> Ty<'tcx> { @@ -793,7 +769,7 @@ impl ClearCrossCrate { } } - pub fn assert_crate_local(self) -> T { + pub fn unwrap_crate_local(self) -> T { match self { ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"), ClearCrossCrate::Set(v) => v, @@ -950,7 +926,7 @@ mod binding_form_impl { /// involved in borrow_check errors, e.g., explanations of where the /// temporaries come from, when their destructors are run, and/or how /// one might revise the code to satisfy the borrow checker's rules. -#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] pub struct BlockTailInfo { /// If `true`, then the value resulting from evaluating this tail /// expression is ignored by the block's expression context. @@ -974,7 +950,6 @@ pub struct LocalDecl<'tcx> { /// Temporaries and the return place are always mutable. pub mutability: Mutability, - // FIXME(matthewjasper) Don't store in this in `Body` pub local_info: ClearCrossCrate>>, /// The type of this local. @@ -984,7 +959,6 @@ pub struct LocalDecl<'tcx> { /// e.g., via `let x: T`, then we carry that type here. The MIR /// borrow checker needs this information since it can affect /// region inference. - // FIXME(matthewjasper) Don't store in this in `Body` pub user_ty: Option>, /// The *syntactic* (i.e., not visibility) source scope the local is defined @@ -1092,7 +1066,6 @@ pub enum LocalInfo<'tcx> { AggregateTemp, /// A temporary created for evaluation of some subexpression of some block's tail expression /// (with no intervening statement context). - // FIXME(matthewjasper) Don't store in this in `Body` BlockTailTemp(BlockTailInfo), /// A temporary created during evaluating `if` predicate, possibly for pattern matching for `let`s, /// and subject to Edition 2024 temporary lifetime rules @@ -1107,7 +1080,7 @@ pub enum LocalInfo<'tcx> { impl<'tcx> LocalDecl<'tcx> { pub fn local_info(&self) -> &LocalInfo<'tcx> { - self.local_info.as_ref().assert_crate_local() + self.local_info.as_ref().unwrap_crate_local() } /// Returns `true` only if local is a binding that can itself be @@ -1365,70 +1338,6 @@ impl<'tcx> BasicBlockData<'tcx> { self.terminator.as_mut().expect("invalid terminator state") } - pub fn retain_statements(&mut self, mut f: F) - where - F: FnMut(&mut Statement<'_>) -> bool, - { - for s in &mut self.statements { - if !f(s) { - s.make_nop(); - } - } - } - - pub fn expand_statements(&mut self, mut f: F) - where - F: FnMut(&mut Statement<'tcx>) -> Option, - I: iter::TrustedLen>, - { - // Gather all the iterators we'll need to splice in, and their positions. - let mut splices: Vec<(usize, I)> = vec![]; - let mut extra_stmts = 0; - for (i, s) in self.statements.iter_mut().enumerate() { - if let Some(mut new_stmts) = f(s) { - if let Some(first) = new_stmts.next() { - // We can already store the first new statement. - *s = first; - - // Save the other statements for optimized splicing. - let remaining = new_stmts.size_hint().0; - if remaining > 0 { - splices.push((i + 1 + extra_stmts, new_stmts)); - extra_stmts += remaining; - } - } else { - s.make_nop(); - } - } - } - - // Splice in the new statements, from the end of the block. - // FIXME(eddyb) This could be more efficient with a "gap buffer" - // where a range of elements ("gap") is left uninitialized, with - // splicing adding new elements to the end of that gap and moving - // existing elements from before the gap to the end of the gap. - // For now, this is safe code, emulating a gap but initializing it. - let mut gap = self.statements.len()..self.statements.len() + extra_stmts; - self.statements.resize( - gap.end, - Statement { source_info: SourceInfo::outermost(DUMMY_SP), kind: StatementKind::Nop }, - ); - for (splice_start, new_stmts) in splices.into_iter().rev() { - let splice_end = splice_start + new_stmts.size_hint().0; - while gap.end > splice_end { - gap.start -= 1; - gap.end -= 1; - self.statements.swap(gap.start, gap.end); - } - self.statements.splice(splice_start..splice_end, new_stmts); - gap.end = splice_start; - } - } - - pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> { - if index < self.statements.len() { &self.statements[index] } else { &self.terminator } - } - /// Does the block have no statements and an unreachable terminator? #[inline] pub fn is_empty_unreachable(&self) -> bool { @@ -1560,7 +1469,7 @@ pub struct SourceScopeLocalData { /// &'static str`. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub struct UserTypeProjections { - pub contents: Vec<(UserTypeProjection, Span)>, + pub contents: Vec, } impl<'tcx> UserTypeProjections { @@ -1572,26 +1481,17 @@ impl<'tcx> UserTypeProjections { self.contents.is_empty() } - pub fn projections_and_spans( - &self, - ) -> impl Iterator + ExactSizeIterator { - self.contents.iter() - } - pub fn projections(&self) -> impl Iterator + ExactSizeIterator { - self.contents.iter().map(|&(ref user_type, _span)| user_type) + self.contents.iter() } - pub fn push_projection(mut self, user_ty: &UserTypeProjection, span: Span) -> Self { - self.contents.push((user_ty.clone(), span)); + pub fn push_user_type(mut self, base_user_type: UserTypeAnnotationIndex) -> Self { + self.contents.push(UserTypeProjection { base: base_user_type, projs: vec![] }); self } - fn map_projections( - mut self, - mut f: impl FnMut(UserTypeProjection) -> UserTypeProjection, - ) -> Self { - self.contents = self.contents.into_iter().map(|(proj, span)| (f(proj), span)).collect(); + fn map_projections(mut self, f: impl FnMut(UserTypeProjection) -> UserTypeProjection) -> Self { + self.contents = self.contents.into_iter().map(f).collect(); self } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index d4a9aac3733ff..58d5c94d03326 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -6,8 +6,9 @@ use rustc_attr_parsing::InlineAttr; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::Hash128; use rustc_hir::ItemId; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE}; use rustc_index::Idx; @@ -242,7 +243,7 @@ impl<'tcx> MonoItem<'tcx> { /// Returns the item's `CrateNum` pub fn krate(&self) -> CrateNum { match self { - MonoItem::Fn(ref instance) => instance.def_id().krate, + MonoItem::Fn(instance) => instance.def_id().krate, MonoItem::Static(def_id) => def_id.krate, MonoItem::GlobalAsm(..) => LOCAL_CRATE, } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index b0df6c71014a3..875f5282bf29f 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -22,7 +22,7 @@ pub(crate) const ALIGN: usize = 40; /// An indication of where we are in the control flow graph. Used for printing /// extra information in `dump_mir` -#[derive(Clone)] +#[derive(Clone, Copy)] pub enum PassWhere { /// We have not started dumping the control flow graph, but we are about to. BeforeCFG, @@ -231,7 +231,8 @@ fn dump_path<'tcx>( let pass_num = if tcx.sess.opts.unstable_opts.dump_mir_exclude_pass_number { String::new() } else if pass_num { - format!(".{:03}-{:03}", body.phase.phase_index(), body.pass_count) + let (dialect_index, phase_index) = body.phase.index(); + format!(".{}-{}-{:03}", dialect_index, phase_index, body.pass_count) } else { ".-------".to_string() }; @@ -969,7 +970,7 @@ impl<'tcx> TerminatorKind<'tcx> { } FalseEdge { .. } => write!(fmt, "falseEdge"), FalseUnwind { .. } => write!(fmt, "falseUnwind"), - InlineAsm { template, ref operands, options, .. } => { + InlineAsm { template, operands, options, .. } => { write!(fmt, "asm!(\"{}\"", InlineAsmTemplatePiece::to_string(template))?; for op in operands { write!(fmt, ", ")?; @@ -1522,7 +1523,7 @@ pub fn write_allocations<'tcx>( ) -> io::Result<()> { fn alloc_ids_from_alloc( alloc: ConstAllocation<'_>, - ) -> impl DoubleEndedIterator + '_ { + ) -> impl DoubleEndedIterator { alloc.inner().provenance().ptrs().values().map(|p| p.alloc_id()) } @@ -1588,7 +1589,7 @@ pub fn write_allocations<'tcx>( Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => { write!(w, " (static: {}", tcx.def_path_str(did))?; if body.phase <= MirPhase::Runtime(RuntimePhase::PostCleanup) - && tcx.hir().body_const_context(body.source.def_id()).is_some() + && tcx.hir_body_const_context(body.source.def_id()).is_some() { // Statics may be cyclic and evaluating them too early // in the MIR pipeline may cause cycle errors even though diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d345c99f902f2..595a5e548b011 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -1,7 +1,10 @@ //! Functionality for statements, operands, places, and things that appear in them. +use tracing::{debug, instrument}; + use super::interpret::GlobalAlloc; use super::*; +use crate::ty::CoroutineArgsExt; /////////////////////////////////////////////////////////////////////////// // Statements @@ -19,15 +22,6 @@ impl Statement<'_> { pub fn make_nop(&mut self) { self.kind = StatementKind::Nop } - - /// Changes a statement to a nop and returns the original statement. - #[must_use = "If you don't need the statement, use `make_nop` instead"] - pub fn replace_nop(&mut self) -> Self { - Statement { - source_info: self.source_info, - kind: mem::replace(&mut self.kind, StatementKind::Nop), - } - } } impl<'tcx> StatementKind<'tcx> { @@ -49,6 +43,162 @@ impl<'tcx> StatementKind<'tcx> { /////////////////////////////////////////////////////////////////////////// // Places +#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] +pub struct PlaceTy<'tcx> { + pub ty: Ty<'tcx>, + /// Downcast to a particular variant of an enum or a coroutine, if included. + pub variant_index: Option, +} + +// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers. +#[cfg(target_pointer_width = "64")] +rustc_data_structures::static_assert_size!(PlaceTy<'_>, 16); + +impl<'tcx> PlaceTy<'tcx> { + #[inline] + pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> { + PlaceTy { ty, variant_index: None } + } + + /// `place_ty.field_ty(tcx, f)` computes the type of a given field. + /// + /// Most clients of `PlaceTy` can instead just extract the relevant type + /// directly from their `PlaceElem`, but some instances of `ProjectionElem` + /// do not carry a `Ty` for `T`. + /// + /// Note that the resulting type has not been normalized. + #[instrument(level = "debug", skip(tcx), ret)] + pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> { + if let Some(variant_index) = self.variant_index { + match *self.ty.kind() { + ty::Adt(adt_def, args) if adt_def.is_enum() => { + adt_def.variant(variant_index).fields[f].ty(tcx, args) + } + ty::Coroutine(def_id, args) => { + let mut variants = args.as_coroutine().state_tys(def_id, tcx); + let Some(mut variant) = variants.nth(variant_index.into()) else { + bug!("variant {variant_index:?} of coroutine out of range: {self:?}"); + }; + + variant + .nth(f.index()) + .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")) + } + _ => bug!("can't downcast non-adt non-coroutine type: {self:?}"), + } + } else { + match self.ty.kind() { + ty::Adt(adt_def, args) if !adt_def.is_enum() => { + adt_def.non_enum_variant().fields[f].ty(tcx, args) + } + ty::Closure(_, args) => args + .as_closure() + .upvar_tys() + .get(f.index()) + .copied() + .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), + ty::CoroutineClosure(_, args) => args + .as_coroutine_closure() + .upvar_tys() + .get(f.index()) + .copied() + .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), + // Only prefix fields (upvars and current state) are + // accessible without a variant index. + ty::Coroutine(_, args) => args + .as_coroutine() + .prefix_tys() + .get(f.index()) + .copied() + .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), + ty::Tuple(tys) => tys + .get(f.index()) + .copied() + .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), + _ => bug!("can't project out of {self:?}"), + } + } + } + + pub fn multi_projection_ty( + self, + tcx: TyCtxt<'tcx>, + elems: &[PlaceElem<'tcx>], + ) -> PlaceTy<'tcx> { + elems.iter().fold(self, |place_ty, &elem| place_ty.projection_ty(tcx, elem)) + } + + /// Convenience wrapper around `projection_ty_core` for + /// `PlaceElem`, where we can just use the `Ty` that is already + /// stored inline on field projection elems. + pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> { + self.projection_ty_core(tcx, &elem, |_, _, ty| ty, |_, ty| ty) + } + + /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` + /// projects `place_ty` onto `elem`, returning the appropriate + /// `Ty` or downcast variant corresponding to that projection. + /// The `handle_field` callback must map a `FieldIdx` to its `Ty`, + /// (which should be trivial when `T` = `Ty`). + pub fn projection_ty_core( + self, + tcx: TyCtxt<'tcx>, + elem: &ProjectionElem, + mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>, + mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>, + ) -> PlaceTy<'tcx> + where + V: ::std::fmt::Debug, + T: ::std::fmt::Debug + Copy, + { + if self.variant_index.is_some() && !matches!(elem, ProjectionElem::Field(..)) { + bug!("cannot use non field projection on downcasted place") + } + let answer = match *elem { + ProjectionElem::Deref => { + let ty = self.ty.builtin_deref(true).unwrap_or_else(|| { + bug!("deref projection of non-dereferenceable ty {:?}", self) + }); + PlaceTy::from_ty(ty) + } + ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => { + PlaceTy::from_ty(self.ty.builtin_index().unwrap()) + } + ProjectionElem::Subslice { from, to, from_end } => { + PlaceTy::from_ty(match self.ty.kind() { + ty::Slice(..) => self.ty, + ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from), + ty::Array(inner, size) if from_end => { + let size = size + .try_to_target_usize(tcx) + .expect("expected subslice projection on fixed-size array"); + let len = size - from - to; + Ty::new_array(tcx, *inner, len) + } + _ => bug!("cannot subslice non-array type: `{:?}`", self), + }) + } + ProjectionElem::Downcast(_name, index) => { + PlaceTy { ty: self.ty, variant_index: Some(index) } + } + ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)), + ProjectionElem::OpaqueCast(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } + ProjectionElem::Subtype(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } + + // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general. + ProjectionElem::UnwrapUnsafeBinder(ty) => { + PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) + } + }; + debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); + answer + } +} + impl ProjectionElem { /// Returns `true` if the target of this projection may refer to a different region of memory /// than the base. @@ -192,6 +342,25 @@ impl<'tcx> Place<'tcx> { self.as_ref().project_deeper(more_projections, tcx) } + + pub fn ty_from( + local: Local, + projection: &[PlaceElem<'tcx>], + local_decls: &D, + tcx: TyCtxt<'tcx>, + ) -> PlaceTy<'tcx> + where + D: HasLocalDecls<'tcx>, + { + PlaceTy::from_ty(local_decls.local_decls()[local].ty).multi_projection_ty(tcx, projection) + } + + pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> + where + D: HasLocalDecls<'tcx>, + { + Place::ty_from(self.local, self.projection, local_decls, tcx) + } } impl From for Place<'_> { @@ -294,6 +463,13 @@ impl<'tcx> PlaceRef<'tcx> { Place { local: self.local, projection: tcx.mk_place_elems(new_projections) } } + + pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> + where + D: HasLocalDecls<'tcx>, + { + Place::ty_from(self.local, self.projection, local_decls, tcx) + } } impl From for PlaceRef<'_> { @@ -388,6 +564,28 @@ impl<'tcx> Operand<'tcx> { let const_ty = self.constant()?.const_.ty(); if let ty::FnDef(def_id, args) = *const_ty.kind() { Some((def_id, args)) } else { None } } + + pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> + where + D: HasLocalDecls<'tcx>, + { + match self { + &Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty, + Operand::Constant(c) => c.const_.ty(), + } + } + + pub fn span(&self, local_decls: &D) -> Span + where + D: HasLocalDecls<'tcx>, + { + match self { + &Operand::Copy(ref l) | &Operand::Move(ref l) => { + local_decls.local_decls()[l.local].source_info.span + } + Operand::Constant(c) => c.span, + } + } } impl<'tcx> ConstOperand<'tcx> { @@ -413,6 +611,11 @@ impl<'tcx> ConstOperand<'tcx> { /////////////////////////////////////////////////////////////////////////// /// Rvalues +pub enum RvalueInitializationState { + Shallow, + Deep, +} + impl<'tcx> Rvalue<'tcx> { /// Returns true if rvalue can be safely removed when the result is unused. #[inline] @@ -452,6 +655,70 @@ impl<'tcx> Rvalue<'tcx> { | Rvalue::WrapUnsafeBinder(_, _) => true, } } + + pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> + where + D: HasLocalDecls<'tcx>, + { + match *self { + Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), + Rvalue::Repeat(ref operand, count) => { + Ty::new_array_with_const_len(tcx, operand.ty(local_decls, tcx), count) + } + Rvalue::ThreadLocalRef(did) => tcx.thread_local_ptr_ty(did), + Rvalue::Ref(reg, bk, ref place) => { + let place_ty = place.ty(local_decls, tcx).ty; + Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy()) + } + Rvalue::RawPtr(kind, ref place) => { + let place_ty = place.ty(local_decls, tcx).ty; + Ty::new_ptr(tcx, place_ty, kind.to_mutbl_lossy()) + } + Rvalue::Len(..) => tcx.types.usize, + Rvalue::Cast(.., ty) => ty, + Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => { + let lhs_ty = lhs.ty(local_decls, tcx); + let rhs_ty = rhs.ty(local_decls, tcx); + op.ty(tcx, lhs_ty, rhs_ty) + } + Rvalue::UnaryOp(op, ref operand) => { + let arg_ty = operand.ty(local_decls, tcx); + op.ty(tcx, arg_ty) + } + Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { + tcx.types.usize + } + Rvalue::NullaryOp(NullOp::ContractChecks, _) + | Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool, + Rvalue::Aggregate(ref ak, ref ops) => match **ak { + AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64), + AggregateKind::Tuple => { + Ty::new_tup_from_iter(tcx, ops.iter().map(|op| op.ty(local_decls, tcx))) + } + AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args), + AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args), + AggregateKind::Coroutine(did, args) => Ty::new_coroutine(tcx, did, args), + AggregateKind::CoroutineClosure(did, args) => { + Ty::new_coroutine_closure(tcx, did, args) + } + AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability), + }, + Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty), + Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty, + Rvalue::WrapUnsafeBinder(_, ty) => ty, + } + } + + #[inline] + /// Returns `true` if this rvalue is deeply initialized (most rvalues) or + /// whether its only shallowly initialized (`Rvalue::Box`). + pub fn initialization_state(&self) -> RvalueInitializationState { + match *self { + Rvalue::ShallowInitBox(_, _) => RvalueInitializationState::Shallow, + _ => RvalueInitializationState::Deep, + } + } } impl BorrowKind { @@ -474,4 +741,124 @@ impl BorrowKind { BorrowKind::Mut { kind: MutBorrowKind::TwoPhaseBorrow } => true, } } + + pub fn to_mutbl_lossy(self) -> hir::Mutability { + match self { + BorrowKind::Mut { .. } => hir::Mutability::Mut, + BorrowKind::Shared => hir::Mutability::Not, + + // We have no type corresponding to a shallow borrow, so use + // `&` as an approximation. + BorrowKind::Fake(_) => hir::Mutability::Not, + } + } +} + +impl<'tcx> UnOp { + pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> { + match self { + UnOp::Not | UnOp::Neg => arg_ty, + UnOp::PtrMetadata => arg_ty.pointee_metadata_ty_or_projection(tcx), + } + } +} + +impl<'tcx> BinOp { + pub fn ty(&self, tcx: TyCtxt<'tcx>, lhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>) -> Ty<'tcx> { + // FIXME: handle SIMD correctly + match self { + &BinOp::Add + | &BinOp::AddUnchecked + | &BinOp::Sub + | &BinOp::SubUnchecked + | &BinOp::Mul + | &BinOp::MulUnchecked + | &BinOp::Div + | &BinOp::Rem + | &BinOp::BitXor + | &BinOp::BitAnd + | &BinOp::BitOr => { + // these should be integers or floats of the same size. + assert_eq!(lhs_ty, rhs_ty); + lhs_ty + } + &BinOp::AddWithOverflow | &BinOp::SubWithOverflow | &BinOp::MulWithOverflow => { + // these should be integers of the same size. + assert_eq!(lhs_ty, rhs_ty); + Ty::new_tup(tcx, &[lhs_ty, tcx.types.bool]) + } + &BinOp::Shl + | &BinOp::ShlUnchecked + | &BinOp::Shr + | &BinOp::ShrUnchecked + | &BinOp::Offset => { + lhs_ty // lhs_ty can be != rhs_ty + } + &BinOp::Eq | &BinOp::Lt | &BinOp::Le | &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => { + tcx.types.bool + } + &BinOp::Cmp => { + // these should be integer-like types of the same size. + assert_eq!(lhs_ty, rhs_ty); + tcx.ty_ordering_enum(None) + } + } + } + pub(crate) fn to_hir_binop(self) -> hir::BinOpKind { + match self { + // HIR `+`/`-`/`*` can map to either of these MIR BinOp, depending + // on whether overflow checks are enabled or not. + BinOp::Add | BinOp::AddWithOverflow => hir::BinOpKind::Add, + BinOp::Sub | BinOp::SubWithOverflow => hir::BinOpKind::Sub, + BinOp::Mul | BinOp::MulWithOverflow => hir::BinOpKind::Mul, + BinOp::Div => hir::BinOpKind::Div, + BinOp::Rem => hir::BinOpKind::Rem, + BinOp::BitXor => hir::BinOpKind::BitXor, + BinOp::BitAnd => hir::BinOpKind::BitAnd, + BinOp::BitOr => hir::BinOpKind::BitOr, + BinOp::Shl => hir::BinOpKind::Shl, + BinOp::Shr => hir::BinOpKind::Shr, + BinOp::Eq => hir::BinOpKind::Eq, + BinOp::Ne => hir::BinOpKind::Ne, + BinOp::Lt => hir::BinOpKind::Lt, + BinOp::Gt => hir::BinOpKind::Gt, + BinOp::Le => hir::BinOpKind::Le, + BinOp::Ge => hir::BinOpKind::Ge, + // We don't have HIR syntax for these. + BinOp::Cmp + | BinOp::AddUnchecked + | BinOp::SubUnchecked + | BinOp::MulUnchecked + | BinOp::ShlUnchecked + | BinOp::ShrUnchecked + | BinOp::Offset => { + unreachable!() + } + } + } + + /// If this is a `FooWithOverflow`, return `Some(Foo)`. + pub fn overflowing_to_wrapping(self) -> Option { + Some(match self { + BinOp::AddWithOverflow => BinOp::Add, + BinOp::SubWithOverflow => BinOp::Sub, + BinOp::MulWithOverflow => BinOp::Mul, + _ => return None, + }) + } + + /// Returns whether this is a `FooWithOverflow` + pub fn is_overflowing(self) -> bool { + self.overflowing_to_wrapping().is_some() + } + + /// If this is a `Foo`, return `Some(FooWithOverflow)`. + pub fn wrapping_to_overflowing(self) -> Option { + Some(match self { + BinOp::Add => BinOp::AddWithOverflow, + BinOp::Sub => BinOp::SubWithOverflow, + BinOp::Mul => BinOp::MulWithOverflow, + _ => return None, + }) + } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 9cec8d832dd14..af6f0e4c55183 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -23,68 +23,77 @@ use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex} /// Represents the "flavors" of MIR. /// -/// All flavors of MIR use the same data structure, but there are some important differences. These -/// differences come in two forms: Dialects and phases. +/// The MIR pipeline is structured into a few major dialects, with one or more phases within each +/// dialect. A MIR flavor is identified by a dialect-phase pair. A single `MirPhase` value +/// specifies such a pair. All flavors of MIR use the same data structure to represent the program. /// -/// Dialects represent a stronger distinction than phases. This is because the transitions between -/// dialects are semantic changes, and therefore technically *lowerings* between distinct IRs. In -/// other words, the same [`Body`](crate::mir::Body) might be well-formed for multiple dialects, but -/// have different semantic meaning and different behavior at runtime. +/// Different MIR dialects have different semantics. (The differences between dialects are small, +/// but they do exist.) The progression from one MIR dialect to the next is technically a lowering +/// from one IR to another. In other words, a single well-formed [`Body`](crate::mir::Body) might +/// have different semantic meaning and different behavior at runtime in the different dialects. +/// The specific differences between dialects are described on the variants below. /// -/// Each dialect additionally has a number of phases. However, phase changes never involve semantic -/// changes. If some MIR is well-formed both before and after a phase change, it is also guaranteed -/// that it has the same semantic meaning. In this sense, phase changes can only add additional -/// restrictions on what MIR is well-formed. +/// Phases exist only to place restrictions on what language constructs are permitted in +/// well-formed MIR, and subsequent phases mostly increase those restrictions. I.e. to convert MIR +/// from one phase to the next might require removing/replacing certain MIR constructs. /// -/// When adding phases, remember to update [`MirPhase::phase_index`]. +/// When adding dialects or phases, remember to update [`MirPhase::index`]. #[derive(Copy, Clone, TyEncodable, TyDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(HashStable)] pub enum MirPhase { - /// The MIR that is generated by MIR building. + /// The "built MIR" dialect, as generated by MIR building. /// /// The only things that operate on this dialect are unsafeck, the various MIR lints, and const /// qualifs. /// - /// This has no distinct phases. + /// This dialect has just the one (implicit) phase, which places few restrictions on what MIR + /// constructs are allowed. Built, - /// The MIR used for most analysis. + + /// The "analysis MIR" dialect, used for borrowck and friends. /// - /// The only semantic change between analysis and built MIR is constant promotion. In built MIR, - /// sequences of statements that would generally be subject to constant promotion are - /// semantically constants, while in analysis MIR all constants are explicit. + /// The only semantic difference between built MIR and analysis MIR relates to constant + /// promotion. In built MIR, sequences of statements that would generally be subject to + /// constant promotion are semantically constants, while in analysis MIR all constants are + /// explicit. /// - /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` queries. + /// The result of const promotion is available from the `mir_promoted` and `promoted_mir` + /// queries. /// - /// This is the version of MIR used by borrowck and friends. + /// The phases of this dialect are described in `AnalysisPhase`. Analysis(AnalysisPhase), - /// The MIR used for CTFE, optimizations, and codegen. - /// - /// The semantic changes that occur in the lowering from analysis to runtime MIR are as follows: - /// - /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly speaking, - /// if dataflow analysis determines that the place being dropped is uninitialized, the drop will - /// not be executed. The exact semantics of this aren't written down anywhere, which means they - /// are essentially "what drop elaboration does." In runtime MIR, the drops are unconditional; - /// when a `Drop` terminator is reached, if the type has drop glue that drop glue is always - /// executed. This may be UB if the underlying place is not initialized. - /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the exception - /// is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be misaligned - /// for this reason implicitly moves `P` to a temporary before dropping. Runtime MIR has no such - /// rules, and dropping a misaligned place is simply UB. - /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In runtime - /// MIR, this is UB. - /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same way - /// that Rust itself has them. Where exactly these are is generally subject to change, and so we - /// don't document this here. Runtime MIR has most retags explicit (though implicit retags - /// can still occur at `Rvalue::{Ref,AddrOf}`). - /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has - /// access to. This occurs in coroutine bodies. Such locals do not behave like other locals, - /// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals - - /// all coroutine bodies are lowered and so all places that look like locals really are locals. + + /// The "runtime MIR" dialect, used for CTFE, optimizations, and codegen. + /// + /// The semantic differences between analysis MIR and runtime MIR are as follows. + /// + /// - Drops: In analysis MIR, `Drop` terminators represent *conditional* drops; roughly + /// speaking, if dataflow analysis determines that the place being dropped is uninitialized, + /// the drop will not be executed. The exact semantics of this aren't written down anywhere, + /// which means they are essentially "what drop elaboration does." In runtime MIR, the drops + /// are unconditional; when a `Drop` terminator is reached, if the type has drop glue that + /// drop glue is always executed. This may be UB if the underlying place is not initialized. + /// - Packed drops: Places might in general be misaligned - in most cases this is UB, the + /// exception is fields of packed structs. In analysis MIR, `Drop(P)` for a `P` that might be + /// misaligned for this reason implicitly moves `P` to a temporary before dropping. Runtime + /// MIR has no such rules, and dropping a misaligned place is simply UB. + /// - Unwinding: in analysis MIR, unwinding from a function which may not unwind aborts. In + /// runtime MIR, this is UB. + /// - Retags: If `-Zmir-emit-retag` is enabled, analysis MIR has "implicit" retags in the same + /// way that Rust itself has them. Where exactly these are is generally subject to change, + /// and so we don't document this here. Runtime MIR has most retags explicit (though implicit + /// retags can still occur at `Rvalue::{Ref,AddrOf}`). + /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code + /// has access to. This occurs in coroutine bodies. Such locals do not behave like other + /// locals, because they e.g. may be aliased in surprising ways. Runtime MIR has no such + /// special locals. All coroutine bodies are lowered and so all places that look like locals + /// really are locals. /// /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that - /// transformations which may suppress such errors should not run on analysis MIR. + /// transformations that can suppress such errors should not run on analysis MIR. + /// + /// The phases of this dialect are described in `RuntimePhase`. Runtime(RuntimePhase), } @@ -111,7 +120,8 @@ pub enum AnalysisPhase { /// * [`TerminatorKind::FalseEdge`] /// * [`StatementKind::FakeRead`] /// * [`StatementKind::AscribeUserType`] - /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or [`CoverageKind::SpanMarker`] + /// * [`StatementKind::Coverage`] with [`CoverageKind::BlockMarker`] or + /// [`CoverageKind::SpanMarker`] /// * [`Rvalue::Ref`] with `BorrowKind::Fake` /// * [`CastKind::PointerCoercion`] with any of the following: /// * [`PointerCoercion::ArrayToPointer`] @@ -1015,22 +1025,30 @@ impl TerminatorKind<'_> { #[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)] pub struct SwitchTargets { - /// Possible values. The locations to branch to in each case - /// are found in the corresponding indices from the `targets` vector. + /// Possible values. For each value, the location to branch to is found in + /// the corresponding element in the `targets` vector. pub(super) values: SmallVec<[Pu128; 1]>, - /// Possible branch sites. The last element of this vector is used - /// for the otherwise branch, so targets.len() == values.len() + 1 - /// should hold. + /// Possible branch targets. The last element of this vector is used for + /// the "otherwise" branch, so `targets.len() == values.len() + 1` always + /// holds. + // + // Note: This invariant is non-obvious and easy to violate. This would be a + // more rigorous representation: // - // This invariant is quite non-obvious and also could be improved. - // One way to make this invariant is to have something like this instead: + // normal: SmallVec<[(Pu128, BasicBlock); 1]>, + // otherwise: BasicBlock, // - // branches: Vec<(ConstInt, BasicBlock)>, - // otherwise: Option // exhaustive if None + // But it's important to have the targets in a sliceable type, because + // target slices show up elsewhere. E.g. `TerminatorKind::InlineAsm` has a + // boxed slice, and `TerminatorKind::FalseEdge` has a single target that + // can be converted to a slice with `slice::from_ref`. // - // However we’ve decided to keep this as-is until we figure a case - // where some other approach seems to be strictly better than other. + // Why does this matter? In functions like `TerminatorKind::successors` we + // return `impl Iterator` and a non-slice-of-targets representation here + // causes problems because multiple different concrete iterator types would + // be involved and we would need a boxed trait object, which requires an + // allocation, which is expensive if done frequently. pub(super) targets: SmallVec<[BasicBlock; 2]>, } @@ -1125,7 +1143,7 @@ pub type AssertMessage<'tcx> = AssertKind>; /// /// 1. The address in memory that the place refers to. /// 2. The provenance with which the place is being accessed. -/// 3. The type of the place and an optional variant index. See [`PlaceTy`][super::tcx::PlaceTy]. +/// 3. The type of the place and an optional variant index. See [`PlaceTy`][super::PlaceTy]. /// 4. Optionally, some metadata. This exists if and only if the type of the place is not `Sized`. /// /// We'll give a description below of how all pieces of the place except for the provenance are diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs deleted file mode 100644 index 862f78d725982..0000000000000 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ /dev/null @@ -1,416 +0,0 @@ -/*! - * Methods for the various MIR types. These are intended for use after - * building is complete. - */ - -use rustc_hir as hir; -use tracing::{debug, instrument}; -use ty::CoroutineArgsExt; - -use crate::mir::*; - -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] -pub struct PlaceTy<'tcx> { - pub ty: Ty<'tcx>, - /// Downcast to a particular variant of an enum or a coroutine, if included. - pub variant_index: Option, -} - -// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers. -#[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(PlaceTy<'_>, 16); - -impl<'tcx> PlaceTy<'tcx> { - #[inline] - pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> { - PlaceTy { ty, variant_index: None } - } - - /// `place_ty.field_ty(tcx, f)` computes the type of a given field. - /// - /// Most clients of `PlaceTy` can instead just extract the relevant type - /// directly from their `PlaceElem`, but some instances of `ProjectionElem` - /// do not carry a `Ty` for `T`. - /// - /// Note that the resulting type has not been normalized. - #[instrument(level = "debug", skip(tcx), ret)] - pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> { - if let Some(variant_index) = self.variant_index { - match *self.ty.kind() { - ty::Adt(adt_def, args) if adt_def.is_enum() => { - adt_def.variant(variant_index).fields[f].ty(tcx, args) - } - ty::Coroutine(def_id, args) => { - let mut variants = args.as_coroutine().state_tys(def_id, tcx); - let Some(mut variant) = variants.nth(variant_index.into()) else { - bug!("variant {variant_index:?} of coroutine out of range: {self:?}"); - }; - - variant - .nth(f.index()) - .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")) - } - _ => bug!("can't downcast non-adt non-coroutine type: {self:?}"), - } - } else { - match self.ty.kind() { - ty::Adt(adt_def, args) if !adt_def.is_enum() => { - adt_def.non_enum_variant().fields[f].ty(tcx, args) - } - ty::Closure(_, args) => args - .as_closure() - .upvar_tys() - .get(f.index()) - .copied() - .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), - ty::CoroutineClosure(_, args) => args - .as_coroutine_closure() - .upvar_tys() - .get(f.index()) - .copied() - .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), - // Only prefix fields (upvars and current state) are - // accessible without a variant index. - ty::Coroutine(_, args) => args - .as_coroutine() - .prefix_tys() - .get(f.index()) - .copied() - .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), - ty::Tuple(tys) => tys - .get(f.index()) - .copied() - .unwrap_or_else(|| bug!("field {f:?} out of range: {self:?}")), - _ => bug!("can't project out of {self:?}"), - } - } - } - - pub fn multi_projection_ty( - self, - tcx: TyCtxt<'tcx>, - elems: &[PlaceElem<'tcx>], - ) -> PlaceTy<'tcx> { - elems.iter().fold(self, |place_ty, &elem| place_ty.projection_ty(tcx, elem)) - } - - /// Convenience wrapper around `projection_ty_core` for - /// `PlaceElem`, where we can just use the `Ty` that is already - /// stored inline on field projection elems. - pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: PlaceElem<'tcx>) -> PlaceTy<'tcx> { - self.projection_ty_core(tcx, &elem, |_, _, ty| ty, |_, ty| ty) - } - - /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` - /// projects `place_ty` onto `elem`, returning the appropriate - /// `Ty` or downcast variant corresponding to that projection. - /// The `handle_field` callback must map a `FieldIdx` to its `Ty`, - /// (which should be trivial when `T` = `Ty`). - pub fn projection_ty_core( - self, - tcx: TyCtxt<'tcx>, - elem: &ProjectionElem, - mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>, - mut handle_opaque_cast_and_subtype: impl FnMut(&Self, T) -> Ty<'tcx>, - ) -> PlaceTy<'tcx> - where - V: ::std::fmt::Debug, - T: ::std::fmt::Debug + Copy, - { - if self.variant_index.is_some() && !matches!(elem, ProjectionElem::Field(..)) { - bug!("cannot use non field projection on downcasted place") - } - let answer = match *elem { - ProjectionElem::Deref => { - let ty = self.ty.builtin_deref(true).unwrap_or_else(|| { - bug!("deref projection of non-dereferenceable ty {:?}", self) - }); - PlaceTy::from_ty(ty) - } - ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => { - PlaceTy::from_ty(self.ty.builtin_index().unwrap()) - } - ProjectionElem::Subslice { from, to, from_end } => { - PlaceTy::from_ty(match self.ty.kind() { - ty::Slice(..) => self.ty, - ty::Array(inner, _) if !from_end => Ty::new_array(tcx, *inner, to - from), - ty::Array(inner, size) if from_end => { - let size = size - .try_to_target_usize(tcx) - .expect("expected subslice projection on fixed-size array"); - let len = size - from - to; - Ty::new_array(tcx, *inner, len) - } - _ => bug!("cannot subslice non-array type: `{:?}`", self), - }) - } - ProjectionElem::Downcast(_name, index) => { - PlaceTy { ty: self.ty, variant_index: Some(index) } - } - ProjectionElem::Field(f, fty) => PlaceTy::from_ty(handle_field(&self, f, fty)), - ProjectionElem::OpaqueCast(ty) => { - PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) - } - ProjectionElem::Subtype(ty) => { - PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) - } - - // FIXME(unsafe_binders): Rename `handle_opaque_cast_and_subtype` to be more general. - ProjectionElem::UnwrapUnsafeBinder(ty) => { - PlaceTy::from_ty(handle_opaque_cast_and_subtype(&self, ty)) - } - }; - debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer); - answer - } -} - -impl<'tcx> Place<'tcx> { - pub fn ty_from( - local: Local, - projection: &[PlaceElem<'tcx>], - local_decls: &D, - tcx: TyCtxt<'tcx>, - ) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, - { - PlaceTy::from_ty(local_decls.local_decls()[local].ty).multi_projection_ty(tcx, projection) - } - - pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, - { - Place::ty_from(self.local, self.projection, local_decls, tcx) - } -} - -impl<'tcx> PlaceRef<'tcx> { - pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> - where - D: HasLocalDecls<'tcx>, - { - Place::ty_from(self.local, self.projection, local_decls, tcx) - } -} - -pub enum RvalueInitializationState { - Shallow, - Deep, -} - -impl<'tcx> Rvalue<'tcx> { - pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> - where - D: HasLocalDecls<'tcx>, - { - match *self { - Rvalue::Use(ref operand) => operand.ty(local_decls, tcx), - Rvalue::Repeat(ref operand, count) => { - Ty::new_array_with_const_len(tcx, operand.ty(local_decls, tcx), count) - } - Rvalue::ThreadLocalRef(did) => tcx.thread_local_ptr_ty(did), - Rvalue::Ref(reg, bk, ref place) => { - let place_ty = place.ty(local_decls, tcx).ty; - Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy()) - } - Rvalue::RawPtr(kind, ref place) => { - let place_ty = place.ty(local_decls, tcx).ty; - Ty::new_ptr(tcx, place_ty, kind.to_mutbl_lossy()) - } - Rvalue::Len(..) => tcx.types.usize, - Rvalue::Cast(.., ty) => ty, - Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) => { - let lhs_ty = lhs.ty(local_decls, tcx); - let rhs_ty = rhs.ty(local_decls, tcx); - op.ty(tcx, lhs_ty, rhs_ty) - } - Rvalue::UnaryOp(op, ref operand) => { - let arg_ty = operand.ty(local_decls, tcx); - op.ty(tcx, arg_ty) - } - Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { - tcx.types.usize - } - Rvalue::NullaryOp(NullOp::ContractChecks, _) - | Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool, - Rvalue::Aggregate(ref ak, ref ops) => match **ak { - AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64), - AggregateKind::Tuple => { - Ty::new_tup_from_iter(tcx, ops.iter().map(|op| op.ty(local_decls, tcx))) - } - AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args), - AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args), - AggregateKind::Coroutine(did, args) => Ty::new_coroutine(tcx, did, args), - AggregateKind::CoroutineClosure(did, args) => { - Ty::new_coroutine_closure(tcx, did, args) - } - AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability), - }, - Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty), - Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty, - Rvalue::WrapUnsafeBinder(_, ty) => ty, - } - } - - #[inline] - /// Returns `true` if this rvalue is deeply initialized (most rvalues) or - /// whether its only shallowly initialized (`Rvalue::Box`). - pub fn initialization_state(&self) -> RvalueInitializationState { - match *self { - Rvalue::ShallowInitBox(_, _) => RvalueInitializationState::Shallow, - _ => RvalueInitializationState::Deep, - } - } -} - -impl<'tcx> Operand<'tcx> { - pub fn ty(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> - where - D: HasLocalDecls<'tcx>, - { - match self { - &Operand::Copy(ref l) | &Operand::Move(ref l) => l.ty(local_decls, tcx).ty, - Operand::Constant(c) => c.const_.ty(), - } - } - - pub fn span(&self, local_decls: &D) -> Span - where - D: HasLocalDecls<'tcx>, - { - match self { - &Operand::Copy(ref l) | &Operand::Move(ref l) => { - local_decls.local_decls()[l.local].source_info.span - } - Operand::Constant(c) => c.span, - } - } -} - -impl<'tcx> BinOp { - pub fn ty(&self, tcx: TyCtxt<'tcx>, lhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>) -> Ty<'tcx> { - // FIXME: handle SIMD correctly - match self { - &BinOp::Add - | &BinOp::AddUnchecked - | &BinOp::Sub - | &BinOp::SubUnchecked - | &BinOp::Mul - | &BinOp::MulUnchecked - | &BinOp::Div - | &BinOp::Rem - | &BinOp::BitXor - | &BinOp::BitAnd - | &BinOp::BitOr => { - // these should be integers or floats of the same size. - assert_eq!(lhs_ty, rhs_ty); - lhs_ty - } - &BinOp::AddWithOverflow | &BinOp::SubWithOverflow | &BinOp::MulWithOverflow => { - // these should be integers of the same size. - assert_eq!(lhs_ty, rhs_ty); - Ty::new_tup(tcx, &[lhs_ty, tcx.types.bool]) - } - &BinOp::Shl - | &BinOp::ShlUnchecked - | &BinOp::Shr - | &BinOp::ShrUnchecked - | &BinOp::Offset => { - lhs_ty // lhs_ty can be != rhs_ty - } - &BinOp::Eq | &BinOp::Lt | &BinOp::Le | &BinOp::Ne | &BinOp::Ge | &BinOp::Gt => { - tcx.types.bool - } - &BinOp::Cmp => { - // these should be integer-like types of the same size. - assert_eq!(lhs_ty, rhs_ty); - tcx.ty_ordering_enum(None) - } - } - } -} - -impl<'tcx> UnOp { - pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> { - match self { - UnOp::Not | UnOp::Neg => arg_ty, - UnOp::PtrMetadata => arg_ty.pointee_metadata_ty_or_projection(tcx), - } - } -} - -impl BorrowKind { - pub fn to_mutbl_lossy(self) -> hir::Mutability { - match self { - BorrowKind::Mut { .. } => hir::Mutability::Mut, - BorrowKind::Shared => hir::Mutability::Not, - - // We have no type corresponding to a shallow borrow, so use - // `&` as an approximation. - BorrowKind::Fake(_) => hir::Mutability::Not, - } - } -} - -impl BinOp { - pub(crate) fn to_hir_binop(self) -> hir::BinOpKind { - match self { - // HIR `+`/`-`/`*` can map to either of these MIR BinOp, depending - // on whether overflow checks are enabled or not. - BinOp::Add | BinOp::AddWithOverflow => hir::BinOpKind::Add, - BinOp::Sub | BinOp::SubWithOverflow => hir::BinOpKind::Sub, - BinOp::Mul | BinOp::MulWithOverflow => hir::BinOpKind::Mul, - BinOp::Div => hir::BinOpKind::Div, - BinOp::Rem => hir::BinOpKind::Rem, - BinOp::BitXor => hir::BinOpKind::BitXor, - BinOp::BitAnd => hir::BinOpKind::BitAnd, - BinOp::BitOr => hir::BinOpKind::BitOr, - BinOp::Shl => hir::BinOpKind::Shl, - BinOp::Shr => hir::BinOpKind::Shr, - BinOp::Eq => hir::BinOpKind::Eq, - BinOp::Ne => hir::BinOpKind::Ne, - BinOp::Lt => hir::BinOpKind::Lt, - BinOp::Gt => hir::BinOpKind::Gt, - BinOp::Le => hir::BinOpKind::Le, - BinOp::Ge => hir::BinOpKind::Ge, - // We don't have HIR syntax for these. - BinOp::Cmp - | BinOp::AddUnchecked - | BinOp::SubUnchecked - | BinOp::MulUnchecked - | BinOp::ShlUnchecked - | BinOp::ShrUnchecked - | BinOp::Offset => { - unreachable!() - } - } - } - - /// If this is a `FooWithOverflow`, return `Some(Foo)`. - pub fn overflowing_to_wrapping(self) -> Option { - Some(match self { - BinOp::AddWithOverflow => BinOp::Add, - BinOp::SubWithOverflow => BinOp::Sub, - BinOp::MulWithOverflow => BinOp::Mul, - _ => return None, - }) - } - - /// Returns whether this is a `FooWithOverflow` - pub fn is_overflowing(self) -> bool { - self.overflowing_to_wrapping().is_some() - } - - /// If this is a `Foo`, return `Some(FooWithOverflow)`. - pub fn wrapping_to_overflowing(self) -> Option { - Some(match self { - BinOp::Add => BinOp::AddWithOverflow, - BinOp::Sub => BinOp::SubWithOverflow, - BinOp::Mul => BinOp::MulWithOverflow, - _ => return None, - }) - } -} diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index 9357e19f7c579..fdfcb128778a7 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -86,7 +86,7 @@ impl SwitchTargets { self.iter().find_map(|(v, t)| (v == value).then_some(t)).unwrap_or_else(|| self.otherwise()) } - /// Adds a new target to the switch. But You cannot add an already present value. + /// Adds a new target to the switch. Panics if you add an already present value. #[inline] pub fn add_target(&mut self, value: u128, bb: BasicBlock) { let value = Pu128(value); @@ -226,7 +226,7 @@ impl AssertKind { { use AssertKind::*; match self { - BoundsCheck { ref len, ref index } => write!( + BoundsCheck { len, index } => write!( f, "\"index out of bounds: the length is {{}} but the index is {{}}\", {len:?}, {index:?}" ), diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 0e7dcc24dafa6..5950ac295af19 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -104,23 +104,21 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { /// ``` /// /// A Postorder traversal of this graph is `D B C A` or `D C B A` -pub struct Postorder<'a, 'tcx, C> { +pub struct Postorder<'a, 'tcx> { basic_blocks: &'a IndexSlice>, visited: DenseBitSet, visit_stack: Vec<(BasicBlock, Successors<'a>)>, root_is_start_block: bool, - extra: C, + /// A non-empty `extra` allows for a precise calculation of the successors. + extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>, } -impl<'a, 'tcx, C> Postorder<'a, 'tcx, C> -where - C: Customization<'tcx>, -{ +impl<'a, 'tcx> Postorder<'a, 'tcx> { pub fn new( basic_blocks: &'a IndexSlice>, root: BasicBlock, - extra: C, - ) -> Postorder<'a, 'tcx, C> { + extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>, + ) -> Postorder<'a, 'tcx> { let mut po = Postorder { basic_blocks, visited: DenseBitSet::new_empty(basic_blocks.len()), @@ -140,7 +138,11 @@ where return; } let data = &self.basic_blocks[bb]; - let successors = C::successors(data, self.extra); + let successors = if let Some(extra) = self.extra { + data.mono_successors(extra.0, extra.1) + } else { + data.terminator().successors() + }; self.visit_stack.push((bb, successors)); } @@ -198,10 +200,7 @@ where } } -impl<'tcx, C> Iterator for Postorder<'_, 'tcx, C> -where - C: Customization<'tcx>, -{ +impl<'tcx> Iterator for Postorder<'_, 'tcx> { type Item = BasicBlock; fn next(&mut self) -> Option { @@ -241,32 +240,12 @@ pub fn postorder<'a, 'tcx>( reverse_postorder(body).rev() } -/// Lets us plug in some additional logic and data into a Postorder traversal. Or not. -pub trait Customization<'tcx>: Copy { - fn successors<'a>(_: &'a BasicBlockData<'tcx>, _: Self) -> Successors<'a>; -} - -impl<'tcx> Customization<'tcx> for () { - fn successors<'a>(data: &'a BasicBlockData<'tcx>, _: ()) -> Successors<'a> { - data.terminator().successors() - } -} - -impl<'tcx> Customization<'tcx> for (TyCtxt<'tcx>, Instance<'tcx>) { - fn successors<'a>( - data: &'a BasicBlockData<'tcx>, - (tcx, instance): (TyCtxt<'tcx>, Instance<'tcx>), - ) -> Successors<'a> { - data.mono_successors(tcx, instance) - } -} - pub fn mono_reachable_reverse_postorder<'a, 'tcx>( body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, ) -> Vec { - let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, (tcx, instance)); + let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, Some((tcx, instance))); let mut items = Vec::with_capacity(body.basic_blocks.len()); while let Some(block) = iter.next() { items.push(block); diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8ad88fbda7c89..3c83d962900ae 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -270,10 +270,12 @@ macro_rules! make_mir_visitor { fn visit_local( &mut self, - _local: $(& $mutability)? Local, - _context: PlaceContext, - _location: Location, - ) {} + local: $(& $mutability)? Local, + context: PlaceContext, + location: Location, + ) { + self.super_local(local, context, location) + } fn visit_source_scope( &mut self, @@ -292,9 +294,11 @@ macro_rules! make_mir_visitor { super_body!(self, body, $($mutability, true)?); } - fn super_basic_block_data(&mut self, - block: BasicBlock, - data: & $($mutability)? BasicBlockData<'tcx>) { + fn super_basic_block_data( + &mut self, + block: BasicBlock, + data: & $($mutability)? BasicBlockData<'tcx>) + { let BasicBlockData { statements, terminator, @@ -339,24 +343,24 @@ macro_rules! make_mir_visitor { match callee_def { ty::InstanceKind::Item(_def_id) => {} - ty::InstanceKind::Intrinsic(_def_id) | - ty::InstanceKind::VTableShim(_def_id) | - ty::InstanceKind::ReifyShim(_def_id, _) | - ty::InstanceKind::Virtual(_def_id, _) | - ty::InstanceKind::ThreadLocalShim(_def_id) | - ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } | - ty::InstanceKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Intrinsic(_def_id) + | ty::InstanceKind::VTableShim(_def_id) + | ty::InstanceKind::ReifyShim(_def_id, _) + | ty::InstanceKind::Virtual(_def_id, _) + | ty::InstanceKind::ThreadLocalShim(_def_id) + | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } + | ty::InstanceKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, receiver_by_ref: _, - } | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) | - ty::InstanceKind::DropGlue(_def_id, None) => {} - - ty::InstanceKind::FnPtrShim(_def_id, ty) | - ty::InstanceKind::DropGlue(_def_id, Some(ty)) | - ty::InstanceKind::CloneShim(_def_id, ty) | - ty::InstanceKind::FnPtrAddrShim(_def_id, ty) | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { + } + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) + | ty::InstanceKind::DropGlue(_def_id, None) => {} + + ty::InstanceKind::FnPtrShim(_def_id, ty) + | ty::InstanceKind::DropGlue(_def_id, Some(ty)) + | ty::InstanceKind::CloneShim(_def_id, ty) + | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } @@ -368,19 +372,16 @@ macro_rules! make_mir_visitor { } } - fn super_statement(&mut self, - statement: & $($mutability)? Statement<'tcx>, - location: Location) { - let Statement { - source_info, - kind, - } = statement; + fn super_statement( + &mut self, + statement: & $($mutability)? Statement<'tcx>, + location: Location + ) { + let Statement { source_info, kind } = statement; self.visit_source_info(source_info); match kind { - StatementKind::Assign( - box (place, rvalue) - ) => { + StatementKind::Assign(box (place, rvalue)) => { self.visit_assign(place, rvalue, location); } StatementKind::FakeRead(box (_, place)) => { @@ -428,11 +429,13 @@ macro_rules! make_mir_visitor { location ); } - StatementKind::AscribeUserType( - box (place, user_ty), - variance - ) => { - self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location); + StatementKind::AscribeUserType(box (place, user_ty), variance) => { + self.visit_ascribe_user_ty( + place, + $(& $mutability)? *variance, + user_ty, + location + ); } StatementKind::Coverage(coverage) => { self.visit_coverage( @@ -440,10 +443,14 @@ macro_rules! make_mir_visitor { location ) } - StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => { + StatementKind::Intrinsic(box intrinsic) => { match intrinsic { NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location), - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => { + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src, + dst, + count + }) => { self.visit_operand(src, location); self.visit_operand(dst, location); self.visit_operand(count, location); @@ -456,10 +463,12 @@ macro_rules! make_mir_visitor { } } - fn super_assign(&mut self, - place: &$($mutability)? Place<'tcx>, - rvalue: &$($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_assign( + &mut self, + place: &$($mutability)? Place<'tcx>, + rvalue: &$($mutability)? Rvalue<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Store), @@ -468,20 +477,22 @@ macro_rules! make_mir_visitor { self.visit_rvalue(rvalue, location); } - fn super_terminator(&mut self, - terminator: &$($mutability)? Terminator<'tcx>, - location: Location) { + fn super_terminator( + &mut self, + terminator: &$($mutability)? Terminator<'tcx>, + location: Location + ) { let Terminator { source_info, kind } = terminator; self.visit_source_info(source_info); match kind { - TerminatorKind::Goto { .. } | - TerminatorKind::UnwindResume | - TerminatorKind::UnwindTerminate(_) | - TerminatorKind::CoroutineDrop | - TerminatorKind::Unreachable | - TerminatorKind::FalseEdge { .. } | - TerminatorKind::FalseUnwind { .. } => {} + TerminatorKind::Goto { .. } + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + | TerminatorKind::CoroutineDrop + | TerminatorKind::Unreachable + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } => {} TerminatorKind::Return => { // `return` logically moves from the return place `_0`. Note that the place @@ -500,19 +511,11 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::SwitchInt { - discr, - targets: _ - } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.visit_operand(discr, location); } - TerminatorKind::Drop { - place, - target: _, - unwind: _, - replace: _, - } => { + TerminatorKind::Drop { place, target: _, unwind: _, replace: _ } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), @@ -541,11 +544,7 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::TailCall { - func, - args, - fn_span, - } => { + TerminatorKind::TailCall { func, args, fn_span } => { self.visit_span($(& $mutability)? *fn_span); self.visit_operand(func, location); for arg in args { @@ -553,23 +552,12 @@ macro_rules! make_mir_visitor { } }, - TerminatorKind::Assert { - cond, - expected: _, - msg, - target: _, - unwind: _, - } => { + TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.visit_operand(cond, location); self.visit_assert_message(msg, location); } - TerminatorKind::Yield { - value, - resume: _, - resume_arg, - drop: _, - } => { + TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => { self.visit_operand(value, location); self.visit_place( resume_arg, @@ -622,9 +610,11 @@ macro_rules! make_mir_visitor { } } - fn super_assert_message(&mut self, - msg: & $($mutability)? AssertMessage<'tcx>, - location: Location) { + fn super_assert_message( + &mut self, + msg: & $($mutability)? AssertMessage<'tcx>, + location: Location + ) { use crate::mir::AssertKind::*; match msg { BoundsCheck { len, index } => { @@ -648,9 +638,11 @@ macro_rules! make_mir_visitor { } } - fn super_rvalue(&mut self, - rvalue: & $($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_rvalue( + &mut self, + rvalue: & $($mutability)? Rvalue<'tcx>, + location: Location + ) { match rvalue { Rvalue::Use(operand) => { self.visit_operand(operand, location); @@ -677,6 +669,7 @@ macro_rules! make_mir_visitor { }; self.visit_place(path, ctx, location); } + Rvalue::CopyForDeref(place) => { self.visit_place( place, @@ -740,8 +733,7 @@ macro_rules! make_mir_visitor { AggregateKind::Array(ty) => { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - AggregateKind::Tuple => { - } + AggregateKind::Tuple => {} AggregateKind::Adt( _adt_def, _variant_index, @@ -751,22 +743,13 @@ macro_rules! make_mir_visitor { ) => { self.visit_args(args, location); } - AggregateKind::Closure( - _, - closure_args - ) => { + AggregateKind::Closure(_, closure_args) => { self.visit_args(closure_args, location); } - AggregateKind::Coroutine( - _, - coroutine_args, - ) => { + AggregateKind::Coroutine(_, coroutine_args) => { self.visit_args(coroutine_args, location); } - AggregateKind::CoroutineClosure( - _, - coroutine_closure_args, - ) => { + AggregateKind::CoroutineClosure(_, coroutine_closure_args) => { self.visit_args(coroutine_closure_args, location); } AggregateKind::RawPtr(ty, _) => { @@ -791,9 +774,11 @@ macro_rules! make_mir_visitor { } } - fn super_operand(&mut self, - operand: & $($mutability)? Operand<'tcx>, - location: Location) { + fn super_operand( + &mut self, + operand: & $($mutability)? Operand<'tcx>, + location: Location + ) { match operand { Operand::Copy(place) => { self.visit_place( @@ -815,28 +800,36 @@ macro_rules! make_mir_visitor { } } - fn super_ascribe_user_ty(&mut self, - place: & $($mutability)? Place<'tcx>, - variance: $(& $mutability)? ty::Variance, - user_ty: & $($mutability)? UserTypeProjection, - location: Location) { + fn super_ascribe_user_ty( + &mut self, + place: & $($mutability)? Place<'tcx>, + variance: $(& $mutability)? ty::Variance, + user_ty: & $($mutability)? UserTypeProjection, + location: Location) + { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)), + PlaceContext::NonUse( + NonUseContext::AscribeUserTy($(* &$mutability *)? variance) + ), location ); self.visit_user_type_projection(user_ty); } - fn super_coverage(&mut self, - _kind: & $($mutability)? coverage::CoverageKind, - _location: Location) { + fn super_coverage( + &mut self, + _kind: & $($mutability)? coverage::CoverageKind, + _location: Location + ) { } - fn super_retag(&mut self, - _kind: $(& $mutability)? RetagKind, - place: & $($mutability)? Place<'tcx>, - location: Location) { + fn super_retag( + &mut self, + _kind: $(& $mutability)? RetagKind, + place: & $($mutability)? Place<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Retag), @@ -844,9 +837,11 @@ macro_rules! make_mir_visitor { ); } - fn super_local_decl(&mut self, - local: Local, - local_decl: & $($mutability)? LocalDecl<'tcx>) { + fn super_local_decl( + &mut self, + local: Local, + local_decl: & $($mutability)? LocalDecl<'tcx> + ) { let LocalDecl { mutability: _, ty, @@ -862,12 +857,20 @@ macro_rules! make_mir_visitor { source_info: *source_info, }); if let Some(user_ty) = user_ty { - for (user_ty, _) in & $($mutability)? user_ty.contents { + for user_ty in & $($mutability)? user_ty.contents { self.visit_user_type_projection(user_ty); } } } + fn super_local( + &mut self, + _local: $(& $mutability)? Local, + _context: PlaceContext, + _location: Location, + ) { + } + fn super_var_debug_info( &mut self, var_debug_info: & $($mutability)? VarDebugInfo<'tcx> @@ -882,7 +885,10 @@ macro_rules! make_mir_visitor { self.visit_source_info(source_info); let location = Location::START; - if let Some(box VarDebugInfoFragment { ref $($mutability)? ty, ref $($mutability)? projection }) = composite { + if let Some(box VarDebugInfoFragment { + ty, + projection + }) = composite { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); for elem in projection { let ProjectionElem::Field(_, ty) = elem else { bug!() }; @@ -900,10 +906,7 @@ macro_rules! make_mir_visitor { } } - fn super_source_scope( - &mut self, - _scope: $(& $mutability)? SourceScope - ) {} + fn super_source_scope(&mut self, _scope: $(& $mutability)? SourceScope) {} fn super_const_operand( &mut self, @@ -919,8 +922,12 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); match const_ { Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location), - Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), - Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), + Const::Val(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } + Const::Unevaluated(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } } } @@ -929,27 +936,18 @@ macro_rules! make_mir_visitor { _ct: $(& $mutability)? ty::Const<'tcx>, _location: Location, ) { - } - fn super_span(&mut self, _span: $(& $mutability)? Span) { - } + fn super_span(&mut self, _span: $(& $mutability)? Span) {} fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) { - let SourceInfo { - span, - scope, - } = source_info; + let SourceInfo { span, scope } = source_info; self.visit_span($(& $mutability)? *span); self.visit_source_scope($(& $mutability)? *scope); } - fn super_user_type_projection( - &mut self, - _ty: & $($mutability)? UserTypeProjection, - ) { - } + fn super_user_type_projection(&mut self, _ty: & $($mutability)? UserTypeProjection) {} fn super_user_type_annotation( &mut self, @@ -960,14 +958,11 @@ macro_rules! make_mir_visitor { self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span)); } - fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) { - } + fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {} - fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) { - } + fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {} - fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) { - } + fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {} // Convenience methods @@ -976,7 +971,8 @@ macro_rules! make_mir_visitor { body: &$($mutability)? Body<'tcx>, location: Location ) { - let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; + let basic_block = + & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; if basic_block.statements.len() == location.statement_index { if let Some(ref $($mutability)? terminator) = basic_block.terminator { self.visit_terminator(terminator, location) @@ -1255,28 +1251,6 @@ macro_rules! visit_place_fns { make_mir_visitor!(Visitor,); make_mir_visitor!(MutVisitor, mut); -pub trait MirVisitable<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>); -} - -impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_statement(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Option> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self.as_ref().unwrap(), location) - } -} - /// Extra information passed to `visit_ty` and friends to give context /// about where the type etc appears. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] @@ -1390,13 +1364,13 @@ impl PlaceContext { matches!(self, PlaceContext::MutatingUse(MutatingUseContext::Drop)) } - /// Returns `true` if this place context represents a borrow. + /// Returns `true` if this place context represents a borrow, excluding fake borrows + /// (which are an artifact of borrowck and not actually borrows in runtime MIR). pub fn is_borrow(self) -> bool { matches!( self, - PlaceContext::NonMutatingUse( - NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::FakeBorrow - ) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) + | PlaceContext::MutatingUse(MutatingUseContext::Borrow) ) } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cd81890598e73..7c4ea06a7461a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -163,7 +163,7 @@ rustc_queries! { /// The items in a module. /// - /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`. + /// This can be conveniently accessed by `tcx.hir_visit_item_likes_in_module`. /// Avoid calling this query directly. query hir_module_items(key: LocalModDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache @@ -771,7 +771,7 @@ rustc_queries! { query type_param_predicates( key: (LocalDefId, LocalDefId, rustc_span::Ident) ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir().ty_param_name(key.1) } + desc { |tcx| "computing the bounds for type parameter `{}`", tcx.hir_ty_param_name(key.1) } } query trait_def(key: DefId) -> &'tcx ty::TraitDef { @@ -802,7 +802,7 @@ rustc_queries! { query adt_dtorck_constraint( key: DefId - ) -> Result<&'tcx DropckConstraint<'tcx>, NoSolution> { + ) -> &'tcx DropckConstraint<'tcx> { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 2ab8750f727c0..e5592de81cd78 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -94,6 +94,7 @@ thir_with_elements! { pub enum BodyTy<'tcx> { Const(Ty<'tcx>), Fn(FnSig<'tcx>), + GlobalAsm(Ty<'tcx>), } /// Description of a type-checked function parameter. @@ -376,7 +377,6 @@ pub enum ExprKind<'tcx> { /// A `match` expression. Match { scrutinee: ExprId, - scrutinee_hir_id: HirId, arms: Box<[ArmId]>, match_source: MatchSource, }, @@ -606,8 +606,7 @@ pub enum InlineAsmOperand<'tcx> { span: Span, }, SymFn { - value: mir::Const<'tcx>, - span: Span, + value: ExprId, }, SymStatic { def_id: DefId, @@ -679,8 +678,7 @@ impl<'tcx> Pat<'tcx> { subpatterns.iter().for_each(|field| field.pattern.walk_(it)) } Or { pats } => pats.iter().for_each(|p| p.walk_(it)), - Array { box ref prefix, ref slice, box ref suffix } - | Slice { box ref prefix, ref slice, box ref suffix } => { + Array { box prefix, slice, box suffix } | Slice { box prefix, slice, box suffix } => { prefix.iter().chain(slice.as_deref()).chain(suffix.iter()).for_each(|p| p.walk_(it)) } } diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 13b8af55e518e..a9df4d1625be3 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -172,7 +172,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( } Out { expr: None, reg: _, late: _ } | Const { value: _, span: _ } - | SymFn { value: _, span: _ } + | SymFn { value: _ } | SymStatic { def_id: _ } => {} Label { block } => visitor.visit_block(&visitor.thir()[*block]), } @@ -194,7 +194,7 @@ pub fn walk_stmt<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>( initializer, remainder_scope: _, init_scope: _, - ref pattern, + pattern, lint_level: _, else_block, span: _, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f039da772fd4d..d033ecc75dbe5 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -12,7 +12,7 @@ use std::borrow::Cow; use std::hash::{Hash, Hasher}; use std::sync::Arc; -use rustc_errors::{Applicability, Diag, EmissionGuarantee}; +use rustc_errors::{Applicability, Diag, EmissionGuarantee, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def_id::DefId; @@ -51,7 +51,7 @@ pub struct ObligationCause<'tcx> { /// information. pub body_id: LocalDefId, - code: InternedObligationCauseCode<'tcx>, + code: ObligationCauseCodeHandle<'tcx>, } // This custom hash function speeds up hashing for `Obligation` deduplication @@ -97,7 +97,7 @@ impl<'tcx> ObligationCause<'tcx> { pub fn map_code( &mut self, - f: impl FnOnce(InternedObligationCauseCode<'tcx>) -> ObligationCauseCode<'tcx>, + f: impl FnOnce(ObligationCauseCodeHandle<'tcx>) -> ObligationCauseCode<'tcx>, ) { self.code = f(std::mem::take(&mut self.code)).into(); } @@ -144,23 +144,16 @@ impl<'tcx> ObligationCause<'tcx> { } } -#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] -#[derive(TypeVisitable, TypeFoldable)] -pub struct UnifyReceiverContext<'tcx> { - pub assoc_item: ty::AssocItem, - pub param_env: ty::ParamEnv<'tcx>, - pub args: GenericArgsRef<'tcx>, -} - +/// A compact form of `ObligationCauseCode`. #[derive(Clone, PartialEq, Eq, Default, HashStable)] #[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)] -pub struct InternedObligationCauseCode<'tcx> { +pub struct ObligationCauseCodeHandle<'tcx> { /// `None` for `ObligationCauseCode::Misc` (a common case, occurs ~60% of /// the time). `Some` otherwise. code: Option>>, } -impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> { +impl<'tcx> std::fmt::Debug for ObligationCauseCodeHandle<'tcx> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let cause: &ObligationCauseCode<'_> = self; cause.fmt(f) @@ -169,14 +162,14 @@ impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> { impl<'tcx> ObligationCauseCode<'tcx> { #[inline(always)] - fn into(self) -> InternedObligationCauseCode<'tcx> { - InternedObligationCauseCode { + fn into(self) -> ObligationCauseCodeHandle<'tcx> { + ObligationCauseCodeHandle { code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) }, } } } -impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> { +impl<'tcx> std::ops::Deref for ObligationCauseCodeHandle<'tcx> { type Target = ObligationCauseCode<'tcx>; fn deref(&self) -> &Self::Target { @@ -305,7 +298,7 @@ pub enum ObligationCauseCode<'tcx> { /// The node of the function call. call_hir_id: HirId, /// The obligation introduced by this argument. - parent_code: InternedObligationCauseCode<'tcx>, + parent_code: ObligationCauseCodeHandle<'tcx>, }, /// Error derived when checking an impl item is compatible with @@ -359,8 +352,6 @@ pub enum ObligationCauseCode<'tcx> { /// Method receiver MethodReceiver, - UnifyReceiver(Box>), - /// `return` with no expression ReturnNoExpression, @@ -390,7 +381,8 @@ pub enum ObligationCauseCode<'tcx> { /// `WellFormed(None)`. WellFormed(Option), - /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against. + /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching + /// against. MatchImpl(ObligationCause<'tcx>, DefId), BinOp { @@ -413,7 +405,7 @@ pub enum ObligationCauseCode<'tcx> { ConstParam(Ty<'tcx>), /// Obligations emitted during the normalization of a weak type alias. - TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId), + TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId), } /// Whether a value can be extracted into a const. @@ -514,12 +506,6 @@ impl<'tcx> ObligationCauseCode<'tcx> { #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48); -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub enum StatementAsExpression { - CorrectType, - NeedsBoxing, -} - #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] #[derive(TypeVisitable, TypeFoldable)] pub struct MatchExpressionArmCause<'tcx> { @@ -584,7 +570,7 @@ pub struct DerivedCause<'tcx> { pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>, /// The parent trait had this cause. - pub parent_code: InternedObligationCauseCode<'tcx>, + pub parent_code: ObligationCauseCodeHandle<'tcx>, } #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] @@ -592,9 +578,9 @@ pub struct DerivedCause<'tcx> { pub struct ImplDerivedCause<'tcx> { pub derived: DerivedCause<'tcx>, /// The `DefId` of the `impl` that gave rise to the `derived` obligation. - /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl, - /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle - /// that exceptional case where appropriate. + /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic + /// impl, then this will be the `DefId` of that trait alias. Care should therefore be taken to + /// handle that exceptional case where appropriate. pub impl_or_alias_def_id: DefId, /// The index of the derived predicate in the parent impl's predicates. pub impl_def_predicate_index: Option, @@ -611,7 +597,7 @@ pub struct DerivedHostCause<'tcx> { pub parent_host_pred: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>, /// The parent trait had this cause. - pub parent_code: InternedObligationCauseCode<'tcx>, + pub parent_code: ObligationCauseCodeHandle<'tcx>, } #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] @@ -790,7 +776,7 @@ impl DynCompatibilityViolation { pub fn error_msg(&self) -> Cow<'static, str> { match self { DynCompatibilityViolation::SizedSelf(_) => "it requires `Self: Sized`".into(), - DynCompatibilityViolation::SupertraitSelf(ref spans) => { + DynCompatibilityViolation::SupertraitSelf(spans) => { if spans.iter().any(|sp| *sp != DUMMY_SP) { "it uses `Self` as a type parameter".into() } else { @@ -1000,4 +986,7 @@ pub enum CodegenObligationError { /// but was included during typeck due to the trivial_bounds feature. Unimplemented, FulfillmentError, + /// The selected impl has unconstrained generic parameters. This will emit an error + /// during impl WF checking. + UnconstrainedParam(ErrorGuaranteed), } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 4203c8fd86149..76f3d2bab9cf4 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -75,12 +75,6 @@ pub type CanonicalPredicateGoal<'tcx> = pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>; -pub type CanonicalTypeOpEqGoal<'tcx> = - CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Eq<'tcx>>>; - -pub type CanonicalTypeOpSubtypeGoal<'tcx> = - CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::Subtype<'tcx>>>; - pub type CanonicalTypeOpProvePredicateGoal<'tcx> = CanonicalQueryInput<'tcx, ty::ParamEnvAnd<'tcx, type_op::ProvePredicate<'tcx>>>; diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index f659bf8125a0e..9c74f6263b3ce 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,9 +1,9 @@ -use rustc_ast_ir::try_visit; use rustc_data_structures::intern::Interned; use rustc_macros::HashStable; use rustc_type_ir as ir; pub use rustc_type_ir::solve::*; +use crate::ty::visit::try_visit; use crate::ty::{ self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index b529d17540a82..3585f28b4a550 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -4,7 +4,6 @@ use std::ops::Range; use std::str; use rustc_abi::{FIRST_VARIANT, ReprOptions, VariantIdx}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; @@ -540,7 +539,7 @@ impl<'tcx> AdtDef<'tcx> { pub fn discriminants( self, tcx: TyCtxt<'tcx>, - ) -> impl Iterator)> + Captures<'tcx> { + ) -> impl Iterator)> { assert!(self.is_enum()); let repr_type = self.repr().discr_type(); let initial = repr_type.initial_discriminant(tcx); diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index c4d5367e2f03a..3605f2402e7ff 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -1,6 +1,5 @@ use std::fmt::Write; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::HirId; @@ -415,7 +414,7 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>( parent_captures: impl IntoIterator>, child_captures: impl IntoIterator>, mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T, -) -> impl Iterator + Captures<'a> + Captures<'tcx> { +) -> impl Iterator { std::iter::from_coroutine( #[coroutine] move || { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ea2b610a727b5..238ba127e2ecf 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1370,7 +1370,6 @@ pub struct GlobalCtxt<'tcx> { // Internal caches for metadata decoding. No need to track deps on this. pub ty_rcache: Lock>>, - pub pred_rcache: Lock>>, /// Caches the results of trait selection. This cache is used /// for things that do not have to do with the parameters in scope. @@ -1473,7 +1472,11 @@ impl<'tcx> TyCtxt<'tcx> { self.codegen_fn_attrs(def_id) } else if matches!( def_kind, - DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst + DefKind::AnonConst + | DefKind::AssocConst + | DefKind::Const + | DefKind::InlineConst + | DefKind::GlobalAsm ) { CodegenFnAttrs::EMPTY } else { @@ -1601,7 +1604,6 @@ impl<'tcx> TyCtxt<'tcx> { query_system, query_kinds, ty_rcache: Default::default(), - pred_rcache: Default::default(), selection_cache: Default::default(), evaluation_cache: Default::default(), new_solver_evaluation_cache: Default::default(), @@ -1941,7 +1943,7 @@ impl<'tcx> TyCtxt<'tcx> { Ok(TyCtxtFeed { key: num, tcx: self }) } - pub fn iter_local_def_id(self) -> impl Iterator + 'tcx { + pub fn iter_local_def_id(self) -> impl Iterator { // Create a dependency to the red node to be sure we re-execute this when the amount of // definitions change. self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); @@ -2079,7 +2081,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> Vec<&'tcx hir::Ty<'tcx>> { let hir_id = self.local_def_id_to_hir_id(scope_def_id); let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = - self.hir().fn_decl_by_hir_id(hir_id) + self.hir_fn_decl_by_hir_id(hir_id) else { return vec![]; }; @@ -2099,7 +2101,7 @@ impl<'tcx> TyCtxt<'tcx> { let hir_id = self.local_def_id_to_hir_id(scope_def_id); let mut v = TraitObjectVisitor(vec![], self.hir()); // when the return type is a type alias - if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) + if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir_fn_decl_by_hir_id(hir_id) && let hir::TyKind::Path(hir::QPath::Resolved( None, hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind @@ -2173,14 +2175,14 @@ impl<'tcx> TyCtxt<'tcx> { } /// All traits in the crate graph, including those not visible to the user. - pub fn all_traits(self) -> impl Iterator + 'tcx { + pub fn all_traits(self) -> impl Iterator { iter::once(LOCAL_CRATE) .chain(self.crates(()).iter().copied()) .flat_map(move |cnum| self.traits(cnum).iter().copied()) } /// All traits that are visible within the crate graph (i.e. excluding private dependencies). - pub fn visible_traits(self) -> impl Iterator + 'tcx { + pub fn visible_traits(self) -> impl Iterator { let visible_crates = self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum)); @@ -2365,7 +2367,7 @@ macro_rules! sty_debug_print { } impl<'tcx> TyCtxt<'tcx> { - pub fn debug_stats(self) -> impl fmt::Debug + 'tcx { + pub fn debug_stats(self) -> impl fmt::Debug { fmt::from_fn(move |fmt| { sty_debug_print!( fmt, @@ -3019,7 +3021,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Find the crate root and the appropriate span where `use` and outer attributes can be /// inserted at. pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option { - for (_hir_id, node) in self.hir().parent_iter(hir_id) { + for (_hir_id, node) in self.hir_parent_iter(hir_id) { if let hir::Node::Crate(m) = node { return Some(m.spans.inject_use_span.shrink_to_lo()); } @@ -3297,9 +3299,9 @@ pub fn provide(providers: &mut Providers) { providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); providers.is_panic_runtime = - |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::panic_runtime); + |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime); providers.is_compiler_builtins = - |tcx, LocalCrate| contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins); + |tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::compiler_builtins); providers.has_panic_handler = |tcx, LocalCrate| { // We want to check if the panic handler was defined in this crate tcx.lang_items().panic_impl().is_some_and(|did| did.is_local()) diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs index fd84d75b53f3d..ed0b3059d7529 100644 --- a/compiler/rustc_middle/src/ty/generic_args.rs +++ b/compiler/rustc_middle/src/ty/generic_args.rs @@ -6,8 +6,6 @@ use std::mem; use std::num::NonZero; use std::ptr::NonNull; -use rustc_ast_ir::visit::VisitorResult; -use rustc_ast_ir::walk_visitable_list; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; @@ -18,7 +16,7 @@ use smallvec::SmallVec; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::ty::visit::{TypeVisitable, TypeVisitor}; +use crate::ty::visit::{TypeVisitable, TypeVisitor, VisitorResult, walk_visitable_list}; use crate::ty::{ self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs, Lift, List, Ty, TyCtxt, }; @@ -481,25 +479,23 @@ impl<'tcx> GenericArgs<'tcx> { } #[inline] - pub fn types(&'tcx self) -> impl DoubleEndedIterator> + 'tcx { + pub fn types(&self) -> impl DoubleEndedIterator> { self.iter().filter_map(|k| k.as_type()) } #[inline] - pub fn regions(&'tcx self) -> impl DoubleEndedIterator> + 'tcx { + pub fn regions(&self) -> impl DoubleEndedIterator> { self.iter().filter_map(|k| k.as_region()) } #[inline] - pub fn consts(&'tcx self) -> impl DoubleEndedIterator> + 'tcx { + pub fn consts(&self) -> impl DoubleEndedIterator> { self.iter().filter_map(|k| k.as_const()) } - /// Returns generic arguments that are not lifetimes or host effect params. + /// Returns generic arguments that are not lifetimes. #[inline] - pub fn non_erasable_generics( - &'tcx self, - ) -> impl DoubleEndedIterator> + 'tcx { + pub fn non_erasable_generics(&self) -> impl DoubleEndedIterator> { self.iter().filter_map(|k| match k.unpack() { ty::GenericArgKind::Lifetime(_) => None, generic => Some(generic), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index e5a4e38c87500..eb14ed20fbace 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -11,6 +11,7 @@ use rustc_error_messages::DiagMessage; use rustc_errors::{ Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, }; +use rustc_hashes::Hash64; use rustc_hir::LangItem; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; @@ -228,11 +229,32 @@ impl fmt::Display for ValidityRequirement { #[derive(Copy, Clone, Debug, HashStable, TyEncodable, TyDecodable)] pub enum LayoutError<'tcx> { + /// A type doesn't have a sensible layout. + /// + /// This variant is used for layout errors that don't necessarily cause + /// compile errors. + /// + /// For example, this can happen if a struct contains an unsized type in a + /// non-tail field, but has an unsatisfiable bound like `str: Sized`. Unknown(Ty<'tcx>), + /// The size of a type exceeds [`TargetDataLayout::obj_size_bound`]. SizeOverflow(Ty<'tcx>), + /// The layout can vary due to a generic parameter. + /// + /// Unlike `Unknown`, this variant is a "soft" error and indicates that the layout + /// may become computable after further instantiating the generic parameter(s). TooGeneric(Ty<'tcx>), + /// An alias failed to normalize. + /// + /// This variant is necessary, because, due to trait solver incompleteness, it is + /// possible than an alias that was rigid during analysis fails to normalize after + /// revealing opaque types. + /// + /// See `tests/ui/layout/normalization-failure.rs` for an example. NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), + /// A non-layout error is reported elsewhere. ReferencesError(ErrorGuaranteed), + /// A type has cyclic layout, i.e. the type contains itself without indirection. Cycle(ErrorGuaranteed), } @@ -242,11 +264,11 @@ impl<'tcx> LayoutError<'tcx> { use crate::fluent_generated::*; match self { - Unknown(_) => middle_unknown_layout, - SizeOverflow(_) => middle_values_too_big, - TooGeneric(_) => middle_too_generic, - NormalizationFailure(_, _) => middle_cannot_be_normalized, - Cycle(_) => middle_cycle, + Unknown(_) => middle_layout_unknown, + SizeOverflow(_) => middle_layout_size_overflow, + TooGeneric(_) => middle_layout_too_generic, + NormalizationFailure(_, _) => middle_layout_normalization_failure, + Cycle(_) => middle_layout_cycle, ReferencesError(_) => middle_layout_references_error, } } @@ -275,7 +297,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { match *self { LayoutError::Unknown(ty) => write!(f, "the type `{ty}` has an unknown layout"), LayoutError::TooGeneric(ty) => { - write!(f, "`{ty}` does not have a fixed size") + write!(f, "the type `{ty}` does not have a fixed layout") } LayoutError::SizeOverflow(ty) => { write!(f, "values of the type `{ty}` are too big for the target architecture") @@ -772,13 +794,14 @@ where Some(fields) => FieldsShape::Union(fields), None => FieldsShape::Arbitrary { offsets: IndexVec::new(), memory_index: IndexVec::new() }, }, - backend_repr: BackendRepr::Uninhabited, + backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, + uninhabited: true, align: tcx.data_layout.i8_align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: tcx.data_layout.i8_align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 04519008711b3..8ed5a118093f3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -27,7 +27,6 @@ pub use intrinsic::IntrinsicDef; use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx}; use rustc_ast::expand::StrippedCfgItem; use rustc_ast::node_id::NodeMap; -pub use rustc_ast_ir::{Movability, Mutability, try_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -48,7 +47,7 @@ pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym}; pub use rustc_type_ir::relate::VarianceDiagInfo; -pub use rustc_type_ir::*; +pub use rustc_type_ir::{Movability, Mutability, *}; use tracing::{debug, instrument}; pub use vtable::*; use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir}; @@ -180,7 +179,7 @@ pub struct ResolverGlobalCtxt { pub confused_type_with_std_module: FxIndexMap, pub doc_link_resolutions: FxIndexMap, pub doc_link_traits_in_scope: FxIndexMap>, - pub all_macro_rules: FxHashMap>, + pub all_macro_rules: FxHashSet, pub stripped_cfg_items: Steal>, } @@ -1470,7 +1469,7 @@ pub enum ImplTraitInTraitData { impl<'tcx> TyCtxt<'tcx> { pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> { - self.typeck(self.hir().body_owner_def_id(body)) + self.typeck(self.hir_body_owner_def_id(body)) } pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { @@ -1487,8 +1486,7 @@ impl<'tcx> TyCtxt<'tcx> { // Generate a deterministically-derived seed from the item's path hash // to allow for cross-crate compilation to actually work - let mut field_shuffle_seed = - self.def_path_hash(did.to_def_id()).0.to_smaller_hash().as_u64(); + let mut field_shuffle_seed = self.def_path_hash(did.to_def_id()).0.to_smaller_hash(); // If the user defined a custom seed for layout randomization, xor the item's // path hash with the user defined seed, this will allowing determinism while @@ -1800,14 +1798,11 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn get_attrs_by_path<'attr>( + pub fn get_attrs_by_path( self, did: DefId, - attr: &'attr [Symbol], - ) -> impl Iterator + 'attr - where - 'tcx: 'attr, - { + attr: &[Symbol], + ) -> impl Iterator { let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr); if let Some(did) = did.as_local() { self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn) diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 584cac22ae8dd..553de83dfcb42 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,6 +1,5 @@ use std::cmp::Ordering; -use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir::def_id::DefId; use rustc_macros::{HashStable, extension}; @@ -336,9 +335,9 @@ impl<'tcx> ty::List> { } #[inline] - pub fn projection_bounds<'a>( - &'a self, - ) -> impl Iterator>> + 'a { + pub fn projection_bounds( + &self, + ) -> impl Iterator>> { self.iter().filter_map(|predicate| { predicate .map_bound(|pred| match pred { @@ -350,16 +349,14 @@ impl<'tcx> ty::List> { } #[inline] - pub fn auto_traits<'a>(&'a self) -> impl Iterator + Captures<'tcx> + 'a { + pub fn auto_traits(&self) -> impl Iterator { self.iter().filter_map(|predicate| match predicate.skip_binder() { ExistentialPredicate::AutoTrait(did) => Some(did), _ => None, }) } - pub fn without_auto_traits( - &self, - ) -> impl Iterator> + '_ { + pub fn without_auto_traits(&self) -> impl Iterator> { self.iter().filter(|predicate| { !matches!(predicate.as_ref().skip_binder(), ExistentialPredicate::AutoTrait(_)) }) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 11b430dd358dd..ed0839f47e696 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -232,7 +232,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { f: F, ) -> Result<(), PrintError> where - T: Print<'tcx, Self> + TypeFoldable>, + T: TypeFoldable>, { f(value.as_ref().skip_binder(), self) } @@ -1056,7 +1056,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound; - for ((bound_args, is_async), entry) in fn_traits { + for ((bound_args_and_self_ty, is_async), entry) in fn_traits { write!(self, "{}", if first { "" } else { " + " })?; write!(self, "{}", if paren_needed { "(" } else { "" })?; @@ -1067,7 +1067,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { }; if let Some(return_ty) = entry.return_ty { - self.wrap_binder(&bound_args, |args, cx| { + self.wrap_binder(&bound_args_and_self_ty, |(args, _), cx| { define_scoped_cx!(cx); p!(write("{}", tcx.item_name(trait_def_id))); p!("("); @@ -1093,9 +1093,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } else { // Otherwise, render this like a regular trait. traits.insert( - bound_args.map_bound(|args| ty::TraitPredicate { + bound_args_and_self_ty.map_bound(|(args, self_ty)| ty::TraitPredicate { polarity: ty::PredicatePolarity::Positive, - trait_ref: ty::TraitRef::new(tcx, trait_def_id, [Ty::new_tup(tcx, args)]), + trait_ref: ty::TraitRef::new( + tcx, + trait_def_id, + [self_ty, Ty::new_tup(tcx, args)], + ), }), FxIndexMap::default(), ); @@ -1229,7 +1233,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { FxIndexMap>>, >, fn_traits: &mut FxIndexMap< - (ty::Binder<'tcx, &'tcx ty::List>>, bool), + (ty::Binder<'tcx, (&'tcx ty::List>, Ty<'tcx>)>, bool), OpaqueFnEntry<'tcx>, >, ) { @@ -1249,7 +1253,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { && let ty::Tuple(types) = *trait_pred.skip_binder().trait_ref.args.type_at(1).kind() { let entry = fn_traits - .entry((trait_pred.rebind(types), is_async)) + .entry((trait_pred.rebind((types, trait_pred.skip_binder().self_ty())), is_async)) .or_insert_with(|| OpaqueFnEntry { kind, return_ty: None }); if kind.extends(entry.kind) { entry.kind = kind; @@ -2379,7 +2383,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { f: C, ) -> Result<(), PrintError> where - T: Print<'tcx, Self> + TypeFoldable>, + T: TypeFoldable>, { self.pretty_wrap_binder(value, f) } @@ -2633,7 +2637,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { value: &ty::Binder<'tcx, T>, ) -> Result<(T, UnordMap>), fmt::Error> where - T: Print<'tcx, Self> + TypeFoldable>, + T: TypeFoldable>, { fn name_by_region_index( index: usize, @@ -2814,7 +2818,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { f: C, ) -> Result<(), fmt::Error> where - T: Print<'tcx, Self> + TypeFoldable>, + T: TypeFoldable>, { let old_region_index = self.region_index; let (new_value, _) = self.name_all_regions(value)?; diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index afdec7a86d445..839c1c346a47b 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -79,20 +79,14 @@ impl<'tcx> Relate> for &'tcx ty::List RelateResult<'tcx, Self> { let tcx = relation.cx(); - - // FIXME: this is wasteful, but want to do a perf run to see how slow it is. - // We need to perform this deduplication as we sometimes generate duplicate projections - // in `a`. - let mut a_v: Vec<_> = a.into_iter().collect(); - let mut b_v: Vec<_> = b.into_iter().collect(); - a_v.dedup(); - b_v.dedup(); - if a_v.len() != b_v.len() { + // Fast path for when the auto traits do not match, or if the principals + // are from different traits and therefore the projections definitely don't + // match up. + if a.len() != b.len() { return Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))); } - - let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { - match (ep_a.skip_binder(), ep_b.skip_binder()) { + let v = + iter::zip(a, b).map(|(ep_a, ep_b)| match (ep_a.skip_binder(), ep_b.skip_binder()) { (ty::ExistentialPredicate::Trait(a), ty::ExistentialPredicate::Trait(b)) => { Ok(ep_a.rebind(ty::ExistentialPredicate::Trait( relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), @@ -109,8 +103,7 @@ impl<'tcx> Relate> for &'tcx ty::List Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))), _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(a, b))), - } - }); + }); tcx.mk_poly_existential_predicates_from_iter(v) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 6c15e033bb04b..db9e9fbc643b2 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -7,13 +7,12 @@ use std::fmt::{self, Debug}; use rustc_abi::TyAndLayout; use rustc_ast::InlineAsmTemplatePiece; -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::Namespace; use rustc_hir::def_id::LocalDefId; use rustc_span::Span; use rustc_span::source_map::Spanned; use rustc_type_ir::ConstKind; +use rustc_type_ir::visit::{VisitorResult, try_visit}; use super::print::PrettyPrinter; use super::{GenericArg, GenericArgKind, Pattern, Region}; @@ -448,23 +447,23 @@ impl<'tcx> TypeSuperVisitable> for Ty<'tcx> { } ty::Slice(typ) => typ.visit_with(visitor), ty::Adt(_, args) => args.visit_with(visitor), - ty::Dynamic(ref trait_ty, ref reg, _) => { + ty::Dynamic(trait_ty, reg, _) => { try_visit!(trait_ty.visit_with(visitor)); reg.visit_with(visitor) } ty::Tuple(ts) => ts.visit_with(visitor), ty::FnDef(_, args) => args.visit_with(visitor), - ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor), - ty::UnsafeBinder(ref f) => f.visit_with(visitor), + ty::FnPtr(sig_tys, _) => sig_tys.visit_with(visitor), + ty::UnsafeBinder(f) => f.visit_with(visitor), ty::Ref(r, ty, _) => { try_visit!(r.visit_with(visitor)); ty.visit_with(visitor) } - ty::Coroutine(_did, ref args) => args.visit_with(visitor), - ty::CoroutineWitness(_did, ref args) => args.visit_with(visitor), - ty::Closure(_did, ref args) => args.visit_with(visitor), - ty::CoroutineClosure(_did, ref args) => args.visit_with(visitor), - ty::Alias(_, ref data) => data.visit_with(visitor), + ty::Coroutine(_did, args) => args.visit_with(visitor), + ty::CoroutineWitness(_did, args) => args.visit_with(visitor), + ty::Closure(_did, args) => args.visit_with(visitor), + ty::CoroutineClosure(_did, args) => args.visit_with(visitor), + ty::Alias(_, data) => data.visit_with(visitor), ty::Pat(ty, pat) => { try_visit!(ty.visit_with(visitor)); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8a31b2960188e..d5617adf26b40 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -9,7 +9,6 @@ use std::ops::{ControlFlow, Range}; use hir::def::{CtorKind, DefKind}; use rustc_abi::{ExternAbi, FIRST_VARIANT, FieldIdx, VariantIdx}; -use rustc_data_structures::captures::Captures; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::LangItem; @@ -18,7 +17,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, extension use rustc_span::{DUMMY_SP, Span, Symbol, sym}; use rustc_type_ir::TyKind::*; use rustc_type_ir::visit::TypeVisitableExt; -use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind}; +use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind, elaborate}; use tracing::instrument; use ty::util::{AsyncDropGlueMorphology, IntTypeExt}; @@ -105,7 +104,7 @@ impl<'tcx> ty::CoroutineArgs> { self, def_id: DefId, tcx: TyCtxt<'tcx>, - ) -> impl Iterator)> + Captures<'tcx> { + ) -> impl Iterator)> { self.variant_range(def_id, tcx).map(move |index| { (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) }) }) @@ -139,7 +138,7 @@ impl<'tcx> ty::CoroutineArgs> { self, def_id: DefId, tcx: TyCtxt<'tcx>, - ) -> impl Iterator> + Captures<'tcx>> { + ) -> impl Iterator>> { let layout = tcx.coroutine_layout(def_id, self.kind_ty()).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| { @@ -720,6 +719,34 @@ impl<'tcx> Ty<'tcx> { reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx> { + if cfg!(debug_assertions) { + let projection_count = obj.projection_bounds().count(); + let expected_count: usize = obj + .principal_def_id() + .into_iter() + .flat_map(|principal_def_id| { + // NOTE: This should agree with `needed_associated_types` in + // dyn trait lowering, or else we'll have ICEs. + elaborate::supertraits( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)), + ) + .map(|principal| { + tcx.associated_items(principal.def_id()) + .in_definition_order() + .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) + .count() + }) + }) + .sum(); + assert_eq!( + projection_count, expected_count, + "expected {obj:?} to have {expected_count} projections, \ + but it has {projection_count}" + ); + } Ty::new(tcx, Dynamic(obj, reg, repr)) } @@ -1121,7 +1148,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn is_param(self, index: u32) -> bool { match self.kind() { - ty::Param(ref data) => data.index == index, + ty::Param(data) => data.index == index, _ => false, } } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index b84cc57234f42..8fa1c569737a0 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -188,7 +188,7 @@ impl<'tcx> TyCtxt<'tcx> { self, trait_def_id: DefId, self_ty: Ty<'tcx>, - ) -> impl Iterator + 'tcx { + ) -> impl Iterator { let impls = self.trait_impls_of(trait_def_id); if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer) @@ -204,7 +204,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns an iterator containing all impls for `trait_def_id`. /// /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn all_impls(self, trait_def_id: DefId) -> impl Iterator + 'tcx { + pub fn all_impls(self, trait_def_id: DefId) -> impl Iterator { let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(trait_def_id); blanket_impls.iter().chain(non_blanket_impls.iter().flat_map(|(_, v)| v)).cloned() @@ -235,7 +235,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait } } - for &impl_def_id in tcx.hir().trait_impls(trait_id) { + for &impl_def_id in tcx.hir_trait_impls(trait_id) { let impl_def_id = impl_def_id.to_def_id(); let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity(); diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 1b5b791bb24ae..d4484a16fea4d 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -147,9 +147,7 @@ pub struct TypeckResults<'tcx> { coercion_casts: ItemLocalSet, /// Set of trait imports actually used in the method resolution. - /// This is used for warning unused imports. During type - /// checking, this `Arc` should not be cloned: it must have a ref-count - /// of 1 so that we can insert things into the set mutably. + /// This is used for warning unused imports. pub used_trait_imports: UnordSet, /// If any errors occurred while type-checking this body, @@ -577,7 +575,7 @@ impl<'a, V> LocalTableInContext<'a, V> { } pub fn items( - &'a self, + &self, ) -> UnordItems<(hir::ItemLocalId, &'a V), impl Iterator> { self.data.items().map(|(id, value)| (*id, value)) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 94bd359f6eb0f..88d5749854231 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -5,9 +5,10 @@ use std::{fmt, iter}; use rustc_abi::{ExternAbi, Float, Integer, IntegerType, Size}; use rustc_apfloat::Float as _; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::ErrorGuaranteed; +use rustc_hashes::Hash128; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 4efaccefcf74b..95256b55bb4a1 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -2,7 +2,7 @@ use std::ops::ControlFlow; use rustc_data_structures::fx::FxIndexSet; use rustc_type_ir::fold::TypeFoldable; -pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +pub use rustc_type_ir::visit::*; use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 1f3689926bcf3..d70d70a31a4a7 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_build" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_mir_build/src/builder/block.rs b/compiler/rustc_mir_build/src/builder/block.rs index ba63a97de89fb..7c76e02fcef6a 100644 --- a/compiler/rustc_mir_build/src/builder/block.rs +++ b/compiler/rustc_mir_build/src/builder/block.rs @@ -244,7 +244,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { StmtKind::Let { remainder_scope, init_scope, - ref pattern, + pattern, initializer, lint_level, else_block: None, @@ -331,8 +331,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr = &this.thir[expr_id]; let tail_result_is_ignored = destination_ty.is_unit() || this.block_context.currently_ignores_tail_results(); - this.block_context - .push(BlockFrame::TailExpr { tail_result_is_ignored, span: expr.span }); + this.block_context.push(BlockFrame::TailExpr { + info: BlockTailInfo { tail_result_is_ignored, span: expr.span }, + }); block = this.expr_into_dest(destination, block, expr_id).into_block(); let popped = this.block_context.pop(); diff --git a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs index eab414e150fa3..19669021eefb4 100644 --- a/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs @@ -1,6 +1,5 @@ use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty; diff --git a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs index 63e9b1dc6cd5a..2059610ee47d7 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs @@ -142,7 +142,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Overwrite temp local info if we have something more interesting to record. if !matches!(local_info, LocalInfo::Boring) { let decl_info = - this.local_decls[operand].local_info.as_mut().assert_crate_local(); + this.local_decls[operand].local_info.as_mut().unwrap_crate_local(); if let LocalInfo::Boring | LocalInfo::BlockTailTemp(_) = **decl_info { **decl_info = local_info; } diff --git a/compiler/rustc_mir_build/src/builder/expr/as_place.rs b/compiler/rustc_mir_build/src/builder/expr/as_place.rs index 308ca442b40cc..581f45db6c483 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_place.rs @@ -216,11 +216,11 @@ fn to_upvars_resolved_place_builder<'tcx>( /// Supports only HIR projection kinds that represent a path that might be /// captured by a closure or a coroutine, i.e., an `Index` or a `Subslice` /// projection kinds are unsupported. -fn strip_prefix<'a, 'tcx>( +fn strip_prefix<'tcx>( mut base_ty: Ty<'tcx>, - projections: &'a [PlaceElem<'tcx>], + projections: &[PlaceElem<'tcx>], prefix_projections: &[HirProjection<'tcx>], -) -> impl Iterator> + 'a { +) -> impl Iterator> { let mut iter = projections .iter() .copied() diff --git a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs index 2927f5b0c45d5..0bd61168fba05 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_temp.rs @@ -85,7 +85,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => LocalInfo::Boring, }; - **local_decl.local_info.as_mut().assert_crate_local() = local_info; + **local_decl.local_info.as_mut().unwrap_crate_local() = local_info; this.local_decls.push(local_decl) }; debug!(?temp); diff --git a/compiler/rustc_mir_build/src/builder/expr/into.rs b/compiler/rustc_mir_build/src/builder/expr/into.rs index 65dd061003d8d..72443e2f60ddc 100644 --- a/compiler/rustc_mir_build/src/builder/expr/into.rs +++ b/compiler/rustc_mir_build/src/builder/expr/into.rs @@ -482,15 +482,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }), } } - thir::InlineAsmOperand::SymFn { value, span } => { - mir::InlineAsmOperand::SymFn { - value: Box::new(ConstOperand { - span, - user_ty: None, - const_: value, - }), - } - } + thir::InlineAsmOperand::SymFn { value } => mir::InlineAsmOperand::SymFn { + value: Box::new(this.as_constant(&this.thir[value])), + }, thir::InlineAsmOperand::SymStatic { def_id } => { mir::InlineAsmOperand::SymStatic { def_id } } @@ -518,10 +512,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let asm_macro = match asm_macro { - AsmMacro::Asm => InlineAsmMacro::Asm, - AsmMacro::GlobalAsm => { - span_bug!(expr_span, "unexpected global_asm! in inline asm") - } + AsmMacro::Asm | AsmMacro::GlobalAsm => InlineAsmMacro::Asm, AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm, }; diff --git a/compiler/rustc_mir_build/src/builder/expr/stmt.rs b/compiler/rustc_mir_build/src/builder/expr/stmt.rs index 58090d3748b46..7f8a0a34c3123 100644 --- a/compiler/rustc_mir_build/src/builder/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/builder/expr/stmt.rs @@ -164,8 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } this.block_context.push(BlockFrame::TailExpr { - tail_result_is_ignored: true, - span: expr.span, + info: BlockTailInfo { tail_result_is_ignored: true, span: expr.span }, }); Some(expr.span) } else { diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ed577f7adeb3d..d05d5b151ff48 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -722,7 +722,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let LocalInfo::User(BindingForm::Var(VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. - })) = **self.local_decls[local].local_info.as_mut().assert_crate_local() + })) = **self.local_decls[local].local_info.as_mut().unwrap_crate_local() { *match_place = Some(place); } else { @@ -926,12 +926,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Note that the variance doesn't apply here, as we are tracking the effect // of `user_ty` on any bindings contained with subpattern. - let projection = UserTypeProjection { - base: self.canonical_user_type_annotations.push(annotation.clone()), - projs: Vec::new(), - }; - let subpattern_user_ty = - pattern_user_ty.push_projection(&projection, annotation.span); + let base_user_ty = self.canonical_user_type_annotations.push(annotation.clone()); + let subpattern_user_ty = pattern_user_ty.push_user_type(base_user_ty); self.visit_primary_bindings(subpattern, subpattern_user_ty, f) } diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index e04c70b588377..949559549345f 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -61,7 +61,9 @@ pub fn build_mir<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> { Ok((thir, expr)) => { let build_mir = |thir: &Thir<'tcx>| 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), + thir::BodyTy::Const(ty) | thir::BodyTy::GlobalAsm(ty) => { + construct_const(tcx, def, thir, expr, ty) + } }; // this must run before MIR dump, because @@ -112,16 +114,7 @@ enum BlockFrame { /// Evaluation is currently within the tail expression of a block. /// /// Example: `{ STMT_1; STMT_2; EXPR }` - TailExpr { - /// If true, then the surrounding context of the block ignores - /// the result of evaluating the block's tail expression. - /// - /// Example: `let _ = { STMT_1; EXPR };` - tail_result_is_ignored: bool, - - /// `Span` of the tail expression. - span: Span, - }, + TailExpr { info: BlockTailInfo }, /// Generic mark meaning that the block occurred as a subexpression /// where the result might be used. @@ -277,9 +270,7 @@ impl BlockContext { match bf { BlockFrame::SubExpr => continue, BlockFrame::Statement { .. } => break, - &BlockFrame::TailExpr { tail_result_is_ignored, span } => { - return Some(BlockTailInfo { tail_result_is_ignored, span }); - } + &BlockFrame::TailExpr { info } => return Some(info), } } @@ -302,9 +293,9 @@ impl BlockContext { // otherwise: use accumulated is_ignored state. Some( - BlockFrame::TailExpr { tail_result_is_ignored: ignored, .. } - | BlockFrame::Statement { ignores_expr_result: ignored }, - ) => *ignored, + BlockFrame::TailExpr { info: BlockTailInfo { tail_result_is_ignored: ign, .. } } + | BlockFrame::Statement { ignores_expr_result: ign }, + ) => *ign, } } } @@ -465,11 +456,10 @@ fn construct_fn<'tcx>( assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body = tcx.hir().body_owned_by(fn_def); + let body = 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) + .hir_fn_decl_by_hir_id(fn_id) .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def)) .output .span(); @@ -588,6 +578,7 @@ fn construct_const<'a, 'tcx>( let span = tcx.def_span(def); (span, span) } + Node::Item(hir::Item { kind: hir::ItemKind::GlobalAsm { .. }, span, .. }) => (*span, *span), _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), }; @@ -758,7 +749,7 @@ 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), + tcx.hir_body_owner_kind(def), hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) ); @@ -968,7 +959,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } => { self.local_decls[local].mutability = mutability; self.local_decls[local].source_info.scope = self.source_scope; - **self.local_decls[local].local_info.as_mut().assert_crate_local() = + **self.local_decls[local].local_info.as_mut().unwrap_crate_local() = if let Some(kind) = param.self_kind { LocalInfo::User(BindingForm::ImplicitSelf(kind)) } else { @@ -1033,7 +1024,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let parent_id = self.source_scopes[original_source_scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; self.maybe_new_source_scope(pattern_span, arg_hir_id, parent_id); } diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index d3551ea3a97b4..8156123949121 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -604,7 +604,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_scope = self.source_scope; if let LintLevel::Explicit(current_hir_id) = lint_level { let parent_id = - self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root; + self.source_scopes[source_scope].local_data.as_ref().unwrap_crate_local().lint_root; self.maybe_new_source_scope(region_scope.1.span, current_hir_id, parent_id); } self.push_scope(region_scope); @@ -992,7 +992,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { lint_root: if let LintLevel::Explicit(lint_root) = lint_level { lint_root } else { - self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root + self.source_scopes[parent].local_data.as_ref().unwrap_crate_local().lint_root }, }; self.source_scopes.push(SourceScopeData { diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8b6fcec3837c1..c2eafd0a74e65 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::mem; use std::ops::Bound; +use rustc_ast::AsmMacro; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::DiagArgValue; use rustc_hir::def::DefKind; @@ -559,7 +560,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } } ExprKind::InlineAsm(box InlineAsmExpr { - asm_macro: _, + asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, ref operands, template: _, options: _, @@ -583,7 +584,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } Out { expr: None, reg: _, late: _ } | Const { value: _, span: _ } - | SymFn { value: _, span: _ } + | SymFn { value: _ } | SymStatic { def_id: _ } => {} Label { block } => { // Label blocks are safe context. @@ -751,7 +752,7 @@ impl UnsafeOpKind { span: Span, suggest_unsafe_block: bool, ) { - let parent_id = tcx.hir().get_parent_item(hir_id); + let parent_id = tcx.hir_get_parent_item(hir_id); let parent_owner = tcx.hir_owner_node(parent_id); let should_suggest = parent_owner.fn_sig().is_some_and(|sig| { // Do not suggest for safe target_feature functions @@ -921,13 +922,13 @@ impl UnsafeOpKind { hir_context: HirId, unsafe_op_in_unsafe_fn_allowed: bool, ) { - let note_non_inherited = tcx.hir().parent_iter(hir_context).find(|(id, node)| { + let note_non_inherited = tcx.hir_parent_iter(hir_context).find(|(id, node)| { if let hir::Node::Expr(block) = node && let hir::ExprKind::Block(block, _) = block.kind && let hir::BlockCheckMode::UnsafeBlock(_) = block.rules { true - } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id) + } else if let Some(sig) = tcx.hir_fn_sig_by_hir_id(*id) && matches!(sig.header.safety, hir::HeaderSafety::Normal(hir::Safety::Unsafe)) { true @@ -1145,7 +1146,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { let thir = &thir.steal(); let hir_id = tcx.local_def_id_to_hir_id(def); - let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { + let safety_context = tcx.hir_fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { match fn_sig.header.safety { // We typeck the body as safe, but otherwise treat it as unsafe everywhere else. // Call sites to other SafeTargetFeatures functions are checked explicitly and don't need diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 54da6924db444..88877d05ffadf 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -429,9 +429,7 @@ impl<'tcx> ThirBuildCx<'tcx> { let user_provided_types = self.typeck_results.user_provided_types(); let user_ty = user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| { - if let ty::UserTypeKind::TypeOf(ref mut did, _) = - &mut u_ty.value.kind - { + if let ty::UserTypeKind::TypeOf(did, _) = &mut u_ty.value.kind { *did = adt_def.did(); } Box::new(u_ty) @@ -739,13 +737,8 @@ impl<'tcx> ThirBuildCx<'tcx> { InlineAsmOperand::Const { value, span } } - hir::InlineAsmOperand::SymFn { ref anon_const } => { - let value = - mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id()) - .instantiate_identity(); - let span = tcx.def_span(anon_const.def_id); - - InlineAsmOperand::SymFn { value, span } + hir::InlineAsmOperand::SymFn { expr } => { + InlineAsmOperand::SymFn { value: self.mirror_expr(expr) } } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { InlineAsmOperand::SymStatic { def_id } @@ -828,7 +821,6 @@ impl<'tcx> ThirBuildCx<'tcx> { }, hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match { scrutinee: self.mirror_expr(discr), - scrutinee_hir_id: discr.hir_id, arms: arms.iter().map(|a| self.convert_arm(a)).collect(), match_source, }, diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index a01609012b8f1..2e069cae4269f 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -22,8 +22,7 @@ pub(crate) fn thir_body( tcx: TyCtxt<'_>, owner_def: LocalDefId, ) -> Result<(&Steal>, ExprId), ErrorGuaranteed> { - let hir = tcx.hir(); - let body = hir.body_owned_by(owner_def); + let body = tcx.hir_body_owned_by(owner_def); let mut cx = ThirBuildCx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); @@ -31,7 +30,7 @@ pub(crate) fn thir_body( let expr = cx.mirror_expr(body.value); let owner_id = tcx.local_def_id_to_hir_id(owner_def); - if let Some(fn_decl) = hir.fn_decl_by_hir_id(owner_id) { + if let Some(fn_decl) = tcx.hir_fn_decl_by_hir_id(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(); @@ -77,23 +76,29 @@ impl<'tcx> ThirBuildCx<'tcx> { let hir = tcx.hir(); let hir_id = tcx.local_def_id_to_hir_id(def); - 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]) - } else { - // Get the revealed type of this const. This is *not* the adjusted - // type of its body, which may be a subtype of this type. For - // example: - // - // fn foo(_: &()) {} - // static X: fn(&'static ()) = foo; - // - // The adjusted type of the body of X is `for<'a> fn(&'a ())` which - // is not the same as the type of X. We need the type of the return - // place to be the type of the constant because NLL typeck will - // equate them. - BodyTy::Const(typeck_results.node_type(hir_id)) + let body_type = match tcx.hir_body_owner_kind(def) { + rustc_hir::BodyOwnerKind::Fn | rustc_hir::BodyOwnerKind::Closure => { + // fetch the fully liberated fn signature (that is, all bound + // types/lifetimes replaced) + BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) + } + rustc_hir::BodyOwnerKind::Const { .. } | rustc_hir::BodyOwnerKind::Static(_) => { + // Get the revealed type of this const. This is *not* the adjusted + // type of its body, which may be a subtype of this type. For + // example: + // + // fn foo(_: &()) {} + // static X: fn(&'static ()) = foo; + // + // The adjusted type of the body of X is `for<'a> fn(&'a ())` which + // is not the same as the type of X. We need the type of the return + // place to be the type of the constant because NLL typeck will + // equate them. + BodyTy::Const(typeck_results.node_type(hir_id)) + } + rustc_hir::BodyOwnerKind::GlobalAsm => { + BodyTy::GlobalAsm(typeck_results.node_type(hir_id)) + } }; Self { @@ -160,12 +165,12 @@ impl<'tcx> ThirBuildCx<'tcx> { }) } - fn explicit_params<'a>( - &'a mut self, + fn explicit_params( + &mut self, owner_id: HirId, fn_decl: &'tcx hir::FnDecl<'tcx>, body: &'tcx hir::Body<'tcx>, - ) -> impl Iterator> + 'a { + ) -> impl Iterator> { let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id]; body.params.iter().enumerate().map(move |(index, param)| { 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 1e7388010115f..d60ae6484afb2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -151,7 +151,7 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> { } return; } - ExprKind::Match { scrutinee, scrutinee_hir_id: _, box ref arms, match_source } => { + ExprKind::Match { scrutinee, box ref arms, match_source } => { self.check_match(scrutinee, arms, match_source, ex.span); } ExprKind::Let { box ref pat, expr } => { @@ -1041,7 +1041,7 @@ fn find_fallback_pattern_typo<'tcx>( let mut imported = vec![]; let mut imported_spans = vec![]; let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env); - let parent = cx.tcx.hir().get_parent_item(hir_id); + let parent = cx.tcx.hir_get_parent_item(hir_id); for item in cx.tcx.hir_crate_items(()).free_items() { if let DefKind::Use = cx.tcx.def_kind(item.owner_id) { @@ -1097,7 +1097,7 @@ fn find_fallback_pattern_typo<'tcx>( } } if let Some((i, &const_name)) = - accessible.iter().enumerate().find(|(_, &const_name)| const_name == name) + accessible.iter().enumerate().find(|&(_, &const_name)| const_name == name) { // The pattern name is an exact match, so the pattern needed to be imported. lint.wanted_constant = Some(WantedConstant { @@ -1115,7 +1115,7 @@ fn find_fallback_pattern_typo<'tcx>( const_path: name.to_string(), }); } else if let Some(i) = - imported.iter().enumerate().find(|(_, &const_name)| const_name == name).map(|(i, _)| i) + imported.iter().enumerate().find(|&(_, &const_name)| const_name == name).map(|(i, _)| i) { // The const with the exact name wasn't re-exported from an import in this // crate, we point at the import. @@ -1137,7 +1137,7 @@ fn find_fallback_pattern_typo<'tcx>( } else { // Look for local bindings for people that might have gotten confused with how // `let` and `const` works. - for (_, node) in cx.tcx.hir().parent_iter(hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(hir_id) { match node { hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Let(let_stmt), .. }) => { if let hir::PatKind::Binding(_, _, binding_name, _) = let_stmt.pat.kind { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 551ec5cf4e9c6..667d59d858e3a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -148,7 +148,7 @@ impl<'tcx> ConstToPat<'tcx> { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Param(param_ty) = ty.kind() { - let def_id = self.tcx.hir().enclosing_body_owner(self.id); + let def_id = self.tcx.hir_enclosing_body_owner(self.id); let generics = self.tcx.generics_of(def_id); let param = generics.type_param(*param_ty, self.tcx); let span = self.tcx.def_span(param.def_id); diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index 9ab87dd99ffc0..cd56d93afcf75 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -921,10 +921,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); print_indented!(self, "}", depth_lvl + 1); } - InlineAsmOperand::SymFn { value, span } => { + InlineAsmOperand::SymFn { value } => { print_indented!(self, "InlineAsmOperand::SymFn {", depth_lvl); - print_indented!(self, format!("value: {:?}", *value), depth_lvl + 1); - print_indented!(self, format!("span: {:?}", span), depth_lvl + 1); + print_indented!(self, "value: ", depth_lvl + 1); + self.print_expr(*value, depth_lvl + 2); print_indented!(self, "}", depth_lvl + 1); } InlineAsmOperand::SymStatic { def_id } => { diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 4dff093afd0d9..60a47a94e3a1f 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -16,7 +16,7 @@ pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>( let ty = typeck_results.node_type(hir_id); match ty.kind() { ty::Adt(adt_def, ..) => { - if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind { + if let ty::UserTypeKind::TypeOf(did, _) = &mut user_ty.value.kind { *did = adt_def.did(); } Some(user_ty) diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index f84a06638976e..293bcbef21b85 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_dataflow" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 07517d7edab01..3d7f9e2d8e71b 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,9 +1,11 @@ use std::ops::RangeInclusive; -use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges}; +use rustc_middle::mir::{ + self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, +}; use super::visitor::ResultsVisitor; -use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget}; +use super::{Analysis, Effect, EffectIndex, Results}; pub trait Direction { const IS_FORWARD: bool; @@ -112,14 +114,10 @@ impl Direction for Backward { mir::TerminatorKind::SwitchInt { targets: _, ref discr } => { if let Some(mut data) = analysis.get_switch_int_data(block, discr) { - let values = &body.basic_blocks.switch_sources()[&(block, pred)]; - let targets = - values.iter().map(|&value| SwitchIntTarget { value, target: block }); - let mut tmp = analysis.bottom_value(body); - for target in targets { - tmp.clone_from(&exit_state); - analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, target); + for &value in &body.basic_blocks.switch_sources()[&(block, pred)] { + tmp.clone_from(exit_state); + analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value); propagate(pred, &tmp); } } else { @@ -292,12 +290,9 @@ impl Direction for Forward { if let Some(mut data) = analysis.get_switch_int_data(block, discr) { let mut tmp = analysis.bottom_value(body); for (value, target) in targets.iter() { - tmp.clone_from(&exit_state); - analysis.apply_switch_int_edge_effect( - &mut data, - &mut tmp, - SwitchIntTarget { value: Some(value), target }, - ); + tmp.clone_from(exit_state); + let value = SwitchTargetValue::Normal(value); + analysis.apply_switch_int_edge_effect(&mut data, &mut tmp, value); propagate(target, &tmp); } @@ -308,7 +303,7 @@ impl Direction for Forward { analysis.apply_switch_int_edge_effect( &mut data, exit_state, - SwitchIntTarget { value: None, target: otherwise }, + SwitchTargetValue::Otherwise, ); propagate(otherwise, exit_state); } else { diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 60c5cb0cae8ad..09f6cdb5c4a72 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -38,7 +38,9 @@ use rustc_data_structures::work_queue::WorkQueue; use rustc_index::bit_set::{DenseBitSet, MixedBitSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::bug; -use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges, traversal}; +use rustc_middle::mir::{ + self, BasicBlock, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, traversal, +}; use rustc_middle::ty::TyCtxt; use tracing::error; @@ -220,7 +222,7 @@ pub trait Analysis<'tcx> { &mut self, _data: &mut Self::SwitchIntData, _state: &mut Self::Domain, - _edge: SwitchIntTarget, + _value: SwitchTargetValue, ) { unreachable!(); } @@ -430,10 +432,5 @@ impl EffectIndex { } } -pub struct SwitchIntTarget { - pub value: Option, - pub target: BasicBlock, -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 3be450a0b3f47..f5ffc42d52ab0 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -4,13 +4,14 @@ use rustc_abi::VariantIdx; use rustc_index::Idx; use rustc_index::bit_set::{DenseBitSet, MixedBitSet}; use rustc_middle::bug; -use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges}; +use rustc_middle::mir::{ + self, Body, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges, +}; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{self, TyCtxt}; use tracing::{debug, instrument}; use crate::drop_flag_effects::DropFlagState; -use crate::framework::SwitchIntTarget; use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex}; use crate::{ Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry, @@ -422,9 +423,9 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { &mut self, data: &mut Self::SwitchIntData, state: &mut Self::Domain, - edge: SwitchIntTarget, + value: SwitchTargetValue, ) { - if let Some(value) = edge.value { + if let SwitchTargetValue::Normal(value) = value { // Kill all move paths that correspond to variants we know to be inactive along this // particular outgoing edge of a `SwitchInt`. drop_flag_effects::on_all_inactive_variants( @@ -535,9 +536,9 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { &mut self, data: &mut Self::SwitchIntData, state: &mut Self::Domain, - edge: SwitchIntTarget, + value: SwitchTargetValue, ) { - if let Some(value) = edge.value { + if let SwitchTargetValue::Normal(value) = value { // Mark all move paths that correspond to variants other than this one as maybe // uninitialized (in reality, they are *definitely* uninitialized). drop_flag_effects::on_all_inactive_variants( diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index b6c259aa4e0ab..8bbc89fdcecb7 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -1,7 +1,6 @@ use std::mem; use rustc_index::IndexVec; -use rustc_middle::mir::tcx::{PlaceTy, RvalueInitializationState}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 8aea8d2ae3ca7..18985ba0da259 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -343,7 +343,7 @@ impl<'tcx> MovePathLookup<'tcx> { /// `MovePathIndex`es. pub fn iter_locals_enumerated( &self, - ) -> impl DoubleEndedIterator + '_ { + ) -> impl DoubleEndedIterator { self.locals.iter_enumerated().filter_map(|(l, &idx)| Some((l, idx?))) } } diff --git a/compiler/rustc_mir_dataflow/src/un_derefer.rs b/compiler/rustc_mir_dataflow/src/un_derefer.rs index b803ecc575ee0..b38dd9d40f521 100644 --- a/compiler/rustc_mir_dataflow/src/un_derefer.rs +++ b/compiler/rustc_mir_dataflow/src/un_derefer.rs @@ -28,7 +28,7 @@ impl<'tcx> UnDerefer<'tcx> { pub(crate) fn iter_projections( &self, place: PlaceRef<'tcx>, - ) -> impl Iterator, PlaceElem<'tcx>)> + '_ { + ) -> impl Iterator, PlaceElem<'tcx>)> { ProjectionIter::new(self.deref_chain(place.local), place) } } @@ -91,7 +91,7 @@ impl SlicePlusOne<'_, T> { #[inline] fn advance(&mut self) { match self.slice { - [_, ref remainder @ ..] => { + [_, remainder @ ..] => { self.slice = remainder; } [] => self.last = None, diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index a51af8c40fd43..36fb1c2b36d02 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -2,12 +2,10 @@ use std::fmt::{Debug, Formatter}; use std::ops::Range; use rustc_abi::{FieldIdx, VariantIdx}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxIndexSet, StdEntry}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -126,7 +124,7 @@ impl State { pub fn all_bottom(&self) -> bool { match self { State::Unreachable => false, - State::Reachable(ref values) => + State::Reachable(values) => { #[allow(rustc::potential_query_instability)] values.map.values().all(V::is_bottom) @@ -350,7 +348,7 @@ impl JoinSemiLattice for State { *self = other.clone(); true } - (State::Reachable(this), State::Reachable(ref other)) => this.join(other), + (State::Reachable(this), State::Reachable(other)) => this.join(other), } } } @@ -677,10 +675,7 @@ impl<'tcx> Map<'tcx> { } /// Iterate over all direct children. - fn children( - &self, - parent: PlaceIndex, - ) -> impl Iterator + Captures<'_> + Captures<'tcx> { + fn children(&self, parent: PlaceIndex) -> impl Iterator { Children::new(self, parent) } diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 2f233f787f0cc..fb8d0ac5e74ac 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_mir_transform" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 3affe4abbfad8..ceea72c6755a0 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -79,7 +79,7 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { let lint_root = self.body.source_scopes[source_info.scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; Some((lint_root, source_info.span, self.tcx.def_span(const_item))) diff --git a/compiler/rustc_mir_transform/src/check_inline.rs b/compiler/rustc_mir_transform/src/check_inline.rs index 497f4a660eaae..83c3cda5a5059 100644 --- a/compiler/rustc_mir_transform/src/check_inline.rs +++ b/compiler/rustc_mir_transform/src/check_inline.rs @@ -16,7 +16,7 @@ pub(super) struct CheckForceInline; impl<'tcx> MirLint<'tcx> for CheckForceInline { fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let def_id = body.source.def_id(); - if !tcx.hir().body_owner_kind(def_id).is_fn_or_closure() || !def_id.is_local() { + if !tcx.hir_body_owner_kind(def_id).is_fn_or_closure() || !def_id.is_local() { return; } let InlineAttr::Force { attr_span, .. } = tcx.codegen_fn_attrs(def_id).inline else { diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index afc49c5cc54af..04d96f117072f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -393,12 +393,13 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove StorageLive and StorageDead statements for remapped locals - data.retain_statements(|s| match s.kind { - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { - !self.remap.contains(l) + for s in &mut data.statements { + if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = s.kind + && self.remap.contains(l) + { + s.make_nop(); } - _ => true, - }); + } let ret_val = match data.terminator().kind { TerminatorKind::Return => { @@ -944,7 +945,7 @@ fn compute_layout<'tcx>( let decl = &body.local_decls[local]; debug!(?decl); - // Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared + // Do not `unwrap_crate_local` here, as post-borrowck cleanup may have already cleared // the information. This is alright, since `ignore_for_traits` is only relevant when // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer // default. diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 6d84248ddfbdd..09384defea86f 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -2,7 +2,6 @@ use std::cmp::Ordering; use std::ops::{Index, IndexMut}; use std::{mem, slice}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::graph::{self, DirectedGraph, StartNode}; @@ -218,7 +217,7 @@ impl CoverageGraph { pub(crate) fn reloop_predecessors( &self, to_bcb: BasicCoverageBlock, - ) -> impl Iterator + Captures<'_> { + ) -> impl Iterator { self.predecessors[to_bcb].iter().copied().filter(move |&pred| self.dominates(to_bcb, pred)) } } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 264995efe8fa7..1ccae0fd7fe95 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -346,35 +346,37 @@ fn extract_hole_spans_from_hir<'tcx>( body_span: Span, // Usually `hir_body.value.span`, but not always hir_body: &hir::Body<'tcx>, ) -> Vec { - struct HolesVisitor<'hir, F> { - tcx: TyCtxt<'hir>, - visit_hole_span: F, + struct HolesVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + body_span: Span, + hole_spans: Vec, } - impl<'hir, F: FnMut(Span)> Visitor<'hir> for HolesVisitor<'hir, F> { - /// - We need `NestedFilter::INTRA = true` so that `visit_item` will be called. - /// - Bodies of nested items don't actually get visited, because of the - /// `visit_item` override. - /// - For nested bodies that are not part of an item, we do want to visit any - /// items contained within them. - type NestedFilter = nested_filter::All; + impl<'tcx> Visitor<'tcx> for HolesVisitor<'tcx> { + /// We have special handling for nested items, but we still want to + /// traverse into nested bodies of things that are not considered items, + /// such as "anon consts" (e.g. array lengths). + type NestedFilter = nested_filter::OnlyBodies; - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { + fn maybe_tcx(&mut self) -> TyCtxt<'tcx> { self.tcx } - fn visit_item(&mut self, item: &'hir hir::Item<'hir>) { - (self.visit_hole_span)(item.span); + /// We override `visit_nested_item` instead of `visit_item` because we + /// only need the item's span, not the item itself. + fn visit_nested_item(&mut self, id: hir::ItemId) -> Self::Result { + let span = self.tcx.def_span(id.owner_id.def_id); + self.visit_hole_span(span); // Having visited this item, we don't care about its children, // so don't call `walk_item`. } // We override `visit_expr` instead of the more specific expression // visitors, so that we have direct access to the expression span. - fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) { + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { match expr.kind { hir::ExprKind::Closure(_) | hir::ExprKind::ConstBlock(_) => { - (self.visit_hole_span)(expr.span); + self.visit_hole_span(expr.span); // Having visited this expression, we don't care about its // children, so don't call `walk_expr`. } @@ -384,18 +386,17 @@ fn extract_hole_spans_from_hir<'tcx>( } } } - - let mut hole_spans = vec![]; - let mut visitor = HolesVisitor { - tcx, - visit_hole_span: |hole_span| { + impl HolesVisitor<'_> { + fn visit_hole_span(&mut self, hole_span: Span) { // Discard any holes that aren't directly visible within the body span. - if body_span.contains(hole_span) && body_span.eq_ctxt(hole_span) { - hole_spans.push(hole_span); + if self.body_span.contains(hole_span) && self.body_span.eq_ctxt(hole_span) { + self.hole_spans.push(hole_span); } - }, - }; + } + } + + let mut visitor = HolesVisitor { tcx, body_span, hole_spans: vec![] }; visitor.visit_body(hir_body); - hole_spans + visitor.hole_spans } diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index ef86358b2057a..58461be01f175 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -1,4 +1,3 @@ -use rustc_data_structures::captures::Captures; use rustc_index::bit_set::DenseBitSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::coverage::{BasicCoverageBlock, CoverageIdsInfo, CoverageKind, MappingKind}; @@ -153,7 +152,7 @@ fn coverage_ids_info<'tcx>( fn all_coverage_in_mir_body<'a, 'tcx>( body: &'a Body<'tcx>, -) -> impl Iterator + Captures<'tcx> { +) -> impl Iterator { body.basic_blocks.iter().flat_map(|bb_data| &bb_data.statements).filter_map(|statement| { match statement.kind { StatementKind::Coverage(ref kind) if !is_inlined(body, statement) => Some(kind), diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 314a86ea52f0a..b9ed6984ddb21 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,6 +1,5 @@ use std::collections::VecDeque; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir; use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span}; @@ -182,7 +181,7 @@ fn divide_spans_into_buckets(input_covspans: Vec, holes: &[Hole]) -> Ve fn drain_front_while<'a, T>( queue: &'a mut VecDeque, mut pred_fn: impl FnMut(&T) -> bool, -) -> impl Iterator + Captures<'a> { +) -> impl Iterator { std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None }) } diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index 2de55e38052e3..0d8cf524661c8 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -185,7 +185,7 @@ where place.ty(self.elaborator.body(), self.tcx()).ty } else { // We don't have a slice with all the locals, since some are in the patch. - tcx::PlaceTy::from_ty(self.elaborator.patch_ref().local_ty(place.local)) + PlaceTy::from_ty(self.elaborator.patch_ref().local_ty(place.local)) .multi_projection_ty(self.elaborator.tcx(), place.projection) .ty } @@ -266,8 +266,21 @@ where let tcx = self.tcx(); assert_eq!(self.elaborator.typing_env().typing_mode, ty::TypingMode::PostAnalysis); - let field_ty = - tcx.normalize_erasing_regions(self.elaborator.typing_env(), f.ty(tcx, args)); + // The type error for normalization may have been in dropck: see + // `compute_drop_data` in rustc_borrowck, in which case we wouldn't have + // deleted the MIR body and could have an error here as well. + let field_ty = match tcx + .try_normalize_erasing_regions(self.elaborator.typing_env(), f.ty(tcx, args)) + { + Ok(t) => t, + Err(_) => Ty::new_error( + self.tcx(), + self.elaborator + .body() + .tainted_by_errors + .expect("Error in drop elaboration not found by dropck."), + ), + }; (tcx.mk_place_field(base_place, field, field_ty), subpath) }) diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index ab6aafab446bb..530c72ca549a6 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { .. } = data.terminator().kind { - assert!(!self.patch.is_patched(bb)); + assert!(!self.patch.is_term_patched(bb)); let loc = Location { block: tgt, statement_index: 0 }; let path = self.move_data().rev_lookup.find(destination.as_ref()); @@ -462,7 +462,7 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { // a Goto; see `MirPatch::new`). } _ => { - assert!(!self.patch.is_patched(bb)); + assert!(!self.patch.is_term_patched(bb)); } } } @@ -486,7 +486,7 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> { .. } = data.terminator().kind { - assert!(!self.patch.is_patched(bb)); + assert!(!self.patch.is_term_patched(bb)); let loc = Location { block: bb, statement_index: data.statements.len() }; let path = self.move_data().rev_lookup.find(destination.as_ref()); diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 9a6a153c7ba95..7b3553e7afd06 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -85,7 +85,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let lint_root = body.source_scopes[terminator.source_info.scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; let span = terminator.source_info.span; @@ -113,7 +113,7 @@ fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option FunctionItemRefChecker<'_, 'tcx> { let lint_root = self.body.source_scopes[source_info.scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; // FIXME: use existing printing routines to print the function signature let fn_sig = self.tcx.fn_sig(fn_id).instantiate(self.tcx, fn_args); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 77a3854ebdef3..2f8a305019999 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1558,8 +1558,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return true; }; + if layout.uninhabited { + return true; + } + match layout.backend_repr { - BackendRepr::Uninhabited => true, BackendRepr::Scalar(a) => !a.is_always_valid(&self.ecx), BackendRepr::ScalarPair(a, b) => { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 1f8392b211870..5981b5031c649 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -463,7 +463,7 @@ fn inline<'tcx, T: Inliner<'tcx>>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> b let def_id = body.source.def_id(); // Only do inlining into fn bodies. - if !tcx.hir().body_owner_kind(def_id).is_fn_or_closure() { + if !tcx.hir_body_owner_kind(def_id).is_fn_or_closure() { return false; } diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 3dc4edaaa5ae4..da346dfc48c1d 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -36,7 +36,7 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify { typing_env: body.typing_env(tcx), }; let preserve_ub_checks = - attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_preserve_ub_checks); + attr::contains_name(tcx.hir_krate_attrs(), sym::rustc_preserve_ub_checks); for block in body.basic_blocks.as_mut() { for statement in block.statements.iter_mut() { match statement.kind { diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 17084eca6e388..0a72a9d669fe6 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -172,11 +172,11 @@ impl HasBottom for ConditionSet<'_> { } impl<'a> ConditionSet<'a> { - fn iter(self) -> impl Iterator + 'a { + fn iter(self) -> impl Iterator { self.0.iter().copied() } - fn iter_matches(self, value: ScalarInt) -> impl Iterator + 'a { + fn iter_matches(self, value: ScalarInt) -> impl Iterator { self.iter().filter(move |c| c.matches(value)) } @@ -467,7 +467,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> { state.insert_place_idx(rhs, lhs, &self.map); } // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`. - Rvalue::Aggregate(box ref kind, ref operands) => { + Rvalue::Aggregate(box kind, operands) => { let agg_ty = lhs_place.ty(self.body, self.tcx).ty; let lhs = match kind { // Do not support unions. diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 59de6ca84a71b..f8db8de4e82c9 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -509,7 +509,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // other overflow checks. AssertKind::Overflow(*bin_op, eval_to_int(op1), eval_to_int(op2)) } - AssertKind::BoundsCheck { ref len, ref index } => { + AssertKind::BoundsCheck { len, index } => { let len = eval_to_int(len); let index = eval_to_int(index); AssertKind::BoundsCheck { len, index } @@ -782,10 +782,10 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { self.super_terminator(terminator, location); match &terminator.kind { - TerminatorKind::Assert { expected, ref msg, ref cond, .. } => { + TerminatorKind::Assert { expected, msg, cond, .. } => { self.check_assertion(*expected, msg, cond, location); } - TerminatorKind::SwitchInt { ref discr, ref targets } => { + TerminatorKind::SwitchInt { discr, targets } => { if let Some(ref value) = self.eval_operand(discr) && let Some(value_const) = self.use_ecx(|this| this.ecx.read_scalar(value)) && let Some(constant) = value_const.to_bits(value_const.size()).discard_err() diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 1e546bfbeb303..47cb478fe33ee 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -6,6 +6,8 @@ use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_session::Session; +use crate::patch::MirPatch; + /// A pass that seeks to optimize unnecessary moves of large enum types, if there is a large /// enough discrepancy between them. /// @@ -41,31 +43,34 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { let mut alloc_cache = FxHashMap::default(); let typing_env = body.typing_env(tcx); - let blocks = body.basic_blocks.as_mut(); - let local_decls = &mut body.local_decls; + let mut patch = MirPatch::new(body); - for bb in blocks { - bb.expand_statements(|st| { + for (block, data) in body.basic_blocks.as_mut().iter_enumerated_mut() { + for (statement_index, st) in data.statements.iter_mut().enumerate() { let StatementKind::Assign(box ( lhs, Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)), )) = &st.kind else { - return None; + continue; }; - let ty = lhs.ty(local_decls, tcx).ty; + let location = Location { block, statement_index }; - let (adt_def, num_variants, alloc_id) = - self.candidate(tcx, typing_env, ty, &mut alloc_cache)?; + let ty = lhs.ty(&body.local_decls, tcx).ty; - let source_info = st.source_info; - let span = source_info.span; + let Some((adt_def, num_variants, alloc_id)) = + self.candidate(tcx, typing_env, ty, &mut alloc_cache) + else { + continue; + }; + + let span = st.source_info.span; let tmp_ty = Ty::new_array(tcx, tcx.types.usize, num_variants as u64); - let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span)); - let store_live = - Statement { source_info, kind: StatementKind::StorageLive(size_array_local) }; + let size_array_local = patch.new_temp(tmp_ty, span); + + let store_live = StatementKind::StorageLive(size_array_local); let place = Place::from(size_array_local); let constant_vals = ConstOperand { @@ -77,108 +82,63 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { ), }; let rval = Rvalue::Use(Operand::Constant(Box::new(constant_vals))); - let const_assign = - Statement { source_info, kind: StatementKind::Assign(Box::new((place, rval))) }; - - let discr_place = Place::from( - local_decls.push(LocalDecl::new(adt_def.repr().discr_type().to_ty(tcx), span)), - ); - let store_discr = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - discr_place, - Rvalue::Discriminant(*rhs), - ))), - }; - - let discr_cast_place = - Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); - let cast_discr = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - discr_cast_place, - Rvalue::Cast( - CastKind::IntToInt, - Operand::Copy(discr_place), - tcx.types.usize, - ), - ))), - }; - - let size_place = - Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span))); - let store_size = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - size_place, - Rvalue::Use(Operand::Copy(Place { - local: size_array_local, - projection: tcx - .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]), - })), - ))), - }; - - let dst = - Place::from(local_decls.push(LocalDecl::new(Ty::new_mut_ptr(tcx, ty), span))); - let dst_ptr = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - dst, - Rvalue::RawPtr(RawPtrKind::Mut, *lhs), - ))), - }; + let const_assign = StatementKind::Assign(Box::new((place, rval))); + + let discr_place = + Place::from(patch.new_temp(adt_def.repr().discr_type().to_ty(tcx), span)); + let store_discr = + StatementKind::Assign(Box::new((discr_place, Rvalue::Discriminant(*rhs)))); + + let discr_cast_place = Place::from(patch.new_temp(tcx.types.usize, span)); + let cast_discr = StatementKind::Assign(Box::new(( + discr_cast_place, + Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr_place), tcx.types.usize), + ))); + + let size_place = Place::from(patch.new_temp(tcx.types.usize, span)); + let store_size = StatementKind::Assign(Box::new(( + size_place, + Rvalue::Use(Operand::Copy(Place { + local: size_array_local, + projection: tcx.mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]), + })), + ))); + + let dst = Place::from(patch.new_temp(Ty::new_mut_ptr(tcx, ty), span)); + let dst_ptr = + StatementKind::Assign(Box::new((dst, Rvalue::RawPtr(RawPtrKind::Mut, *lhs)))); let dst_cast_ty = Ty::new_mut_ptr(tcx, tcx.types.u8); - let dst_cast_place = - Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span))); - let dst_cast = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - dst_cast_place, - Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty), - ))), - }; + let dst_cast_place = Place::from(patch.new_temp(dst_cast_ty, span)); + let dst_cast = StatementKind::Assign(Box::new(( + dst_cast_place, + Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty), + ))); - let src = - Place::from(local_decls.push(LocalDecl::new(Ty::new_imm_ptr(tcx, ty), span))); - let src_ptr = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - src, - Rvalue::RawPtr(RawPtrKind::Const, *rhs), - ))), - }; + let src = Place::from(patch.new_temp(Ty::new_imm_ptr(tcx, ty), span)); + let src_ptr = + StatementKind::Assign(Box::new((src, Rvalue::RawPtr(RawPtrKind::Const, *rhs)))); let src_cast_ty = Ty::new_imm_ptr(tcx, tcx.types.u8); - let src_cast_place = - Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span))); - let src_cast = Statement { - source_info, - kind: StatementKind::Assign(Box::new(( - src_cast_place, - Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty), - ))), - }; + let src_cast_place = Place::from(patch.new_temp(src_cast_ty, span)); + let src_cast = StatementKind::Assign(Box::new(( + src_cast_place, + Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty), + ))); - let deinit_old = - Statement { source_info, kind: StatementKind::Deinit(Box::new(dst)) }; - - let copy_bytes = Statement { - source_info, - kind: StatementKind::Intrinsic(Box::new( - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { - src: Operand::Copy(src_cast_place), - dst: Operand::Copy(dst_cast_place), - count: Operand::Copy(size_place), - }), - )), - }; + let deinit_old = StatementKind::Deinit(Box::new(dst)); + + let copy_bytes = StatementKind::Intrinsic(Box::new( + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src: Operand::Copy(src_cast_place), + dst: Operand::Copy(dst_cast_place), + count: Operand::Copy(size_place), + }), + )); - let store_dead = - Statement { source_info, kind: StatementKind::StorageDead(size_array_local) }; + let store_dead = StatementKind::StorageDead(size_array_local); - let iter = [ + let stmts = [ store_live, const_assign, store_discr, @@ -191,14 +151,16 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt { deinit_old, copy_bytes, store_dead, - ] - .into_iter(); + ]; + for stmt in stmts { + patch.add_statement(location, stmt); + } st.make_nop(); - - Some(iter) - }); + } } + + patch.apply(body); } fn is_required(&self) -> bool { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 46abdcb2a8709..04c9375b83176 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -314,11 +314,11 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// MIR associated with them. fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet { // All body-owners have MIR associated with them. - let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect(); + let mut set: FxIndexSet<_> = tcx.hir_body_owners().collect(); // Coroutine-closures (e.g. async closures) have an additional by-move MIR // body that isn't in the HIR. - for body_owner in tcx.hir().body_owners() { + for body_owner in tcx.hir_body_owners() { if let DefKind::Closure = tcx.def_kind(body_owner) && tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id()) { @@ -470,7 +470,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { } let body = tcx.mir_drops_elaborated_and_const_checked(def); - let body = match tcx.hir().body_const_context(def) { + let body = match tcx.hir_body_const_context(def) { // consts and statics do not have `optimized_mir`, so we can steal the body instead of // cloning it. Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => body.steal(), @@ -729,7 +729,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { return shim::build_adt_ctor(tcx, did.to_def_id()); } - match tcx.hir().body_const_context(did) { + match tcx.hir_body_const_context(did) { // Run the `mir_for_ctfe` query, which depends on `mir_drops_elaborated_and_const_checked` // which we are going to steal below. Thus we need to run `mir_for_ctfe` first, so it // computes and caches its result. diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 50d10883d2cad..e3260e45bc524 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -186,7 +186,7 @@ fn true_significant_drop_ty<'tcx>( debug!(?name_str); match name_str[..] { // These are the types from Rust core ecosystem - ["sym" | "proc_macro2", ..] + ["syn" | "proc_macro2", ..] | ["core" | "std", "task", "LocalWaker" | "Waker"] | ["core" | "std", "task", "wake", "LocalWaker" | "Waker"] => Some(smallvec![]), // These are important types from Rust ecosystem diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs index f5c57418467a1..9fd8d81d64a26 100644 --- a/compiler/rustc_mir_transform/src/mentioned_items.rs +++ b/compiler/rustc_mir_transform/src/mentioned_items.rs @@ -51,7 +51,7 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> { let ty = place.ty(self.body, self.tcx).ty; self.mentioned_items.push(Spanned { node: MentionedItem::Drop(ty), span: span() }); } - mir::TerminatorKind::InlineAsm { ref operands, .. } => { + mir::TerminatorKind::InlineAsm { operands, .. } => { for op in operands { match *op { mir::InlineAsmOperand::SymFn { ref value } => { diff --git a/compiler/rustc_mir_transform/src/patch.rs b/compiler/rustc_mir_transform/src/patch.rs index b4f6fa514a487..6a177faeac81f 100644 --- a/compiler/rustc_mir_transform/src/patch.rs +++ b/compiler/rustc_mir_transform/src/patch.rs @@ -4,11 +4,12 @@ use rustc_middle::ty::Ty; use rustc_span::Span; use tracing::debug; -/// This struct represents a patch to MIR, which can add -/// new statements and basic blocks and patch over block -/// terminators. +/// This struct lets you "patch" a MIR body, i.e. modify it. You can queue up +/// various changes, such as the addition of new statements and basic blocks +/// and replacement of terminators, and then apply the queued changes all at +/// once with `apply`. This is useful for MIR transformation passes. pub(crate) struct MirPatch<'tcx> { - patch_map: IndexVec>>, + term_patch_map: IndexVec>>, new_blocks: Vec>, new_statements: Vec<(Location, StatementKind<'tcx>)>, new_locals: Vec>, @@ -24,9 +25,10 @@ pub(crate) struct MirPatch<'tcx> { } impl<'tcx> MirPatch<'tcx> { + /// Creates a new, empty patch. pub(crate) fn new(body: &Body<'tcx>) -> Self { let mut result = MirPatch { - patch_map: IndexVec::from_elem(None, &body.basic_blocks), + term_patch_map: IndexVec::from_elem(None, &body.basic_blocks), new_blocks: vec![], new_statements: vec![], new_locals: vec![], @@ -141,10 +143,12 @@ impl<'tcx> MirPatch<'tcx> { bb } - pub(crate) fn is_patched(&self, bb: BasicBlock) -> bool { - self.patch_map[bb].is_some() + /// Has a replacement of this block's terminator been queued in this patch? + pub(crate) fn is_term_patched(&self, bb: BasicBlock) -> bool { + self.term_patch_map[bb].is_some() } + /// Queues the addition of a new temporary with additional local info. pub(crate) fn new_local_with_info( &mut self, ty: Ty<'tcx>, @@ -154,11 +158,12 @@ impl<'tcx> MirPatch<'tcx> { let index = self.next_local; self.next_local += 1; let mut new_decl = LocalDecl::new(ty, span); - **new_decl.local_info.as_mut().assert_crate_local() = local_info; + **new_decl.local_info.as_mut().unwrap_crate_local() = local_info; self.new_locals.push(new_decl); Local::new(index) } + /// Queues the addition of a new temporary. pub(crate) fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local { let index = self.next_local; self.next_local += 1; @@ -174,29 +179,46 @@ impl<'tcx> MirPatch<'tcx> { self.new_locals[new_local_idx].ty } + /// Queues the addition of a new basic block. pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock { - let block = BasicBlock::new(self.patch_map.len()); + let block = BasicBlock::new(self.term_patch_map.len()); debug!("MirPatch: new_block: {:?}: {:?}", block, data); self.new_blocks.push(data); - self.patch_map.push(None); + self.term_patch_map.push(None); block } + /// Queues the replacement of a block's terminator. pub(crate) fn patch_terminator(&mut self, block: BasicBlock, new: TerminatorKind<'tcx>) { - assert!(self.patch_map[block].is_none()); + assert!(self.term_patch_map[block].is_none()); debug!("MirPatch: patch_terminator({:?}, {:?})", block, new); - self.patch_map[block] = Some(new); + self.term_patch_map[block] = Some(new); } + /// Queues the insertion of a statement at a given location. The statement + /// currently at that location, and all statements that follow, are shifted + /// down. If multiple statements are queued for addition at the same + /// location, the final statement order after calling `apply` will match + /// the queue insertion order. + /// + /// E.g. if we have `s0` at location `loc` and do these calls: + /// + /// p.add_statement(loc, s1); + /// p.add_statement(loc, s2); + /// p.apply(body); + /// + /// then the final order will be `s1, s2, s0`, with `s1` at `loc`. pub(crate) fn add_statement(&mut self, loc: Location, stmt: StatementKind<'tcx>) { debug!("MirPatch: add_statement({:?}, {:?})", loc, stmt); self.new_statements.push((loc, stmt)); } + /// Like `add_statement`, but specialized for assignments. pub(crate) fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) { self.add_statement(loc, StatementKind::Assign(Box::new((place, rv)))); } + /// Applies the queued changes. pub(crate) fn apply(self, body: &mut Body<'tcx>) { debug!( "MirPatch: {:?} new temps, starting from index {}: {:?}", @@ -209,14 +231,14 @@ impl<'tcx> MirPatch<'tcx> { self.new_blocks.len(), body.basic_blocks.len() ); - let bbs = if self.patch_map.is_empty() && self.new_blocks.is_empty() { + let bbs = if self.term_patch_map.is_empty() && self.new_blocks.is_empty() { body.basic_blocks.as_mut_preserves_cfg() } else { body.basic_blocks.as_mut() }; bbs.extend(self.new_blocks); body.local_decls.extend(self.new_locals); - for (src, patch) in self.patch_map.into_iter_enumerated() { + for (src, patch) in self.term_patch_map.into_iter_enumerated() { if let Some(patch) = patch { debug!("MirPatch: patching block {:?}", src); bbs[src].terminator_mut().kind = patch; @@ -224,6 +246,9 @@ impl<'tcx> MirPatch<'tcx> { } let mut new_statements = self.new_statements; + + // This must be a stable sort to provide the ordering described in the + // comment for `add_statement`. new_statements.sort_by_key(|s| s.0); let mut delta = 0; diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 67070f03dedbd..84905f4a400f3 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -568,9 +568,9 @@ fn remove_unused_definitions_helper(used_locals: &mut UsedLocals, body: &mut Bod } StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local), - StatementKind::SetDiscriminant { ref place, .. } - | StatementKind::BackwardIncompatibleDropHint { ref place, reason: _ } - | StatementKind::Deinit(ref place) => used_locals.is_used(place.local), + StatementKind::SetDiscriminant { place, .. } + | StatementKind::BackwardIncompatibleDropHint { place, reason: _ } + | StatementKind::Deinit(place) => used_locals.is_used(place.local), StatementKind::Nop => false, _ => true, }; diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 12c3503879fb9..886f4d6e50900 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -24,7 +24,7 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition { // Simplify `assume` of a known value: either a NOP or unreachable. if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind && let NonDivergingIntrinsic::Assume(discr) = intrinsic - && let Operand::Constant(ref c) = discr + && let Operand::Constant(c) = discr && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env) { if constant { diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 21bc51ecca14e..bd00823073139 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -89,10 +89,10 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral { use Operand::*; match rhs { - Rvalue::BinaryOp(_, box (ref mut left @ Move(_), Constant(_))) => { + Rvalue::BinaryOp(_, box (left @ Move(_), Constant(_))) => { *left = Copy(opt.to_switch_on); } - Rvalue::BinaryOp(_, box (Constant(_), ref mut right @ Move(_))) => { + Rvalue::BinaryOp(_, box (Constant(_), right @ Move(_))) => { *right = Copy(opt.to_switch_on); } _ => (), diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs index c5e951eb8b2c2..02caa92ad3fc8 100644 --- a/compiler/rustc_mir_transform/src/single_use_consts.rs +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -48,9 +48,11 @@ impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts { // We're only changing an operand, not the terminator kinds or successors let basic_blocks = body.basic_blocks.as_mut_preserves_cfg(); - let init_statement = - basic_blocks[init_loc.block].statements[init_loc.statement_index].replace_nop(); - let StatementKind::Assign(place_and_rvalue) = init_statement.kind else { + let init_statement_kind = std::mem::replace( + &mut basic_blocks[init_loc.block].statements[init_loc.statement_index].kind, + StatementKind::Nop, + ); + let StatementKind::Assign(place_and_rvalue) = init_statement_kind else { bug!("No longer an assign?"); }; let (place, rvalue) = *place_and_rvalue; diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 28de99f9193d9..7c6ccc89c4f30 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -185,7 +185,7 @@ impl<'tcx> ReplacementMap<'tcx> { fn place_fragments( &self, place: Place<'tcx>, - ) -> Option, Local)> + '_> { + ) -> Option, Local)>> { let local = place.as_local()?; let fields = self.fragments[local].as_ref()?; Some(fields.iter_enumerated().filter_map(|(field, &opt_ty_local)| { diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 9f769077e77e2..3d512fb064ec4 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -138,7 +138,7 @@ impl SsaLocals { pub(super) fn assignments<'a, 'tcx>( &'a self, body: &'a Body<'tcx>, - ) -> impl Iterator, Location)> + 'a { + ) -> impl Iterator, Location)> { self.assignment_order.iter().filter_map(|&local| { if let Set1::One(DefLocation::Assignment(loc)) = self.assignments[local] { let stmt = body.stmt_at(loc).left()?; diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 5462105e5e8e4..36b76d261de68 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_monomorphize" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 463c42b69b1af..bdeab12ab503b 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -1,18 +1,40 @@ -monomorphize_abi_error_disabled_vector_type_call = - this function call uses SIMD vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled in the caller - .label = function called here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) -monomorphize_abi_error_disabled_vector_type_def = - this function definition uses SIMD vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled - .label = function defined here +monomorphize_abi_error_disabled_vector_type = + this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {" "}in the caller + *[false] {""} + } + .label = function {$is_call -> + [true] called + *[false] defined + } here .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) -monomorphize_abi_error_unsupported_vector_type_call = - this function call uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI - .label = function called here -monomorphize_abi_error_unsupported_vector_type_def = - this function definition uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI - .label = function defined here +monomorphize_abi_error_unsupported_vector_type = + this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI + .label = function {$is_call -> + [true] called + *[false] defined + } here + +monomorphize_abi_required_target_feature = + this function {$is_call -> + [true] call + *[false] definition + } uses ABI "{$abi}" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {" "}in the caller + *[false] {""} + } + .label = function {$is_call -> + [true] called + *[false] defined + } here + .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) monomorphize_couldnt_dump_mono_stats = unexpected error occurred while dumping monomorphization stats: {$error} diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 1195c25e13087..d7cb8f18f8268 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -323,7 +323,7 @@ impl<'tcx> MonoItems<'tcx> { self.items.entry(item.node).or_insert(item.span); } - fn items(&self) -> impl Iterator> + '_ { + fn items(&self) -> impl Iterator> { self.items.keys().cloned() } } @@ -479,24 +479,23 @@ fn collect_items_rec<'tcx>( recursion_depth_reset = None; let item = tcx.hir_item(item_id); - if let hir::ItemKind::GlobalAsm(asm) = item.kind { + if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind { for (op, op_sp) in asm.operands { - match op { + match *op { hir::InlineAsmOperand::Const { .. } => { // Only constants which resolve to a plain integer // are supported. Therefore the value should not // depend on any other items. } - hir::InlineAsmOperand::SymFn { anon_const } => { - let fn_ty = - tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); + hir::InlineAsmOperand::SymFn { expr } => { + let fn_ty = tcx.typeck(item_id.owner_id).expr_ty(expr); visit_fn_use(tcx, fn_ty, false, *op_sp, &mut used_items); } hir::InlineAsmOperand::SymStatic { path: _, def_id } => { - let instance = Instance::mono(tcx, *def_id); + let instance = Instance::mono(tcx, def_id); if tcx.should_codegen_locally(instance) { trace!("collecting static {:?}", def_id); - used_items.push(dummy_spanned(MonoItem::Static(*def_id))); + used_items.push(dummy_spanned(MonoItem::Static(def_id))); } } hir::InlineAsmOperand::In { .. } diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 75687a80b82ae..8dafbbca905f7 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -70,37 +70,36 @@ pub(crate) struct UnknownCguCollectionMode<'a> { } #[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type_def)] +#[diag(monomorphize_abi_error_disabled_vector_type)] #[help] -pub(crate) struct AbiErrorDisabledVectorTypeDef<'a> { +pub(crate) struct AbiErrorDisabledVectorType<'a> { #[label] pub span: Span, pub required_feature: &'a str, pub ty: Ty<'a>, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } #[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type_call)] -#[help] -pub(crate) struct AbiErrorDisabledVectorTypeCall<'a> { - #[label] - pub span: Span, - pub required_feature: &'a str, - pub ty: Ty<'a>, -} - -#[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type_def)] -pub(crate) struct AbiErrorUnsupportedVectorTypeDef<'a> { +#[diag(monomorphize_abi_error_unsupported_vector_type)] +pub(crate) struct AbiErrorUnsupportedVectorType<'a> { #[label] pub span: Span, pub ty: Ty<'a>, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } -#[derive(LintDiagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type_call)] -pub(crate) struct AbiErrorUnsupportedVectorTypeCall<'a> { +#[derive(Diagnostic)] +#[diag(monomorphize_abi_required_target_feature)] +#[help] +pub(crate) struct AbiRequiredTargetFeature<'a> { + #[primary_span] #[label] pub span: Span, - pub ty: Ty<'a>, + pub required_feature: &'a str, + pub abi: &'a str, + /// Whether this is a problem at a call site or at a declaration. + pub is_call: bool, } diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index 36cd3e00b76c8..4c8dd933317ef 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -1,19 +1,15 @@ //! This module ensures that if a function's ABI requires a particular target feature, //! that target feature is enabled both on the callee and all callers. -use rustc_abi::{BackendRepr, RegKind}; +use rustc_abi::{BackendRepr, ExternAbi, RegKind}; use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::{self, traversal}; -use rustc_middle::ty::inherent::*; use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt}; use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES; use rustc_span::def_id::DefId; -use rustc_span::{DUMMY_SP, Span, Symbol}; -use rustc_target::callconv::{FnAbi, PassMode}; +use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_target::callconv::{Conv, FnAbi, PassMode}; -use crate::errors::{ - AbiErrorDisabledVectorTypeCall, AbiErrorDisabledVectorTypeDef, - AbiErrorUnsupportedVectorTypeCall, AbiErrorUnsupportedVectorTypeDef, -}; +use crate::errors; fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { match mode { @@ -28,16 +24,21 @@ fn uses_vector_registers(mode: &PassMode, repr: &BackendRepr) -> bool { /// Checks whether a certain function ABI is compatible with the target features currently enabled /// for a certain function. -/// If not, `emit_err` is called, with `Some(feature)` if a certain feature should be enabled and -/// with `None` if no feature is known that would make the ABI compatible. +/// `is_call` indicates whether this is a call-site check or a definition-site check; +/// this is only relevant for the wording in the emitted error. fn do_check_abi<'tcx>( tcx: TyCtxt<'tcx>, abi: &FnAbi<'tcx, Ty<'tcx>>, - target_feature_def: DefId, - mut emit_err: impl FnMut(Ty<'tcx>, Option<&'static str>), + def_id: DefId, + is_call: bool, + span: impl Fn() -> Span, ) { let feature_def = tcx.sess.target.features_for_correct_vector_abi(); - let codegen_attrs = tcx.codegen_fn_attrs(target_feature_def); + let codegen_attrs = tcx.codegen_fn_attrs(def_id); + let have_feature = |feat: Symbol| { + tcx.sess.unstable_target_features.contains(&feat) + || codegen_attrs.target_features.iter().any(|x| x.name == feat) + }; for arg_abi in abi.args.iter().chain(std::iter::once(&abi.ret)) { let size = arg_abi.layout.size; if uses_vector_registers(&arg_abi.mode, &arg_abi.layout.backend_repr) { @@ -45,18 +46,46 @@ fn do_check_abi<'tcx>( let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) { Some((_, feature)) => feature, None => { - emit_err(arg_abi.layout.ty, None); + let span = span(); + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + errors::AbiErrorUnsupportedVectorType { + span, + ty: arg_abi.layout.ty, + is_call, + }, + ); continue; } }; - let feature_sym = Symbol::intern(feature); - if !tcx.sess.unstable_target_features.contains(&feature_sym) - && !codegen_attrs.target_features.iter().any(|x| x.name == feature_sym) - { - emit_err(arg_abi.layout.ty, Some(&feature)); + if !have_feature(Symbol::intern(feature)) { + // Emit error. + let span = span(); + tcx.emit_node_span_lint( + ABI_UNSUPPORTED_VECTOR_TYPES, + CRATE_HIR_ID, + span, + errors::AbiErrorDisabledVectorType { + span, + required_feature: feature, + ty: arg_abi.layout.ty, + is_call, + }, + ); } } } + // The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed. + if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) { + tcx.dcx().emit_err(errors::AbiRequiredTargetFeature { + span: span(), + required_feature: "sse2", + abi: "vectorcall", + is_call, + }); + } } /// Checks that the ABI of a given instance of a function does not contain vector-passed arguments @@ -69,24 +98,13 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { // function. return; }; - do_check_abi(tcx, abi, instance.def_id(), |ty, required_feature| { - let span = tcx.def_span(instance.def_id()); - if let Some(required_feature) = required_feature { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeDef { span, required_feature, ty }, - ); - } else { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorUnsupportedVectorTypeDef { span, ty }, - ); - } - }) + do_check_abi( + tcx, + abi, + instance.def_id(), + /*is_call*/ false, + || tcx.def_span(instance.def_id()), + ) } /// Checks that a call expression does not try to pass a vector-passed argument which requires a @@ -97,7 +115,7 @@ fn check_call_site_abi<'tcx>( span: Span, caller: InstanceKind<'tcx>, ) { - if callee.fn_sig(tcx).abi().is_rust() { + if callee.fn_sig(tcx).abi() == ExternAbi::Rust { // "Rust" ABI never passes arguments in vector registers. return; } @@ -123,23 +141,7 @@ fn check_call_site_abi<'tcx>( // ABI failed to compute; this will not get through codegen. return; }; - do_check_abi(tcx, callee_abi, caller.def_id(), |ty, required_feature| { - if let Some(required_feature) = required_feature { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorDisabledVectorTypeCall { span, required_feature, ty }, - ); - } else { - tcx.emit_node_span_lint( - ABI_UNSUPPORTED_VECTOR_TYPES, - CRATE_HIR_ID, - span, - AbiErrorUnsupportedVectorTypeCall { span, ty }, - ); - } - }); + do_check_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, || span); } fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) { diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index d826d03918e08..b1b6f10e0fe2c 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -1269,7 +1269,7 @@ fn dump_mono_items_stats<'tcx>( output_directory: &Option, crate_name: Symbol, ) -> Result<(), Box> { - let output_directory = if let Some(ref directory) = output_directory { + let output_directory = if let Some(directory) = output_directory { fs::create_dir_all(directory)?; directory } else { diff --git a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs index bce31bf0748e0..0c855508434e0 100644 --- a/compiler/rustc_monomorphize/src/partitioning/autodiff.rs +++ b/compiler/rustc_monomorphize/src/partitioning/autodiff.rs @@ -66,7 +66,7 @@ pub(crate) fn find_autodiff_source_functions<'tcx>( let mut autodiff_items: Vec = vec![]; for (item, instance) in autodiff_mono_items { let target_id = instance.def_id(); - let cg_fn_attr = tcx.codegen_fn_attrs(target_id).autodiff_item.clone(); + let cg_fn_attr = &tcx.codegen_fn_attrs(target_id).autodiff_item; let Some(target_attrs) = cg_fn_attr else { continue; }; diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 451c215566be2..63aa60f2f26b9 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -1,12 +1,11 @@ [package] name = "rustc_next_trait_solver" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start derive-where = "1.2.7" -rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } @@ -22,7 +21,6 @@ nightly = [ "dep:rustc_data_structures", "dep:rustc_macros", "dep:rustc_serialize", - "rustc_ast_ir/nightly", "rustc_index/nightly", "rustc_type_ir/nightly", ] diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 7eeed721d5a0f..9cae7f27947b4 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; -use rustc_type_ir::data_structures::HashMap; +use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack}; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::solve::{Goal, QueryInput}; @@ -389,7 +389,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { | ty::Alias(_, _) | ty::Bound(_, _) | ty::Error(_) => { - return t.super_fold_with(self); + return ensure_sufficient_stack(|| t.super_fold_with(self)); } }; diff --git a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs b/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs index d8c1dc8b4e9f3..0fc313e33b323 100644 --- a/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs +++ b/compiler/rustc_next_trait_solver/src/solve/alias_relate.rs @@ -34,7 +34,17 @@ where ) -> QueryResult { let cx = self.cx(); let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; - debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some()); + + // Check that the alias-relate goal is reasonable. Writeback for + // `coroutine_stalled_predicates` can replace alias terms with + // `{type error}` if the alias still contains infer vars, so we also + // accept alias-relate goals where one of the terms is an error. + debug_assert!( + lhs.to_alias_term().is_some() + || rhs.to_alias_term().is_some() + || lhs.is_error() + || rhs.is_error() + ); // Structurally normalize the lhs. let lhs = if let Some(alias) = lhs.to_alias_term() { diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index b0f59ed1474c2..bfb590e87679d 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -791,7 +791,7 @@ where return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Ambiguity)); }; - let responses: Vec<_> = match proven_via { + match proven_via { // Even when a trait bound has been proven using a where-bound, we // still need to consider alias-bounds for normalization, see // tests/ui/next-solver/alias-bound-shadowed-by-env.rs. @@ -800,7 +800,7 @@ where // constness checking. Doing so is *at least theoretically* breaking, // see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754 TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => { - let mut candidates_from_env: Vec<_> = candidates + let mut candidates_from_env_and_bounds: Vec<_> = candidates .iter() .filter(|c| { matches!( @@ -813,16 +813,37 @@ where // If the trait goal has been proven by using the environment, we want to treat // aliases as rigid if there are no applicable projection bounds in the environment. - if candidates_from_env.is_empty() { + if candidates_from_env_and_bounds.is_empty() { if let Ok(response) = inject_normalize_to_rigid_candidate(self) { - candidates_from_env.push(response); + candidates_from_env_and_bounds.push(response); } } - candidates_from_env + + if let Some(response) = self.try_merge_responses(&candidates_from_env_and_bounds) { + Ok(response) + } else { + self.flounder(&candidates_from_env_and_bounds) + } } - TraitGoalProvenVia::Misc => candidates.iter().map(|c| c.result).collect(), - }; + TraitGoalProvenVia::Misc => { + // Prefer "orphaned" param-env normalization predicates, which are used + // (for example, and ideally only) when proving item bounds for an impl. + let candidates_from_env: Vec<_> = candidates + .iter() + .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) + .map(|c| c.result) + .collect(); + if let Some(response) = self.try_merge_responses(&candidates_from_env) { + return Ok(response); + } - self.try_merge_responses(&responses).map_or_else(|| self.flounder(&responses), Ok) + let responses: Vec<_> = candidates.iter().map(|c| c.result).collect(); + if let Some(response) = self.try_merge_responses(&responses) { + Ok(response) + } else { + self.flounder(&responses) + } + } + } } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 082c356cc5fbd..dc0f4c4483e6f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -2,12 +2,11 @@ //! traits, `Copy`/`Clone`. use derive_where::derive_where; -use rustc_ast_ir::{Movability, Mutability}; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; -use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate}; +use rustc_type_ir::{self as ty, Interner, Movability, Mutability, Upcast as _, elaborate}; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use tracing::instrument; diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index dabfa5cc04c8d..1665dbb30189e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1,13 +1,14 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. -use rustc_ast_ir::Movability; use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::solve::CanonicalResponse; use rustc_type_ir::visit::TypeVisitableExt as _; -use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate}; +use rustc_type_ir::{ + self as ty, Interner, Movability, TraitPredicate, TypingMode, Upcast as _, elaborate, +}; use tracing::{instrument, trace}; use crate::delegate::SolverDelegate; diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 2360914a0aba1..c9dcab0c871dd 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_parse" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 72aebb5d12144..67abc2d539401 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -301,13 +301,6 @@ impl<'a> Parser<'a> { &mut self, recover: bool, ) -> PResult<'a, (Ident, IdentIsRaw)> { - if let TokenKind::DocComment(..) = self.prev_token.kind { - return Err(self.dcx().create_err(DocCommentDoesNotDocumentAnything { - span: self.prev_token.span, - missing_comma: None, - })); - } - let valid_follow = &[ TokenKind::Eq, TokenKind::Colon, @@ -319,6 +312,15 @@ impl<'a> Parser<'a> { TokenKind::CloseDelim(Delimiter::Brace), TokenKind::CloseDelim(Delimiter::Parenthesis), ]; + if let TokenKind::DocComment(..) = self.prev_token.kind + && valid_follow.contains(&self.token.kind) + { + let err = self.dcx().create_err(DocCommentDoesNotDocumentAnything { + span: self.prev_token.span, + missing_comma: None, + }); + return Err(err); + } let mut recovered_ident = None; // we take this here so that the correct original token is retained in diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e0e6c2177da54..b2e58c9428064 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3125,10 +3125,11 @@ impl<'a> Parser<'a> { let mut result = if armless { // A pattern without a body, allowed for never patterns. arm_body = None; + let span = lo.to(this.prev_token.span); this.expect_one_of(&[exp!(Comma)], &[exp!(CloseBrace)]).map(|x| { // Don't gate twice if !pat.contains_never_pattern() { - this.psess.gated_spans.gate(sym::never_patterns, pat.span); + this.psess.gated_spans.gate(sym::never_patterns, span); } x }) diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 1de452dcf3965..80a33a7600599 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -117,12 +117,15 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { ($self: expr, $allow_qpath_recovery: expr) => { if $allow_qpath_recovery && $self.may_recover() - && $self.look_ahead(1, |t| t == &token::PathSep) - && let token::Interpolated(nt) = &$self.token.kind - && let token::NtTy(ty) = &**nt + && let Some(mv_kind) = $self.token.is_metavar_seq() + && let token::MetaVarKind::Ty { .. } = mv_kind + && $self.check_noexpect_past_close_delim(&token::PathSep) { - let ty = ty.clone(); - $self.bump(); + // Reparse the type, then move to recovery. + let ty = $self + .eat_metavar_seq(mv_kind, |this| this.parse_ty_no_question_mark_recover()) + .expect("metavar seq ty"); + return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty); } }; @@ -614,6 +617,24 @@ impl<'a> Parser<'a> { self.token == *tok } + // Check the first token after the delimiter that closes the current + // delimited sequence. (Panics if used in the outermost token stream, which + // has no delimiters.) It uses a clone of the relevant tree cursor to skip + // past the entire `TokenTree::Delimited` in a single step, avoiding the + // need for unbounded token lookahead. + // + // Primarily used when `self.token` matches + // `OpenDelim(Delimiter::Invisible(_))`, to look ahead through the current + // metavar expansion. + fn check_noexpect_past_close_delim(&self, tok: &TokenKind) -> bool { + let mut tree_cursor = self.token_cursor.stack.last().unwrap().clone(); + tree_cursor.bump(); + matches!( + tree_cursor.curr(), + Some(TokenTree::Token(token::Token { kind, .. }, _)) if kind == tok + ) + } + /// Consumes a token 'tok' if it exists. Returns whether the given token was present. /// /// the main purpose of this function is to reduce the cluttering of the suggestions list @@ -721,6 +742,43 @@ impl<'a> Parser<'a> { if !self.eat_keyword(exp) { self.unexpected() } else { Ok(()) } } + /// Consume a sequence produced by a metavar expansion, if present. + fn eat_metavar_seq( + &mut self, + mv_kind: MetaVarKind, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> Option { + self.eat_metavar_seq_with_matcher(|mvk| mvk == mv_kind, f) + } + + /// A slightly more general form of `eat_metavar_seq`, for use with the + /// `MetaVarKind` variants that have parameters, where an exact match isn't + /// desired. + fn eat_metavar_seq_with_matcher( + &mut self, + match_mv_kind: impl Fn(MetaVarKind) -> bool, + mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> Option { + if let token::OpenDelim(delim) = self.token.kind + && let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim + && match_mv_kind(mv_kind) + { + self.bump(); + let res = f(self).expect("failed to reparse {mv_kind:?}"); + if let token::CloseDelim(delim) = self.token.kind + && let Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind)) = delim + && match_mv_kind(mv_kind) + { + self.bump(); + Some(res) + } else { + panic!("no close delim when reparsing {mv_kind:?}"); + } + } else { + None + } + } + /// Is the given keyword `kw` followed by a non-reserved identifier? fn is_kw_followed_by_ident(&self, kw: Symbol) -> bool { self.token.is_keyword(kw) && self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident()) @@ -1455,7 +1513,11 @@ impl<'a> Parser<'a> { /// so emit a proper diagnostic. // Public for rustfmt usage. pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { - maybe_whole!(self, NtVis, |vis| vis.into_inner()); + if let Some(vis) = self + .eat_metavar_seq(MetaVarKind::Vis, |this| this.parse_visibility(FollowedByType::Yes)) + { + return Ok(vis); + } if !self.eat_keyword(exp!(Pub)) { // We need a span for our `Spanned`, but there's inherently no @@ -1595,7 +1657,7 @@ impl<'a> Parser<'a> { // Debug view of the parser's token stream, up to `{lookahead}` tokens. // Only used when debugging. #[allow(unused)] - pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ { + pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug { fmt::from_fn(move |f| { let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of @@ -1683,7 +1745,9 @@ pub enum ParseNtResult { Tt(TokenTree), Ident(Ident, IdentIsRaw), Lifetime(Ident, IdentIsRaw), + Ty(P), + Vis(P), - /// This case will eventually be removed, along with `Token::Interpolate`. + /// This variant will eventually be removed, along with `Token::Interpolate`. Nt(Arc), } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index eefdb641da22a..f202f85752e19 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -30,7 +30,7 @@ impl<'a> Parser<'a> { MetaVarKind::Stmt | MetaVarKind::Pat(_) | MetaVarKind::Expr { .. } - | MetaVarKind::Ty + | MetaVarKind::Ty { .. } | MetaVarKind::Literal // `true`, `false` | MetaVarKind::Meta | MetaVarKind::Path => true, @@ -51,14 +51,11 @@ impl<'a> Parser<'a> { NtStmt(_) | NtPat(_) | NtExpr(_) - | NtTy(_) | NtLiteral(_) // `true`, `false` | NtMeta(_) | NtPath(_) => true, - NtItem(_) - | NtBlock(_) - | NtVis(_) => false, + NtItem(_) | NtBlock(_) => false, } } @@ -88,7 +85,7 @@ impl<'a> Parser<'a> { NonterminalKind::Ident => get_macro_ident(token).is_some(), NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), NonterminalKind::Vis => match token.kind { - // The follow-set of :vis + "priv" keyword + interpolated + // The follow-set of :vis + "priv" keyword + interpolated/metavar-expansion. token::Comma | token::Ident(..) | token::NtIdent(..) @@ -102,7 +99,7 @@ impl<'a> Parser<'a> { token::NtLifetime(..) => true, token::Interpolated(nt) => match &**nt { NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) | NtVis(_) => false, + NtItem(_) | NtPat(_) | NtMeta(_) | NtPath(_) => false, }, token::OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(k))) => match k { MetaVarKind::Block @@ -111,7 +108,7 @@ impl<'a> Parser<'a> { | MetaVarKind::Literal => true, MetaVarKind::Item | MetaVarKind::Pat(_) - | MetaVarKind::Ty + | MetaVarKind::Ty { .. } | MetaVarKind::Meta | MetaVarKind::Path | MetaVarKind::Vis => false, @@ -189,7 +186,9 @@ impl<'a> Parser<'a> { NtLiteral(self.collect_tokens_no_attrs(|this| this.parse_literal_maybe_minus())?) } NonterminalKind::Ty => { - NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?) + return Ok(ParseNtResult::Ty( + self.collect_tokens_no_attrs(|this| this.parse_ty_no_question_mark_recover())?, + )); } // this could be handled like a token, since it is one NonterminalKind::Ident => { @@ -208,8 +207,9 @@ impl<'a> Parser<'a> { } NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)), NonterminalKind::Vis => { - NtVis(P(self - .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?)) + return Ok(ParseNtResult::Vis(P(self.collect_tokens_no_attrs(|this| { + this.parse_visibility(FollowedByType::Yes) + })?))); } NonterminalKind::Lifetime => { // We want to keep `'keyword` parsing, just like `keyword` is still diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index b241aa892db92..c24305ea9a866 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -2,7 +2,7 @@ use std::mem; use ast::token::IdentIsRaw; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, MetaVarKind, Token, TokenKind}; use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint, AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, @@ -196,14 +196,12 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner())); - if let token::Interpolated(nt) = &self.token.kind { - if let token::NtTy(ty) = &**nt { - if let ast::TyKind::Path(None, path) = &ty.kind { - let path = path.clone(); - self.bump(); - return Ok(reject_generics_if_mod_style(self, path)); - } - } + // If we have a `ty` metavar in the form of a path, reparse it directly as a path, instead + // of reparsing it as a `ty` and then extracting the path. + if let Some(path) = self.eat_metavar_seq(MetaVarKind::Ty { is_path: true }, |this| { + this.parse_path(PathStyle::Type) + }) { + return Ok(reject_generics_if_mod_style(self, path)); } let lo = self.token.span; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index dc5919b3630ce..18af0a1c79aa2 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1,5 +1,5 @@ use rustc_ast::ptr::P; -use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; +use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, @@ -18,7 +18,7 @@ use crate::errors::{ HelpUseLatestEdition, InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow, }; -use crate::{exp, maybe_recover_from_interpolated_ty_qpath, maybe_whole}; +use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; /// Signals whether parsing a type should allow `+`. /// @@ -183,7 +183,8 @@ impl<'a> Parser<'a> { ) } - /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>` + /// Parse a type without recovering `:` as `->` to avoid breaking code such + /// as `where fn() : for<'a>`. pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P> { self.parse_ty_common( AllowPlus::Yes, @@ -247,7 +248,13 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P> { let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes; maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery); - maybe_whole!(self, NtTy, |ty| ty); + + if let Some(ty) = self.eat_metavar_seq_with_matcher( + |mv_kind| matches!(mv_kind, MetaVarKind::Ty { .. }), + |this| this.parse_ty_no_question_mark_recover(), + ) { + return Ok(ty); + } let lo = self.token.span; let mut impl_dyn_multi = false; diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index 707c4e318474a..a39cca716d23e 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_parse_format" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index f592a12ab75c1..ba81ef3103bd9 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_passes" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 396a0cbc88958..9a4db612cfed8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -48,7 +48,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) match impl_item.kind { hir::ImplItemKind::Const(..) => Target::AssocConst, hir::ImplItemKind::Fn(..) => { - let parent_def_id = tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent_def_id = tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let containing_item = tcx.hir().expect_item(parent_def_id); let containing_impl_is_for_trait = match &containing_item.kind { hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(), @@ -868,7 +868,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let span = meta.span(); if let Some(location) = match target { Target::AssocTy => { - let parent_def_id = self.tcx.hir().get_parent_item(hir_id).def_id; + let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; let containing_item = self.tcx.hir().expect_item(parent_def_id); if Target::from_item(containing_item) == Target::Impl { Some("type alias in implementation block") @@ -877,7 +877,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } Target::AssocConst => { - let parent_def_id = self.tcx.hir().get_parent_item(hir_id).def_id; + let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id; let containing_item = self.tcx.hir().expect_item(parent_def_id); // We can't link to trait impl's consts. let err = "associated constant in trait implementation block"; @@ -1161,7 +1161,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // insert a bang between `#` and `[...` let bang_span = attr.span.lo() + BytePos(1); let sugg = (attr.style == AttrStyle::Outer - && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID) + && self.tcx.hir_get_parent_item(hir_id) == CRATE_OWNER_ID) .then_some(errors::AttrCrateLevelOnlySugg { attr: attr.span.with_lo(bang_span).with_hi(bang_span), }); @@ -1431,37 +1431,48 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Warns against some misuses of `#[must_use]` fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) { - if !matches!( + if matches!( target, Target::Fn | Target::Enum | Target::Struct | Target::Union - | Target::Method(_) + | Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent) | Target::ForeignFn // `impl Trait` in return position can trip // `unused_must_use` if `Trait` is marked as // `#[must_use]` | Target::Trait ) { - let article = match target { - Target::ExternCrate - | Target::Enum - | Target::Impl - | Target::Expression - | Target::Arm - | Target::AssocConst - | Target::AssocTy => "an", - _ => "a", - }; + return; + } - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseNoEffect { article, target }, - ); + // `#[must_use]` can be applied to a trait method definition with a default body + if let Target::Method(MethodKind::Trait { body: true }) = target + && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id + && let containing_item = self.tcx.hir().expect_item(parent_def_id) + && let hir::ItemKind::Trait(..) = containing_item.kind + { + return; } + + let article = match target { + Target::ExternCrate + | Target::Enum + | Target::Impl + | Target::Expression + | Target::Arm + | Target::AssocConst + | Target::AssocTy => "an", + _ => "a", + }; + + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::MustUseNoEffect { article, target }, + ); } /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait. @@ -2461,7 +2472,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) { let mut diag = tcx.dcx().create_err(errors::ProcMacroBadSig { span, kind }); - let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id); + let hir_sig = tcx.hir_fn_sig_by_hir_id(hir_id); if let Some(hir_sig) = hir_sig { #[allow(rustc::diagnostic_outside_of_impl)] // FIXME match terr { @@ -2569,7 +2580,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .. }) ); - let parent_did = self.tcx.hir().get_parent_item(hir_id).to_def_id(); + let parent_did = self.tcx.hir_get_parent_item(hir_id).to_def_id(); let parent_span = self.tcx.def_span(parent_did); let parent_force_inline_attr = self.tcx.get_attr(parent_did, sym::rustc_force_inline); @@ -2791,10 +2802,10 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let check_attr_visitor = &mut CheckAttrVisitor { tcx, abort: Cell::new(false) }; - tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor); + tcx.hir_visit_item_likes_in_module(module_def_id, check_attr_visitor); if module_def_id.to_local_def_id().is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); - check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); + check_invalid_crate_level_attr(tcx, tcx.hir_krate_attrs()); } if check_attr_visitor.abort.get() { tcx.dcx().abort_if_errors() diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 696cc79bfeb65..7a14a7a5db299 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -184,7 +184,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { rhs: &'tcx hir::Expr<'tcx>, ) -> bool { match (&lhs.kind, &rhs.kind) { - (hir::ExprKind::Path(ref qpath_l), hir::ExprKind::Path(ref qpath_r)) => { + (hir::ExprKind::Path(qpath_l), hir::ExprKind::Path(qpath_r)) => { if let (Res::Local(id_l), Res::Local(id_r)) = ( typeck_results.qpath_res(qpath_l, lhs.hir_id), typeck_results.qpath_res(qpath_r, rhs.hir_id), @@ -358,7 +358,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let Some(local_impl_of) = impl_of.as_local() && let Some(local_def_id) = def_id.as_local() && let Some(fn_sig) = - self.tcx.hir().fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) + self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id)) && matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None) && let TyKind::Path(hir::QPath::Resolved(_, path)) = self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind @@ -779,7 +779,7 @@ fn check_item<'tcx>( // check the function may construct Self let mut may_construct_self = false; if let Some(fn_sig) = - tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) + tcx.hir_fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) { may_construct_self = matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None); diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs index 43f2f892e77dd..509c2f5477524 100644 --- a/compiler/rustc_passes/src/hir_id_validator.rs +++ b/compiler/rustc_passes/src/hir_id_validator.rs @@ -9,11 +9,11 @@ use rustc_middle::ty::TyCtxt; pub fn check_crate(tcx: TyCtxt<'_>) { let errors = Lock::new(Vec::new()); - tcx.hir().par_for_each_module(|module_id| { + tcx.par_hir_for_each_module(|module_id| { let mut v = HirIdValidator { tcx, owner: None, hir_ids_seen: Default::default(), errors: &errors }; - tcx.hir().visit_item_likes_in_module(module_id, &mut v); + tcx.hir_visit_item_likes_in_module(module_id, &mut v); }); let errors = errors.into_inner(); diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index e60dcc807c963..92ea49f18e5d1 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -63,8 +63,8 @@ struct StatCollector<'k> { pub fn print_hir_stats(tcx: TyCtxt<'_>) { let mut collector = StatCollector { tcx: Some(tcx), nodes: FxHashMap::default(), seen: FxHashSet::default() }; - tcx.hir().walk_toplevel_module(&mut collector); - tcx.hir().walk_attributes(&mut collector); + tcx.hir_walk_toplevel_module(&mut collector); + tcx.hir_walk_attributes(&mut collector); collector.print("HIR STATS", "hir-stats"); } diff --git a/compiler/rustc_passes/src/lib_features.rs b/compiler/rustc_passes/src/lib_features.rs index 09d59e1f7172c..e123fbac1bee6 100644 --- a/compiler/rustc_passes/src/lib_features.rs +++ b/compiler/rustc_passes/src/lib_features.rs @@ -148,7 +148,7 @@ fn lib_features(tcx: TyCtxt<'_>, LocalCrate: LocalCrate) -> LibFeatures { } let mut collector = LibFeatureCollector::new(tcx); - tcx.hir().walk_attributes(&mut collector); + tcx.hir_walk_attributes(&mut collector); collector.lib_features } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 60f7616a5fbad..24dc018c66124 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -152,8 +152,8 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { } let mut maps = IrMaps::new(tcx); - let body = tcx.hir().body_owned_by(def_id); - let hir_id = tcx.hir().body_owner(body.id()); + let body = tcx.hir_body_owned_by(def_id); + let hir_id = tcx.hir_body_owner(body.id()); if let Some(upvars) = tcx.upvars_mentioned(def_id) { for &var_hir_id in upvars.keys() { @@ -1522,8 +1522,7 @@ impl<'tcx> Liveness<'_, 'tcx> { } fn warn_about_unused_args(&self, body: &hir::Body<'_>, entry_ln: LiveNode) { - if let Some(intrinsic) = - self.ir.tcx.intrinsic(self.ir.tcx.hir().body_owner_def_id(body.id())) + if let Some(intrinsic) = self.ir.tcx.intrinsic(self.ir.tcx.hir_body_owner_def_id(body.id())) { if intrinsic.must_be_overridden { return; @@ -1624,7 +1623,7 @@ impl<'tcx> Liveness<'_, 'tcx> { && let hir::Node::Pat(pat) = self.ir.tcx.hir_node(var_hid) && let hir::Node::Param(hir::Param { ty_span, .. }) = self.ir.tcx.parent_hir_node(pat.hir_id) - && let item_id = self.ir.tcx.hir().get_parent_item(pat.hir_id) + && let item_id = self.ir.tcx.hir_get_parent_item(pat.hir_id) && let item = self.ir.tcx.hir_owner_node(item_id) && let Some(fn_decl) = item.fn_decl() && let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index 0fd980af0b540..8e59c0b3251ca 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -76,7 +76,7 @@ struct CheckLoopVisitor<'tcx> { fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { let mut check = CheckLoopVisitor { tcx, cx_stack: vec![Normal], block_breaks: Default::default() }; - tcx.hir().visit_item_likes_in_module(module_def_id, &mut check); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut check); check.report_outside_loop_error(); } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 1fe44bd3d21a9..fd465717bf766 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -246,7 +246,7 @@ impl<'tcx> ReachableContext<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..) - | hir::ItemKind::GlobalAsm(..) => {} + | hir::ItemKind::GlobalAsm { .. } => {} } } Node::TraitItem(trait_method) => { diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index d045e61d1d4c3..d92edf959aff4 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -645,7 +645,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> { } fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) { - let impl_def_id = self.tcx.hir().get_parent_item(ii.hir_id()); + let impl_def_id = self.tcx.hir_get_parent_item(ii.hir_id()); if self.tcx.impl_trait_ref(impl_def_id).is_none() { self.check_missing_stability(ii.owner_id.def_id, ii.span); self.check_missing_const_stability(ii.owner_id.def_id, ii.span); @@ -721,7 +721,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { InheritDeprecation::Yes, InheritConstStability::No, InheritStability::No, - |v| tcx.hir().walk_toplevel_module(v), + |v| tcx.hir_walk_toplevel_module(v), ); } index @@ -730,7 +730,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index { /// Cross-references the feature names of unstable APIs with enabled /// features and possibly prints errors. fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { - tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut Checker { tcx }); } pub(crate) fn provide(providers: &mut Providers) { @@ -780,11 +780,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // individually as it's possible to have a stable trait with unstable // items. hir::ItemKind::Impl(hir::Impl { - of_trait: Some(ref t), - self_ty, - items, - constness, - .. + of_trait: Some(t), self_ty, items, constness, .. }) => { let features = self.tcx.features(); if features.staged_api() { @@ -1059,8 +1055,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { let effective_visibilities = &tcx.effective_visibilities(()); let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities }; missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID)); - tcx.hir().walk_toplevel_module(&mut missing); - tcx.hir().visit_all_item_likes_in_crate(&mut missing); + tcx.hir_walk_toplevel_module(&mut missing); + tcx.hir_visit_all_item_likes_in_crate(&mut missing); } let enabled_lang_features = tcx.features().enabled_lang_features(); diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 0544d08f5b196..fae88fbba3604 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -16,7 +16,7 @@ pub(crate) fn provide(providers: &mut Providers) { } let local_def_id = def_id.expect_local(); - let body = tcx.hir().maybe_body_owned_by(local_def_id)?; + let body = tcx.hir_maybe_body_owned_by(local_def_id)?; let mut local_collector = LocalCollector::default(); local_collector.visit_body(&body); diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml index 16eea9e4ff90a..40d549630acae 100644 --- a/compiler/rustc_pattern_analysis/Cargo.toml +++ b/compiler/rustc_pattern_analysis/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_pattern_analysis" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index fec44d5af55da..a3400ebb79937 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -61,11 +61,11 @@ pub trait PatCx: Sized + fmt::Debug { fn ctor_arity(&self, ctor: &Constructor, ty: &Self::Ty) -> usize; /// The types of the fields for this constructor. The result must contain `ctor_arity()` fields. - fn ctor_sub_tys<'a>( - &'a self, - ctor: &'a Constructor, - ty: &'a Self::Ty, - ) -> impl Iterator + ExactSizeIterator + Captures<'a>; + fn ctor_sub_tys( + &self, + ctor: &Constructor, + ty: &Self::Ty, + ) -> impl Iterator + ExactSizeIterator; /// The set of all the constructors for `ty`. /// diff --git a/compiler/rustc_pattern_analysis/src/pat_column.rs b/compiler/rustc_pattern_analysis/src/pat_column.rs index eb4e095c1c662..814eb8afcfc0d 100644 --- a/compiler/rustc_pattern_analysis/src/pat_column.rs +++ b/compiler/rustc_pattern_analysis/src/pat_column.rs @@ -1,6 +1,6 @@ use crate::constructor::{Constructor, SplitConstructorSet}; use crate::pat::{DeconstructedPat, PatOrWild}; -use crate::{Captures, MatchArm, PatCx}; +use crate::{MatchArm, PatCx}; /// A column of patterns in a match, where a column is the intuitive notion of "subpatterns that /// inspect the same subvalue/place". @@ -41,7 +41,7 @@ impl<'p, Cx: PatCx> PatternColumn<'p, Cx> { pub fn head_ty(&self) -> Option<&Cx::Ty> { self.patterns.first().map(|pat| pat.ty()) } - pub fn iter<'a>(&'a self) -> impl Iterator> + Captures<'a> { + pub fn iter(&self) -> impl Iterator> { self.patterns.iter().copied() } diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 0b1e954d64d4b..88194c737a6cc 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -25,7 +25,7 @@ use crate::lints::lint_nonexhaustive_missing_variants; use crate::pat_column::PatternColumn; use crate::rustc::print::EnumInfo; use crate::usefulness::{PlaceValidity, compute_match_usefulness}; -use crate::{Captures, PatCx, PrivateUninhabitedField, errors}; +use crate::{PatCx, PrivateUninhabitedField, errors}; mod print; @@ -175,8 +175,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { &self, ty: RevealedTy<'tcx>, variant: &'tcx VariantDef, - ) -> impl Iterator)> + Captures<'p> + Captures<'_> - { + ) -> impl Iterator)> { let ty::Adt(_, args) = ty.kind() else { bug!() }; variant.fields.iter().map(move |field| { let ty = field.ty(self.tcx, args); @@ -203,13 +202,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { /// Returns the types of the fields for a given constructor. The result must have a length of /// `ctor.arity()`. - pub(crate) fn ctor_sub_tys<'a>( - &'a self, - ctor: &'a Constructor<'p, 'tcx>, + pub(crate) fn ctor_sub_tys( + &self, + ctor: &Constructor<'p, 'tcx>, ty: RevealedTy<'tcx>, - ) -> impl Iterator, PrivateUninhabitedField)> - + ExactSizeIterator - + Captures<'a> { + ) -> impl Iterator, PrivateUninhabitedField)> + ExactSizeIterator { fn reveal_and_alloc<'a, 'tcx>( cx: &'a RustcPatCtxt<'_, 'tcx>, iter: impl Iterator>, @@ -936,12 +933,11 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { fn ctor_arity(&self, ctor: &crate::constructor::Constructor, ty: &Self::Ty) -> usize { self.ctor_arity(ctor, *ty) } - fn ctor_sub_tys<'a>( - &'a self, - ctor: &'a crate::constructor::Constructor, - ty: &'a Self::Ty, - ) -> impl Iterator + ExactSizeIterator + Captures<'a> - { + fn ctor_sub_tys( + &self, + ctor: &crate::constructor::Constructor, + ty: &Self::Ty, + ) -> impl Iterator + ExactSizeIterator { self.ctor_sub_tys(ctor, *ty) } fn ctors_for_ty( diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 1dff76141da5d..11ebbea07fa4e 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -719,7 +719,7 @@ use tracing::{debug, instrument}; use self::PlaceValidity::*; use crate::constructor::{Constructor, ConstructorSet, IntRange}; use crate::pat::{DeconstructedPat, PatId, PatOrWild, WitnessPat}; -use crate::{Captures, MatchArm, PatCx, PrivateUninhabitedField}; +use crate::{MatchArm, PatCx, PrivateUninhabitedField}; #[cfg(not(feature = "rustc"))] pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { f() @@ -902,11 +902,11 @@ struct PlaceInfo { impl PlaceInfo { /// Given a constructor for the current place, we return one `PlaceInfo` for each field of the /// constructor. - fn specialize<'a>( - &'a self, - cx: &'a Cx, - ctor: &'a Constructor, - ) -> impl Iterator + ExactSizeIterator + Captures<'a> { + fn specialize( + &self, + cx: &Cx, + ctor: &Constructor, + ) -> impl Iterator + ExactSizeIterator { let ctor_sub_tys = cx.ctor_sub_tys(ctor, &self.ty); let ctor_sub_validity = self.validity.specialize(ctor); ctor_sub_tys.map(move |(ty, PrivateUninhabitedField(private_uninhabited))| PlaceInfo { @@ -1046,13 +1046,13 @@ impl<'p, Cx: PatCx> PatStack<'p, Cx> { self.pats[0] } - fn iter(&self) -> impl Iterator> + Captures<'_> { + fn iter(&self) -> impl Iterator> { self.pats.iter().copied() } // Expand the first or-pattern into its subpatterns. Only useful if the pattern is an // or-pattern. Panics if `self` is empty. - fn expand_or_pat(&self) -> impl Iterator> + Captures<'_> { + fn expand_or_pat(&self) -> impl Iterator> { self.head().expand_or_pat().into_iter().map(move |pat| { let mut new = self.clone(); new.pats[0] = pat; @@ -1157,15 +1157,12 @@ impl<'p, Cx: PatCx> MatrixRow<'p, Cx> { self.pats.head() } - fn iter(&self) -> impl Iterator> + Captures<'_> { + fn iter(&self) -> impl Iterator> { self.pats.iter() } // Expand the first or-pattern (if any) into its subpatterns. Panics if `self` is empty. - fn expand_or_pat( - &self, - parent_row: usize, - ) -> impl Iterator> + Captures<'_> { + fn expand_or_pat(&self, parent_row: usize) -> impl Iterator> { let is_or_pat = self.pats.head().is_or_pat(); self.pats.expand_or_pat().map(move |patstack| MatrixRow { pats: patstack, @@ -1275,7 +1272,7 @@ impl<'p, Cx: PatCx> Matrix<'p, Cx> { } /// Iterate over the first pattern of each row. - fn heads(&self) -> impl Iterator> + Clone + Captures<'_> { + fn heads(&self) -> impl Iterator> + Clone { self.rows().map(|r| r.head()) } diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs index 23560ad64190c..365bc2d863f47 100644 --- a/compiler/rustc_pattern_analysis/tests/common/mod.rs +++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs @@ -2,7 +2,7 @@ use rustc_pattern_analysis::constructor::{ Constructor, ConstructorSet, IntRange, MaybeInfiniteInt, RangeEnd, VariantVisibility, }; use rustc_pattern_analysis::usefulness::{PlaceValidity, UsefulnessReport}; -use rustc_pattern_analysis::{Captures, MatchArm, PatCx, PrivateUninhabitedField}; +use rustc_pattern_analysis::{MatchArm, PatCx, PrivateUninhabitedField}; /// Sets up `tracing` for easier debugging. Tries to look like the `rustc` setup. pub fn init_tracing() { @@ -156,12 +156,11 @@ impl PatCx for Cx { ty.sub_tys(ctor).len() } - fn ctor_sub_tys<'a>( - &'a self, - ctor: &'a Constructor, - ty: &'a Self::Ty, - ) -> impl Iterator + ExactSizeIterator + Captures<'a> - { + fn ctor_sub_tys( + &self, + ctor: &Constructor, + ty: &Self::Ty, + ) -> impl Iterator + ExactSizeIterator { ty.sub_tys(ctor).into_iter().map(|ty| (ty, PrivateUninhabitedField(false))) } diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index eb48155919fee..242c67d732aff 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_privacy" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index b8490da26f4ed..41725d0c6a4f9 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -645,7 +645,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { // The interface is empty, and no nested items. hir::ItemKind::Use(..) | hir::ItemKind::ExternCrate(..) - | hir::ItemKind::GlobalAsm(..) => {} + | hir::ItemKind::GlobalAsm { .. } => {} // The interface is empty, and all nested items are processed by `visit_item`. hir::ItemKind::Mod(..) => {} hir::ItemKind::Macro(macro_def, _) => { @@ -1771,7 +1771,7 @@ pub fn provide(providers: &mut Providers) { fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { // Check privacy of names not checked in previous compilation stages. let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None }; - tcx.hir().visit_item_likes_in_module(module_def_id, &mut visitor); + tcx.hir_visit_item_likes_in_module(module_def_id, &mut visitor); // Check privacy of explicitly written types and traits as well as // inferred types of expressions and patterns. @@ -1782,7 +1782,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { for def_id in module.definitions() { rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor); - if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id) { + if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) { visitor.visit_nested_body(body_id.id()); } } @@ -1863,7 +1863,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { } loop { - tcx.hir().visit_all_item_likes_in_crate(&mut visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut visitor); if visitor.changed { visitor.changed = false; } else { @@ -1875,7 +1875,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { let mut check_visitor = TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID); - tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor); + tcx.hir_visit_all_item_likes_in_crate(&mut check_visitor); tcx.arena.alloc(visitor.effective_visibilities) } diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 8b0cc9d726b80..d89e1355ca671 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "rustc_query_impl" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start measureme = "11" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index e95c186f6b680..f98d6421307ad 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -4,10 +4,11 @@ use std::num::NonZero; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; +use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_middle::bug; use rustc_middle::dep_graph::{ diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index a42329b4614f0..839465f9273bb 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_query_system" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -13,6 +13,7 @@ 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_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a4fb0a5b07220..bc78878a84a24 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -98,7 +98,7 @@ impl SerializedDepGraph { pub fn edge_targets_from( &self, source: SerializedDepNodeIndex, - ) -> impl Iterator + Clone + '_ { + ) -> impl Iterator + Clone { let header = self.edge_list_indices[source]; let mut raw = &self.edge_list_data[header.start()..]; // Figure out where the edge list for `source` ends by getting the start index of the next diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 82c51193a19d3..7490a3f35032e 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -11,9 +11,9 @@ mod caches; pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache}; mod config; -use rustc_data_structures::stable_hasher::Hash64; use rustc_data_structures::sync::Lock; use rustc_errors::DiagInner; +use rustc_hashes::Hash64; use rustc_hir::def::DefKind; use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 309227176d4e5..f4771f1af2cfd 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_resolve" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index c6781ecc56681..87f7eda391d9d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1241,7 +1241,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }; let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); - self.r.all_macro_rules.insert(ident.name, res); + self.r.all_macro_rules.insert(ident.name); if is_macro_export { let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::MacroExport, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index b1b234eb75737..6b8a7493cd429 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -98,13 +98,13 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { use ImportKind::*; match self { Single { - ref source, - ref target, - ref source_bindings, - ref target_bindings, - ref type_ns_only, - ref nested, - ref id, + source, + target, + source_bindings, + target_bindings, + type_ns_only, + nested, + id, } => f .debug_struct("Single") .field("source", source) @@ -122,13 +122,13 @@ impl<'ra> std::fmt::Debug for ImportKind<'ra> { .field("nested", nested) .field("id", id) .finish(), - Glob { ref is_prelude, ref max_vis, ref id } => f + Glob { is_prelude, max_vis, id } => f .debug_struct("Glob") .field("is_prelude", is_prelude) .field("max_vis", max_vis) .field("id", id) .finish(), - ExternCrate { ref source, ref target, ref id } => f + ExternCrate { source, target, id } => f .debug_struct("ExternCrate") .field("source", source) .field("target", target) @@ -182,6 +182,19 @@ pub(crate) struct ImportData<'ra> { /// so we can use referential equality to compare them. pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>; +// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the +// contained data. +// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees +// are upheld. +impl std::hash::Hash for ImportData<'_> { + fn hash(&self, _: &mut H) + where + H: std::hash::Hasher, + { + unreachable!() + } +} + impl<'ra> ImportData<'ra> { pub(crate) fn is_glob(&self) -> bool { matches!(self.kind, ImportKind::Glob { .. }) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 03aeb8720ca62..ad9c3465f0cc6 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1191,7 +1191,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r debug!("visit_generic_arg({:?})", arg); let prev = replace(&mut self.diag_metadata.currently_processing_generic_args, true); match arg { - GenericArg::Type(ref ty) => { + GenericArg::Type(ty) => { // We parse const arguments as path types as we cannot distinguish them during // parsing. We try to resolve that ambiguity by attempting resolution the type // namespace first, and if that fails we try again in the value namespace. If @@ -1583,7 +1583,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.visit_param_bound(bound, BoundKind::Bound); } - if let Some(ref ty) = default { + if let Some(ty) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); this.visit_ty(ty); @@ -1608,7 +1608,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { this.ribs[TypeNS].pop().unwrap(); this.ribs[ValueNS].pop().unwrap(); - if let Some(ref expr) = default { + if let Some(expr) = default { this.ribs[TypeNS].push(forward_ty_ban_rib); this.ribs[ValueNS].push(forward_const_ban_rib); this.resolve_anon_const( @@ -5044,16 +5044,16 @@ impl ItemInfoCollector<'_, '_, '_> { impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { fn visit_item(&mut self, item: &'ast Item) { match &item.kind { - ItemKind::TyAlias(box TyAlias { ref generics, .. }) - | ItemKind::Const(box ConstItem { ref generics, .. }) - | ItemKind::Fn(box Fn { ref generics, .. }) - | ItemKind::Enum(_, ref generics) - | ItemKind::Struct(_, ref generics) - | ItemKind::Union(_, ref generics) - | ItemKind::Impl(box Impl { ref generics, .. }) - | ItemKind::Trait(box Trait { ref generics, .. }) - | ItemKind::TraitAlias(ref generics, _) => { - if let ItemKind::Fn(box Fn { ref sig, .. }) = &item.kind { + ItemKind::TyAlias(box TyAlias { generics, .. }) + | ItemKind::Const(box ConstItem { generics, .. }) + | ItemKind::Fn(box Fn { generics, .. }) + | ItemKind::Enum(_, generics) + | ItemKind::Struct(_, generics) + | ItemKind::Union(_, generics) + | ItemKind::Impl(box Impl { generics, .. }) + | ItemKind::Trait(box Trait { generics, .. }) + | ItemKind::TraitAlias(generics, _) => { + if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind { self.collect_fn_info(sig, item.id, &item.attrs); } @@ -5086,7 +5086,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { } fn visit_assoc_item(&mut self, item: &'ast AssocItem, ctxt: AssocCtxt) { - if let AssocItemKind::Fn(box Fn { ref sig, .. }) = &item.kind { + if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind { self.collect_fn_info(sig, item.id, &item.attrs); } visit::walk_assoc_item(self, item, ctxt); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0962865e7f190..fa9c42e359333 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt, Visitor, walk_ty}; use rustc_ast::{ self as ast, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericParam, GenericParamKind, - Item, ItemKind, MethodCall, NodeId, Path, Ty, TyKind, + Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind, }; use rustc_ast_pretty::pprust::where_bound_predicate_to_string; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; @@ -516,7 +516,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let Some(params) = &segment.args else { continue; }; - let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { + let ast::GenericArgs::AngleBracketed(params) = params.deref() else { continue; }; for param in ¶ms.args { @@ -1529,7 +1529,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { Applicability::MaybeIncorrect, ); true - } else if kind == DefKind::Struct + } else if matches!(kind, DefKind::Struct | DefKind::TyAlias) && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span) && let Ok(snippet) = this.r.tcx.sess.source_map().span_to_snippet(lhs_source_span) { @@ -1566,7 +1566,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let mut bad_struct_syntax_suggestion = |this: &mut Self, def_id: DefId| { + let bad_struct_syntax_suggestion = |this: &mut Self, err: &mut Diag<'_>, def_id: DefId| { let (followed_by_brace, closing_brace) = this.followed_by_brace(span); match source { @@ -1668,7 +1668,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); } if let PathSource::Expr(Some(Expr { - kind: ExprKind::Call(path, ref args), + kind: ExprKind::Call(path, args), span: call_span, .. })) = source @@ -1740,12 +1740,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } ( - Res::Def(kind @ (DefKind::Mod | DefKind::Trait), _), + Res::Def(kind @ (DefKind::Mod | DefKind::Trait | DefKind::TyAlias), _), PathSource::Expr(Some(parent)), - ) => { - if !path_sep(self, err, parent, kind) { - return false; - } + ) if path_sep(self, err, parent, kind) => { + return true; } ( Res::Def(DefKind::Enum, def_id), @@ -1777,13 +1775,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let (ctor_def, ctor_vis, fields) = if let Some(struct_ctor) = struct_ctor { if let PathSource::Expr(Some(parent)) = source { if let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); return true; } } struct_ctor } else { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); return true; }; @@ -1804,7 +1802,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } // e.g. `let _ = Enum::TupleVariant(field1, field2);` PathSource::Expr(Some(Expr { - kind: ExprKind::Call(path, ref args), + kind: ExprKind::Call(path, args), span: call_span, .. })) => { @@ -1861,7 +1859,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_label(span, "constructor is not visible here due to private fields"); } (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => { - bad_struct_syntax_suggestion(self, def_id); + bad_struct_syntax_suggestion(self, err, def_id); } (Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => { match source { @@ -2471,31 +2469,73 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { def_id: DefId, span: Span, ) { - let Some(variants) = self.collect_enum_ctors(def_id) else { + let Some(variant_ctors) = self.collect_enum_ctors(def_id) else { err.note("you might have meant to use one of the enum's variants"); return; }; - let suggest_only_tuple_variants = - matches!(source, PathSource::TupleStruct(..)) || source.is_call(); - if suggest_only_tuple_variants { + // If the expression is a field-access or method-call, try to find a variant with the field/method name + // that could have been intended, and suggest replacing the `.` with `::`. + // Otherwise, suggest adding `::VariantName` after the enum; + // and if the expression is call-like, only suggest tuple variants. + let (suggest_path_sep_dot_span, suggest_only_tuple_variants) = match source { + // `Type(a, b)` in a pattern, only suggest adding a tuple variant after `Type`. + PathSource::TupleStruct(..) => (None, true), + PathSource::Expr(Some(expr)) => match &expr.kind { + // `Type(a, b)`, only suggest adding a tuple variant after `Type`. + ExprKind::Call(..) => (None, true), + // `Type.Foo(a, b)`, suggest replacing `.` -> `::` if variant `Foo` exists and is a tuple variant, + // otherwise suggest adding a variant after `Type`. + ExprKind::MethodCall(box MethodCall { + receiver, + span, + seg: PathSegment { ident, .. }, + .. + }) => { + let dot_span = receiver.span.between(*span); + let found_tuple_variant = variant_ctors.iter().any(|(path, _, ctor_kind)| { + *ctor_kind == CtorKind::Fn + && path.segments.last().is_some_and(|seg| seg.ident == *ident) + }); + (found_tuple_variant.then_some(dot_span), false) + } + // `Type.Foo`, suggest replacing `.` -> `::` if variant `Foo` exists and is a unit or tuple variant, + // otherwise suggest adding a variant after `Type`. + ExprKind::Field(base, ident) => { + let dot_span = base.span.between(ident.span); + let found_tuple_or_unit_variant = variant_ctors.iter().any(|(path, ..)| { + path.segments.last().is_some_and(|seg| seg.ident == *ident) + }); + (found_tuple_or_unit_variant.then_some(dot_span), false) + } + _ => (None, false), + }, + _ => (None, false), + }; + + if let Some(dot_span) = suggest_path_sep_dot_span { + err.span_suggestion_verbose( + dot_span, + "use the path separator to refer to a variant", + "::", + Applicability::MaybeIncorrect, + ); + } else if suggest_only_tuple_variants { // Suggest only tuple variants regardless of whether they have fields and do not // suggest path with added parentheses. - let mut suggestable_variants = variants + let mut suggestable_variants = variant_ctors .iter() .filter(|(.., kind)| *kind == CtorKind::Fn) .map(|(variant, ..)| path_names_to_string(variant)) .collect::>(); suggestable_variants.sort(); - let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); + let non_suggestable_variant_count = variant_ctors.len() - suggestable_variants.len(); - let source_msg = if source.is_call() { - "to construct" - } else if matches!(source, PathSource::TupleStruct(..)) { + let source_msg = if matches!(source, PathSource::TupleStruct(..)) { "to match against" } else { - unreachable!() + "to construct" }; if !suggestable_variants.is_empty() { @@ -2514,7 +2554,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } // If the enum has no tuple variants.. - if non_suggestable_variant_count == variants.len() { + if non_suggestable_variant_count == variant_ctors.len() { err.help(format!("the enum has no tuple variants {source_msg}")); } @@ -2537,7 +2577,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let mut suggestable_variants = variants + let mut suggestable_variants = variant_ctors .iter() .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) @@ -2564,7 +2604,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); } - let mut suggestable_variants_with_placeholders = variants + let mut suggestable_variants_with_placeholders = variant_ctors .iter() .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 90191b7776f32..eb4ac6ce77c9c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -589,6 +589,19 @@ struct ModuleData<'ra> { #[rustc_pass_by_value] struct Module<'ra>(Interned<'ra, ModuleData<'ra>>); +// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the +// contained data. +// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees +// are upheld. +impl std::hash::Hash for ModuleData<'_> { + fn hash(&self, _: &mut H) + where + H: std::hash::Hasher, + { + unreachable!() + } +} + impl<'ra> ModuleData<'ra> { fn new( parent: Option>, @@ -739,6 +752,19 @@ struct NameBindingData<'ra> { /// so we can use referential equality to compare them. type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>; +// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the +// contained data. +// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees +// are upheld. +impl std::hash::Hash for NameBindingData<'_> { + fn hash(&self, _: &mut H) + where + H: std::hash::Hasher, + { + unreachable!() + } +} + trait ToNameBinding<'ra> { fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra>; } @@ -1194,7 +1220,7 @@ pub struct Resolver<'ra, 'tcx> { effective_visibilities: EffectiveVisibilities, doc_link_resolutions: FxIndexMap, doc_link_traits_in_scope: FxIndexMap>, - all_macro_rules: FxHashMap, + all_macro_rules: FxHashSet, /// Invocation ids of all glob delegations. glob_delegation_invoc_ids: FxHashSet, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index cca01a01e9877..a70def2f6c93c 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -857,8 +857,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ), path_res @ (PathResult::NonModule(..) | PathResult::Failed { .. }) => { let mut suggestion = None; - let (span, label, module) = - if let PathResult::Failed { span, label, module, .. } = path_res { + let (span, label, module, segment) = + if let PathResult::Failed { span, label, module, segment_name, .. } = + path_res + { // try to suggest if it's not a macro, maybe a function if let PathResult::NonModule(partial_res) = self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope, None) @@ -876,7 +878,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Applicability::MaybeIncorrect, )); } - (span, label, module) + (span, label, module, segment_name) } else { ( path_span, @@ -886,12 +888,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { kind.descr() ), None, + path.last().map(|segment| segment.ident.name).unwrap(), ) }; self.report_error( span, ResolutionError::FailedToResolve { - segment: path.last().map(|segment| segment.ident.name), + segment: Some(segment), label, suggestion, module, @@ -1067,11 +1070,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None, ); if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) { + let location = match parent_scope.module.kind { + ModuleKind::Def(_, _, name) if name == kw::Empty => { + "the crate root".to_string() + } + ModuleKind::Def(kind, def_id, name) => { + format!("{} `{name}`", kind.descr(def_id)) + } + ModuleKind::Block => "this scope".to_string(), + }; self.tcx.sess.psess.buffer_lint( OUT_OF_SCOPE_MACRO_CALLS, path.span, node_id, - BuiltinLintDiag::OutOfScopeMacroCalls { path: pprust::path_to_string(path) }, + BuiltinLintDiag::OutOfScopeMacroCalls { + span: path.span, + path: pprust::path_to_string(path), + location, + }, ); } } diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml index 5623a493cf009..66488bc962594 100644 --- a/compiler/rustc_sanitizers/Cargo.toml +++ b/compiler/rustc_sanitizers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_sanitizers" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] bitflags = "2.5.0" diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index 8bf98c16361eb..948242352e7a8 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -1,11 +1,12 @@ [package] name = "rustc_serialize" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start indexmap = "2.0.0" +rustc_hashes = { path = "../rustc_hashes" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" # tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 47f72298e22ce..9e9b78cfdd57c 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -13,7 +13,6 @@ #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(ptr_sub_ptr)] #![feature(rustdoc_internals)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 27e9f817894f3..d4907b69b720b 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -280,13 +280,13 @@ impl<'a> MemDecoder<'a> { #[inline] pub fn len(&self) -> usize { // SAFETY: This recovers the length of the original slice, only using members we never modify. - unsafe { self.end.sub_ptr(self.start) } + unsafe { self.end.offset_from_unsigned(self.start) } } #[inline] pub fn remaining(&self) -> usize { // SAFETY: This type guarantees current <= end. - unsafe { self.end.sub_ptr(self.current) } + unsafe { self.end.offset_from_unsigned(self.current) } } #[cold] @@ -400,7 +400,7 @@ impl<'a> Decoder for MemDecoder<'a> { #[inline] fn position(&self) -> usize { // SAFETY: This type guarantees start <= current - unsafe { self.current.sub_ptr(self.start) } + unsafe { self.current.offset_from_unsigned(self.start) } } } diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index db8555edd0f8f..1eefd76f92b49 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -10,6 +10,7 @@ use std::path; use std::rc::Rc; use std::sync::Arc; +use rustc_hashes::{Hash64, Hash128}; use smallvec::{Array, SmallVec}; use thin_vec::ThinVec; @@ -716,3 +717,31 @@ impl> Decodable for Arc<[T]> { vec.into() } } + +impl Encodable for Hash64 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.as_u64().to_le_bytes()); + } +} + +impl Encodable for Hash128 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.as_u128().to_le_bytes()); + } +} + +impl Decodable for Hash64 { + #[inline] + fn decode(d: &mut D) -> Self { + Self::new(u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap())) + } +} + +impl Decodable for Hash128 { + #[inline] + fn decode(d: &mut D) -> Self { + Self::new(u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap())) + } +} diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index b9c535df4bd09..a087725d34dd1 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_session" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -14,6 +14,7 @@ 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_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7d473b86ff58a..8f0b17b5e8879 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -198,33 +198,26 @@ pub enum CoverageLevel { /// The different settings that the `-Z autodiff` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum AutoDiff { + /// Enable the autodiff opt pipeline + Enable, + /// Print TypeAnalysis information PrintTA, /// Print ActivityAnalysis Information PrintAA, /// Print Performance Warnings from Enzyme PrintPerf, - /// Combines the three print flags above. - Print, + /// Print intermediate IR generation steps + PrintSteps, /// Print the whole module, before running opts. PrintModBefore, - /// Print the whole module just before we pass it to Enzyme. - /// For Debug purpose, prefer the OPT flag below - PrintModAfterOpts, /// Print the module after Enzyme differentiated everything. - PrintModAfterEnzyme, + PrintModAfter, - /// Enzyme's loose type debug helper (can cause incorrect gradients) + /// Enzyme's loose type debug helper (can cause incorrect gradients!!) + /// Usable in cases where Enzyme errors with `can not deduce type of X`. LooseTypes, - - /// More flags - NoModOptAfter, - /// Tell Enzyme to run LLVM Opts on each function it generated. By default off, - /// since we already optimize the whole module after Enzyme is done. - EnableFncOpt, - NoVecUnroll, - RuntimeActivity, - /// Runs Enzyme specific Inlining + /// Runs Enzyme's aggressive inlining Inline, } @@ -2928,15 +2921,16 @@ pub enum WasiExecModel { /// how the hash should be calculated when adding a new command-line argument. pub(crate) mod dep_tracking { use std::collections::BTreeMap; - use std::hash::{DefaultHasher, Hash}; + use std::hash::Hash; use std::num::NonZero; use std::path::PathBuf; use rustc_abi::Align; use rustc_data_structures::fx::FxIndexMap; - use rustc_data_structures::stable_hasher::Hash64; + use rustc_data_structures::stable_hasher::StableHasher; use rustc_errors::LanguageIdentifier; use rustc_feature::UnstableFeatures; + use rustc_hashes::Hash64; use rustc_span::RealFileName; use rustc_span::edition::Edition; use rustc_target::spec::{ @@ -2960,7 +2954,7 @@ pub(crate) mod dep_tracking { pub(crate) trait DepTrackingHash { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ); @@ -2969,7 +2963,7 @@ pub(crate) mod dep_tracking { macro_rules! impl_dep_tracking_hash_via_hash { ($($t:ty),+ $(,)?) => {$( impl DepTrackingHash for $t { - fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType, _for_crate_hash: bool) { + fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) { Hash::hash(self, hasher); } } @@ -2979,7 +2973,7 @@ pub(crate) mod dep_tracking { impl DepTrackingHash for Option { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3064,7 +3058,7 @@ pub(crate) mod dep_tracking { { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3083,7 +3077,7 @@ pub(crate) mod dep_tracking { { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3099,7 +3093,7 @@ pub(crate) mod dep_tracking { impl DepTrackingHash for Vec { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3114,7 +3108,7 @@ pub(crate) mod dep_tracking { impl DepTrackingHash for FxIndexMap { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3129,7 +3123,7 @@ pub(crate) mod dep_tracking { impl DepTrackingHash for OutputTypes { fn hash( &self, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { @@ -3146,7 +3140,7 @@ pub(crate) mod dep_tracking { // This is a stable hash because BTreeMap is a sorted container pub(crate) fn stable_hash( sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>, - hasher: &mut DefaultHasher, + hasher: &mut StableHasher, error_format: ErrorOutputType, for_crate_hash: bool, ) { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 35819f896c5bd..8977365ee73d9 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::hash::{DefaultHasher, Hasher}; use std::num::{IntErrorKind, NonZero}; use std::path::PathBuf; use std::str; @@ -7,9 +6,10 @@ use std::str; use rustc_abi::Align; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::TimePassesFormat; -use rustc_data_structures::stable_hasher::Hash64; +use rustc_data_structures::stable_hasher::StableHasher; use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl}; use rustc_feature::UnstableFeatures; +use rustc_hashes::Hash64; use rustc_macros::{Decodable, Encodable}; use rustc_span::edition::Edition; use rustc_span::{RealFileName, SourceFileHashAlgorithm}; @@ -251,7 +251,7 @@ macro_rules! top_level_options { } impl Options { - pub fn dep_tracking_hash(&self, for_crate_hash: bool) -> u64 { + pub fn dep_tracking_hash(&self, for_crate_hash: bool) -> Hash64 { let mut sub_hashes = BTreeMap::new(); $({ hash_opt!($opt, @@ -260,7 +260,7 @@ macro_rules! top_level_options { for_crate_hash, [$dep_tracking_marker]); })* - let mut hasher = DefaultHasher::new(); + let mut hasher = StableHasher::new(); dep_tracking::stable_hash(sub_hashes, &mut hasher, self.error_format, @@ -545,7 +545,7 @@ macro_rules! options { build_options(early_dcx, matches, target_modifiers, $stat, $prefix, $outputname) } - fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> u64 { + fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> Hash64 { let mut sub_hashes = BTreeMap::new(); $({ hash_opt!($opt, @@ -554,7 +554,7 @@ macro_rules! options { for_crate_hash, [$dep_tracking_marker]); })* - let mut hasher = DefaultHasher::new(); + let mut hasher = StableHasher::new(); dep_tracking::stable_hash(sub_hashes, &mut hasher, error_format, @@ -707,7 +707,7 @@ mod desc { pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; - pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Print`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfterOpts`, `PrintModAfterEnzyme`, `LooseTypes`, `NoModOptAfter`, `EnableFncOpt`, `NoVecUnroll`, `Inline`"; + pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `LooseTypes`, `Inline`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1348,17 +1348,14 @@ pub mod parse { v.sort_unstable(); for &val in v.iter() { let variant = match val { + "Enable" => AutoDiff::Enable, "PrintTA" => AutoDiff::PrintTA, "PrintAA" => AutoDiff::PrintAA, "PrintPerf" => AutoDiff::PrintPerf, - "Print" => AutoDiff::Print, + "PrintSteps" => AutoDiff::PrintSteps, "PrintModBefore" => AutoDiff::PrintModBefore, - "PrintModAfterOpts" => AutoDiff::PrintModAfterOpts, - "PrintModAfterEnzyme" => AutoDiff::PrintModAfterEnzyme, + "PrintModAfter" => AutoDiff::PrintModAfter, "LooseTypes" => AutoDiff::LooseTypes, - "NoModOptAfter" => AutoDiff::NoModOptAfter, - "EnableFncOpt" => AutoDiff::EnableFncOpt, - "NoVecUnroll" => AutoDiff::NoVecUnroll, "Inline" => AutoDiff::Inline, _ => { // FIXME(ZuseZ4): print an error saying which value is not recognized @@ -2081,21 +2078,19 @@ options! { assume_incomplete_release: bool = (false, parse_bool, [TRACKED], "make cfg(version) treat the current version as incomplete (default: no)"), autodiff: Vec = (Vec::new(), parse_autodiff, [TRACKED], - "a list of optional autodiff flags to enable - Optional extra settings: - `=PrintTA` - `=PrintAA` - `=PrintPerf` - `=Print` - `=PrintModBefore` - `=PrintModAfterOpts` - `=PrintModAfterEnzyme` - `=LooseTypes` - `=NoModOptAfter` - `=EnableFncOpt` - `=NoVecUnroll` - `=Inline` - Multiple options can be combined with commas."), + "a list of autodiff flags to enable + Mandatory setting: + `=Enable` + Optional extra settings: + `=PrintTA` + `=PrintAA` + `=PrintPerf` + `=PrintSteps` + `=PrintModBefore` + `=PrintModAfter` + `=LooseTypes` + `=Inline` + Multiple options can be combined with commas."), #[rustc_lint_opt_deny_field_access("use `Session::binary_dep_depinfo` instead of this field")] binary_dep_depinfo: bool = (false, parse_bool, [TRACKED], "include artifacts (sysroot, crate dependencies) used during compilation in dep-info \ diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index e0405a71f65af..1fe521bd32d54 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -329,7 +329,7 @@ impl ParseSess { self.proc_macro_quoted_spans.push(span) } - pub fn proc_macro_quoted_spans(&self) -> impl Iterator + '_ { + pub fn proc_macro_quoted_spans(&self) -> impl Iterator { // This is equivalent to `.iter().copied().enumerate()`, but that isn't possible for // AppendOnlyVec, so we resort to this scheme. self.proc_macro_quoted_spans.iter_enumerated() diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs index b750d870cb6f7..00e12b45bafb1 100644 --- a/compiler/rustc_session/src/search_paths.rs +++ b/compiler/rustc_session/src/search_paths.rs @@ -20,12 +20,11 @@ pub struct FilesIndex(Vec<(Arc, SearchPathFile)>); impl FilesIndex { /// Look up [SearchPathFile] by (prefix, suffix) pair. - pub fn query<'this, 'prefix, 'suffix>( - &'this self, - prefix: &'prefix str, - suffix: &'suffix str, - ) -> Option + use<'this, 'prefix, 'suffix>> - { + pub fn query<'s>( + &'s self, + prefix: &str, + suffix: &str, + ) -> Option> { let start = self.0.partition_point(|(k, _)| **k < *prefix); if start == self.0.len() { return None; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index c4d45ee02eea1..8e5ff1d3bc48e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1019,8 +1019,7 @@ pub fn build_session( let self_profiler = if let SwitchWithOptPath::Enabled(ref d) = sopts.unstable_opts.self_profile { - let directory = - if let Some(ref directory) = d { directory } else { std::path::Path::new(".") }; + let directory = if let Some(directory) = d { directory } else { std::path::Path::new(".") }; let profiler = SelfProfiler::new( directory, diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 29ce24e8b7849..a11df9a9c9bc9 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_smir" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index fb2e838cdc998..a627e0e69b62f 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -202,7 +202,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { fn stable(&self, tables: &mut Tables<'_>) -> Self::T { match *self { - rustc_abi::BackendRepr::Uninhabited => ValueAbi::Uninhabited, rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)), rustc_abi::BackendRepr::ScalarPair(first, second) => { ValueAbi::ScalarPair(first.stable(tables), second.stable(tables)) diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 781fe6a11fe8d..43a2d692577eb 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_span" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -12,6 +12,7 @@ itoa = "1.0" md5 = { package = "md-5", version = "0.10.0" } rustc_arena = { path = "../rustc_arena" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs index 47cc16b623d10..a39bb884faadc 100644 --- a/compiler/rustc_span/src/analyze_source_file.rs +++ b/compiler/rustc_span/src/analyze_source_file.rs @@ -29,132 +29,6 @@ pub(crate) fn analyze_source_file(src: &str) -> (Vec, Vec { - fn analyze_source_file_dispatch( - src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - ) { - if is_x86_feature_detected!("sse2") { - unsafe { - analyze_source_file_sse2(src, lines, multi_byte_chars); - } - } else { - analyze_source_file_generic( - src, - src.len(), - RelativeBytePos::from_u32(0), - lines, - multi_byte_chars, - ); - } - } - - /// Checks 16 byte chunks of text at a time. If the chunk contains - /// something other than printable ASCII characters and newlines, the - /// function falls back to the generic implementation. Otherwise it uses - /// SSE2 intrinsics to quickly find all newlines. - #[target_feature(enable = "sse2")] - unsafe fn analyze_source_file_sse2( - src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - ) { - #[cfg(target_arch = "x86")] - use std::arch::x86::*; - #[cfg(target_arch = "x86_64")] - use std::arch::x86_64::*; - - const CHUNK_SIZE: usize = 16; - - let src_bytes = src.as_bytes(); - - let chunk_count = src.len() / CHUNK_SIZE; - - // This variable keeps track of where we should start decoding a - // chunk. If a multi-byte character spans across chunk boundaries, - // we need to skip that part in the next chunk because we already - // handled it. - let mut intra_chunk_offset = 0; - - for chunk_index in 0..chunk_count { - let ptr = src_bytes.as_ptr() as *const __m128i; - // We don't know if the pointer is aligned to 16 bytes, so we - // use `loadu`, which supports unaligned loading. - let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) }; - - // For character in the chunk, see if its byte value is < 0, which - // indicates that it's part of a UTF-8 char. - let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) }; - // Create a bit mask from the comparison results. - let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) }; - - // If the bit mask is all zero, we only have ASCII chars here: - if multibyte_mask == 0 { - assert!(intra_chunk_offset == 0); - - // Check for newlines in the chunk - let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) }; - let mut newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) }; - - let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1); - - while newlines_mask != 0 { - let index = newlines_mask.trailing_zeros(); - - lines.push(RelativeBytePos(index) + output_offset); - - // Clear the bit, so we can find the next one. - newlines_mask &= newlines_mask - 1; - } - } else { - // The slow path. - // There are multibyte chars in here, fallback to generic decoding. - let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset; - intra_chunk_offset = analyze_source_file_generic( - &src[scan_start..], - CHUNK_SIZE - intra_chunk_offset, - RelativeBytePos::from_usize(scan_start), - lines, - multi_byte_chars, - ); - } - } - - // There might still be a tail left to analyze - let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset; - if tail_start < src.len() { - analyze_source_file_generic( - &src[tail_start..], - src.len() - tail_start, - RelativeBytePos::from_usize(tail_start), - lines, - multi_byte_chars, - ); - } - } - } - _ => { - // The target (or compiler version) does not support SSE2 ... - fn analyze_source_file_dispatch( - src: &str, - lines: &mut Vec, - multi_byte_chars: &mut Vec, - ) { - analyze_source_file_generic( - src, - src.len(), - RelativeBytePos::from_u32(0), - lines, - multi_byte_chars, - ); - } - } -} - -#[cfg(not(bootstrap))] cfg_match! { any(target_arch = "x86", target_arch = "x86_64") => { fn analyze_source_file_dispatch( diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index f61ce37131eb4..641bac88ad025 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -3,10 +3,9 @@ use std::hash::{BuildHasherDefault, Hash, Hasher}; use rustc_data_structures::AtomicRef; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{ - Hash64, HashStable, StableHasher, StableOrd, ToStableHashKey, -}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey}; use rustc_data_structures::unhash::Unhasher; +use rustc_hashes::Hash64; use rustc_index::Idx; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Encodable}; diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 2910bcdf51d94..9bf1d305e5413 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -33,9 +33,10 @@ use std::sync::Arc; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; use rustc_data_structures::sync::{Lock, WorkerLocal}; use rustc_data_structures::unhash::UnhashMap; +use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 0e146baef3751..c09669d959c93 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -87,9 +87,10 @@ use std::sync::Arc; use std::{fmt, iter}; use md5::{Digest, Md5}; -use rustc_data_structures::stable_hasher::{Hash64, Hash128, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock}; use rustc_data_structures::unord::UnordMap; +use rustc_hashes::{Hash64, Hash128}; use sha1::Sha1; use sha2::Sha256; @@ -403,7 +404,7 @@ impl fmt::Display for FileNameDisplay<'_> { impl<'a> FileNameDisplay<'a> { pub fn to_string_lossy(&self) -> Cow<'a, str> { match self.inner { - FileName::Real(ref inner) => inner.to_string_lossy(self.display_pref), + FileName::Real(inner) => inner.to_string_lossy(self.display_pref), _ => Cow::from(self.to_string()), } } @@ -1441,7 +1442,7 @@ pub enum ExternalSourceKind { impl ExternalSource { pub fn get_source(&self) -> Option<&str> { match self { - ExternalSource::Foreign { kind: ExternalSourceKind::Present(ref src), .. } => Some(src), + ExternalSource::Foreign { kind: ExternalSourceKind::Present(src), .. } => Some(src), _ => None, } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9403908948082..10c79b1be82d9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -192,6 +192,7 @@ symbols! { Capture, Cell, Center, + Child, Cleanup, Clone, CoercePointee, @@ -288,6 +289,7 @@ symbols! { OsString, Output, Param, + ParamSet, PartialEq, PartialOrd, Path, @@ -336,6 +338,7 @@ symbols! { SliceIter, Some, SpanCtxt, + Stdin, String, StructuralPartialEq, SubdiagMessage, @@ -518,6 +521,7 @@ symbols! { bang, begin_panic, bench, + bevy_ecs, bikeshed_guaranteed_no_drop, bin, binaryheap_iter, @@ -599,6 +603,9 @@ symbols! { cfi, cfi_encoding, char, + char_is_ascii, + child_id, + child_kill, client, clippy, clobber_abi, @@ -1360,10 +1367,6 @@ symbols! { native_link_modifiers_whole_archive, natvis_file, ne, - nearbyintf128, - nearbyintf16, - nearbyintf32, - nearbyintf64, needs_allocator, needs_drop, needs_panic_runtime, @@ -1468,6 +1471,7 @@ symbols! { panic_2015, panic_2021, panic_abort, + panic_any, panic_bounds_check, panic_cannot_unwind, panic_const_add_overflow, @@ -1573,6 +1577,7 @@ symbols! { proc_macro_mod, proc_macro_non_items, proc_macro_path_invoc, + process_abort, process_exit, profiler_builtins, profiler_runtime, @@ -1679,20 +1684,16 @@ symbols! { return_position_impl_trait_in_trait, return_type_notation, rhs, - rintf128, - rintf16, - rintf32, - rintf64, riscv_target_feature, rlib, ropi, ropi_rwpi: "ropi-rwpi", rotate_left, rotate_right, - roundevenf128, - roundevenf16, - roundevenf32, - roundevenf64, + round_ties_even_f128, + round_ties_even_f16, + round_ties_even_f32, + round_ties_even_f64, roundf128, roundf16, roundf32, diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 1fb647cab5b57..12fe6b719f9b8 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_symbol_mangling" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start @@ -11,6 +11,7 @@ rustc-demangle = "0.1.21" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_symbol_mangling/src/hashed.rs b/compiler/rustc_symbol_mangling/src/hashed.rs index 07c5f54479232..e965e6a7d53aa 100644 --- a/compiler/rustc_symbol_mangling/src/hashed.rs +++ b/compiler/rustc_symbol_mangling/src/hashed.rs @@ -1,6 +1,7 @@ use std::fmt::Write; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::CrateNum; use rustc_middle::ty::{Instance, TyCtxt}; diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 8ae35572d012d..88754f1f15b46 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -1,7 +1,8 @@ use std::fmt::{self, Write}; use std::mem::{self, discriminant}; -use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_hashes::Hash64; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::bug; diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index e33431ba12259..189b19b028617 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_target" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index 47566bde6b4a4..3fa67c624a7be 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -80,7 +80,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 2bde105562218..1c044fe98b3ef 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -7,7 +7,7 @@ use rustc_abi::{ }; use rustc_macros::HashStable_Generic; -use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi}; +use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, RustcAbi, WasmCAbi}; mod aarch64; mod amdgpu; @@ -38,7 +38,7 @@ mod xtensa; pub enum PassMode { /// Ignore the argument. /// - /// The argument is either uninhabited or a ZST. + /// The argument is a ZST. Ignore, /// Pass the argument directly. /// @@ -350,7 +350,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> { scalar_attrs: impl Fn(&TyAndLayout<'a, Ty>, Scalar, Size) -> ArgAttributes, ) -> Self { let mode = match layout.backend_repr { - BackendRepr::Uninhabited => PassMode::Ignore, BackendRepr::Scalar(scalar) => { PassMode::Direct(scalar_attrs(&layout, scalar, Size::ZERO)) } @@ -386,6 +385,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { /// Pass this argument directly instead. Should NOT be used! /// Only exists because of past ABI mistakes that will take time to fix /// (see ). + #[track_caller] pub fn make_direct_deprecated(&mut self) { match self.mode { PassMode::Indirect { .. } => { @@ -398,6 +398,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { /// Pass this argument indirectly, by passing a (thin or wide) pointer to the argument instead. /// This is valid for both sized and unsized arguments. + #[track_caller] pub fn make_indirect(&mut self) { match self.mode { PassMode::Direct(_) | PassMode::Pair(_, _) => { @@ -412,6 +413,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { /// Same as `make_indirect`, but for arguments that are ignored. Only needed for ABIs that pass /// ZSTs indirectly. + #[track_caller] pub fn make_indirect_from_ignore(&mut self) { match self.mode { PassMode::Ignore => { @@ -716,7 +718,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { C: HasDataLayout + HasTargetSpec, { let spec = cx.target_spec(); - match &spec.arch[..] { + match &*spec.arch { "x86" => x86::compute_rust_abi_info(cx, self, abi), "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi), "loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi), @@ -724,6 +726,24 @@ impl<'a, Ty> FnAbi<'a, Ty> { _ => {} }; + // Decides whether we can pass the given SIMD argument via `PassMode::Direct`. + // May only return `true` if the target will always pass those arguments the same way, + // no matter what the user does with `-Ctarget-feature`! In other words, whatever + // target features are required to pass a SIMD value in registers must be listed in + // the `abi_required_features` for the current target and ABI. + let can_pass_simd_directly = |arg: &ArgAbi<'_, Ty>| match &*spec.arch { + // On x86, if we have SSE2 (which we have by default for x86_64), we can always pass up + // to 128-bit-sized vectors. + "x86" if spec.rustc_abi == Some(RustcAbi::X86Sse2) => arg.layout.size.bits() <= 128, + "x86_64" if spec.rustc_abi != Some(RustcAbi::X86Softfloat) => { + // FIXME once https://github.com/bytecodealliance/wasmtime/issues/10254 is fixed + // accept vectors up to 128bit rather than vectors of exactly 128bit. + arg.layout.size.bits() == 128 + } + // So far, we haven't implemented this logic for any other target. + _ => false, + }; + for (arg_idx, arg) in self .args .iter_mut() @@ -731,12 +751,15 @@ impl<'a, Ty> FnAbi<'a, Ty> { .map(|(idx, arg)| (Some(idx), arg)) .chain(iter::once((None, &mut self.ret))) { - if arg.is_ignore() { + // If the logic above already picked a specific type to cast the argument to, leave that + // in place. + if matches!(arg.mode, PassMode::Ignore | PassMode::Cast { .. }) { continue; } if arg_idx.is_none() && arg.layout.size > Primitive::Pointer(AddressSpace::DATA).size(cx) * 2 + && !matches!(arg.layout.backend_repr, BackendRepr::Vector { .. }) { // Return values larger than 2 registers using a return area // pointer. LLVM and Cranelift disagree about how to return @@ -746,7 +769,8 @@ impl<'a, Ty> FnAbi<'a, Ty> { // return value independently and decide to pass it in a // register or not, which would result in the return value // being passed partially in registers and partially through a - // return area pointer. + // return area pointer. For large IR-level values such as `i128`, + // cranelift will even split up the value into smaller chunks. // // While Cranelift may need to be fixed as the LLVM behavior is // generally more correct with respect to the surface language, @@ -776,53 +800,60 @@ impl<'a, Ty> FnAbi<'a, Ty> { // rustc_target already ensure any return value which doesn't // fit in the available amount of return registers is passed in // the right way for the current target. + // + // The adjustment is not necessary nor desired for types with a vector + // representation; those are handled below. arg.make_indirect(); continue; } match arg.layout.backend_repr { - BackendRepr::Memory { .. } => {} - - // This is a fun case! The gist of what this is doing is - // that we want callers and callees to always agree on the - // ABI of how they pass SIMD arguments. If we were to *not* - // make these arguments indirect then they'd be immediates - // in LLVM, which means that they'd used whatever the - // appropriate ABI is for the callee and the caller. That - // means, for example, if the caller doesn't have AVX - // enabled but the callee does, then passing an AVX argument - // across this boundary would cause corrupt data to show up. - // - // This problem is fixed by unconditionally passing SIMD - // arguments through memory between callers and callees - // which should get them all to agree on ABI regardless of - // target feature sets. Some more information about this - // issue can be found in #44367. - // - // Note that the intrinsic ABI is exempt here as - // that's how we connect up to LLVM and it's unstable - // anyway, we control all calls to it in libstd. - BackendRepr::Vector { .. } - if abi != ExternAbi::RustIntrinsic && spec.simd_types_indirect => - { - arg.make_indirect(); - continue; + BackendRepr::Memory { .. } => { + // Compute `Aggregate` ABI. + + let is_indirect_not_on_stack = + matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); + assert!(is_indirect_not_on_stack); + + let size = arg.layout.size; + if arg.layout.is_sized() + && size <= Primitive::Pointer(AddressSpace::DATA).size(cx) + { + // We want to pass small aggregates as immediates, but using + // an LLVM aggregate type for this leads to bad optimizations, + // so we pick an appropriately sized integer type instead. + arg.cast_to(Reg { kind: RegKind::Integer, size }); + } } - _ => continue, - } - // Compute `Aggregate` ABI. - - let is_indirect_not_on_stack = - matches!(arg.mode, PassMode::Indirect { on_stack: false, .. }); - assert!(is_indirect_not_on_stack); - - let size = arg.layout.size; - if !arg.layout.is_unsized() && size <= Primitive::Pointer(AddressSpace::DATA).size(cx) { - // We want to pass small aggregates as immediates, but using - // an LLVM aggregate type for this leads to bad optimizations, - // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { kind: RegKind::Integer, size }); + BackendRepr::Vector { .. } => { + // This is a fun case! The gist of what this is doing is + // that we want callers and callees to always agree on the + // ABI of how they pass SIMD arguments. If we were to *not* + // make these arguments indirect then they'd be immediates + // in LLVM, which means that they'd used whatever the + // appropriate ABI is for the callee and the caller. That + // means, for example, if the caller doesn't have AVX + // enabled but the callee does, then passing an AVX argument + // across this boundary would cause corrupt data to show up. + // + // This problem is fixed by unconditionally passing SIMD + // arguments through memory between callers and callees + // which should get them all to agree on ABI regardless of + // target feature sets. Some more information about this + // issue can be found in #44367. + // + // Note that the intrinsic ABI is exempt here as those are not + // real functions anyway, and the backend expects very specific types. + if abi != ExternAbi::RustIntrinsic + && spec.simd_types_indirect + && !can_pass_simd_directly(arg) + { + arg.make_indirect(); + } + } + + _ => {} } } } diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index 265ae20f9919d..785175229b031 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -86,7 +86,7 @@ where } } }, - BackendRepr::Vector { .. } | BackendRepr::Uninhabited => return Err(CannotUseFpConv), + BackendRepr::Vector { .. } => return Err(CannotUseFpConv), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 5b9414536d8ca..7e5aab0201b6d 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -4,7 +4,7 @@ use rustc_abi::{ }; use crate::callconv::{ArgAttribute, FnAbi, PassMode}; -use crate::spec::HasTargetSpec; +use crate::spec::{HasTargetSpec, RustcAbi}; #[derive(PartialEq)] pub(crate) enum Flavor { @@ -108,9 +108,7 @@ where Ty: TyAbiInterface<'a, C> + Copy, { match layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::ScalarPair(..) => false, + BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false, BackendRepr::Vector { .. } => true, BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { @@ -236,8 +234,16 @@ where _ => false, // anyway not passed via registers on x86 }; if has_float { - if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::DATA).size(cx) { - // Same size or smaller than pointer, return in a register. + if cx.target_spec().rustc_abi == Some(RustcAbi::X86Sse2) + && fn_abi.ret.layout.backend_repr.is_scalar() + && fn_abi.ret.layout.size.bits() <= 128 + { + // This is a single scalar that fits into an SSE register, and the target uses the + // SSE ABI. We prefer this over integer registers as float scalars need to be in SSE + // registers for float operations, so that's the best place to pass them around. + fn_abi.ret.cast_to(Reg { kind: RegKind::Vector, size: fn_abi.ret.layout.size }); + } else if fn_abi.ret.layout.size <= Primitive::Pointer(AddressSpace::DATA).size(cx) { + // Same size or smaller than pointer, return in an integer register. fn_abi.ret.cast_to(Reg { kind: RegKind::Integer, size: fn_abi.ret.layout.size }); } else { // Larger than a pointer, return indirectly. diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index b15d82c26dac2..ab306e202396b 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -51,8 +51,6 @@ where } let mut c = match layout.backend_repr { - BackendRepr::Uninhabited => return Ok(()), - BackendRepr::Scalar(scalar) => match scalar.primitive() { Primitive::Int(..) | Primitive::Pointer(_) => Class::Int, Primitive::Float(_) => Class::Sse, diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 23ef2cf828409..4d99a9f9ba064 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -1,14 +1,14 @@ use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size}; use crate::callconv::{ArgAbi, FnAbi, Reg}; -use crate::spec::HasTargetSpec; +use crate::spec::{HasTargetSpec, RustcAbi}; // Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing -pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { +pub(crate) fn compute_abi_info(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) { let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| { match a.layout.backend_repr { - BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {} + BackendRepr::Memory { sized: false } => {} BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => { match a.layout.size.bits() { 8 => a.cast_to(Reg::i8()), @@ -24,10 +24,14 @@ pub(crate) fn compute_abi_info(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi< } BackendRepr::Scalar(scalar) => { if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) { - // `i128` is returned in xmm0 by Clang and GCC - // FIXME(#134288): This may change for the `-msvc` targets in the future. - let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) }; - a.cast_to(reg); + if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) { + // Use the native `i128` LLVM type for the softfloat ABI -- in other words, adjust nothing. + } else { + // `i128` is returned in xmm0 by Clang and GCC + // FIXME(#134288): This may change for the `-msvc` targets in the future. + let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) }; + a.cast_to(reg); + } } else if a.layout.size.bytes() > 8 && !matches!(scalar.primitive(), Primitive::Float(Float::F128)) { diff --git a/compiler/rustc_target/src/spec/base/aix.rs b/compiler/rustc_target/src/spec/base/aix.rs index a92d104f9108e..aa42b4d1c5027 100644 --- a/compiler/rustc_target/src/spec/base/aix.rs +++ b/compiler/rustc_target/src/spec/base/aix.rs @@ -1,6 +1,8 @@ use rustc_abi::Endian; -use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs}; +use crate::spec::{ + BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs, +}; pub(crate) fn opts() -> TargetOptions { TargetOptions { @@ -21,6 +23,7 @@ pub(crate) fn opts() -> TargetOptions { linker: Some("ld".into()), eh_frame_header: false, is_like_aix: true, + binary_format: BinaryFormat::Xcoff, default_dwarf_version: 3, function_sections: true, pre_link_objects: crt_objects::new(&[ diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 1b56143545f61..66c85146c2944 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use std::env; use crate::spec::{ - Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo, - StackProbeType, StaticCow, TargetOptions, cvs, + BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, + SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs, }; #[cfg(test)] @@ -116,6 +116,7 @@ pub(crate) fn base( dynamic_linking: true, families: cvs!["unix"], is_like_osx: true, + binary_format: BinaryFormat::MachO, // LLVM notes that macOS 10.11+ and iOS 9+ default // to v4, so we do the same. // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203 diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr.rs similarity index 91% rename from compiler/rustc_target/src/spec/base/avr_gnu.rs rename to compiler/rustc_target/src/spec/base/avr.rs index 3554dcfcb4a13..85b73e61e52cd 100644 --- a/compiler/rustc_target/src/spec/base/avr_gnu.rs +++ b/compiler/rustc_target/src/spec/base/avr.rs @@ -1,45 +1,5 @@ use object::elf; -use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; - -/// A base target for AVR devices using the GNU toolchain. -/// -/// Requires GNU avr-gcc and avr-binutils on the host system. -/// FIXME: Remove the second parameter when const string concatenation is possible. -pub(crate) fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { - Target { - arch: "avr".into(), - metadata: crate::spec::TargetMetadata { - description: None, - tier: None, - host_tools: None, - std: None, - }, - data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(), - llvm_target: "avr-unknown-unknown".into(), - pointer_width: 16, - options: TargetOptions { - env: "gnu".into(), - - c_int_width: "16".into(), - cpu: target_cpu.into(), - exe_suffix: ".elf".into(), - - linker: Some("avr-gcc".into()), - eh_frame_header: false, - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]), - late_link_args: TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &["-lgcc"], - ), - max_atomic_width: Some(16), - atomic_cas: false, - relocation_model: RelocModel::Static, - ..TargetOptions::default() - }, - } -} - /// Resolve the value of the EF_AVR_ARCH field for AVR ELF files, given the /// name of the target CPU / MCU. /// diff --git a/compiler/rustc_target/src/spec/base/cygwin.rs b/compiler/rustc_target/src/spec/base/cygwin.rs index fe3efb3f46ba0..819d1d68a71d9 100644 --- a/compiler/rustc_target/src/spec/base/cygwin.rs +++ b/compiler/rustc_target/src/spec/base/cygwin.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs}; +use crate::spec::{ + BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs, +}; pub(crate) fn opts() -> TargetOptions { let mut pre_link_args = TargetOptions::link_args( @@ -32,6 +34,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["unix"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, late_link_args, diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index b9139c8452c5f..6f88be5d37f16 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -1,7 +1,7 @@ pub(crate) mod aix; pub(crate) mod android; pub(crate) mod apple; -pub(crate) mod avr_gnu; +pub(crate) mod avr; pub(crate) mod bpf; pub(crate) mod cygwin; pub(crate) mod dragonfly; diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs index b0fb2ef4b27f2..486d7158723f8 100644 --- a/compiler/rustc_target/src/spec/base/msvc.rs +++ b/compiler/rustc_target/src/spec/base/msvc.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; +use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; pub(crate) fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly @@ -12,6 +12,7 @@ pub(crate) fn opts() -> TargetOptions { dll_tls_export: false, is_like_windows: true, is_like_msvc: true, + binary_format: BinaryFormat::Coff, pre_link_args, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index 81b96cd39ffac..88e7af5e66978 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -1,6 +1,6 @@ use crate::spec::{ - Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel, - add_link_args, cvs, + BinaryFormat, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, + TargetOptions, TlsModel, add_link_args, cvs, }; pub(crate) fn options() -> TargetOptions { @@ -53,6 +53,7 @@ pub(crate) fn options() -> TargetOptions { TargetOptions { is_like_wasm: true, + binary_format: BinaryFormat::Wasm, families: cvs!["wasm"], // we allow dynamic linking, but only cdylibs. Basically we allow a diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index 024b10f2faad7..4ba1102198847 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use crate::spec::{ - Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, - add_link_args, crt_objects, cvs, + BinaryFormat, Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, + TargetOptions, add_link_args, crt_objects, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -90,6 +90,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["windows"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, pre_link_objects: crt_objects::pre_mingw(), diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 4a6e7c75200f6..f24ad781e2b81 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -1,6 +1,8 @@ use std::borrow::Cow; -use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs}; +use crate::spec::{ + BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs, +}; pub(crate) fn opts() -> TargetOptions { // We cannot use `-nodefaultlibs` because compiler-rt has to be passed @@ -30,6 +32,7 @@ pub(crate) fn opts() -> TargetOptions { exe_suffix: ".exe".into(), families: cvs!["windows"], is_like_windows: true, + binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, late_link_args, diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs index f703132e51f0a..134405f3630e7 100644 --- a/compiler/rustc_target/src/spec/json.rs +++ b/compiler/rustc_target/src/spec/json.rs @@ -103,6 +103,19 @@ impl Target { base.$key_name = Some(s); } } ); + ($key_name:ident, BinaryFormat) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|f| f.as_str().and_then(|s| { + match s.parse::() { + Ok(binary_format) => base.$key_name = binary_format, + _ => return Some(Err(format!( + "'{s}' is not a valid value for binary_format. \ + Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' " + ))), + } + Some(Ok(())) + })).unwrap_or(Ok(())) + } ); ($key_name:ident, MergeFunctions) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { @@ -585,6 +598,7 @@ impl Target { key!(is_like_msvc, bool); key!(is_like_wasm, bool); key!(is_like_android, bool); + key!(binary_format, BinaryFormat)?; key!(default_dwarf_version, u32); key!(allows_weak_linkage, bool); key!(has_rpath, bool); @@ -762,6 +776,7 @@ impl ToJson for Target { target_option_val!(is_like_msvc); target_option_val!(is_like_wasm); target_option_val!(is_like_android); + target_option_val!(binary_format); target_option_val!(default_dwarf_version); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f7e467b0c1155..761d2848a059c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -60,7 +60,7 @@ pub mod crt_objects; mod base; mod json; -pub use base::avr_gnu::ef_avr_arch; +pub use base::avr::ef_avr_arch; /// Linker is called through a C/C++ compiler. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -303,15 +303,16 @@ impl LinkerFlavor { } } - fn infer_linker_hints(linker_stem: &str) -> (Option, Option) { + fn infer_linker_hints(linker_stem: &str) -> Result, Option)> { // Remove any version postfix. let stem = linker_stem .rsplit_once('-') .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs)) .unwrap_or(linker_stem); - // GCC/Clang can have an optional target prefix. - if stem == "emcc" + if stem == "llvm-bitcode-linker" { + Ok(Self::Llbc) + } else if stem == "emcc" // GCC/Clang can have an optional target prefix. || stem == "gcc" || stem.ends_with("-gcc") || stem == "g++" @@ -321,7 +322,7 @@ impl LinkerFlavor { || stem == "clang++" || stem.ends_with("-clang++") { - (Some(Cc::Yes), Some(Lld::No)) + Err((Some(Cc::Yes), Some(Lld::No))) } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") || stem == "ld.lld" @@ -329,11 +330,11 @@ impl LinkerFlavor { || stem == "rust-lld" || stem == "lld-link" { - (Some(Cc::No), Some(Lld::Yes)) + Err((Some(Cc::No), Some(Lld::Yes))) } else if stem == "ld" || stem.ends_with("-ld") || stem == "link" { - (Some(Cc::No), Some(Lld::No)) + Err((Some(Cc::No), Some(Lld::No))) } else { - (None, None) + Err((None, None)) } } @@ -357,7 +358,10 @@ impl LinkerFlavor { } pub fn with_linker_hints(self, linker_stem: &str) -> LinkerFlavor { - self.with_hints(LinkerFlavor::infer_linker_hints(linker_stem)) + match LinkerFlavor::infer_linker_hints(linker_stem) { + Ok(linker_flavor) => linker_flavor, + Err(hints) => self.with_hints(hints), + } } pub fn check_compatibility(self, cli: LinkerFlavorCli) -> Option { @@ -1640,6 +1644,55 @@ impl fmt::Display for StackProtector { } } +#[derive(PartialEq, Clone, Debug)] +pub enum BinaryFormat { + Coff, + Elf, + MachO, + Wasm, + Xcoff, +} + +impl BinaryFormat { + /// Returns [`object::BinaryFormat`] for given `BinaryFormat` + pub fn to_object(&self) -> object::BinaryFormat { + match self { + Self::Coff => object::BinaryFormat::Coff, + Self::Elf => object::BinaryFormat::Elf, + Self::MachO => object::BinaryFormat::MachO, + Self::Wasm => object::BinaryFormat::Wasm, + Self::Xcoff => object::BinaryFormat::Xcoff, + } + } +} + +impl FromStr for BinaryFormat { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "coff" => Ok(Self::Coff), + "elf" => Ok(Self::Elf), + "mach-o" => Ok(Self::MachO), + "wasm" => Ok(Self::Wasm), + "xcoff" => Ok(Self::Xcoff), + _ => Err(()), + } + } +} + +impl ToJson for BinaryFormat { + fn to_json(&self) -> Json { + match self { + Self::Coff => "coff", + Self::Elf => "elf", + Self::MachO => "mach-o", + Self::Wasm => "wasm", + Self::Xcoff => "xcoff", + } + .to_json() + } +} + macro_rules! supported_targets { ( $(($tuple:literal, $module:ident),)+ ) => { mod targets { @@ -1797,7 +1850,7 @@ supported_targets! { ("riscv64gc-unknown-fuchsia", riscv64gc_unknown_fuchsia), ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), - ("avr-unknown-gnu-atmega328", avr_unknown_gnu_atmega328), + ("avr-none", avr_none), ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), @@ -2001,7 +2054,7 @@ supported_targets! { ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock), ("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800), - ("i586-pc-nto-qnx700", i586_pc_nto_qnx700), + ("i686-pc-nto-qnx700", i686_pc_nto_qnx700), ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), @@ -2377,6 +2430,8 @@ pub struct TargetOptions { pub is_like_wasm: bool, /// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc pub is_like_android: bool, + /// Target's binary file format. Defaults to BinaryFormat::Elf + pub binary_format: BinaryFormat, /// Default supported version of DWARF on this platform. /// Useful because some platforms (osx, bsd) only want up to DWARF2. pub default_dwarf_version: u32, @@ -2752,6 +2807,7 @@ impl Default for TargetOptions { is_like_msvc: false, is_like_wasm: false, is_like_android: false, + binary_format: BinaryFormat::Elf, default_dwarf_version: 4, allows_weak_linkage: true, has_rpath: false, @@ -3062,7 +3118,10 @@ impl Target { &self.post_link_args, ] { for (&flavor, flavor_args) in args { - check!(!flavor_args.is_empty(), "linker flavor args must not be empty"); + check!( + !flavor_args.is_empty() || self.arch == "avr", + "linker flavor args must not be empty" + ); // Check that flavors mentioned in link args are compatible with the default flavor. match self.linker_flavor { LinkerFlavor::Gnu(..) => { diff --git a/compiler/rustc_target/src/spec/targets/avr_none.rs b/compiler/rustc_target/src/spec/targets/avr_none.rs new file mode 100644 index 0000000000000..91d3197d0998e --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/avr_none.rs @@ -0,0 +1,32 @@ +use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; + +pub(crate) fn target() -> Target { + Target { + arch: "avr".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + data_layout: "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8".into(), + llvm_target: "avr-unknown-unknown".into(), + pointer_width: 16, + options: TargetOptions { + c_int_width: "16".into(), + exe_suffix: ".elf".into(), + linker: Some("avr-gcc".into()), + eh_frame_header: false, + pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[]), + late_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-lgcc"], + ), + max_atomic_width: Some(16), + atomic_cas: false, + relocation_model: RelocModel::Static, + need_explicit_cpu: true, + ..TargetOptions::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs deleted file mode 100644 index c3d6fb722733d..0000000000000 --- a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::spec::{Target, base}; - -pub(crate) fn target() -> Target { - base::avr_gnu::target("atmega328", "-mmcu=atmega328") -} diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs index dd38f86bced2e..394e6f9e6bf65 100644 --- a/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i586_pc_windows_msvc.rs @@ -2,6 +2,7 @@ use crate::spec::Target; pub(crate) fn target() -> Target { let mut base = super::i686_pc_windows_msvc::target(); + base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target base.cpu = "pentium".into(); base.llvm_target = "i586-pc-windows-msvc".into(); base diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs similarity index 100% rename from compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs rename to compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index bb41d03e87f58..b98bca60c9de4 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -611,7 +611,26 @@ static LOONGARCH_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start ("backchain", Unstable(sym::s390x_target_feature), &[]), + ("deflate-conversion", Unstable(sym::s390x_target_feature), &[]), + ("enhanced-sort", Unstable(sym::s390x_target_feature), &[]), + ("guarded-storage", Unstable(sym::s390x_target_feature), &[]), + ("high-word", Unstable(sym::s390x_target_feature), &[]), + ("nnp-assist", Unstable(sym::s390x_target_feature), &["vector"]), + ("transactional-execution", Unstable(sym::s390x_target_feature), &[]), ("vector", Unstable(sym::s390x_target_feature), &[]), + ("vector-enhancements-1", Unstable(sym::s390x_target_feature), &["vector"]), + ("vector-enhancements-2", Unstable(sym::s390x_target_feature), &["vector-enhancements-1"]), + ("vector-packed-decimal", Unstable(sym::s390x_target_feature), &["vector"]), + ( + "vector-packed-decimal-enhancement", + Unstable(sym::s390x_target_feature), + &["vector-packed-decimal"], + ), + ( + "vector-packed-decimal-enhancement-2", + Unstable(sym::s390x_target_feature), + &["vector-packed-decimal-enhancement"], + ), // tidy-alphabetical-end ]; @@ -768,7 +787,7 @@ impl Target { /// the first list contains target features that must be enabled for ABI reasons, /// and the second list contains target feature that must be disabled for ABI reasons. /// - /// These features are automatically appended to whatever the target spec sats as default + /// These features are automatically appended to whatever the target spec sets as default /// features for the target. /// /// All features enabled/disabled via `-Ctarget-features` and `#[target_features]` are checked diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index b13a753c4ed1e..1c61e23362a83 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -1,14 +1,13 @@ [package] name = "rustc_trait_selection" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index 055a3edcc3293..4db9d9915b139 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -225,14 +225,6 @@ trait_selection_mismatched_static_lifetime = incompatible lifetime on type trait_selection_missing_options_for_on_unimplemented_attr = missing options for `on_unimplemented` attribute .help = at least one of the `message`, `note` and `label` options are expected -trait_selection_more_targeted = {$has_param_name -> - [true] `{$param_name}` - *[false] `fn` parameter -} has {$has_lifetime -> - [true] lifetime `{$lifetime}` - *[false] an anonymous lifetime `'_` -} but calling `{$ident}` introduces an implicit `'static` lifetime requirement - trait_selection_msl_introduces_static = introduces a `'static` lifetime requirement trait_selection_msl_unmet_req = because this has an unmet lifetime requirement diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index 55eb3f777d6b9..bed9734f389c7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -18,7 +18,6 @@ use rustc_middle::ty::{ TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, }; use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym}; -use rustc_type_ir::inherent::*; use rustc_type_ir::visit::TypeVisitableExt; use tracing::{debug, instrument, warn}; @@ -217,7 +216,7 @@ impl<'a, 'tcx> TypeFolder> for ClosureEraser<'a, 'tcx> { // `_` because then we'd end up with `Vec<_, _>`, instead of // `Vec<_>`. arg - } else if let GenericArgKind::Type(_) = arg.kind() { + } else if let GenericArgKind::Type(_) = arg.unpack() { // We don't replace lifetime or const params, only type params. self.new_infer().into() } else { @@ -489,7 +488,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, arg); - if let Some(body) = self.tcx.hir().maybe_body_owned_by( + if let Some(body) = self.tcx.hir_maybe_body_owned_by( self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(), ) { let expr = body.value; @@ -1075,7 +1074,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { &self, path: &'tcx hir::Path<'tcx>, args: GenericArgsRef<'tcx>, - ) -> impl Iterator> + 'a { + ) -> impl Iterator> + 'tcx { let tcx = self.tecx.tcx; let have_turbofish = path.segments.iter().any(|segment| { segment.args.is_some_and(|args| args.args.iter().any(|arg| arg.is_ty_or_const())) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs index ad2f7f00fa53d..0904177ea8bb1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/mismatched_static_lifetime.rs @@ -33,11 +33,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; // If we added a "points at argument expression" obligation, we remove it here, we care // about the original obligation only. - let code = match cause.code() { - ObligationCauseCode::FunctionArg { parent_code, .. } => &*parent_code, - code => code, - }; - let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { + let ObligationCauseCode::MatchImpl(parent, impl_def_id) = cause.code() else { return None; }; let (ObligationCauseCode::WhereClause(_, binding_span) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 35fd4e588ef98..083ce022238a0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -1,27 +1,21 @@ //! Error Reporting for static impl Traits. use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, Subdiagnostic}; +use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{Visitor, VisitorExt, walk_ty}; use rustc_hir::{ self as hir, AmbigArg, GenericBound, GenericParam, GenericParamKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, MissingLifetimeKind, Node, TyKind, }; -use rustc_middle::ty::{ - self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, -}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::LocalDefId; use rustc_span::{Ident, Span}; use tracing::debug; use crate::error_reporting::infer::nice_region_error::NiceRegionError; -use crate::errors::{ - ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted, - ReqIntroducedLocations, -}; -use crate::infer::{RegionResolutionError, SubregionOrigin, TypeTrace}; -use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; +use crate::errors::ButNeedsToSatisfy; +use crate::infer::{RegionResolutionError, SubregionOrigin}; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { /// Print the error message for lifetime errors when the return type is a static `impl Trait`, @@ -39,52 +33,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sup_r, spans, ) if sub_r.is_static() => (var_origin, sub_origin, sub_r, sup_origin, sup_r, spans), - RegionResolutionError::ConcreteFailure( - SubregionOrigin::Subtype(box TypeTrace { cause, .. }), - sub_r, - sup_r, - ) if sub_r.is_static() => { - // This is for an implicit `'static` requirement coming from `impl dyn Trait {}`. - if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() { - // This may have a closure and it would cause ICE - // through `find_param_with_region` (#78262). - let anon_reg_sup = tcx.is_suitable_region(self.generic_param_scope, *sup_r)?; - let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.scope); - if fn_returns.is_empty() { - return None; - } - - let param = self.find_param_with_region(*sup_r, *sub_r)?; - let simple_ident = param.param.pat.simple_ident(); - - let (has_impl_path, impl_path) = match ctxt.assoc_item.container { - AssocItemContainer::Trait => { - let id = ctxt.assoc_item.container_id(tcx); - (true, tcx.def_path_str(id)) - } - AssocItemContainer::Impl => (false, String::new()), - }; - - let mut err = self.tcx().dcx().create_err(ButCallingIntroduces { - param_ty_span: param.param_ty_span, - cause_span: cause.span, - has_param_name: simple_ident.is_some(), - param_name: simple_ident.map(|x| x.to_string()).unwrap_or_default(), - has_lifetime: sup_r.has_name(), - lifetime: sup_r.to_string(), - assoc_item: ctxt.assoc_item.name, - has_impl_path, - impl_path, - }); - if self.find_impl_on_dyn_trait(&mut err, param.param_ty, ctxt) { - let reported = err.emit(); - return Some(reported); - } else { - err.cancel() - } - } - return None; - } _ => return None, }; debug!( @@ -140,39 +88,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None }; - let mut subdiag = None; - - if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin { - if let ObligationCauseCode::ReturnValue(hir_id) - | ObligationCauseCode::BlockTailExpression(hir_id, ..) = cause.code() - { - let parent_id = tcx.hir().get_parent_item(*hir_id); - if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) { - let mut span: MultiSpan = fn_decl.output.span().into(); - let mut spans = Vec::new(); - let mut add_label = true; - if let hir::FnRetTy::Return(ty) = fn_decl.output { - let mut v = StaticLifetimeVisitor(vec![], tcx.hir()); - v.visit_ty_unambig(ty); - if !v.0.is_empty() { - span = v.0.clone().into(); - spans = v.0; - add_label = false; - } - } - let fn_decl_span = fn_decl.output.span(); - - subdiag = Some(ReqIntroducedLocations { - span, - spans, - fn_decl_span, - cause_span: cause.span, - add_label, - }); - } - } - } - let diag = ButNeedsToSatisfy { sp, influencer_point, @@ -183,7 +98,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { require_span_as_note: require_as_note.then_some(require_span), // We don't need a note, it's already at the end, it can be shown as a `span_label`. require_span_as_label: (!require_as_note).then_some(require_span), - req_introduces_loc: subdiag, has_lifetime: sup_r.has_name(), lifetime: lifetime_name.clone(), @@ -197,45 +111,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.scope); - let mut override_error_code = None; - if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin - && let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() - // Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a - // `'static` lifetime when called as a method on a binding: `bar.qux()`. - && self.find_impl_on_dyn_trait(&mut err, param.param_ty, ctxt) - { - override_error_code = Some(ctxt.assoc_item.name); - } - - if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin - && let code = match cause.code() { - ObligationCauseCode::MatchImpl(parent, ..) => parent.code(), - _ => cause.code(), - } - && let ( - &ObligationCauseCode::WhereClause(item_def_id, _) - | &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..), - None, - ) = (code, override_error_code) - { - // Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static` - // lifetime as above, but called using a fully-qualified path to the method: - // `Foo::qux(bar)`. - let mut v = TraitObjectVisitor(FxIndexSet::default()); - v.visit_ty(param.param_ty); - if let Some((ident, self_ty)) = - NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, item_def_id, &v.0) - && self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) - { - override_error_code = Some(ident.name); - } - } - if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) { - // Provide a more targeted error code and description. - let retarget_subdiag = MoreTargeted { ident }; - retarget_subdiag.add_to_diag(&mut err); - } - let arg = match param.param.pat.simple_ident() { Some(simple_ident) => format!("argument `{simple_ident}`"), None => "the argument".to_string(), @@ -472,7 +347,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { match tcx.hir_get_if_local(def_id)? { Node::ImplItem(impl_item) => { - let impl_did = tcx.hir().get_parent_item(impl_item.hir_id()); + let impl_did = tcx.hir_get_parent_item(impl_item.hir_id()); if let hir::OwnerNode::Item(Item { kind: ItemKind::Impl(hir::Impl { self_ty, .. }), .. @@ -484,19 +359,18 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } Node::TraitItem(trait_item) => { - let trait_id = tcx.hir().get_parent_item(trait_item.hir_id()); + let trait_id = tcx.hir_get_parent_item(trait_item.hir_id()); debug_assert_eq!(tcx.def_kind(trait_id.def_id), hir::def::DefKind::Trait); // The method being called is defined in the `trait`, but the `'static` // obligation comes from the `impl`. Find that `impl` so that we can point // at it in the suggestion. let trait_did = trait_id.to_def_id(); - tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { + tcx.hir_trait_impls(trait_did).iter().find_map(|&impl_did| { if let Node::Item(Item { kind: ItemKind::Impl(hir::Impl { self_ty, .. }), .. }) = tcx.hir_node_by_def_id(impl_did) && trait_objects.iter().all(|did| { - // FIXME: we should check `self_ty` against the receiver - // type in the `UnifyReceiver` context, but for now, use + // FIXME: we should check `self_ty`, but for now, use // this imperfect proxy. This will fail if there are // multiple `impl`s for the same trait like // `impl Foo for Box` and `impl Foo for dyn Bar`. @@ -516,62 +390,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _ => None, } } - - /// When we call a method coming from an `impl Foo for dyn Bar`, `dyn Bar` introduces a default - /// `'static` obligation. Suggest relaxing that implicit bound. - fn find_impl_on_dyn_trait( - &self, - err: &mut Diag<'_>, - ty: Ty<'_>, - ctxt: &UnifyReceiverContext<'tcx>, - ) -> bool { - let tcx = self.tcx(); - - // Find the method being called. - let Ok(Some(instance)) = ty::Instance::try_resolve( - tcx, - self.cx.typing_env(ctxt.param_env), - ctxt.assoc_item.def_id, - self.cx.resolve_vars_if_possible(ctxt.args), - ) else { - return false; - }; - - let mut v = TraitObjectVisitor(FxIndexSet::default()); - v.visit_ty(ty); - - // Get the `Ident` of the method being called and the corresponding `impl` (to point at - // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called). - let Some((ident, self_ty)) = - NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) - else { - return false; - }; - - // Find the trait object types in the argument, so we point at *only* the trait object. - self.suggest_constrain_dyn_trait_in_impl(err, &v.0, ident, self_ty) - } - - fn suggest_constrain_dyn_trait_in_impl( - &self, - err: &mut Diag<'_>, - found_dids: &FxIndexSet, - ident: Ident, - self_ty: &hir::Ty<'_>, - ) -> bool { - let mut suggested = false; - for found_did in found_dids { - let mut traits = vec![]; - let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did); - hir_v.visit_ty_unambig(self_ty); - for &span in &traits { - let subdiag = DynTraitConstraintSuggestion { span, ident }; - subdiag.add_to_diag(err); - suggested = true; - } - } - suggested - } } /// Collect all the trait objects in a type that could have received an implicit `'static` lifetime. diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 0695cc5797876..cc2ab1c343289 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -99,11 +99,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; match assoc_item.kind { ty::AssocKind::Fn => { - let hir = self.tcx().hir(); if let Some(hir_id) = assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id)) { - if let Some(decl) = hir.fn_decl_by_hir_id(hir_id) { + if let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id) { visitor.visit_fn_decl(decl); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 445937ad16928..245764c94abf0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -64,10 +64,10 @@ pub fn find_param_with_region<'tcx>( _ => {} } - let body = hir.maybe_body_owned_by(def_id)?; + let body = tcx.hir_maybe_body_owned_by(def_id)?; - let owner_id = hir.body_owner(body.id()); - let fn_decl = hir.fn_decl_by_hir_id(owner_id)?; + let owner_id = tcx.hir_body_owner(body.id()); + let fn_decl = tcx.hir_fn_decl_by_hir_id(owner_id)?; let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 37032b5390187..36726cc6cae0d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -586,7 +586,7 @@ impl Trait for X { hir::Node::TraitItem(item) => item.hir_id(), _ => return false, }; - let parent = tcx.hir().get_parent_item(hir_id).def_id; + let parent = tcx.hir_get_parent_item(hir_id).def_id; self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty) } @@ -820,7 +820,7 @@ fn foo(&self) -> Self::T { String::new() } // When `body_owner` is an `impl` or `trait` item, look in its associated types for // `expected` and point at it. let hir_id = tcx.local_def_id_to_hir_id(def_id); - let parent_id = tcx.hir().get_parent_item(hir_id); + let parent_id = tcx.hir_get_parent_item(hir_id); let item = tcx.hir_node_by_def_id(parent_id.def_id); debug!("expected_projection parent item {:?}", item); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index d009687ef14d6..fecb38ab597e4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -2,7 +2,7 @@ use std::iter; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ - Applicability, Diag, E0309, E0310, E0311, E0495, Subdiagnostic, struct_span_code_err, + Applicability, Diag, E0309, E0310, E0311, E0803, Subdiagnostic, struct_span_code_err, }; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -1032,7 +1032,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { struct_span_code_err!( self.dcx(), var_origin.span(), - E0495, + E0803, "cannot infer an appropriate lifetime{} due to conflicting requirements", var_description ) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index bb25c5e8bd1b3..a7e68e6419d84 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -10,7 +10,6 @@ use rustc_hir::def::Res; use rustc_hir::{MatchSource, Node}; use rustc_middle::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, - StatementAsExpression, }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -26,8 +25,14 @@ use crate::errors::{ SuggestTuplePatternMany, SuggestTuplePatternOne, TypeErrorAdditionalDiags, }; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +enum StatementAsExpression { + CorrectType, + NeedsBoxing, +} + #[derive(Clone, Copy)] -pub enum SuggestAsRefKind { +enum SuggestAsRefKind { Option, Result, } @@ -232,7 +237,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Some(ConsiderAddingAwait::FutureSugg { span: then_span.shrink_to_hi() }) } ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { - ref prior_non_diverging_arms, + prior_non_diverging_arms, .. }) => Some({ ConsiderAddingAwait::FutureSuggMultiple { @@ -382,7 +387,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - pub fn suggest_function_pointers_impl( + pub(crate) fn suggest_function_pointers_impl( &self, span: Option, exp_found: &ty::error::ExpectedFound>, @@ -518,7 +523,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - pub fn should_suggest_as_ref_kind( + fn should_suggest_as_ref_kind( &self, expected: Ty<'tcx>, found: Ty<'tcx>, @@ -588,8 +593,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) -> Option { /// Find the if expression with given span struct IfVisitor { - pub found_if: bool, - pub err_span: Span, + found_if: bool, + err_span: Span, } impl<'v> Visitor<'v> for IfVisitor { @@ -624,7 +629,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - self.tcx.hir().maybe_body_owned_by(cause.body_id).and_then(|body| { + self.tcx.hir_maybe_body_owned_by(cause.body_id).and_then(|body| { IfVisitor { err_span: span, found_if: false } .visit_body(&body) .is_break() @@ -736,7 +741,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> TypeErrCtxt<'_, 'tcx> { /// Be helpful when the user wrote `{... expr; }` and taking the `;` off /// is enough to fix the error. - pub fn could_remove_semicolon( + fn could_remove_semicolon( &self, blk: &'tcx hir::Block<'tcx>, expected_ty: Ty<'tcx>, @@ -816,7 +821,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { /// Suggest returning a local binding with a compatible type if the block /// has no return expression. - pub fn consider_returning_binding_diag( + fn consider_returning_binding_diag( &self, blk: &'tcx hir::Block<'tcx>, expected_ty: Ty<'tcx>, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 6beb108bc3aee..f15f1b78b5282 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -316,7 +316,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack()) - && let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + && let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(&body.value); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index ecfffb65fbc1e..596f794568c5d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -192,19 +192,38 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, main_trait_predicate.def_id()); + let is_question_mark = matches!( + root_obligation.cause.code().peel_derives(), + ObligationCauseCode::QuestionMark, + ) && !( + self.tcx.is_diagnostic_item(sym::FromResidual, main_trait_predicate.def_id()) + || self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::Try) + ); let is_unsize = self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Unsize); + let question_mark_message = "the question mark operation (`?`) implicitly \ + performs a conversion on the error value \ + using the `From` trait"; let (message, notes, append_const_msg) = if is_try_conversion { + // We have a `-> Result<_, E1>` and `gives_E2()?`. ( Some(format!( "`?` couldn't convert the error to `{}`", main_trait_predicate.skip_binder().self_ty(), )), - vec![ - "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" - .to_owned(), - ], + vec![question_mark_message.to_owned()], + Some(AppendConstMessage::Default), + ) + } else if is_question_mark { + // Similar to the case above, but in this case the conversion is for a + // trait object: `-> Result<_, Box` and `gives_E()?` when + // `E: Error` isn't met. + ( + Some(format!( + "`?` couldn't convert the error: `{main_trait_predicate}` is \ + not satisfied", + )), + vec![question_mark_message.to_owned()], Some(AppendConstMessage::Default), ) } else { @@ -220,8 +239,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &mut long_ty_file, ); - let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait) - { + let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item( + main_trait_predicate.def_id(), + LangItem::TransmuteTrait, + ) { // Recompute the safe transmute reason and use that for the error reporting match self.get_safe_transmute_error_and_reason( obligation.clone(), @@ -249,18 +270,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { *err.long_ty_path() = long_ty_file; let mut suggested = false; - if is_try_conversion { + if is_try_conversion || is_question_mark { suggested = self.try_conversion_context(&obligation, main_trait_predicate, &mut err); } - if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) { - err.span_label( - ret_span, - format!( - "expected `{}` because of this", - main_trait_predicate.skip_binder().self_ty() - ), - ); + if let Some(ret_span) = self.return_type_span(&obligation) { + if is_try_conversion { + err.span_label( + ret_span, + format!( + "expected `{}` because of this", + main_trait_predicate.skip_binder().self_ty() + ), + ); + } else if is_question_mark { + err.span_label(ret_span, format!("required `{main_trait_predicate}` because of this")); + } } if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Tuple) { @@ -302,10 +327,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label! err.span_label(span, s); - if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_)) { + if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_)) // When the self type is a type param We don't need to "the trait // `std::marker::Sized` is not implemented for `T`" as we will point // at the type param with a label to suggest constraining it. + && !self.tcx.is_diagnostic_item(sym::FromResidual, leaf_trait_predicate.def_id()) + // Don't say "the trait `FromResidual>` is + // not implemented for `Result`". + { err.help(explanation); } } else if let Some(custom_explanation) = safe_transmute_explanation { @@ -367,7 +396,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { (span.shrink_to_lo(), format!("(")), (span.shrink_to_hi(), format!(" as {})", cand.self_ty())), ] - } else if let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { + } else if let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) { let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); if let Some(expr) = expr_finder.result && @@ -932,16 +961,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let Some(typeck) = &self.typeck_results else { return false; }; - let Some((ObligationCauseCode::QuestionMark, Some(y))) = - obligation.cause.code().parent_with_predicate() - else { + let ObligationCauseCode::QuestionMark = obligation.cause.code().peel_derives() else { return false; }; - if !self.tcx.is_diagnostic_item(sym::FromResidual, y.def_id()) { - return false; - } let self_ty = trait_pred.skip_binder().self_ty(); let found_ty = trait_pred.skip_binder().trait_ref.args.get(1).and_then(|a| a.as_type()); + self.note_missing_impl_for_question_mark(err, self_ty, found_ty, trait_pred); let mut prev_ty = self.resolve_vars_if_possible( typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)), @@ -1106,6 +1131,56 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { suggested } + fn note_missing_impl_for_question_mark( + &self, + err: &mut Diag<'_>, + self_ty: Ty<'_>, + found_ty: Option>, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) { + match (self_ty.kind(), found_ty) { + (ty::Adt(def, _), Some(ty)) + if let ty::Adt(found, _) = ty.kind() + && def.did().is_local() + && found.did().is_local() => + { + err.span_note( + self.tcx.def_span(def.did()), + format!("`{self_ty}` needs to implement `From<{ty}>`"), + ); + err.span_note( + self.tcx.def_span(found.did()), + format!("alternatively, `{ty}` needs to implement `Into<{self_ty}>`"), + ); + } + (ty::Adt(def, _), None) if def.did().is_local() => { + err.span_note( + self.tcx.def_span(def.did()), + format!( + "`{self_ty}` needs to implement `{}`", + trait_pred.skip_binder().trait_ref.print_only_trait_path(), + ), + ); + } + (ty::Adt(def, _), Some(ty)) if def.did().is_local() => { + err.span_note( + self.tcx.def_span(def.did()), + format!("`{self_ty}` needs to implement `From<{ty}>`"), + ); + } + (_, Some(ty)) + if let ty::Adt(def, _) = ty.kind() + && def.did().is_local() => + { + err.span_note( + self.tcx.def_span(def.did()), + format!("`{ty}` needs to implement `Into<{self_ty}>`"), + ); + } + _ => {} + } + } + fn report_const_param_not_wf( &self, ty: Ty<'tcx>, @@ -2035,6 +2110,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; } if let &[cand] = &candidates[..] { + if self.tcx.is_diagnostic_item(sym::FromResidual, cand.def_id) + && !self.tcx.features().enabled(sym::try_trait_v2) + { + return false; + } let (desc, mention_castable) = match (cand.self_ty().kind(), trait_pred.self_ty().skip_binder().kind()) { (ty::FnPtr(..), ty::FnDef(..)) => { @@ -2357,7 +2437,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligated_types: &mut Vec>, cause_code: &ObligationCauseCode<'tcx>, ) -> bool { - if let ObligationCauseCode::BuiltinDerived(ref data) = cause_code { + if let ObligationCauseCode::BuiltinDerived(data) = cause_code { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); let self_ty = parent_trait_ref.skip_binder().self_ty(); if obligated_types.iter().any(|ot| ot == &self_ty) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 22d219cd64d27..4d87a93be0ca0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -587,7 +587,7 @@ fn attempt_dyn_to_impl_suggestion(tcx: TyCtxt<'_>, hir_id: Option, e // `type Alias = Box;` to // `type Alias = Box;` let Some((_id, first_non_type_parent_node)) = - tcx.hir().parent_iter(hir_id).find(|(_id, node)| !matches!(node, hir::Node::Ty(_))) + tcx.hir_parent_iter(hir_id).find(|(_id, node)| !matches!(node, hir::Node::Ty(_))) else { return; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ac1ced2ed3c3d..c7e71a626dc51 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -876,7 +876,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return; }; expr_finder.visit_expr(body.value); @@ -974,7 +974,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { hir::ExprKind::MethodCall( hir::PathSegment { ident, .. }, _receiver, - &[], + [], call_span, ), hir_id, @@ -1347,8 +1347,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` - let Some(body) = - self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return false; }; @@ -1447,7 +1446,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { span.remove_mark(); } let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); - let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { + let Some(body) = self.tcx.hir_maybe_body_owned_by(obligation.cause.body_id) else { return false; }; expr_finder.visit_expr(body.value); @@ -1553,7 +1552,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, err: &mut Diag<'_>, ) { - let hir = self.tcx.hir(); if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives() && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id) { @@ -1563,7 +1561,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // it is from the local crate. // use nth(1) to skip one layer of desugaring from `IntoIter::into_iter` - if let Some((_, hir::Node::Expr(await_expr))) = hir.parent_iter(*hir_id).nth(1) + if let Some((_, hir::Node::Expr(await_expr))) = self.tcx.hir_parent_iter(*hir_id).nth(1) && let Some(expr_span) = expr.span.find_ancestor_inside_same_ctxt(await_expr.span) { let removal_span = self @@ -1766,7 +1764,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.children.clear(); let span = obligation.cause.span; - let body = self.tcx.hir().body_owned_by(obligation.cause.body_id); + let body = self.tcx.hir_body_owned_by(obligation.cause.body_id); let mut visitor = ReturnsVisitor::default(); visitor.visit_body(&body); @@ -2300,7 +2298,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); let coroutine_body = - coroutine_did.as_local().and_then(|def_id| hir.maybe_body_owned_by(def_id)); + coroutine_did.as_local().and_then(|def_id| self.tcx.hir_maybe_body_owned_by(def_id)); let mut visitor = AwaitsVisitor::default(); if let Some(body) = coroutine_body { visitor.visit_body(&body); @@ -2682,7 +2680,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { | ObligationCauseCode::IntrinsicType | ObligationCauseCode::MethodReceiver | ObligationCauseCode::ReturnNoExpression - | ObligationCauseCode::UnifyReceiver(..) | ObligationCauseCode::Misc | ObligationCauseCode::WellFormed(..) | ObligationCauseCode::MatchImpl(..) @@ -3290,6 +3287,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut parent_trait_pred = self.resolve_vars_if_possible(data.derived.parent_trait_pred); let parent_def_id = parent_trait_pred.def_id(); + if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id) + && !tcx.features().enabled(sym::try_trait_v2) + { + // If `#![feature(try_trait_v2)]` is not enabled, then there's no point on + // talking about `FromResidual>`, as the end user has nothing they + // can do about it. As far as they are concerned, `?` is compiler magic. + return; + } let self_ty_str = tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path()); let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string(); @@ -4111,8 +4116,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let ty::Param(..) = ty.kind() else { continue; }; - let hir = tcx.hir(); - let node = tcx.hir_node_by_def_id(hir.get_parent_item(expr.hir_id).def_id); + let node = + tcx.hir_node_by_def_id(tcx.hir_get_parent_item(expr.hir_id).def_id); let pred = ty::Binder::dummy(ty::TraitPredicate { trait_ref: ty::TraitRef::new( @@ -4130,7 +4135,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; suggest_restriction( tcx, - hir.body_owner_def_id(body_id), + tcx.hir_body_owner_def_id(body_id), generics, &format!("type parameter `{ty}`"), err, @@ -4352,7 +4357,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { term: ty.into(), }), )); - let body_def_id = self.tcx.hir().enclosing_body_owner(body_id); + let body_def_id = self.tcx.hir_enclosing_body_owner(body_id); // Add `::Item = _` obligation. ocx.register_obligation(Obligation::misc( self.tcx, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index ac4399750f598..23aa380066043 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -509,21 +509,18 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { let node = self.tcx.hir_node_by_def_id(anon_reg.scope); let is_impl = matches!(&node, hir::Node::ImplItem(_)); let (generics, parent_generics) = match node { - hir::Node::Item(&hir::Item { - kind: hir::ItemKind::Fn { ref generics, .. }, - .. - }) - | hir::Node::TraitItem(&hir::TraitItem { ref generics, .. }) - | hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => ( + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { generics, .. }, .. }) + | hir::Node::TraitItem(hir::TraitItem { generics, .. }) + | hir::Node::ImplItem(hir::ImplItem { generics, .. }) => ( generics, match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.scope)) { hir::Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, _, ref generics, ..), + kind: hir::ItemKind::Trait(_, _, generics, ..), .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { ref generics, .. }), + kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), .. }) => Some(generics), _ => None, @@ -1119,22 +1116,6 @@ impl Subdiagnostic for ReqIntroducedLocations { } } -pub struct MoreTargeted { - pub ident: Symbol, -} - -impl Subdiagnostic for MoreTargeted { - fn add_to_diag_with>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - diag.code(E0772); - diag.primary_message(fluent::trait_selection_more_targeted); - diag.arg("ident", self.ident); - } -} - #[derive(Diagnostic)] #[diag(trait_selection_but_needs_to_satisfy, code = E0759)] pub struct ButNeedsToSatisfy { @@ -1151,9 +1132,6 @@ pub struct ButNeedsToSatisfy { #[note(trait_selection_introduced_by_bound)] pub bound: Option, - #[subdiagnostic] - pub req_introduces_loc: Option, - pub has_param_name: bool, pub param_name: String, pub spans_empty: bool, @@ -1880,8 +1858,7 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( let opaque_hir_id = tcx.local_def_id_to_hir_id(opaque_def_id); // FIXME: This is a bit too conservative, since it ignores parens already written in AST. let (lparen, rparen) = match tcx - .hir() - .parent_iter(opaque_hir_id) + .hir_parent_iter(opaque_hir_id) .nth(1) .expect("expected ty to have a parent always") .1 diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index c238e708ab8fa..704ba6e501d8c 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -67,7 +67,7 @@ impl<'tcx> ObligationStorage<'tcx> { obligations } - fn unstalled_for_select(&mut self) -> impl Iterator> { + fn unstalled_for_select(&mut self) -> impl Iterator> + 'tcx { mem::take(&mut self.pending).into_iter() } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 9fbc1d64d7429..4b1bc316d5f1d 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -11,12 +11,11 @@ use std::assert_matches::assert_matches; -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_macros::extension; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult}; +use rustc_middle::ty::visit::{VisitorResult, try_visit}; use rustc_middle::ty::{TyCtxt, TypeFoldable}; use rustc_middle::{bug, ty}; use rustc_next_trait_solver::resolve::EagerResolver; diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index efe2386d014b3..740f44ebcade2 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -698,11 +698,11 @@ impl<'tcx> TypeVisitor> for IllegalSelfTypeVisitor<'tcx> { ControlFlow::Continue(()) } } - ty::Alias(ty::Projection, ref data) if self.tcx.is_impl_trait_in_trait(data.def_id) => { + ty::Alias(ty::Projection, data) if self.tcx.is_impl_trait_in_trait(data.def_id) => { // We'll deny these later in their own pass ControlFlow::Continue(()) } - ty::Alias(ty::Projection, ref data) => { + ty::Alias(ty::Projection, data) => { match self.allow_self_projections { AllowSelfProjections::Yes => { // This is a projected type `::X`. diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index f2d2dd2f3ce59..e39f8e673dbac 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,6 +1,5 @@ use std::marker::PhantomData; -use rustc_data_structures::captures::Captures; use rustc_data_structures::obligation_forest::{ Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult, }; @@ -900,10 +899,10 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { } /// Returns the set of inference variables contained in `args`. -fn args_infer_vars<'a, 'tcx>( - selcx: &SelectionContext<'a, 'tcx>, +fn args_infer_vars<'tcx>( + selcx: &SelectionContext<'_, 'tcx>, args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, -) -> impl Iterator + Captures<'tcx> { +) -> impl Iterator { selcx .infcx .resolve_vars_if_possible(args) diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 92098e204487a..f04a5feba3011 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -2,12 +2,13 @@ use rustc_data_structures::fx::FxHashSet; use rustc_infer::traits::query::type_op::DropckOutlives; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt}; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::Span; use tracing::{debug, instrument}; +use crate::solve::NextSolverError; use crate::traits::query::NoSolution; use crate::traits::query::normalize::QueryNormalizeExt; -use crate::traits::{Normalized, ObligationCause, ObligationCtxt}; +use crate::traits::{FromSolverError, Normalized, ObligationCause, ObligationCtxt}; /// This returns true if the type `ty` is "trivial" for /// dropck-outlives -- that is, if it doesn't require any types to @@ -93,6 +94,20 @@ pub fn compute_dropck_outlives_inner<'tcx>( goal: ParamEnvAnd<'tcx, DropckOutlives<'tcx>>, span: Span, ) -> Result, NoSolution> { + match compute_dropck_outlives_with_errors(ocx, goal, span) { + Ok(r) => Ok(r), + Err(_) => Err(NoSolution), + } +} + +pub fn compute_dropck_outlives_with_errors<'tcx, E>( + ocx: &ObligationCtxt<'_, 'tcx, E>, + goal: ParamEnvAnd<'tcx, DropckOutlives<'tcx>>, + span: Span, +) -> Result, Vec> +where + E: FromSolverError<'tcx, NextSolverError<'tcx>>, +{ let tcx = ocx.infcx.tcx; let ParamEnvAnd { param_env, value: DropckOutlives { dropped_ty } } = goal; @@ -149,11 +164,11 @@ pub fn compute_dropck_outlives_inner<'tcx>( dtorck_constraint_for_ty_inner( tcx, ocx.infcx.typing_env(param_env), - DUMMY_SP, + span, depth, ty, &mut constraints, - )?; + ); // "outlives" represent types/regions that may be touched // by a destructor. @@ -173,11 +188,20 @@ pub fn compute_dropck_outlives_inner<'tcx>( // do not themselves define a destructor", more or less. We have // to push them onto the stack to be expanded. for ty in constraints.dtorck_types.drain(..) { - let Normalized { value: ty, obligations } = - ocx.infcx.at(&cause, param_env).query_normalize(ty)?; - ocx.register_obligations(obligations); + let ty = if let Ok(Normalized { value: ty, obligations }) = + ocx.infcx.at(&cause, param_env).query_normalize(ty) + { + ocx.register_obligations(obligations); + + debug!("dropck_outlives: ty from dtorck_types = {:?}", ty); + ty + } else { + ocx.deeply_normalize(&cause, param_env, ty)?; - debug!("dropck_outlives: ty from dtorck_types = {:?}", ty); + let errors = ocx.select_where_possible(); + debug!("normalize errors: {ty} ~> {errors:#?}"); + return Err(errors); + }; match ty.kind() { // All parameters live for the duration of the @@ -213,14 +237,14 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( depth: usize, ty: Ty<'tcx>, constraints: &mut DropckConstraint<'tcx>, -) -> Result<(), NoSolution> { +) { if !tcx.recursion_limit().value_within_limit(depth) { constraints.overflows.push(ty); - return Ok(()); + return; } if trivial_dropck_outlives(tcx, ty) { - return Ok(()); + return; } match ty.kind() { @@ -244,22 +268,20 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( // single-element containers, behave like their element rustc_data_structures::stack::ensure_sufficient_stack(|| { dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, *ety, constraints) - })?; + }); } ty::Tuple(tys) => rustc_data_structures::stack::ensure_sufficient_stack(|| { for ty in tys.iter() { - dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints); } - Ok::<_, NoSolution>(()) - })?, + }), ty::Closure(_, args) => rustc_data_structures::stack::ensure_sufficient_stack(|| { for ty in args.as_closure().upvar_tys() { - dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, depth + 1, ty, constraints); } - Ok::<_, NoSolution>(()) - })?, + }), ty::CoroutineClosure(_, args) => { rustc_data_structures::stack::ensure_sufficient_stack(|| { @@ -271,10 +293,9 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( depth + 1, ty, constraints, - )?; + ); } - Ok::<_, NoSolution>(()) - })? + }) } ty::Coroutine(_, args) => { @@ -313,7 +334,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( ty::Adt(def, args) => { let DropckConstraint { dtorck_types, outlives, overflows } = - tcx.at(span).adt_dtorck_constraint(def.did())?; + tcx.at(span).adt_dtorck_constraint(def.did()); // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. constraints @@ -346,9 +367,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>( ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => { // By the time this code runs, all type variables ought to // be fully resolved. - return Err(NoSolution); + tcx.dcx().span_delayed_bug(span, format!("Unresolved type in dropck: {:?}.", ty)); } } - - Ok(()) } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index f39c611d19fe0..19d3561dd595c 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -200,15 +200,12 @@ impl<'tcx> Children { } } -fn iter_children(children: &Children) -> impl Iterator + '_ { +fn iter_children(children: &Children) -> impl Iterator { let nonblanket = children.non_blanket_impls.iter().flat_map(|(_, v)| v.iter()); children.blanket_impls.iter().chain(nonblanket).cloned() } -fn filtered_children( - children: &mut Children, - st: SimplifiedType, -) -> impl Iterator + '_ { +fn filtered_children(children: &mut Children, st: SimplifiedType) -> impl Iterator { let nonblanket = children.non_blanket_impls.entry(st).or_default().iter(); children.blanket_impls.iter().chain(nonblanket).cloned() } diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 0024316b877c5..165174c0bcc15 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -196,7 +196,7 @@ fn own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> &[Def fn own_existential_vtable_entries_iter( tcx: TyCtxt<'_>, trait_def_id: DefId, -) -> impl Iterator + '_ { +) -> impl Iterator { let trait_methods = tcx .associated_items(trait_def_id) .in_definition_order() diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 9c788116d98c3..04aef4e7b9e03 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_traits" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index e5276e6d51585..cc329ca33288c 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -80,16 +80,14 @@ pub(crate) fn codegen_select_candidate<'tcx>( // but never resolved, causing the return value of a query to contain inference // vars. We do not have a concept for this and will in fact ICE in stable hashing // of the return value. So bail out instead. - match impl_source { - ImplSource::UserDefined(impl_) => { - tcx.dcx().span_delayed_bug( - tcx.def_span(impl_.impl_def_id), - "this impl has unconstrained generic parameters", - ); - } + let guar = match impl_source { + ImplSource::UserDefined(impl_) => tcx.dcx().span_delayed_bug( + tcx.def_span(impl_.impl_def_id), + "this impl has unconstrained generic parameters", + ), _ => unreachable!(), - } - return Err(CodegenObligationError::FulfillmentError); + }; + return Err(CodegenObligationError::UnconstrainedParam(guar)); } Ok(&*tcx.arena.alloc(impl_source)) diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index b3377e15aa791..5eddad39e2be2 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -30,10 +30,7 @@ fn dropck_outlives<'tcx>( } /// Calculates the dtorck constraint for a type. -pub(crate) fn adt_dtorck_constraint( - tcx: TyCtxt<'_>, - def_id: DefId, -) -> Result<&DropckConstraint<'_>, NoSolution> { +pub(crate) fn adt_dtorck_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &DropckConstraint<'_> { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id); @@ -52,20 +49,20 @@ pub(crate) fn adt_dtorck_constraint( overflows: vec![], }; debug!("dtorck_constraint: {:?} => {:?}", def, result); - return Ok(tcx.arena.alloc(result)); + return tcx.arena.alloc(result); } let mut result = DropckConstraint::empty(); for field in def.all_fields() { let fty = tcx.type_of(field.did).instantiate_identity(); - dtorck_constraint_for_ty_inner(tcx, typing_env, span, 0, fty, &mut result)?; + dtorck_constraint_for_ty_inner(tcx, typing_env, span, 0, fty, &mut result); } result.outlives.extend(tcx.destructor_constraints(def)); dedup_dtorck_constraint(&mut result); debug!("dtorck_constraint: {:?} => {:?}", def, result); - Ok(tcx.arena.alloc(result)) + tcx.arena.alloc(result) } fn dedup_dtorck_constraint(c: &mut DropckConstraint<'_>) { diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 6a98be1850390..e9daf6b0c384a 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -1,12 +1,11 @@ [package] name = "rustc_transmute" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi", optional = true } -rustc_ast_ir = { path = "../rustc_ast_ir", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir", optional = true } rustc_infer = { path = "../rustc_infer", optional = true } @@ -19,7 +18,6 @@ tracing = "0.1" [features] rustc = [ "dep:rustc_abi", - "dep:rustc_ast_ir", "dep:rustc_hir", "dep:rustc_infer", "dep:rustc_macros", diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 40356e0c97855..4c7a57f2931bf 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "rustc_ty_utils" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start itertools = "0.12" rustc_abi = { path = "../rustc_abi" } -rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index c5d2d0afbfad2..0ff82f0c256de 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -464,7 +464,7 @@ fn fn_abi_sanity_check<'tcx>( match &arg.mode { PassMode::Ignore => { - assert!(arg.layout.is_zst() || arg.layout.is_uninhabited()); + assert!(arg.layout.is_zst()); } PassMode::Direct(_) => { // Here the Rust type is used to determine the actual ABI, so we have to be very @@ -472,9 +472,7 @@ fn fn_abi_sanity_check<'tcx>( // `layout.backend_repr` and ignore everything else. We should just reject //`Aggregate` entirely here, but some targets need to be fixed first. match arg.layout.backend_repr { - BackendRepr::Uninhabited - | BackendRepr::Scalar(_) - | BackendRepr::Vector { .. } => {} + BackendRepr::Scalar(_) | BackendRepr::Vector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index f71b924b177a5..c8034f4e7b9f6 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -95,7 +95,7 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem { let id = tcx.local_def_id_to_hir_id(def_id); - let parent_def_id = tcx.hir().get_parent_item(id); + let parent_def_id = tcx.hir_get_parent_item(id); let parent_item = tcx.hir().expect_item(parent_def_id.def_id); match parent_item.kind { hir::ItemKind::Impl(impl_) => { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index cc7baf8daac54..6205578bf7476 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -151,7 +151,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' } } -fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator + '_ { +fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator { let node = tcx.hir_node_by_def_id(def_id); if let Some(decl) = node.fn_decl() { decl.inputs.iter().map(|ty| ty.span).chain(iter::once(decl.output.span())) @@ -160,7 +160,7 @@ fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator, def_id: LocalDefId) -> impl Iterator + '_ { +fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator { let item = tcx.hir().expect_item(def_id); if let hir::ItemKind::Impl(impl_) = item.kind { let trait_args = impl_ diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 8c6e3c86bf5c8..d059d6dcd139c 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -112,6 +112,7 @@ fn resolve_associated_item<'tcx>( | CodegenObligationError::Unimplemented | CodegenObligationError::FulfillmentError, ) => return Ok(None), + Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar), }; // Now that we know which impl is being used, we can dispatch to diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index ee271048fc171..2ab6b8e17c4cc 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -9,6 +9,7 @@ use rustc_abi::{ HasDataLayout, Layout, LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, }; +use rustc_hashes::Hash64; use rustc_index::bit_set::DenseBitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::bug; @@ -133,42 +134,45 @@ fn univariant_uninterned<'tcx>( cx: &LayoutCx<'tcx>, ty: Ty<'tcx>, fields: &IndexSlice>, - repr: &ReprOptions, kind: StructKind, ) -> Result, &'tcx LayoutError<'tcx>> { - let pack = repr.pack; - if pack.is_some() && repr.align.is_some() { - cx.tcx().dcx().bug("struct cannot be packed and aligned"); - } - - cx.calc.univariant(fields, repr, kind).map_err(|err| map_error(cx, ty, err)) + let repr = ReprOptions::default(); + cx.calc.univariant(fields, &repr, kind).map_err(|err| map_error(cx, ty, err)) } fn extract_const_value<'tcx>( - const_: ty::Const<'tcx>, - ty: Ty<'tcx>, cx: &LayoutCx<'tcx>, + ty: Ty<'tcx>, + ct: ty::Const<'tcx>, ) -> Result, &'tcx LayoutError<'tcx>> { - match const_.kind() { + match ct.kind() { ty::ConstKind::Value(cv) => Ok(cv), - ty::ConstKind::Error(guar) => { - return Err(error(cx, LayoutError::ReferencesError(guar))); - } ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) => { - if !const_.has_param() { - bug!("no generic type found in the type: {ty:?}"); + if !ct.has_param() { + bug!("failed to normalize const, but it is not generic: {ct:?}"); } - return Err(error(cx, LayoutError::TooGeneric(ty))); + Err(error(cx, LayoutError::TooGeneric(ty))) } ty::ConstKind::Unevaluated(_) => { - if !const_.has_param() { - return Err(error(cx, LayoutError::Unknown(ty))); + let err = if ct.has_param() { + LayoutError::TooGeneric(ty) } else { - return Err(error(cx, LayoutError::TooGeneric(ty))); - } + // This case is reachable with unsatisfiable predicates and GCE (which will + // cause anon consts to inherit the unsatisfiable predicates). For example + // if we have an unsatisfiable `u8: Trait` bound, then it's not a compile + // error to mention `[u8; ::CONST]`, but we can't compute its + // layout. + LayoutError::Unknown(ty) + }; + Err(error(cx, err)) } - ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { - bug!("unexpected type: {ty:?}"); + ty::ConstKind::Infer(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Error(_) => { + // `ty::ConstKind::Error` is handled at the top of `layout_of_uncached` + // (via `ty.error_reported()`). + bug!("layout_of: unexpected const: {ct:?}"); } } } @@ -193,10 +197,9 @@ fn layout_of_uncached<'tcx>( }; let scalar = |value: Primitive| tcx.mk_layout(LayoutData::scalar(cx, scalar_unit(value))); - let univariant = - |fields: &IndexSlice>, repr: &ReprOptions, kind| { - Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?)) - }; + let univariant = |fields: &IndexSlice>, kind| { + Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, kind)?)) + }; debug_assert!(!ty.has_non_region_infer()); Ok(match *ty.kind() { @@ -209,12 +212,12 @@ fn layout_of_uncached<'tcx>( &mut layout.backend_repr { if let Some(start) = start { - scalar.valid_range_mut().start = extract_const_value(start, ty, cx)? + scalar.valid_range_mut().start = extract_const_value(cx, ty, start)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; } if let Some(end) = end { - let mut end = extract_const_value(end, ty, cx)? + let mut end = extract_const_value(cx, ty, end)? .try_to_bits(tcx, cx.typing_env) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; if !include_end { @@ -273,16 +276,11 @@ fn layout_of_uncached<'tcx>( data_ptr.valid_range_mut().start = 1; } - let pointee = tcx.normalize_erasing_regions(cx.typing_env, pointee); if pointee.is_sized(tcx, cx.typing_env) { return Ok(tcx.mk_layout(LayoutData::scalar(cx, data_ptr))); } - let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() - // Projection eagerly bails out when the pointee references errors, - // fall back to structurally deducing metadata. - && !pointee.references_error() - { + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); let metadata_ty = match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) { @@ -353,7 +351,7 @@ fn layout_of_uncached<'tcx>( // Arrays and slices. ty::Array(element, count) => { - let count = extract_const_value(count, ty, cx)? + let count = extract_const_value(cx, ty, count)? .try_to_target_usize(tcx) .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?; @@ -363,24 +361,22 @@ fn layout_of_uncached<'tcx>( .checked_mul(count, dl) .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?; - let abi = if count != 0 && ty.is_privately_uninhabited(tcx, cx.typing_env) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let abi = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; tcx.mk_layout(LayoutData { variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr: abi, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, unadjusted_abi_align: element.align.abi, - randomization_seed: element.randomization_seed.wrapping_add(count), + randomization_seed: element.randomization_seed.wrapping_add(Hash64::new(count)), }) } ty::Slice(element) => { @@ -390,12 +386,15 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: element.align.abi, // adding a randomly chosen value to distinguish slices - randomization_seed: element.randomization_seed.wrapping_add(0x2dcba99c39784102), + randomization_seed: element + .randomization_seed + .wrapping_add(Hash64::new(0x2dcba99c39784102)), }) } ty::Str => tcx.mk_layout(LayoutData { @@ -403,26 +402,20 @@ fn layout_of_uncached<'tcx>( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, // another random value - randomization_seed: 0xc1325f37d127be22, + randomization_seed: Hash64::new(0xc1325f37d127be22), }), // Odd unit types. - ty::FnDef(..) => { - univariant(IndexSlice::empty(), &ReprOptions::default(), StructKind::AlwaysSized)? - } + ty::FnDef(..) => univariant(IndexSlice::empty(), StructKind::AlwaysSized)?, ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => { - let mut unit = univariant_uninterned( - cx, - ty, - IndexSlice::empty(), - &ReprOptions::default(), - StructKind::AlwaysSized, - )?; + let mut unit = + univariant_uninterned(cx, ty, IndexSlice::empty(), StructKind::AlwaysSized)?; match unit.backend_repr { BackendRepr::Memory { ref mut sized } => *sized = false, _ => bug!(), @@ -436,7 +429,6 @@ fn layout_of_uncached<'tcx>( let tys = args.as_closure().upvar_tys(); univariant( &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::>()?, - &ReprOptions::default(), StructKind::AlwaysSized, )? } @@ -445,7 +437,6 @@ fn layout_of_uncached<'tcx>( let tys = args.as_coroutine_closure().upvar_tys(); univariant( &tys.iter().map(|ty| cx.layout_of(ty)).try_collect::>()?, - &ReprOptions::default(), StructKind::AlwaysSized, )? } @@ -454,11 +445,7 @@ fn layout_of_uncached<'tcx>( let kind = if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - univariant( - &tys.iter().map(|k| cx.layout_of(k)).try_collect::>()?, - &ReprOptions::default(), - kind, - )? + univariant(&tys.iter().map(|k| cx.layout_of(k)).try_collect::>()?, kind)? } // SIMD vector types. @@ -560,12 +547,15 @@ fn layout_of_uncached<'tcx>( ( BackendRepr::Memory { sized: true }, AbiAndPrefAlign { - abi: Align::max_for_offset(size), - pref: dl.vector_align(size).pref, + abi: Align::max_aligned_factor(size), + pref: dl.llvmlike_vector_align(size).pref, }, ) } else { - (BackendRepr::Vector { element: e_abi, count: e_len }, dl.vector_align(size)) + ( + BackendRepr::Vector { element: e_abi, count: e_len }, + dl.llvmlike_vector_align(size), + ) }; let size = size.align_to(align.abi); @@ -581,11 +571,12 @@ fn layout_of_uncached<'tcx>( fields, backend_repr: abi, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed: e_ly.randomization_seed.wrapping_add(e_len), + randomization_seed: e_ly.randomization_seed.wrapping_add(Hash64::new(e_len)), }) } @@ -716,25 +707,30 @@ fn layout_of_uncached<'tcx>( } // Types with no meaningful known layout. + ty::Param(_) => { + return Err(error(cx, LayoutError::TooGeneric(ty))); + } + ty::Alias(..) => { - if ty.has_param() { - return Err(error(cx, LayoutError::TooGeneric(ty))); - } // NOTE(eddyb) `layout_of` query should've normalized these away, // if that was possible, so there's no reason to try again here. - return Err(error(cx, LayoutError::Unknown(ty))); - } - - ty::Bound(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => { - bug!("Layout::compute: unexpected type `{}`", ty) - } - - ty::Param(_) => { - return Err(error(cx, LayoutError::TooGeneric(ty))); + let err = if ty.has_param() { + LayoutError::TooGeneric(ty) + } else { + // This is only reachable with unsatisfiable predicates. For example, if we have + // `u8: Iterator`, then we can't compute the layout of `::Item`. + LayoutError::Unknown(ty) + }; + return Err(error(cx, err)); } - ty::Placeholder(..) => { - return Err(error(cx, LayoutError::Unknown(ty))); + ty::Placeholder(..) + | ty::Bound(..) + | ty::CoroutineWitness(..) + | ty::Infer(_) + | ty::Error(_) => { + // `ty::Error` is handled at the top of this function. + bug!("layout_of: unexpected type `{ty}`") } }) } @@ -908,13 +904,7 @@ fn coroutine_layout<'tcx>( .chain(iter::once(Ok(tag_layout))) .chain(promoted_layouts) .try_collect::>()?; - let prefix = univariant_uninterned( - cx, - ty, - &prefix_layouts, - &ReprOptions::default(), - StructKind::AlwaysSized, - )?; + let prefix = univariant_uninterned(cx, ty, &prefix_layouts, StructKind::AlwaysSized)?; let (prefix_size, prefix_align) = (prefix.size, prefix.align); @@ -979,7 +969,6 @@ fn coroutine_layout<'tcx>( cx, ty, &variant_only_tys.map(|ty| cx.layout_of(ty)).try_collect::>()?, - &ReprOptions::default(), StructKind::Prefixed(prefix_size, prefix_align.abi), )?; variant.variants = Variants::Single { index }; @@ -1042,16 +1031,11 @@ fn coroutine_layout<'tcx>( size = size.align_to(align.abi); - let abi = if prefix.backend_repr.is_uninhabited() - || variants.iter().all(|v| v.backend_repr.is_uninhabited()) - { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let uninhabited = prefix.uninhabited || variants.iter().all(|v| v.is_uninhabited()); + let abi = BackendRepr::Memory { sized: true }; // this is similar to how ReprOptions populates its field_shuffle_seed - let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash().as_u64(); + let def_hash = tcx.def_path_hash(def_id).0.to_smaller_hash(); let layout = tcx.mk_layout(LayoutData { variants: Variants::Multiple { @@ -1069,6 +1053,7 @@ fn coroutine_layout<'tcx>( // See , . // FIXME: Remove when is implemented and aliased coroutine fields are wrapped in `UnsafePinned`. largest_niche: None, + uninhabited, size, align, max_repr_align: None, diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 8d5403ed32468..c695e2887fd6f 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -10,7 +10,11 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou // Type-level uninhabitedness should always imply ABI uninhabitedness. if layout.ty.is_privately_uninhabited(tcx, cx.typing_env) { - assert!(layout.is_uninhabited()); + assert!( + layout.is_uninhabited(), + "{:?} is type-level uninhabited but not ABI-uninhabited?", + layout.ty + ); } if layout.size.bytes() % layout.align.abi.bytes() != 0 { @@ -29,7 +33,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou fn non_zst_fields<'tcx, 'a>( cx: &'a LayoutCx<'tcx>, layout: &'a TyAndLayout<'tcx>, - ) -> impl Iterator)> + 'a { + ) -> impl Iterator)> { (0..layout.layout.fields().count()).filter_map(|i| { let field = layout.field(cx, i); // Also checking `align == 1` here leads to test failures in @@ -65,31 +69,30 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou } fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { - // Verify the ABI mandated alignment and size. - let align = layout.backend_repr.inherent_align(cx).map(|align| align.abi); - let size = layout.backend_repr.inherent_size(cx); - let Some((align, size)) = align.zip(size) else { - assert_matches!( - layout.layout.backend_repr(), - BackendRepr::Uninhabited | BackendRepr::Memory { .. }, - "ABI unexpectedly missing alignment and/or size in {layout:#?}" + // Verify the ABI-mandated alignment and size for scalars. + let align = layout.backend_repr.scalar_align(cx); + let size = layout.backend_repr.scalar_size(cx); + if let Some(align) = align { + assert_eq!( + layout.layout.align().abi, + align, + "alignment mismatch between ABI and layout in {layout:#?}" ); - return; - }; - assert_eq!( - layout.layout.align().abi, - align, - "alignment mismatch between ABI and layout in {layout:#?}" - ); - assert_eq!( - layout.layout.size(), - size, - "size mismatch between ABI and layout in {layout:#?}" - ); + } + if let Some(size) = size { + assert_eq!( + layout.layout.size(), + size, + "size mismatch between ABI and layout in {layout:#?}" + ); + } // Verify per-ABI invariants match layout.layout.backend_repr() { BackendRepr::Scalar(_) => { + // These must always be present for `Scalar` types. + let align = align.unwrap(); + let size = size.unwrap(); // Check that this matches the underlying field. let inner = skip_newtypes(cx, layout); assert!( @@ -231,11 +234,17 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou "`ScalarPair` second field with bad ABI in {inner:#?}", ); } - BackendRepr::Vector { element, .. } => { - assert!(align >= element.align(cx).abi); // just sanity-checking `vector_align`. - // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. + BackendRepr::Vector { element, count } => { + let align = layout.align.abi; + let size = layout.size; + let element_align = element.align(cx).abi; + let element_size = element.size(cx); + // Currently, vectors must always be aligned to at least their elements: + assert!(align >= element_align); + // And the size has to be element * count plus alignment padding, of course + assert!(size == (element_size * count).align_to(align)); } - BackendRepr::Uninhabited | BackendRepr::Memory { .. } => {} // Nothing to check. + BackendRepr::Memory { .. } => {} // Nothing to check. } } @@ -291,8 +300,8 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check - // for them. They also fail that check, since they have - // `Aggregate`/`Uninhabited` ABI even when the main type is + // for them. They also fail that check, since they may have + // a different ABI even when the main type is // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size // 0, and sometimes, variants without fields have non-0 size.) continue; @@ -306,7 +315,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou (BackendRepr::ScalarPair(a1, b1), BackendRepr::ScalarPair(a2, b2)) => { scalar_coherent(a1, a2) && scalar_coherent(b1, b2) } - (BackendRepr::Uninhabited, _) => true, (BackendRepr::Memory { .. }, _) => true, _ => false, }; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 80de7e20951a7..52955ec59a4a0 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -373,7 +373,7 @@ fn drop_tys_helper<'tcx>( fn adt_consider_insignificant_dtor<'tcx>( tcx: TyCtxt<'tcx>, -) -> impl Fn(ty::AdtDef<'tcx>) -> Option + 'tcx { +) -> impl Fn(ty::AdtDef<'tcx>) -> Option { move |adt_def: ty::AdtDef<'tcx>| { let is_marked_insig = tcx.has_attr(adt_def.did(), sym::rustc_insignificant_dtor); if is_marked_insig { diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 32d9469c296ca..98881905bcf88 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -98,10 +98,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { let opaque_hir_id = self.tcx.local_def_id_to_hir_id(opaque_def_id); // Named opaque types can be defined by any siblings or children of siblings. - let scope = self.tcx.hir().get_defining_scope(opaque_hir_id); + let scope = self.tcx.hir_get_defining_scope(opaque_hir_id); // We walk up the node tree until we hit the root or the scope of the opaque type. while hir_id != scope && hir_id != CRATE_HIR_ID { - hir_id = self.tcx.hir().get_parent_item(hir_id).into(); + hir_id = self.tcx.hir_get_parent_item(hir_id).into(); } // Syntactically, we are allowed to define the concrete type if: hir_id == scope @@ -109,7 +109,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { - let body = self.tcx.hir().body_owned_by(self.item).value; + let body = self.tcx.hir_body_owned_by(self.item).value; struct TaitInBodyFinder<'a, 'tcx> { collector: &'a mut OpaqueTypeCollector<'tcx>, } diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 64e5a609b2f6d..d6f9277813d12 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -1,11 +1,10 @@ //! This module contains helpers for walking all types of //! a signature, while preserving spans as much as possible -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; +use rustc_middle::ty::visit::{VisitorResult, try_visit}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 8d97ec728304e..d8184da927c3c 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_type_ir" version = "0.0.0" -edition = "2021" +edition = "2024" [dependencies] # tidy-alphabetical-start diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs index 923b74abdfd2f..b11bcff1d8bbb 100644 --- a/compiler/rustc_type_ir/src/elaborate.rs +++ b/compiler/rustc_type_ir/src/elaborate.rs @@ -44,25 +44,22 @@ pub trait Elaboratable { } pub struct ClauseWithSupertraitSpan { - pub pred: I::Predicate, + pub clause: I::Clause, // Span of the supertrait predicatae that lead to this clause. pub supertrait_span: I::Span, } impl ClauseWithSupertraitSpan { - pub fn new(pred: I::Predicate, span: I::Span) -> Self { - ClauseWithSupertraitSpan { pred, supertrait_span: span } + pub fn new(clause: I::Clause, span: I::Span) -> Self { + ClauseWithSupertraitSpan { clause, supertrait_span: span } } } impl Elaboratable for ClauseWithSupertraitSpan { fn predicate(&self) -> ::Predicate { - self.pred + self.clause.as_predicate() } fn child(&self, clause: ::Clause) -> Self { - ClauseWithSupertraitSpan { - pred: clause.as_predicate(), - supertrait_span: self.supertrait_span, - } + ClauseWithSupertraitSpan { clause, supertrait_span: self.supertrait_span } } fn child_with_derived_cause( @@ -72,7 +69,7 @@ impl Elaboratable for ClauseWithSupertraitSpan { _parent_trait_pred: crate::Binder>, _index: usize, ) -> Self { - ClauseWithSupertraitSpan { pred: clause.as_predicate(), supertrait_span } + ClauseWithSupertraitSpan { clause, supertrait_span } } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 6924216bd26e6..9277226b718b1 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -126,6 +126,10 @@ pub trait Ty>: matches!(self.kind(), ty::Infer(ty::TyVar(_))) } + fn is_ty_error(self) -> bool { + matches!(self.kind(), ty::Error(_)) + } + fn is_floating_point(self) -> bool { matches!(self.kind(), ty::Float(_) | ty::Infer(ty::FloatVar(_))) } @@ -284,6 +288,10 @@ pub trait Const>: fn is_ct_var(self) -> bool { matches!(self.kind(), ty::ConstKind::Infer(ty::InferConst::Var(_))) } + + fn is_ct_error(self) -> bool { + matches!(self.kind(), ty::ConstKind::Error(_)) + } } pub trait ValueConst>: Copy + Debug + Hash + Eq { @@ -370,6 +378,13 @@ pub trait Term>: } } + fn is_error(self) -> bool { + match self.kind() { + ty::TermKind::Ty(ty) => ty.is_ty_error(), + ty::TermKind::Const(ct) => ct.is_ct_error(), + } + } + fn to_alias_term(self) -> Option> { match self.kind() { ty::TermKind::Ty(ty) => match ty.kind() { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e7ca24178cbf7..15ef4e7d6c1d2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -74,6 +74,7 @@ pub use opaque_ty::*; pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; +pub use rustc_ast_ir::{Movability, Mutability, Pinnedness}; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 3cc2dcbaca6d3..082cfff72e20f 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -285,7 +285,7 @@ impl NestedGoals { #[cfg_attr(feature = "nightly", rustc_lint_query_instability)] #[allow(rustc::potential_query_instability)] - fn iter(&self) -> impl Iterator + '_ { + fn iter(&self) -> impl Iterator { self.nested_goals.iter().map(|(i, p)| (*i, *p)) } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 52e4fa19cb020..83631f7fe343f 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -14,6 +14,7 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen use self::TyKind::*; pub use self::closure::*; use crate::inherent::*; +#[cfg(feature = "nightly")] use crate::visit::TypeVisitable; use crate::{self as ty, DebruijnIndex, Interner}; diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index a12e9856304a9..119b658a2bf3f 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -45,8 +45,8 @@ use std::fmt; use std::ops::ControlFlow; use std::sync::Arc; -use rustc_ast_ir::visit::VisitorResult; -use rustc_ast_ir::{try_visit, walk_visitable_list}; +pub use rustc_ast_ir::visit::VisitorResult; +pub use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; use smallvec::SmallVec; use thin_vec::ThinVec; @@ -224,6 +224,13 @@ impl, Ix: Idx> TypeVisitable for IndexVec, S> TypeVisitable for indexmap::IndexSet { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + walk_visitable_list!(visitor, self.iter()); + V::Result::output() + } +} + pub trait Flags { fn flags(&self) -> TypeFlags; fn outer_exclusive_binder(&self) -> ty::DebruijnIndex; diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index cb95ca6834623..15a5557509929 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustc_type_ir_macros" version = "0.0.0" -edition = "2021" +edition = "2024" [lib] proc-macro = true diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index ede6dcd469cce..640299c216796 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -45,12 +45,12 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok s.add_bounds(synstructure::AddBounds::Fields); let body_visit = s.each(|bind| { quote! { - match ::rustc_ast_ir::visit::VisitorResult::branch( + match ::rustc_type_ir::visit::VisitorResult::branch( ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) ) { ::core::ops::ControlFlow::Continue(()) => {}, ::core::ops::ControlFlow::Break(r) => { - return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + return ::rustc_type_ir::visit::VisitorResult::from_residual(r); }, } } @@ -65,7 +65,7 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok __visitor: &mut __V ) -> __V::Result { match *self { #body_visit } - <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + <__V::Result as ::rustc_type_ir::visit::VisitorResult>::output() } }, ) diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index 2edb3f140d7ac..d691a0e4f22f5 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stable_mir" version = "0.1.0-preview" -edition = "2021" +edition = "2024" [dependencies] scoped-tls = "1.0" diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index 861b6692b5367..091f3e1a95e95 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -227,7 +227,6 @@ pub enum TagEncoding { /// in terms of categories of C types there are ABI rules for. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum ValueAbi { - Uninhabited, Scalar(Scalar), ScalarPair(Scalar, Scalar), Vector { @@ -244,10 +243,7 @@ impl ValueAbi { /// Returns `true` if the layout corresponds to an unsized type. pub fn is_unsized(&self) -> bool { match *self { - ValueAbi::Uninhabited - | ValueAbi::Scalar(_) - | ValueAbi::ScalarPair(..) - | ValueAbi::Vector { .. } => false, + ValueAbi::Scalar(_) | ValueAbi::ScalarPair(..) | ValueAbi::Vector { .. } => false, ValueAbi::Aggregate { sized } => !sized, } } diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index bc2e427f50cb0..f8b46f50a5298 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -864,7 +864,7 @@ impl SwitchTargets { } /// The conditional targets which are only taken if the pattern matches the given value. - pub fn branches(&self) -> impl Iterator + '_ { + pub fn branches(&self) -> impl Iterator { self.branches.iter().copied() } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 9ef80edb82a6e..b857a735b7259 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -809,7 +809,7 @@ impl AdtDef { } /// Iterate over the variants in this ADT. - pub fn variants_iter(&self) -> impl Iterator + '_ { + pub fn variants_iter(&self) -> impl Iterator { (0..self.num_variants()) .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self }) } diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 3533ed2e8511d..8463174f9a468 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -161,7 +161,7 @@ impl Visitable for RigidTy { RigidTy::Slice(inner) => inner.visit(visitor), RigidTy::RawPtr(ty, _) => ty.visit(visitor), RigidTy::Ref(reg, ty, _) => { - reg.visit(visitor); + reg.visit(visitor)?; ty.visit(visitor) } RigidTy::Adt(_, args) diff --git a/config.example.toml b/config.example.toml index f5395375afe4c..a17d3ec9f8841 100644 --- a/config.example.toml +++ b/config.example.toml @@ -729,7 +729,8 @@ #remap-debuginfo = false # Link the compiler and LLVM against `jemalloc` instead of the default libc allocator. -# This option is only tested on Linux and OSX. +# This option is only tested on Linux and OSX. It can also be configured per-target in the +# [target.] section. #jemalloc = false # Run tests in various test suites with the "nll compare mode" in addition to @@ -792,12 +793,12 @@ # C compiler to be used to compile C code. Note that the # default value is platform specific, and if not specified it may also depend on # what platform is crossing to what platform. -# See `src/bootstrap/cc_detect.rs` for details. +# See `src/bootstrap/src/utils/cc_detect.rs` for details. #cc = "cc" (path) # C++ compiler to be used to compile C++ code (e.g. LLVM and our LLVM shims). # This is only used for host targets. -# See `src/bootstrap/cc_detect.rs` for details. +# See `src/bootstrap/src/utils/cc_detect.rs` for details. #cxx = "c++" (path) # Archiver to be used to assemble static libraries compiled from C/C++ code. @@ -927,6 +928,10 @@ # order to run `x check`. #optimized-compiler-builtins = build.optimized-compiler-builtins (bool) +# Link the compiler and LLVM against `jemalloc` instead of the default libc allocator. +# This overrides the global `rust.jemalloc` option. See that option for more info. +#jemalloc = rust.jemalloc (bool) + # ============================================================================= # Distribution options # diff --git a/library/Cargo.lock b/library/Cargo.lock index 0be2f9a154939..0ad56f3ce47ab 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.146" +version = "0.1.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97117b1434b79833f39a5fabdf82f890bd98c1988334dea1cb67f7e627fa311" +checksum = "7170335a76fbcba350c3ea795c15df3b2c02934e35e502e82c4dd7837d4d0161" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index c1d7f324f1770..6f9074d91b01d 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["public-dependency"] + [package] name = "alloc" version = "0.0.0" @@ -9,8 +11,8 @@ autobenches = false edition = "2021" [dependencies] -core = { path = "../core" } -compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] } +core = { path = "../core", public = true } +compiler_builtins = { version = "=0.1.147", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index dbfd2e74abee6..17dad3277b95d 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -340,8 +340,18 @@ where } } +// `Cow<'_, T>` can only implement `DerefPure` if `>` (and `BorrowMut`) is trusted. +// For now, we restrict `DerefPure for Cow` to `T: Sized` (`T as Borrow` is trusted), +// `str` (`String as Borrow` is trusted) and `[T]` (`Vec as Borrow<[T]>` is trusted). +// In the future, a `BorrowPure` trait analogous to `DerefPure` might generalize this. #[unstable(feature = "deref_pure_trait", issue = "87121")] -unsafe impl DerefPure for Cow<'_, B> where B::Owned: Borrow {} +unsafe impl DerefPure for Cow<'_, T> {} +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Cow<'_, str> {} +#[cfg(not(no_global_oom_handling))] +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for Cow<'_, [T]> {} #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Cow<'_, B> where B: Eq + ToOwned {} diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 4b124b5a3b38f..e2a55d3139532 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -237,7 +237,6 @@ pub struct Box< /// the newly allocated memory. This is an intrinsic to avoid unnecessary copies. /// /// This is the surface syntax for `box ` expressions. -#[cfg(not(bootstrap))] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[unstable(feature = "liballoc_internals", issue = "none")] @@ -245,15 +244,6 @@ pub fn box_new(_x: T) -> Box { unreachable!() } -/// Transition function for the next bootstrap bump. -#[cfg(bootstrap)] -#[unstable(feature = "liballoc_internals", issue = "none")] -#[inline(always)] -pub fn box_new(x: T) -> Box { - #[rustc_box] - Box::new(x) -} - impl Box { /// Allocates memory on the heap and then places `x` into it. /// @@ -1689,7 +1679,20 @@ impl Default for Box { /// Creates a `Box`, with the `Default` value for T. #[inline] fn default() -> Self { - Box::write(Box::new_uninit(), T::default()) + let mut x: Box> = Box::new_uninit(); + unsafe { + // SAFETY: `x` is valid for writing and has the same layout as `T`. + // If `T::default()` panics, dropping `x` will just deallocate the Box as `MaybeUninit` + // does not have a destructor. + // + // We use `ptr::write` as `MaybeUninit::write` creates + // extra stack copies of `T` in debug mode. + // + // See https://github.com/rust-lang/rust/issues/136043 for more context. + ptr::write(&raw mut *x as *mut T, T::default()); + // SAFETY: `x` was just initialized above. + x.assume_init() + } } } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 1bb0f76106472..2e9dd98571537 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -105,6 +105,7 @@ #![feature(box_uninit_write)] #![feature(bstr)] #![feature(bstr_internals)] +#![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] #![feature(const_eval_select)] @@ -136,7 +137,6 @@ #![feature(pointer_like_trait)] #![feature(ptr_internals)] #![feature(ptr_metadata)] -#![feature(ptr_sub_ptr)] #![feature(set_ptr_value)] #![feature(sized_type_properties)] #![feature(slice_from_ptr_range)] diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index c83b1962eb691..dcd95ddf00ff5 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -27,7 +27,7 @@ pub use core::slice::ArrayChunksMut; pub use core::slice::ArrayWindows; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use core::slice::EscapeAscii; -#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "get_many_mut", since = "1.86.0")] pub use core::slice::GetDisjointMutError; #[stable(feature = "slice_get_slice", since = "1.28.0")] pub use core::slice::SliceIndex; diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 154da69107884..9446afd4b24b0 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1419,7 +1419,9 @@ impl String { pub fn push(&mut self, ch: char) { match ch.len_utf8() { 1 => self.vec.push(ch as u8), - _ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()), + _ => { + self.vec.extend_from_slice(ch.encode_utf8(&mut [0; char::MAX_LEN_UTF8]).as_bytes()) + } } } @@ -1716,7 +1718,7 @@ impl String { #[rustc_confusables("set")] pub fn insert(&mut self, idx: usize, ch: char) { assert!(self.is_char_boundary(idx)); - let mut bits = [0; 4]; + let mut bits = [0; char::MAX_LEN_UTF8]; let bits = ch.encode_utf8(&mut bits).as_bytes(); unsafe { @@ -2797,7 +2799,7 @@ impl SpecToString for core::ascii::Char { impl SpecToString for char { #[inline] fn spec_to_string(&self) -> String { - String::from(self.encode_utf8(&mut [0; 4])) + String::from(self.encode_utf8(&mut [0; char::MAX_LEN_UTF8])) } } @@ -3155,6 +3157,24 @@ impl From for Vec { } } +#[stable(feature = "try_from_vec_u8_for_string", since = "CURRENT_RUSTC_VERSION")] +impl TryFrom> for String { + type Error = FromUtf8Error; + /// Converts the given [`Vec`] into a [`String`] if it contains valid UTF-8 data. + /// + /// # Examples + /// + /// ``` + /// let s1 = b"hello world".to_vec(); + /// let v1 = String::try_from(s1).unwrap(); + /// assert_eq!(v1, "hello world"); + /// + /// ``` + fn try_from(bytes: Vec) -> Result { + Self::from_utf8(bytes) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Write for String { diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 9362cef2a1b00..8705a9c3d2679 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -232,7 +232,7 @@ impl Drop for Drain<'_, T, A> { // it from the original vec but also avoid creating a &mut to the front since that could // invalidate raw pointers to it which some unsafe code might rely on. let vec_ptr = vec.as_mut().as_mut_ptr(); - let drop_offset = drop_ptr.sub_ptr(vec_ptr); + let drop_offset = drop_ptr.offset_from_unsigned(vec_ptr); let to_drop = ptr::slice_from_raw_parts_mut(vec_ptr.add(drop_offset), drop_len); ptr::drop_in_place(to_drop); } diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index a7dba16944e7d..dffd85f13aa50 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -379,7 +379,7 @@ where let sink = self.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(end)).into_ok(); // iteration succeeded, don't drop head - unsafe { ManuallyDrop::new(sink).dst.sub_ptr(dst_buf) } + unsafe { ManuallyDrop::new(sink).dst.offset_from_unsigned(dst_buf) } } } diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index 4d5b4e47d39e4..997c4c7525b5a 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -14,7 +14,7 @@ pub(super) struct InPlaceDrop { impl InPlaceDrop { fn len(&self) -> usize { - unsafe { self.dst.sub_ptr(self.inner) } + unsafe { self.dst.offset_from_unsigned(self.inner) } } } diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 9a6745fdbc0a3..52597e41c1cf8 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -179,7 +179,7 @@ impl IntoIter { // say that they're all at the beginning of the "allocation". 0..this.len() } else { - this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf) + this.ptr.offset_from_unsigned(this.buf)..this.end.offset_from_unsigned(buf) }; let cap = this.cap; let alloc = ManuallyDrop::take(&mut this.alloc); @@ -230,7 +230,7 @@ impl Iterator for IntoIter { let exact = if T::IS_ZST { self.end.addr().wrapping_sub(self.ptr.as_ptr().addr()) } else { - unsafe { non_null!(self.end, T).sub_ptr(self.ptr) } + unsafe { non_null!(self.end, T).offset_from_unsigned(self.ptr) } }; (exact, Some(exact)) } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 7d02a15ed7a51..a84bb724473a1 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2526,7 +2526,7 @@ impl Vec { /// assert_eq!(vec, [1, 2, 3]); /// assert_eq!(vec.pop_if(pred), None); /// ``` - #[stable(feature = "vec_pop_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "vec_pop_if", since = "1.86.0")] pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option { let last = self.last_mut()?; if predicate(last) { self.pop() } else { None } diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 1bcec4037cdd6..f95be6a6df0b3 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -3,6 +3,7 @@ #![feature(iter_array_chunks)] #![feature(assert_matches)] #![feature(btree_extract_if)] +#![feature(char_max_len)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] #![feature(downcast_unchecked)] diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index 23a0e5e525643..906fa2d425e77 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -2,6 +2,7 @@ use std::assert_matches::assert_matches; use std::borrow::Cow; +use std::char::MAX_LEN_UTF8; use std::cmp::Ordering::{Equal, Greater, Less}; use std::str::{from_utf8, from_utf8_unchecked}; @@ -1231,7 +1232,7 @@ fn test_to_uppercase_rev_iterator() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_chars_decoding() { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().next() { @@ -1243,7 +1244,7 @@ fn test_chars_decoding() { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_chars_rev_decoding() { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; for c in (0..0x110000).filter_map(std::char::from_u32) { let s = c.encode_utf8(&mut bytes); if Some(c) != s.chars().rev().next() { diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index b7c6db6c78dde..1538ecc6b9297 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -23,6 +23,8 @@ optimize_for_size = [] # Make `RefCell` store additional debugging information, which is printed out when # a borrow error occurs debug_refcell = [] +# Make `TypeId` store a reference to the name of the type, so that it can print that name. +debug_typeid = [] [lints.rust.unexpected_cfgs] level = "warn" @@ -30,7 +32,6 @@ check-cfg = [ 'cfg(bootstrap)', 'cfg(no_fp_fmt_parse)', 'cfg(stdarch_intel_sde)', - 'cfg(target_arch, values("xtensa"))', # core use #[path] imports to portable-simd `core_simd` crate # and to stdarch `core_arch` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/core/src/any.rs b/library/core/src/any.rs index f90de1f5ced40..9ed2c8e9f3ad1 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -711,6 +711,8 @@ pub struct TypeId { // We avoid using `u128` because that imposes higher alignment requirements on many platforms. // See issue #115620 for more information. t: (u64, u64), + #[cfg(feature = "debug_typeid")] + name: &'static str, } #[stable(feature = "rust1", since = "1.0.0")] @@ -741,10 +743,14 @@ impl TypeId { #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] pub const fn of() -> TypeId { let t: u128 = intrinsics::type_id::(); - let t1 = (t >> 64) as u64; let t2 = t as u64; - TypeId { t: (t1, t2) } + + TypeId { + t: (t1, t2), + #[cfg(feature = "debug_typeid")] + name: type_name::(), + } } fn as_u128(self) -> u128 { @@ -775,7 +781,15 @@ impl hash::Hash for TypeId { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for TypeId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(f, "TypeId({:#034x})", self.as_u128()) + #[cfg(feature = "debug_typeid")] + { + write!(f, "TypeId({:#034x} = {})", self.as_u128(), self.name)?; + } + #[cfg(not(feature = "debug_typeid"))] + { + write!(f, "TypeId({:#034x})", self.as_u128())?; + } + Ok(()) } } diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index ccfdbf0eb704d..85cc315626d4b 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -71,6 +71,16 @@ impl char { #[stable(feature = "assoc_char_consts", since = "1.52.0")] pub const MAX: char = '\u{10FFFF}'; + /// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to + /// UTF-8 encoding. + #[unstable(feature = "char_max_len", issue = "121714")] + pub const MAX_LEN_UTF8: usize = 4; + + /// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` + /// to UTF-16 encoding. + #[unstable(feature = "char_max_len", issue = "121714")] + pub const MAX_LEN_UTF16: usize = 2; + /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a /// decoding error. /// @@ -1168,6 +1178,7 @@ impl char { #[must_use] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_char_is_ascii", since = "1.32.0")] + #[cfg_attr(not(test), rustc_diagnostic_item = "char_is_ascii")] #[inline] pub const fn is_ascii(&self) -> bool { *self as u32 <= 0x7F diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index 59fd7250e8f8e..088c709f1a2af 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -95,6 +95,16 @@ const MAX_THREE_B: u32 = 0x10000; #[stable(feature = "rust1", since = "1.0.0")] pub const MAX: char = char::MAX; +/// The maximum number of bytes required to [encode](char::encode_utf8) a `char` to +/// UTF-8 encoding. +#[unstable(feature = "char_max_len", issue = "121714")] +pub const MAX_LEN_UTF8: usize = char::MAX_LEN_UTF8; + +/// The maximum number of two-byte units required to [encode](char::encode_utf16) a `char` +/// to UTF-16 encoding. +#[unstable(feature = "char_max_len", issue = "121714")] +pub const MAX_LEN_UTF16: usize = char::MAX_LEN_UTF16; + /// `U+FFFD REPLACEMENT CHARACTER` (�) is used in Unicode to represent a /// decoding error. Use [`char::REPLACEMENT_CHARACTER`] instead. #[stable(feature = "decode_utf16", since = "1.9.0")] diff --git a/library/core/src/contracts.rs b/library/core/src/contracts.rs index c769e219e4d49..8b79a3a7eba86 100644 --- a/library/core/src/contracts.rs +++ b/library/core/src/contracts.rs @@ -1,5 +1,4 @@ //! Unstable module containing the unstable contracts lang items and attribute macros. -#![cfg(not(bootstrap))] pub use crate::macros::builtin::{contracts_ensures as ensures, contracts_requires as requires}; diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 69ad7239954ac..94847685ec965 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -1099,5 +1099,5 @@ impl Error for crate::time::TryFromFloatSecsError {} #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] impl Error for crate::ffi::FromBytesUntilNulError {} -#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "get_many_mut", since = "1.86.0")] impl Error for crate::slice::GetDisjointMutError {} diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index a1bf3a4d7a706..764e7fff33ec7 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -3,7 +3,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell}; -use crate::char::EscapeDebugExtArgs; +use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8}; use crate::marker::PhantomData; use crate::num::fmt as numfmt; use crate::ops::Deref; @@ -187,7 +187,7 @@ pub trait Write { /// ``` #[stable(feature = "fmt_write_char", since = "1.1.0")] fn write_char(&mut self, c: char) -> Result { - self.write_str(c.encode_utf8(&mut [0; 4])) + self.write_str(c.encode_utf8(&mut [0; MAX_LEN_UTF8])) } /// Glue for usage of the [`write!`] macro with implementors of this trait. @@ -2768,7 +2768,7 @@ impl Display for char { if f.options.width.is_none() && f.options.precision.is_none() { f.write_char(*self) } else { - f.pad(self.encode_utf8(&mut [0; 4])) + f.pad(self.encode_utf8(&mut [0; MAX_LEN_UTF8])) } } } diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 76afb3b8e20c0..5ce282b05de73 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -472,7 +472,7 @@ pub fn spin_loop() { /// During constant evaluation, `black_box` is treated as a no-op. #[inline] #[stable(feature = "bench_black_box", since = "1.66.0")] -#[rustc_const_stable(feature = "const_black_box", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_black_box", since = "1.86.0")] pub const fn black_box(dummy: T) -> T { crate::intrinsics::black_box(dummy) } diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 99c42f3626e7c..ae2b3b92b823f 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -78,11 +78,7 @@ pub mod simd; use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering}; #[stable(feature = "drop_in_place", since = "1.8.0")] -#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] -#[cfg_attr( - not(bootstrap), - rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" -)] +#[rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"] #[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")] #[inline] pub unsafe fn drop_in_place(to_drop: *mut T) { @@ -1901,11 +1897,7 @@ pub const fn forget(_: T) { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] -#[cfg_attr( - not(bootstrap), - rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" -)] +#[rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead"] #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] #[rustc_diagnostic_item = "transmute"] #[rustc_nounwind] @@ -2739,110 +2731,124 @@ pub unsafe fn truncf128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf16` and `roundevenf16`. +/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf16(_x: f16) -> f16 { +#[cfg(not(bootstrap))] +pub fn round_ties_even_f16(_x: f16) -> f16 { unreachable!() } -/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`. + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub fn round_ties_even_f16(x: f16) -> f16 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf16(_x: f16) -> f16 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf16(x) } +} + +/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf32(_x: f32) -> f32 { +#[cfg(not(bootstrap))] +pub fn round_ties_even_f32(_x: f32) -> f32 { unreachable!() } -/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`. -/// -/// The stabilized version of this intrinsic is -/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn rintf64(_x: f64) -> f64 { - unreachable!() + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub fn round_ties_even_f32(x: f32) -> f32 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf32(_x: f32) -> f32 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf32(x) } } -/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// May raise an inexact floating-point exception if the argument is not an integer. -/// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions -/// cannot actually be utilized from Rust code. -/// In other words, this intrinsic is equivalent in behavior to `nearbyintf128` and `roundevenf128`. + +/// Provided for compatibility with stdarch. DO NOT USE. +#[inline(always)] +pub unsafe fn rintf32(x: f32) -> f32 { + round_ties_even_f32(x) +} + +/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even +/// least significant digit. /// /// The stabilized version of this intrinsic is -/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) +/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn rintf128(_x: f128) -> f128 { +#[cfg(not(bootstrap))] +pub fn round_ties_even_f64(_x: f64) -> f64 { unreachable!() } -/// Returns the nearest integer to an `f16`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf16(_x: f16) -> f16 { - unreachable!() +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub fn round_ties_even_f64(x: f64) -> f64 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf64(_x: f64) -> f64 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf64(x) } } -/// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf32(_x: f32) -> f32 { - unreachable!() + +/// Provided for compatibility with stdarch. DO NOT USE. +#[inline(always)] +pub unsafe fn rintf64(x: f64) -> f64 { + round_ties_even_f64(x) } -/// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. + +/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even +/// least significant digit. /// -/// This intrinsic does not have a stable counterpart. +/// The stabilized version of this intrinsic is +/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even) #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] #[rustc_nounwind] -pub unsafe fn nearbyintf64(_x: f64) -> f64 { +#[cfg(not(bootstrap))] +pub fn round_ties_even_f128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f128`. Changing the rounding mode is not possible in Rust, -/// so this rounds half-way cases to the number with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn nearbyintf128(_x: f128) -> f128 { - unreachable!() + +/// To be removed on next bootstrap bump. +#[cfg(bootstrap)] +pub fn round_ties_even_f128(x: f128) -> f128 { + #[rustc_intrinsic] + #[rustc_intrinsic_must_be_overridden] + #[rustc_nounwind] + unsafe fn rintf128(_x: f128) -> f128 { + unreachable!() + } + + // SAFETY: this intrinsic isn't actually unsafe + unsafe { rintf128(x) } } /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero. @@ -2886,47 +2892,6 @@ pub unsafe fn roundf128(_x: f128) -> f128 { unreachable!() } -/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf16(_x: f16) -> f16 { - unreachable!() -} -/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf32(_x: f32) -> f32 { - unreachable!() -} -/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf64(_x: f64) -> f64 { - unreachable!() -} -/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number -/// with an even least significant digit. -/// -/// This intrinsic does not have a stable counterpart. -#[rustc_intrinsic] -#[rustc_intrinsic_must_be_overridden] -#[rustc_nounwind] -pub unsafe fn roundevenf128(_x: f128) -> f128 { - unreachable!() -} - /// Float addition that allows optimizations based on algebraic rules. /// May assume inputs are finite. /// @@ -3260,7 +3225,7 @@ pub const fn three_way_compare(_lhs: T, _rhss: T) -> crate::cmp::Orderi /// Otherwise it's immediate UB. #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] #[rustc_nounwind] -#[cfg_attr(not(bootstrap), rustc_intrinsic)] +#[rustc_intrinsic] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell Miri pub const unsafe fn disjoint_bitor(a: T, b: T) -> T { @@ -3675,6 +3640,7 @@ pub const unsafe fn ptr_offset_from(_ptr: *const T, _base: *const T) -> isize #[rustc_nounwind] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] +#[rustc_intrinsic_const_stable_indirect] pub const unsafe fn ptr_offset_from_unsigned(_ptr: *const T, _base: *const T) -> usize { unimplemented!() } @@ -4070,7 +4036,6 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) /// of not prematurely commiting at compile-time to whether contract /// checking is turned on, so that we can specify contracts in libstd /// and let an end user opt into turning them on. -#[cfg(not(bootstrap))] #[rustc_const_unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] #[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] #[inline(always)] @@ -4086,7 +4051,6 @@ pub const fn contract_checks() -> bool { /// /// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition /// returns false. -#[cfg(not(bootstrap))] #[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] #[lang = "contract_check_requires"] #[rustc_intrinsic] @@ -4101,7 +4065,6 @@ pub fn contract_check_requires bool>(cond: C) { /// /// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition /// returns false. -#[cfg(not(bootstrap))] #[unstable(feature = "contracts_internals", issue = "128044" /* compiler-team#759 */)] #[rustc_intrinsic] pub fn contract_check_ensures<'a, Ret, C: Fn(&'a Ret) -> bool>(ret: &'a Ret, cond: C) { @@ -4400,11 +4363,7 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append #[doc(alias = "memcpy")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] -#[cfg_attr( - not(bootstrap), - rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" -)] +#[rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead"] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4508,11 +4467,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us /// ``` #[doc(alias = "memmove")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] -#[cfg_attr( - not(bootstrap), - rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" -)] +#[rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead"] #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -4595,11 +4550,7 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { /// ``` #[doc(alias = "memset")] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)] -#[cfg_attr( - not(bootstrap), - rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead" -)] +#[rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead"] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 0c38811590877..8090c98e7edb7 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -556,13 +556,13 @@ impl { -/// fn foo() { /* unix specific functionality */ } -/// } -/// cfg(target_pointer_width = "32") => { -/// fn foo() { /* non-unix, 32-bit functionality */ } -/// } -/// _ => { -/// fn foo() { /* fallback implementation */ } -/// } -/// } -/// ``` -#[cfg(bootstrap)] -#[unstable(feature = "cfg_match", issue = "115585")] -#[rustc_diagnostic_item = "cfg_match"] -pub macro cfg_match { - // with a final wildcard - ( - $(cfg($initial_meta:meta) => { $($initial_tokens:tt)* })+ - _ => { $($extra_tokens:tt)* } - ) => { - cfg_match! { - @__items (); - $((($initial_meta) ($($initial_tokens)*)),)+ - (() ($($extra_tokens)*)), - } - }, - - // without a final wildcard - ( - $(cfg($extra_meta:meta) => { $($extra_tokens:tt)* })* - ) => { - cfg_match! { - @__items (); - $((($extra_meta) ($($extra_tokens)*)),)* - } - }, - - // Internal and recursive macro to emit all the items - // - // Collects all the previous cfgs in a list at the beginning, so they can be - // negated. After the semicolon is all the remaining items. - (@__items ($($_:meta,)*);) => {}, - ( - @__items ($($no:meta,)*); - (($($yes:meta)?) ($($tokens:tt)*)), - $($rest:tt,)* - ) => { - // Emit all items within one block, applying an appropriate #[cfg]. The - // #[cfg] will require all `$yes` matchers specified and must also negate - // all previous matchers. - #[cfg(all( - $($yes,)? - not(any($($no),*)) - ))] - cfg_match! { @__identity $($tokens)* } - - // Recurse to emit all other items in `$rest`, and when we do so add all - // our `$yes` matchers to the list of `$no` matchers as future emissions - // will have to negate everything we just matched as well. - cfg_match! { - @__items ($($no,)* $($yes,)?); - $($rest,)* - } - }, - - // Internal macro to make __apply work out right for different match types, - // because of how macros match/expand stuff. - (@__identity $($tokens:tt)*) => { - $($tokens)* - } -} - /// A macro for defining `#[cfg]` match-like statements. /// /// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of @@ -324,7 +235,6 @@ pub macro cfg_match { /// _ => { "Behind every successful diet is an unwatched pizza" } /// }}; /// ``` -#[cfg(not(bootstrap))] #[unstable(feature = "cfg_match", issue = "115585")] #[rustc_diagnostic_item = "cfg_match"] pub macro cfg_match { @@ -1782,7 +1692,6 @@ pub(crate) mod builtin { /// The attribute carries an argument token-tree which is /// eventually parsed as a unary closure expression that is /// invoked on a reference to the return value. - #[cfg(not(bootstrap))] #[unstable(feature = "contracts", issue = "128044")] #[allow_internal_unstable(contracts_internals)] #[rustc_builtin_macro] @@ -1795,7 +1704,6 @@ pub(crate) mod builtin { /// The attribute carries an argument token-tree which is /// eventually parsed as an boolean expression with access to the /// function's formal parameters - #[cfg(not(bootstrap))] #[unstable(feature = "contracts", issue = "128044")] #[allow_internal_unstable(contracts_internals)] #[rustc_builtin_macro] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 042ee419d57e4..842a48e1606de 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -467,7 +467,7 @@ impl Copy for &T {} /// /// Bikeshed name for now. #[unstable(feature = "bikeshed_guaranteed_no_drop", issue = "none")] -#[cfg_attr(not(bootstrap), lang = "bikeshed_guaranteed_no_drop")] +#[lang = "bikeshed_guaranteed_no_drop"] pub trait BikeshedGuaranteedNoDrop {} /// Types for which it is safe to share references between threads. @@ -1313,7 +1313,6 @@ pub macro CoercePointee($item:item) { /// /// This trait is not intended to be implemented by users or used other than /// validation, so it should never be stabilized. -#[cfg(not(bootstrap))] #[lang = "coerce_pointee_validated"] #[unstable(feature = "coerce_pointee_validated", issue = "none")] #[doc(hidden)] diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index b11ba05685352..8e4417ec461b8 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -451,6 +451,28 @@ impl IpAddr { IpAddr::V6(v6) => v6.to_canonical(), } } + + /// Returns the eight-bit integers this address consists of as a slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip_as_octets)] + /// + /// use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; + /// + /// assert_eq!(IpAddr::V4(Ipv4Addr::LOCALHOST).as_octets(), &[127, 0, 0, 1]); + /// assert_eq!(IpAddr::V6(Ipv6Addr::LOCALHOST).as_octets(), + /// &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) + /// ``` + #[unstable(feature = "ip_as_octets", issue = "137259")] + #[inline] + pub const fn as_octets(&self) -> &[u8] { + match self { + IpAddr::V4(ip) => ip.as_octets().as_slice(), + IpAddr::V6(ip) => ip.as_octets().as_slice(), + } + } } impl Ipv4Addr { @@ -616,6 +638,25 @@ impl Ipv4Addr { Ipv4Addr { octets } } + /// Returns the four eight-bit integers that make up this address + /// as a slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip_as_octets)] + /// + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::new(127, 0, 0, 1); + /// assert_eq!(addr.as_octets(), &[127, 0, 0, 1]); + /// ``` + #[unstable(feature = "ip_as_octets", issue = "137259")] + #[inline] + pub const fn as_octets(&self) -> &[u8; 4] { + &self.octets + } + /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`). /// /// This property is defined in _UNIX Network Programming, Second Edition_, @@ -2001,6 +2042,25 @@ impl Ipv6Addr { pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr { Ipv6Addr { octets } } + + /// Returns the sixteen eight-bit integers the IPv6 address consists of + /// as a slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip_as_octets)] + /// + /// use std::net::Ipv6Addr; + /// + /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).as_octets(), + /// &[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + /// ``` + #[unstable(feature = "ip_as_octets", issue = "137259")] + #[inline] + pub const fn as_octets(&self) -> &[u8; 16] { + &self.octets + } } /// Writes an Ipv6Addr, conforming to the canonical style described by diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 4d42997369ffb..a200fd5318669 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -741,8 +741,8 @@ impl f32 { /// [`MAX`]: Self::MAX #[inline] #[doc(alias = "nextUp")] - #[stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "float_next_up_down", since = "1.86.0")] + #[rustc_const_stable(feature = "float_next_up_down", since = "1.86.0")] pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here @@ -792,8 +792,8 @@ impl f32 { /// [`MAX`]: Self::MAX #[inline] #[doc(alias = "nextDown")] - #[stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "float_next_up_down", since = "1.86.0")] + #[rustc_const_stable(feature = "float_next_up_down", since = "1.86.0")] pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 907971d303ffc..de63a462b61ac 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -758,8 +758,8 @@ impl f64 { /// [`MAX`]: Self::MAX #[inline] #[doc(alias = "nextUp")] - #[stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "float_next_up_down", since = "1.86.0")] + #[rustc_const_stable(feature = "float_next_up_down", since = "1.86.0")] pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here @@ -809,8 +809,8 @@ impl f64 { /// [`MAX`]: Self::MAX #[inline] #[doc(alias = "nextDown")] - #[stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "float_next_up_down", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "float_next_up_down", since = "1.86.0")] + #[rustc_const_stable(feature = "float_next_up_down", since = "1.86.0")] pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 96a290ad5a09d..74221e2168751 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -183,6 +183,52 @@ macro_rules! int_impl { (self as $UnsignedT).trailing_ones() } + /// Returns `self` with only the most significant bit set, or `0` if + /// the input is `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] + /// + /// assert_eq!(n.isolate_most_significant_one(), 0b_01000000); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_most_significant_one(), 0);")] + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_most_significant_one(self) -> Self { + self & (((1 as $SelfT) << (<$SelfT>::BITS - 1)).wrapping_shr(self.leading_zeros())) + } + + /// Returns `self` with only the least significant bit set, or `0` if + /// the input is `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] + /// + /// assert_eq!(n.isolate_least_significant_one(), 0b_00000100); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_least_significant_one(), 0);")] + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_least_significant_one(self) -> Self { + self & self.wrapping_neg() + } + /// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size. /// /// This produces the same result as an `as` cast, but ensures that the bit-width remains @@ -193,13 +239,13 @@ macro_rules! int_impl { /// Basic usage: /// /// ``` - /// #![feature(integer_sign_cast)] /// #[doc = concat!("let n = -1", stringify!($SelfT), ";")] /// #[doc = concat!("assert_eq!(n.cast_unsigned(), ", stringify!($UnsignedT), "::MAX);")] /// ``` - #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 55f4ccd958e77..80a38a6013dd0 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -163,14 +163,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint_signed", issue = "110840")] + #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -215,14 +215,14 @@ macro_rules! midpoint_impl { /// # Examples /// /// ``` - /// #![feature(num_midpoint_signed)] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(4), 2);")] #[doc = concat!("assert_eq!((-1", stringify!($SelfT), ").midpoint(2), 0);")] #[doc = concat!("assert_eq!((-7", stringify!($SelfT), ").midpoint(0), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(-7), -3);")] #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".midpoint(7), 3);")] /// ``` - #[unstable(feature = "num_midpoint_signed", issue = "110840")] + #[stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "num_midpoint_signed", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 21bad6705ab80..a967b72c4fa9b 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -605,6 +605,70 @@ macro_rules! nonzero_integer { } } + /// Returns `self` with only the most significant bit set. + /// + /// # Example + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + /// # use core::num::NonZero; + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b_01100100)?;")] + #[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b_01000000)?;")] + /// + /// assert_eq!(a.isolate_most_significant_one(), b); + /// # Some(()) + /// # } + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_most_significant_one(self) -> Self { + let n = self.get() & (((1 as $Int) << (<$Int>::BITS - 1)).wrapping_shr(self.leading_zeros())); + + // SAFETY: + // `self` is non-zero, so masking to preserve only the most + // significant set bit will result in a non-zero `n`. + unsafe { NonZero::new_unchecked(n) } + } + + /// Returns `self` with only the least significant bit set. + /// + /// # Example + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + /// # use core::num::NonZero; + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let a = NonZero::<", stringify!($Int), ">::new(0b_01100100)?;")] + #[doc = concat!("let b = NonZero::<", stringify!($Int), ">::new(0b_00000100)?;")] + /// + /// assert_eq!(a.isolate_least_significant_one(), b); + /// # Some(()) + /// # } + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_least_significant_one(self) -> Self { + let n = self.get(); + let n = n & n.wrapping_neg(); + + // SAFETY: `self` is non-zero, so `self` with only its least + // significant set bit will remain non-zero. + unsafe { NonZero::new_unchecked(n) } + } + /// Returns the number of ones in the binary representation of `self`. /// /// # Examples @@ -625,8 +689,8 @@ macro_rules! nonzero_integer { /// # } /// ``` /// - #[stable(feature = "non_zero_count_ones", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_zero_count_ones", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_zero_count_ones", since = "1.86.0")] + #[rustc_const_stable(feature = "non_zero_count_ones", since = "1.86.0")] #[doc(alias = "popcount")] #[doc(alias = "popcnt")] #[must_use = "this returns the result of the operation, \ @@ -1633,14 +1697,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Basic usage: /// /// ``` - /// #![feature(integer_sign_cast)] /// # use std::num::NonZero; /// #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::MAX;")] /// #[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1", stringify!($Sint), ").unwrap());")] /// ``` - #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -2072,14 +2136,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Basic usage: /// /// ``` - /// #![feature(integer_sign_cast)] /// # use std::num::NonZero; /// #[doc = concat!("let n = NonZero::new(-1", stringify!($Int), ").unwrap();")] /// #[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<", stringify!($Uint), ">::MAX);")] /// ``` - #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 29f6791ee6ad2..2682273b7f185 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -213,6 +213,52 @@ macro_rules! uint_impl { (!self).trailing_zeros() } + /// Returns `self` with only the most significant bit set, or `0` if + /// the input is `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] + /// + /// assert_eq!(n.isolate_most_significant_one(), 0b_01000000); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_most_significant_one(), 0);")] + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_most_significant_one(self) -> Self { + self & (((1 as $SelfT) << (<$SelfT>::BITS - 1)).wrapping_shr(self.leading_zeros())) + } + + /// Returns `self` with only the least significant bit set, or `0` if + /// the input is `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(isolate_most_least_significant_one)] + /// + #[doc = concat!("let n: ", stringify!($SelfT), " = 0b_01100100;")] + /// + /// assert_eq!(n.isolate_least_significant_one(), 0b_00000100); + #[doc = concat!("assert_eq!(0_", stringify!($SelfT), ".isolate_least_significant_one(), 0);")] + /// ``` + #[unstable(feature = "isolate_most_least_significant_one", issue = "136909")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline(always)] + pub const fn isolate_least_significant_one(self) -> Self { + self & self.wrapping_neg() + } + /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size. /// /// This produces the same result as an `as` cast, but ensures that the bit-width remains @@ -223,13 +269,12 @@ macro_rules! uint_impl { /// Basic usage: /// /// ``` - /// #![feature(integer_sign_cast)] - /// #[doc = concat!("let n = ", stringify!($SelfT), "::MAX;")] /// #[doc = concat!("assert_eq!(n.cast_signed(), -1", stringify!($SignedT), ");")] /// ``` - #[unstable(feature = "integer_sign_cast", issue = "125882")] + #[stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "integer_sign_cast", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] @@ -3275,14 +3320,14 @@ macro_rules! uint_impl { /// Basic usage: /// /// ``` - /// #![feature(unsigned_is_multiple_of)] #[doc = concat!("assert!(6_", stringify!($SelfT), ".is_multiple_of(2));")] #[doc = concat!("assert!(!5_", stringify!($SelfT), ".is_multiple_of(2));")] /// #[doc = concat!("assert!(0_", stringify!($SelfT), ".is_multiple_of(0));")] #[doc = concat!("assert!(!6_", stringify!($SelfT), ".is_multiple_of(0));")] /// ``` - #[unstable(feature = "unsigned_is_multiple_of", issue = "128101")] + #[stable(feature = "unsigned_is_multiple_of", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unsigned_is_multiple_of", since = "CURRENT_RUSTC_VERSION")] #[must_use] #[inline] #[rustc_inherit_overflow_checks] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index d36e677d21a18..33ad59916e391 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -294,7 +294,7 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[track_caller] -#[cfg_attr(not(bootstrap), lang = "panic_null_pointer_dereference")] // needed by codegen for panic on null pointer deref +#[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref #[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind fn panic_null_pointer_dereference() -> ! { if cfg!(feature = "panic_immediate_abort") { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 974946a7818d7..8db620596dde7 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -723,9 +723,8 @@ impl *const T { /// to [`sub`](#method.sub)). The following are all equivalent, assuming /// that their safety preconditions are met: /// ```rust - /// # #![feature(ptr_sub_ptr)] /// # unsafe fn blah(ptr: *const i32, origin: *const i32, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -752,26 +751,24 @@ impl *const T { /// # Examples /// /// ``` - /// #![feature(ptr_sub_ptr)] - /// /// let a = [0; 5]; /// let ptr1: *const i32 = &a[1]; /// let ptr2: *const i32 = &a[3]; /// unsafe { - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: - /// // ptr1.sub_ptr(ptr2) + /// // ptr1.offset_from_unsigned(ptr2) /// ``` - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn sub_ptr(self, origin: *const T) -> usize + pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, { @@ -789,7 +786,7 @@ impl *const T { ub_checks::assert_unsafe_precondition!( check_language_ub, - "ptr::sub_ptr requires `self >= origin`", + "ptr::offset_from_unsigned requires `self >= origin`", ( this: *const () = self as *const (), origin: *const () = origin as *const (), @@ -807,18 +804,18 @@ impl *const T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn byte_sub_ptr(self, origin: *const U) -> usize { + pub const unsafe fn byte_offset_from_unsigned(self, origin: *const U) -> usize { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.cast::().sub_ptr(origin.cast::()) } + unsafe { self.cast::().offset_from_unsigned(origin.cast::()) } } /// Returns whether two pointers are guaranteed to be equal. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 94ebd0d2522ee..5a64f12ca99ff 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -895,9 +895,8 @@ impl *mut T { /// to [`sub`](#method.sub)). The following are all equivalent, assuming /// that their safety preconditions are met: /// ```rust - /// # #![feature(ptr_sub_ptr)] /// # unsafe fn blah(ptr: *mut i32, origin: *mut i32, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -924,32 +923,30 @@ impl *mut T { /// # Examples /// /// ``` - /// #![feature(ptr_sub_ptr)] - /// /// let mut a = [0; 5]; /// let p: *mut i32 = a.as_mut_ptr(); /// unsafe { /// let ptr1: *mut i32 = p.add(1); /// let ptr2: *mut i32 = p.add(3); /// - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: /// // ptr1.offset_from(ptr2) - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn sub_ptr(self, origin: *const T) -> usize + pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { (self as *const T).sub_ptr(origin) } + unsafe { (self as *const T).offset_from_unsigned(origin) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -957,18 +954,18 @@ impl *mut T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// using [`sub_ptr`][pointer::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - pub const unsafe fn byte_sub_ptr(self, origin: *mut U) -> usize { + pub const unsafe fn byte_offset_from_unsigned(self, origin: *mut U) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { (self as *const T).byte_sub_ptr(origin) } + unsafe { (self as *const T).byte_offset_from_unsigned(origin) } } /// Adds an unsigned offset to a pointer. diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index f4ac00062d733..7abd3ddaa9efc 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -856,9 +856,8 @@ impl NonNull { /// to [`sub`](#method.sub)). The following are all equivalent, assuming /// that their safety preconditions are met: /// ```rust - /// # #![feature(ptr_sub_ptr)] /// # unsafe fn blah(ptr: std::ptr::NonNull, origin: std::ptr::NonNull, count: usize) -> bool { unsafe { - /// ptr.sub_ptr(origin) == count + /// ptr.offset_from_unsigned(origin) == count /// # && /// origin.add(count) == ptr /// # && @@ -885,32 +884,31 @@ impl NonNull { /// # Examples /// /// ``` - /// #![feature(ptr_sub_ptr)] /// use std::ptr::NonNull; /// /// let a = [0; 5]; /// let ptr1: NonNull = NonNull::from(&a[1]); /// let ptr2: NonNull = NonNull::from(&a[3]); /// unsafe { - /// assert_eq!(ptr2.sub_ptr(ptr1), 2); + /// assert_eq!(ptr2.offset_from_unsigned(ptr1), 2); /// assert_eq!(ptr1.add(2), ptr2); /// assert_eq!(ptr2.sub(2), ptr1); - /// assert_eq!(ptr2.sub_ptr(ptr2), 0); + /// assert_eq!(ptr2.offset_from_unsigned(ptr2), 0); /// } /// /// // This would be incorrect, as the pointers are not correctly ordered: - /// // ptr1.sub_ptr(ptr2) + /// // ptr1.offset_from_unsigned(ptr2) /// ``` #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] - pub const unsafe fn sub_ptr(self, subtracted: NonNull) -> usize + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + pub const unsafe fn offset_from_unsigned(self, subtracted: NonNull) -> usize where T: Sized, { // SAFETY: the caller must uphold the safety contract for `sub_ptr`. - unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) } + unsafe { self.as_ptr().offset_from_unsigned(subtracted.as_ptr()) } } /// Calculates the distance between two pointers within the same allocation, *where it's known that @@ -918,18 +916,18 @@ impl NonNull { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for + /// using [`sub_ptr`][NonNull::offset_from_unsigned] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, /// ignoring the metadata. #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[unstable(feature = "ptr_sub_ptr", issue = "95892")] - #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] - pub const unsafe fn byte_sub_ptr(self, origin: NonNull) -> usize { + #[stable(feature = "ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "CURRENT_RUSTC_VERSION")] + pub const unsafe fn byte_offset_from_unsigned(self, origin: NonNull) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. - unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) } + unsafe { self.as_ptr().byte_offset_from_unsigned(origin.as_ptr()) } } /// Reads the value from `self` without moving it. This leaves the diff --git a/library/core/src/range.rs b/library/core/src/range.rs index e94499065ac9a..2276112a27bb3 100644 --- a/library/core/src/range.rs +++ b/library/core/src/range.rs @@ -50,7 +50,7 @@ pub use crate::ops::{ /// assert_eq!(Range::from(3..5), Range { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum()); /// ``` -#[cfg_attr(not(bootstrap), lang = "RangeCopy")] +#[lang = "RangeCopy"] #[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] #[unstable(feature = "new_range_api", issue = "125687")] pub struct Range { @@ -216,7 +216,7 @@ impl From> for Range { /// assert_eq!(RangeInclusive::from(3..=5), RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, RangeInclusive::from(3..=5).into_iter().sum()); /// ``` -#[cfg_attr(not(bootstrap), lang = "RangeInclusiveCopy")] +#[lang = "RangeInclusiveCopy"] #[derive(Clone, Copy, PartialEq, Eq, Hash)] #[unstable(feature = "new_range_api", issue = "125687")] pub struct RangeInclusive { @@ -408,7 +408,7 @@ impl From> for RangeInclusive { /// assert_eq!(RangeFrom::from(2..), core::range::RangeFrom { start: 2 }); /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum()); /// ``` -#[cfg_attr(not(bootstrap), lang = "RangeFromCopy")] +#[lang = "RangeFromCopy"] #[derive(Clone, Copy, PartialEq, Eq, Hash)] #[unstable(feature = "new_range_api", issue = "125687")] pub struct RangeFrom { diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 45e320e66bc1a..7c1ed3fe8a246 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -54,7 +54,7 @@ macro_rules! len { // To get rid of some bounds checks (see `position`), we use ptr_sub instead of // offset_from (Tested by `codegen/slice-position-bounds-check`.) // SAFETY: by the type invariant pointers are aligned and `start <= end` - unsafe { end.sub_ptr($self.ptr) } + unsafe { end.offset_from_unsigned($self.ptr) } }, ) }}; @@ -154,16 +154,39 @@ macro_rules! iterator { #[inline] fn next(&mut self) -> Option<$elem> { - // could be implemented with slices, but this avoids bounds checks + // intentionally not using the helpers because this is + // one of the most mono'd things in the library. - // SAFETY: The call to `next_unchecked` is - // safe since we check if the iterator is empty first. + let ptr = self.ptr; + let end_or_len = self.end_or_len; + // SAFETY: See inner comments. (For some reason having multiple + // block breaks inlining this -- if you can fix that please do!) unsafe { - if is_empty!(self) { - None + if T::IS_ZST { + let len = end_or_len.addr(); + if len == 0 { + return None; + } + // SAFETY: just checked that it's not zero, so subtracting one + // cannot wrap. (Ideally this would be `checked_sub`, which + // does the same thing internally, but as of 2025-02 that + // doesn't optimize quite as small in MIR.) + self.end_or_len = without_provenance_mut(len.unchecked_sub(1)); } else { - Some(self.next_unchecked()) + // SAFETY: by type invariant, the `end_or_len` field is always + // non-null for a non-ZST pointee. (This transmute ensures we + // get `!nonnull` metadata on the load of the field.) + if ptr == crate::intrinsics::transmute::<$ptr, NonNull>(end_or_len) { + return None; + } + // SAFETY: since it's not empty, per the check above, moving + // forward one keeps us inside the slice, and this is valid. + self.ptr = ptr.add(1); } + // SAFETY: Now that we know it wasn't empty and we've moved past + // the first one (to avoid giving a duplicate `&mut` next time), + // we can give out a reference to it. + Some({ptr}.$into_ref()) } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ed45e26256e55..471150cfd9671 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4569,7 +4569,7 @@ impl [T] { /// /// [`get_disjoint_mut`]: slice::get_disjoint_mut /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html - #[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "get_many_mut", since = "1.86.0")] #[inline] pub unsafe fn get_disjoint_unchecked_mut( &mut self, @@ -4636,7 +4636,7 @@ impl [T] { /// } /// assert_eq!(v, &[1, 11, 111]); /// ``` - #[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "get_many_mut", since = "1.86.0")] #[inline] pub fn get_disjoint_mut( &mut self, @@ -4796,7 +4796,7 @@ impl [[T; N]] { /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); /// ``` #[stable(feature = "slice_flatten", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] + #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub const fn as_flattened(&self) -> &[T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") @@ -4833,7 +4833,7 @@ impl [[T; N]] { /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]); /// ``` #[stable(feature = "slice_flatten", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] + #[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")] pub const fn as_flattened_mut(&mut self) -> &mut [T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") @@ -5025,7 +5025,7 @@ fn get_disjoint_check_valid( /// assert_eq!(v.get_disjoint_mut([0, 999]), Err(GetDisjointMutError::IndexOutOfBounds)); /// assert_eq!(v.get_disjoint_mut([1, 1]), Err(GetDisjointMutError::OverlappingIndices)); /// ``` -#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "get_many_mut", since = "1.86.0")] #[derive(Debug, Clone, PartialEq, Eq)] pub enum GetDisjointMutError { /// An index provided was out-of-bounds for the slice. @@ -5034,7 +5034,7 @@ pub enum GetDisjointMutError { OverlappingIndices, } -#[stable(feature = "get_many_mut", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "get_many_mut", since = "1.86.0")] impl fmt::Display for GetDisjointMutError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let msg = match self { diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 319b76899bf8e..e24b52cff82e1 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -272,7 +272,7 @@ pub const fn from_mut(s: &mut T) -> &mut [T] { #[rustc_const_unstable(feature = "const_slice_from_ptr_range", issue = "89792")] pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { // SAFETY: the caller must uphold the safety contract for `from_ptr_range`. - unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } + unsafe { from_raw_parts(range.start, range.end.offset_from_unsigned(range.start)) } } /// Forms a mutable slice from a pointer range. @@ -342,5 +342,5 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { #[rustc_const_unstable(feature = "const_slice_from_mut_ptr_range", issue = "89792")] pub const unsafe fn from_mut_ptr_range<'a, T>(range: Range<*mut T>) -> &'a mut [T] { // SAFETY: the caller must uphold the safety contract for `from_mut_ptr_range`. - unsafe { from_raw_parts_mut(range.start, range.end.sub_ptr(range.start)) } + unsafe { from_raw_parts_mut(range.start, range.end.offset_from_unsigned(range.start)) } } diff --git a/library/core/src/slice/sort/shared/pivot.rs b/library/core/src/slice/sort/shared/pivot.rs index 255a1eb6c88a8..3aace484b6a89 100644 --- a/library/core/src/slice/sort/shared/pivot.rs +++ b/library/core/src/slice/sort/shared/pivot.rs @@ -31,9 +31,9 @@ pub fn choose_pivot bool>(v: &[T], is_less: &mut F) -> us let c = v_base.add(len_div_8 * 7); // [7*floor(n/8), 8*floor(n/8)) if len < PSEUDO_MEDIAN_REC_THRESHOLD { - median3(&*a, &*b, &*c, is_less).sub_ptr(v_base) + median3(&*a, &*b, &*c, is_less).offset_from_unsigned(v_base) } else { - median3_rec(a, b, c, len_div_8, is_less).sub_ptr(v_base) + median3_rec(a, b, c, len_div_8, is_less).offset_from_unsigned(v_base) } } } diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs index 09f898309bd65..f6dcf42ba6037 100644 --- a/library/core/src/slice/sort/shared/smallsort.rs +++ b/library/core/src/slice/sort/shared/smallsort.rs @@ -387,7 +387,7 @@ unsafe fn swap_if_less(v_base: *mut T, a_pos: usize, b_pos: usize, is_less where F: FnMut(&T, &T) -> bool, { - // SAFETY: the caller must guarantee that `a` and `b` each added to `v_base` yield valid + // SAFETY: the caller must guarantee that `a_pos` and `b_pos` each added to `v_base` yield valid // pointers into `v_base`, and are properly aligned, and part of the same allocation. unsafe { let v_a = v_base.add(a_pos); @@ -404,16 +404,16 @@ where // The equivalent code with a branch would be: // // if should_swap { - // ptr::swap(left, right, 1); + // ptr::swap(v_a, v_b, 1); // } // The goal is to generate cmov instructions here. - let left_swap = if should_swap { v_b } else { v_a }; - let right_swap = if should_swap { v_a } else { v_b }; + let v_a_swap = should_swap.select_unpredictable(v_b, v_a); + let v_b_swap = should_swap.select_unpredictable(v_a, v_b); - let right_swap_tmp = ManuallyDrop::new(ptr::read(right_swap)); - ptr::copy(left_swap, v_a, 1); - ptr::copy_nonoverlapping(&*right_swap_tmp, v_b, 1); + let v_b_swap_tmp = ManuallyDrop::new(ptr::read(v_b_swap)); + ptr::copy(v_a_swap, v_a, 1); + ptr::copy_nonoverlapping(&*v_b_swap_tmp, v_b, 1); } } @@ -640,26 +640,21 @@ pub unsafe fn sort4_stable bool>( // 1, 1 | c b a d let c3 = is_less(&*c, &*a); let c4 = is_less(&*d, &*b); - let min = select(c3, c, a); - let max = select(c4, b, d); - let unknown_left = select(c3, a, select(c4, c, b)); - let unknown_right = select(c4, d, select(c3, b, c)); + let min = c3.select_unpredictable(c, a); + let max = c4.select_unpredictable(b, d); + let unknown_left = c3.select_unpredictable(a, c4.select_unpredictable(c, b)); + let unknown_right = c4.select_unpredictable(d, c3.select_unpredictable(b, c)); // Sort the last two unknown elements. let c5 = is_less(&*unknown_right, &*unknown_left); - let lo = select(c5, unknown_right, unknown_left); - let hi = select(c5, unknown_left, unknown_right); + let lo = c5.select_unpredictable(unknown_right, unknown_left); + let hi = c5.select_unpredictable(unknown_left, unknown_right); ptr::copy_nonoverlapping(min, dst, 1); ptr::copy_nonoverlapping(lo, dst.add(1), 1); ptr::copy_nonoverlapping(hi, dst.add(2), 1); ptr::copy_nonoverlapping(max, dst.add(3), 1); } - - #[inline(always)] - fn select(cond: bool, if_true: *const T, if_false: *const T) -> *const T { - if cond { if_true } else { if_false } - } } /// SAFETY: The caller MUST guarantee that `v_base` is valid for 8 reads and diff --git a/library/core/src/slice/sort/stable/merge.rs b/library/core/src/slice/sort/stable/merge.rs index 0cb21740795b7..bb2747bfc78ac 100644 --- a/library/core/src/slice/sort/stable/merge.rs +++ b/library/core/src/slice/sort/stable/merge.rs @@ -143,7 +143,7 @@ impl Drop for MergeState { // leave the input slice `v` with each original element and all possible // modifications observed. unsafe { - let len = self.end.sub_ptr(self.start); + let len = self.end.offset_from_unsigned(self.start); ptr::copy_nonoverlapping(self.start, self.dst, len); } } diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs index 4feef5deeb0fb..bb9f90fc881a0 100644 --- a/library/core/src/slice/sort/unstable/quicksort.rs +++ b/library/core/src/slice/sort/unstable/quicksort.rs @@ -224,7 +224,7 @@ where left = left.add(1); } - left.sub_ptr(v_base) + left.offset_from_unsigned(v_base) // `gap_opt` goes out of scope and overwrites the last wrong-side element on the right side // with the first wrong-side element of the left side that was initially overwritten by the diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index fd2cd59f88e08..064923edb41f6 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -198,8 +198,6 @@ impl str { /// Basic usage: /// /// ``` - /// use std::str; - /// /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// @@ -207,14 +205,12 @@ impl str { /// let sparkle_heart = str::from_utf8(&sparkle_heart)?; /// /// assert_eq!("💖", sparkle_heart); - /// # Ok::<_, str::Utf8Error>(()) + /// # Ok::<_, std::str::Utf8Error>(()) /// ``` /// /// Incorrect bytes: /// /// ``` - /// use std::str; - /// /// // some invalid bytes, in a vector /// let sparkle_heart = vec![0, 159, 146, 150]; /// @@ -227,8 +223,6 @@ impl str { /// A "stack allocated string": /// /// ``` - /// use std::str; - /// /// // some bytes, in a stack-allocated array /// let sparkle_heart = [240, 159, 146, 150]; /// @@ -237,7 +231,8 @@ impl str { /// /// assert_eq!("💖", sparkle_heart); /// ``` - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8"] pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { converts::from_utf8(v) @@ -250,8 +245,6 @@ impl str { /// Basic usage: /// /// ``` - /// use std::str; - /// /// // "Hello, Rust!" as a mutable vector /// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33]; /// @@ -264,8 +257,6 @@ impl str { /// Incorrect bytes: /// /// ``` - /// use std::str; - /// /// // Some invalid bytes in a mutable vector /// let mut invalid = vec![128, 223]; /// @@ -273,7 +264,7 @@ impl str { /// ``` /// See the docs for [`Utf8Error`] for more details on the kinds of /// errors that can be returned. - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] #[rustc_diagnostic_item = "str_inherent_from_utf8_mut"] pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { @@ -294,8 +285,6 @@ impl str { /// Basic usage: /// /// ``` - /// use std::str; - /// /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// @@ -307,7 +296,8 @@ impl str { /// ``` #[inline] #[must_use] - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked"] pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { // SAFETY: converts::from_utf8_unchecked has the same safety requirements as this function. @@ -324,8 +314,6 @@ impl str { /// Basic usage: /// /// ``` - /// use std::str; - /// /// let mut heart = vec![240, 159, 146, 150]; /// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) }; /// @@ -333,7 +321,8 @@ impl str { /// ``` #[inline] #[must_use] - #[unstable(feature = "inherent_str_constructors", issue = "131114")] + #[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked_mut"] pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { // SAFETY: converts::from_utf8_unchecked_mut has the same safety requirements as this function. @@ -365,7 +354,7 @@ impl str { /// ``` #[must_use] #[stable(feature = "is_char_boundary", since = "1.9.0")] - #[rustc_const_stable(feature = "const_is_char_boundary", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_is_char_boundary", since = "1.86.0")] #[inline] pub const fn is_char_boundary(&self, index: usize) -> bool { // 0 is always ok. @@ -822,7 +811,7 @@ impl str { #[inline] #[must_use] #[stable(feature = "str_split_at", since = "1.4.0")] - #[rustc_const_stable(feature = "const_str_split_at", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_split_at", since = "1.86.0")] pub const fn split_at(&self, mid: usize) -> (&str, &str) { match self.split_at_checked(mid) { None => slice_error_fail(self, 0, mid), @@ -863,7 +852,7 @@ impl str { #[inline] #[must_use] #[stable(feature = "str_split_at", since = "1.4.0")] - #[rustc_const_stable(feature = "const_str_split_at", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_split_at", since = "1.86.0")] pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { @@ -903,7 +892,7 @@ impl str { #[inline] #[must_use] #[stable(feature = "split_at_checked", since = "1.80.0")] - #[rustc_const_stable(feature = "const_str_split_at", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_split_at", since = "1.86.0")] pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { @@ -944,7 +933,7 @@ impl str { #[inline] #[must_use] #[stable(feature = "split_at_checked", since = "1.80.0")] - #[rustc_const_stable(feature = "const_str_split_at", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_split_at", since = "1.86.0")] pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index 52e2364893eb1..2d941adfd859c 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -38,6 +38,7 @@ issue = "27721" )] +use crate::char::MAX_LEN_UTF8; use crate::cmp::Ordering; use crate::convert::TryInto as _; use crate::slice::memchr; @@ -561,8 +562,8 @@ impl Pattern for char { type Searcher<'a> = CharSearcher<'a>; #[inline] - fn into_searcher(self, haystack: &str) -> Self::Searcher<'_> { - let mut utf8_encoded = [0; 4]; + fn into_searcher<'a>(self, haystack: &'a str) -> Self::Searcher<'a> { + let mut utf8_encoded = [0; MAX_LEN_UTF8]; let utf8_size = self .encode_utf8(&mut utf8_encoded) .len() diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 22bd46c567eaa..8b211b442eab6 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1168,6 +1168,7 @@ impl Div for Duration { type Output = Duration; #[inline] + #[track_caller] fn div(self, rhs: u32) -> Duration { self.checked_div(rhs).expect("divide by zero error when dividing duration by scalar") } @@ -1176,6 +1177,7 @@ impl Div for Duration { #[stable(feature = "time_augmented_assignment", since = "1.9.0")] impl DivAssign for Duration { #[inline] + #[track_caller] fn div_assign(&mut self, rhs: u32) { *self = *self / rhs; } diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index b289f6026ffcb..9eb71922218f3 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -65,9 +65,9 @@ macro_rules! assert_unsafe_precondition { #[rustc_nounwind] const fn precondition_check($($name:$ty),*) { if !$e { - ::core::panicking::panic_nounwind( - concat!("unsafe precondition(s) violated: ", $message) - ); + ::core::panicking::panic_nounwind(concat!("unsafe precondition(s) violated: ", $message, + "\n\nThis indicates a bug in the program. \ + This Undefined Behavior check is optional, and cannot be relied on for safety.")); } } diff --git a/library/coretests/tests/any.rs b/library/coretests/tests/any.rs index 25002617d0bbd..117ef0042380d 100644 --- a/library/coretests/tests/any.rs +++ b/library/coretests/tests/any.rs @@ -118,6 +118,14 @@ fn any_unsized() { is_any::<[i32]>(); } +#[cfg(feature = "debug_typeid")] +#[test] +fn debug_typeid_includes_name() { + let type_id = TypeId::of::<[usize; 2]>(); + let debug_str = format!("{type_id:?}"); + assert!(debug_str.ends_with("= [usize; 2])"), "{debug_str:?} did not match"); +} + #[test] fn distinct_type_names() { // https://github.com/rust-lang/rust/issues/84666 diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs index 6422387e9560b..153fb36925e66 100644 --- a/library/coretests/tests/char.rs +++ b/library/coretests/tests/char.rs @@ -1,3 +1,4 @@ +use std::char::MAX_LEN_UTF8; use std::str::FromStr; use std::{char, str}; @@ -259,7 +260,7 @@ fn test_escape_unicode() { #[test] fn test_encode_utf8() { fn check(input: char, expect: &[u8]) { - let mut buf = [0; 4]; + let mut buf = [0; MAX_LEN_UTF8]; let ptr = buf.as_ptr(); let s = input.encode_utf8(&mut buf); assert_eq!(s.as_ptr() as usize, ptr as usize); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 1e1ff29e16151..4f21ae5013b66 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,6 +13,7 @@ #![feature(bigint_helper_methods)] #![feature(bstr)] #![feature(cell_update)] +#![feature(char_max_len)] #![feature(clone_to_uninit)] #![feature(const_eval_select)] #![feature(const_swap_nonoverlapping)] @@ -43,6 +44,7 @@ #![feature(ip)] #![feature(ip_from)] #![feature(is_ascii_octdigit)] +#![feature(isolate_most_least_significant_one)] #![feature(iter_advance_by)] #![feature(iter_array_chunks)] #![feature(iter_chain)] @@ -62,7 +64,6 @@ #![feature(maybe_uninit_write_slice)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(num_midpoint_signed)] #![feature(numfmt)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] @@ -86,7 +87,6 @@ #![feature(try_blocks)] #![feature(try_find)] #![feature(try_trait_v2)] -#![feature(unsigned_is_multiple_of)] #![feature(unsize)] #![feature(unsized_tuple_coercion)] #![feature(unwrap_infallible)] @@ -153,10 +153,7 @@ mod intrinsics; mod io; mod iter; mod lazy; -#[cfg(not(bootstrap))] mod macros; -#[cfg(bootstrap)] -mod macros_bootstrap; mod manually_drop; mod mem; mod net; diff --git a/library/coretests/tests/macros_bootstrap.rs b/library/coretests/tests/macros_bootstrap.rs deleted file mode 100644 index f10ef862c5dd9..0000000000000 --- a/library/coretests/tests/macros_bootstrap.rs +++ /dev/null @@ -1,193 +0,0 @@ -#![allow(unused_must_use)] - -#[allow(dead_code)] -trait Trait { - fn blah(&self); -} - -#[allow(dead_code)] -struct Struct; - -impl Trait for Struct { - cfg_match! { - cfg(feature = "blah") => { - fn blah(&self) { - unimplemented!(); - } - } - _ => { - fn blah(&self) { - unimplemented!(); - } - } - } -} - -#[test] -fn assert_eq_trailing_comma() { - assert_eq!(1, 1,); -} - -#[test] -fn assert_escape() { - assert!(r#"☃\backslash"#.contains("\\")); -} - -#[test] -fn assert_ne_trailing_comma() { - assert_ne!(1, 2,); -} - -#[rustfmt::skip] -#[test] -fn matches_leading_pipe() { - matches!(1, | 1 | 2 | 3); -} - -#[test] -fn cfg_match_basic() { - cfg_match! { - cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }} - } - - cfg_match! { - cfg(unix) => { fn f1_() -> bool { true }} - cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }} - } - - cfg_match! { - cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }} - cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }} - } - - cfg_match! { - cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }} - _ => { fn f3_() -> i32 { 2 }} - } - - #[cfg(target_pointer_width = "64")] - assert!(f0_()); - - #[cfg(unix)] - assert!(f1_()); - - #[cfg(target_pointer_width = "32")] - assert!(!f2_()); - #[cfg(target_pointer_width = "64")] - assert!(f2_()); - - #[cfg(not(target_pointer_width = "16"))] - assert_eq!(f3_(), 2); -} - -#[test] -fn cfg_match_debug_assertions() { - cfg_match! { - cfg(debug_assertions) => { - assert!(cfg!(debug_assertions)); - assert_eq!(4, 2+2); - } - _ => { - assert!(cfg!(not(debug_assertions))); - assert_eq!(10, 5+5); - } - } -} - -#[cfg(target_pointer_width = "64")] -#[test] -fn cfg_match_no_duplication_on_64() { - cfg_match! { - cfg(windows) => { - fn foo() {} - } - cfg(unix) => { - fn foo() {} - } - cfg(target_pointer_width = "64") => { - fn foo() {} - } - } - foo(); -} - -#[test] -fn cfg_match_options() { - cfg_match! { - cfg(test) => { - use core::option::Option as Option2; - fn works1() -> Option2 { Some(1) } - } - _ => { fn works1() -> Option { None } } - } - - cfg_match! { - cfg(feature = "foo") => { fn works2() -> bool { false } } - cfg(test) => { fn works2() -> bool { true } } - _ => { fn works2() -> bool { false } } - } - - cfg_match! { - cfg(feature = "foo") => { fn works3() -> bool { false } } - _ => { fn works3() -> bool { true } } - } - - cfg_match! { - cfg(test) => { - use core::option::Option as Option3; - fn works4() -> Option3 { Some(1) } - } - } - - cfg_match! { - cfg(feature = "foo") => { fn works5() -> bool { false } } - cfg(test) => { fn works5() -> bool { true } } - } - - assert!(works1().is_some()); - assert!(works2()); - assert!(works3()); - assert!(works4().is_some()); - assert!(works5()); -} - -#[test] -fn cfg_match_two_functions() { - cfg_match! { - cfg(target_pointer_width = "64") => { - fn foo1() {} - fn bar1() {} - } - _ => { - fn foo2() {} - fn bar2() {} - } - } - - #[cfg(target_pointer_width = "64")] - { - foo1(); - bar1(); - } - #[cfg(not(target_pointer_width = "64"))] - { - foo2(); - bar2(); - } -} - -fn _accepts_expressions() -> i32 { - cfg_match! { - cfg(unix) => { 1 } - _ => { 2 } - } -} - -fn _allows_stmt_expr_attributes() { - let one = 1; - let two = 2; - cfg_match! { - cfg(unix) => { one * two; } - _ => { one + two; } - } -} diff --git a/library/coretests/tests/nonzero.rs b/library/coretests/tests/nonzero.rs index 43c279053d829..bdc5701d9fd23 100644 --- a/library/coretests/tests/nonzero.rs +++ b/library/coretests/tests/nonzero.rs @@ -321,6 +321,106 @@ fn nonzero_trailing_zeros() { assert_eq!(TRAILING_ZEROS, 2); } +#[test] +fn test_nonzero_isolate_most_significant_one() { + // Signed most significant one + macro_rules! nonzero_int_impl { + ($($T:ty),+) => { + $( + { + const BITS: $T = -1; + const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); + + // Right shift the most significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + NonZero::<$T>::new(BITS >> i).unwrap().isolate_most_significant_one(), + NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_most_significant_one() + ); + i += 1; + } + } + )+ + }; + } + + // Unsigned most significant one + macro_rules! nonzero_uint_impl { + ($($T:ty),+) => { + $( + { + const BITS: $T = <$T>::MAX; + const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); + + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + NonZero::<$T>::new(BITS >> i).unwrap().isolate_most_significant_one(), + NonZero::<$T>::new(MOST_SIG_ONE >> i).unwrap().isolate_most_significant_one(), + ); + i += 1; + } + } + )+ + }; + } + + nonzero_int_impl!(i8, i16, i32, i64, i128, isize); + nonzero_uint_impl!(u8, u16, u32, u64, u128, usize); +} + +#[test] +fn test_nonzero_isolate_least_significant_one() { + // Signed least significant one + macro_rules! nonzero_int_impl { + ($($T:ty),+) => { + $( + { + const BITS: $T = -1; + const LEAST_SIG_ONE: $T = 1; + + // Left shift the least significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + NonZero::<$T>::new(BITS << i).unwrap().isolate_least_significant_one(), + NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_least_significant_one() + ); + i += 1; + } + } + )+ + }; + } + + // Unsigned least significant one + macro_rules! nonzero_uint_impl { + ($($T:ty),+) => { + $( + { + const BITS: $T = <$T>::MAX; + const LEAST_SIG_ONE: $T = 1; + + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + NonZero::<$T>::new(BITS << i).unwrap().isolate_least_significant_one(), + NonZero::<$T>::new(LEAST_SIG_ONE << i).unwrap().isolate_least_significant_one(), + ); + i += 1; + } + } + )+ + }; + } + + nonzero_int_impl!(i8, i16, i32, i64, i128, isize); + nonzero_uint_impl!(u8, u16, u32, u64, u128, usize); +} + #[test] fn test_nonzero_uint_div() { let nz = NonZero::new(1).unwrap(); diff --git a/library/coretests/tests/num/int_macros.rs b/library/coretests/tests/num/int_macros.rs index f13b836378b9e..392704e7509ac 100644 --- a/library/coretests/tests/num/int_macros.rs +++ b/library/coretests/tests/num/int_macros.rs @@ -192,6 +192,40 @@ macro_rules! int_module { } } + #[test] + fn test_isolate_most_significant_one() { + const BITS: $T = -1; + const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); + + // Right shift the most significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + (BITS >> i).isolate_most_significant_one(), + (MOST_SIG_ONE >> i).isolate_most_significant_one() + ); + i += 1; + } + } + + #[test] + fn test_isolate_least_significant_one() { + const BITS: $T = -1; + const LEAST_SIG_ONE: $T = 1; + + // Left shift the least significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + (BITS << i).isolate_least_significant_one(), + (LEAST_SIG_ONE << i).isolate_least_significant_one() + ); + i += 1; + } + } + #[test] fn test_from_str() { fn from_str(t: &str) -> Option { diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs index 99a2d4cd462b1..c085ba5a249af 100644 --- a/library/coretests/tests/num/uint_macros.rs +++ b/library/coretests/tests/num/uint_macros.rs @@ -141,6 +141,40 @@ macro_rules! uint_module { } } + #[test] + fn test_isolate_most_significant_one() { + const BITS: $T = <$T>::MAX; + const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1); + + // Right shift the most significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + (BITS >> i).isolate_most_significant_one(), + (MOST_SIG_ONE >> i).isolate_most_significant_one(), + ); + i += 1; + } + } + + #[test] + fn test_isolate_least_significant_one() { + const BITS: $T = <$T>::MAX; + const LEAST_SIG_ONE: $T = 1; + + // Left shift the least significant one through each + // bit position, starting with all bits set + let mut i = 0; + while i < <$T>::BITS { + assert_eq!( + (BITS << i).isolate_least_significant_one(), + (LEAST_SIG_ONE << i).isolate_least_significant_one(), + ); + i += 1; + } + } + fn from_str(t: &str) -> Option { core::str::FromStr::from_str(t).ok() } diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 1111c2009b3dd..a284633ea2fc7 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -14,6 +14,7 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] #![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] +#![feature(cfg_emscripten_wasm_eh)] #![feature(core_intrinsics)] #![feature(lang_items)] #![feature(panic_unwind)] @@ -25,7 +26,6 @@ // `real_imp` is unused with Miri, so silence warnings. #![cfg_attr(miri, allow(dead_code))] #![allow(internal_features)] -#![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))] #![warn(unreachable_pub)] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index b763a7c75a5a6..19d45f4d3b31a 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -401,7 +401,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a defaulted mask with all elements set to false (0)"] fn default() -> Self { Self::splat(false) } @@ -413,7 +412,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new bool and does not mutate the original value"] fn eq(&self, other: &Self) -> bool { self.0 == other.0 } @@ -425,7 +423,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new Ordering and does not mutate the original value"] fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } @@ -451,7 +448,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { Self(self.0 & rhs.0) } @@ -464,7 +460,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: bool) -> Self { self & Self::splat(rhs) } @@ -477,7 +472,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Mask) -> Mask { Mask::splat(self) & rhs } @@ -490,7 +484,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { Self(self.0 | rhs.0) } @@ -503,7 +496,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: bool) -> Self { self | Self::splat(rhs) } @@ -516,7 +508,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Mask) -> Mask { Mask::splat(self) | rhs } @@ -529,7 +520,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self::Output { Self(self.0 ^ rhs.0) } @@ -542,7 +532,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: bool) -> Self::Output { self ^ Self::splat(rhs) } @@ -555,7 +544,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Mask) -> Self::Output { Mask::splat(self) ^ rhs } @@ -568,7 +556,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self(!self.0) } diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index 2d01946b5747c..387b508c4b4ef 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -21,7 +21,6 @@ where LaneCount: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn clone(&self) -> Self { *self } @@ -252,7 +251,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) } @@ -266,7 +264,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) } @@ -280,7 +277,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Self) -> Self { // Safety: `self` is an integer vector unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) } @@ -294,7 +290,6 @@ where { type Output = Self; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self::splat(true) ^ self } diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs index d3bd14a340278..4ac64a253a3bd 100644 --- a/library/portable-simd/crates/core_simd/src/ops.rs +++ b/library/portable-simd/crates/core_simd/src/ops.rs @@ -135,7 +135,6 @@ macro_rules! for_base_types { type Output = $out; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] // TODO: only useful for int Div::div, but we hope that this // will essentially always get inlined anyway. #[track_caller] diff --git a/library/portable-simd/crates/core_simd/src/ops/deref.rs b/library/portable-simd/crates/core_simd/src/ops/deref.rs index 0ff76cfba39bb..913cbbe977c46 100644 --- a/library/portable-simd/crates/core_simd/src/ops/deref.rs +++ b/library/portable-simd/crates/core_simd/src/ops/deref.rs @@ -18,7 +18,6 @@ macro_rules! deref_lhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: $simd) -> Self::Output { (*self).$call(rhs) } @@ -39,7 +38,6 @@ macro_rules! deref_rhs { type Output = Simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &$simd) -> Self::Output { self.$call(*rhs) } @@ -71,7 +69,6 @@ macro_rules! deref_ops { type Output = $simd; #[inline] - #[must_use = "operator returns a new vector without mutating the inputs"] fn $call(self, rhs: &'rhs $simd) -> Self::Output { (*self).$call(*rhs) } diff --git a/library/portable-simd/crates/core_simd/src/ops/unary.rs b/library/portable-simd/crates/core_simd/src/ops/unary.rs index bdae96332a3ae..412a5b801171b 100644 --- a/library/portable-simd/crates/core_simd/src/ops/unary.rs +++ b/library/portable-simd/crates/core_simd/src/ops/unary.rs @@ -11,7 +11,6 @@ macro_rules! neg { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn neg(self) -> Self::Output { // Safety: `self` is a signed vector unsafe { core::intrinsics::simd::simd_neg(self) } @@ -46,7 +45,6 @@ macro_rules! not { type Output = Self; #[inline] - #[must_use = "operator returns a new vector without mutating the input"] fn not(self) -> Self::Output { self ^ (Simd::splat(!(0 as $scalar))) } diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index 79954b937b397..db705dfe20221 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -371,7 +371,6 @@ macro_rules! impl_trait { } #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn is_normal(self) -> Self::Mask { !(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite()) } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 36a0a59d939f3..a0a28e8079601 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.146" } +compiler_builtins = { version = "=0.1.147" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', @@ -110,6 +110,13 @@ panic_immediate_abort = [ # Choose algorithms that are optimized for binary size instead of runtime performance optimize_for_size = ["core/optimize_for_size", "alloc/optimize_for_size"] +# Make `RefCell` store additional debugging information, which is printed out when +# a borrow error occurs +debug_refcell = ["core/debug_refcell"] +# Make `TypeId` store a reference to the name of the type, so that it can print that name. +debug_typeid = ["core/debug_typeid"] + + # Enable std_detect default features for stdarch/crates/std_detect: # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml std_detect_file_io = ["std_detect/std_detect_file_io"] @@ -152,8 +159,6 @@ test = true level = "warn" check-cfg = [ 'cfg(bootstrap)', - 'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock", "x86_64-pc-nto-qnx800","aarch64-unknown-nto-qnx800"))', - 'cfg(target_env, values("nto71_iosock", "nto80"))', # std use #[path] imports to portable-simd `std_float` crate # and to the `backtrace` crate which messes-up with Cargo list # of declared features, we therefor expect any feature cfg diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 6a0ff3a29e08f..93d254e34f5eb 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1024,7 +1024,7 @@ where /// ``` #[inline] #[doc(alias = "get_many_mut")] - #[stable(feature = "map_many_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "map_many_mut", since = "1.86.0")] pub fn get_disjoint_mut( &mut self, ks: [&Q; N], @@ -1091,7 +1091,7 @@ where /// ``` #[inline] #[doc(alias = "get_many_unchecked_mut")] - #[stable(feature = "map_many_mut", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "map_many_mut", since = "1.86.0")] pub unsafe fn get_disjoint_unchecked_mut( &mut self, ks: [&Q; N], diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 14ce2b69ca427..974514c9c4556 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -126,7 +126,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f128 { - unsafe { intrinsics::rintf128(self) } + intrinsics::round_ties_even_f128(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index bdbe3e2199466..c3b51bf31de70 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -126,7 +126,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] #[must_use = "method returns a new number and does not mutate the original value"] pub fn round_ties_even(self) -> f16 { - unsafe { intrinsics::rintf16(self) } + intrinsics::round_ties_even_f16(self) } /// Returns the integer part of `self`. @@ -1321,12 +1321,14 @@ impl f16 { /// ``` /// #![feature(f16)] /// #![feature(float_erf)] + /// # #[cfg(reliable_f16_math)] { /// let x: f16 = 0.123; /// /// let one = x.erf() + x.erfc(); /// let abs_difference = (one - 1.0).abs(); /// /// assert!(abs_difference <= f16::EPSILON); + /// # } /// ``` #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 295eee8700af2..19fb24c8ee26c 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -122,7 +122,7 @@ impl f32 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f32 { - unsafe { intrinsics::rintf32(self) } + intrinsics::round_ties_even_f32(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 0d713ecbc7312..f1c3cb561271a 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -122,7 +122,7 @@ impl f64 { #[stable(feature = "round_ties_even", since = "1.77.0")] #[inline] pub fn round_ties_even(self) -> f64 { - unsafe { intrinsics::rintf64(self) } + intrinsics::round_ties_even_f64(self) } /// Returns the integer part of `self`. diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 7d7cce09a3f09..860ec3a6be16e 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -201,5 +201,5 @@ pub use self::c_str::{CStr, CString}; #[doc(inline)] pub use self::os_str::{OsStr, OsString}; -#[unstable(feature = "os_str_display", issue = "120048")] +#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] pub mod os_str; diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index c4c8dbccd7a44..f4a02802336d5 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1204,13 +1204,12 @@ impl OsStr { /// # Examples /// /// ``` - /// #![feature(os_str_display)] /// use std::ffi::OsStr; /// /// let s = OsStr::new("Hello, world!"); /// println!("{}", s.display()); /// ``` - #[unstable(feature = "os_str_display", issue = "120048")] + #[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this does not display the `OsStr`; \ it returns an object that can be displayed"] #[inline] @@ -1559,7 +1558,6 @@ impl fmt::Debug for OsStr { /// # Examples /// /// ``` -/// #![feature(os_str_display)] /// use std::ffi::OsStr; /// /// let s = OsStr::new("Hello, world!"); @@ -1568,19 +1566,19 @@ impl fmt::Debug for OsStr { /// /// [`Display`]: fmt::Display /// [`format!`]: crate::format -#[unstable(feature = "os_str_display", issue = "120048")] +#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] pub struct Display<'a> { os_str: &'a OsStr, } -#[unstable(feature = "os_str_display", issue = "120048")] +#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.os_str, f) } } -#[unstable(feature = "os_str_display", issue = "120048")] +#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] impl fmt::Display for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.os_str.inner, f) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 83b009c86dc08..57e235c3efe1d 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -624,20 +624,20 @@ impl File { self.inner.datasync() } - /// Acquire an exclusive advisory lock on the file. Blocks until the lock can be acquired. + /// Acquire an exclusive lock on the file. Blocks until the lock can be acquired. /// - /// This acquires an exclusive advisory lock; no other file handle to this file may acquire - /// another lock. + /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. /// - /// If this file handle/descriptor, or a clone of it, already holds an advisory lock the exact - /// behavior is unspecified and platform dependent, including the possibility that it will - /// deadlock. However, if this method returns, then an exclusive lock is held. + /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], + /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with + /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not + /// cause non-lockholders to block. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If this file handle/descriptor, or a clone of it, already holds an lock the exact behavior + /// is unspecified and platform dependent, including the possibility that it will deadlock. + /// However, if this method returns, then an exclusive lock is held. /// - /// Note, this is an advisory lock meant to interact with [`lock_shared`], [`try_lock`], - /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] - /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. + /// If the file not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -648,8 +648,12 @@ impl File { /// and the `LockFileEx` function on Windows with the `LOCKFILE_EXCLUSIVE_LOCK` flag. Note that, /// this [may change in the future][changes]. /// + /// On Windows, locking a file will fail if the file is opened only for append. To lock a file, + /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`. + /// /// [changes]: io#platform-specific-behavior /// + /// [`lock`]: File::lock /// [`lock_shared`]: File::lock_shared /// [`try_lock`]: File::try_lock /// [`try_lock_shared`]: File::try_lock_shared @@ -660,7 +664,6 @@ impl File { /// # Examples /// /// ```no_run - /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -669,23 +672,24 @@ impl File { /// Ok(()) /// } /// ``` - #[unstable(feature = "file_lock", issue = "130994")] + #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] pub fn lock(&self) -> io::Result<()> { self.inner.lock() } - /// Acquire a shared (non-exclusive) advisory lock on the file. Blocks until the lock can be acquired. + /// Acquire a shared (non-exclusive) lock on the file. Blocks until the lock can be acquired. /// - /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but - /// none may hold an exclusive lock at the same time. + /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may + /// hold an exclusive lock at the same time. /// - /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact - /// behavior is unspecified and platform dependent, including the possibility that it will - /// deadlock. However, if this method returns, then a shared lock is held. + /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], + /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with + /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not + /// cause non-lockholders to block. /// - /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`], - /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] - /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. + /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// is unspecified and platform dependent, including the possibility that it will deadlock. + /// However, if this method returns, then a shared lock is held. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -696,9 +700,13 @@ impl File { /// and the `LockFileEx` function on Windows. Note that, this /// [may change in the future][changes]. /// + /// On Windows, locking a file will fail if the file is opened only for append. To lock a file, + /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`. + /// /// [changes]: io#platform-specific-behavior /// /// [`lock`]: File::lock + /// [`lock_shared`]: File::lock_shared /// [`try_lock`]: File::try_lock /// [`try_lock_shared`]: File::try_lock_shared /// [`unlock`]: File::unlock @@ -708,7 +716,6 @@ impl File { /// # Examples /// /// ```no_run - /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -717,29 +724,28 @@ impl File { /// Ok(()) /// } /// ``` - #[unstable(feature = "file_lock", issue = "130994")] + #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] pub fn lock_shared(&self) -> io::Result<()> { self.inner.lock_shared() } - /// Try to acquire an exclusive advisory lock on the file. + /// Try to acquire an exclusive lock on the file. /// /// Returns `Ok(false)` if a different lock is already held on this file (via another /// handle/descriptor). /// - /// This acquires an exclusive advisory lock; no other file handle to this file may acquire - /// another lock. + /// This acquires an exclusive lock; no other file handle to this file may acquire another lock. /// - /// If this file handle/descriptor, or a clone of it, already holds an advisory lock, the exact - /// behavior is unspecified and platform dependent, including the possibility that it will - /// deadlock. However, if this method returns `Ok(true)`, then it has acquired an exclusive - /// lock. + /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], + /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with + /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not + /// cause non-lockholders to block. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// is unspecified and platform dependent, including the possibility that it will deadlock. + /// However, if this method returns `Ok(true)`, then it has acquired an exclusive lock. /// - /// Note, this is an advisory lock meant to interact with [`lock`], [`lock_shared`], - /// [`try_lock_shared`], and [`unlock`]. Its interactions with other methods, such as [`read`] - /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. + /// If the file not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -751,10 +757,14 @@ impl File { /// and `LOCKFILE_FAIL_IMMEDIATELY` flags. Note that, this /// [may change in the future][changes]. /// + /// On Windows, locking a file will fail if the file is opened only for append. To lock a file, + /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`. + /// /// [changes]: io#platform-specific-behavior /// /// [`lock`]: File::lock /// [`lock_shared`]: File::lock_shared + /// [`try_lock`]: File::try_lock /// [`try_lock_shared`]: File::try_lock_shared /// [`unlock`]: File::unlock /// [`read`]: Read::read @@ -763,7 +773,6 @@ impl File { /// # Examples /// /// ```no_run - /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -772,27 +781,28 @@ impl File { /// Ok(()) /// } /// ``` - #[unstable(feature = "file_lock", issue = "130994")] + #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] pub fn try_lock(&self) -> io::Result { self.inner.try_lock() } - /// Try to acquire a shared (non-exclusive) advisory lock on the file. + /// Try to acquire a shared (non-exclusive) lock on the file. /// /// Returns `Ok(false)` if an exclusive lock is already held on this file (via another /// handle/descriptor). /// - /// This acquires a shared advisory lock; more than one file handle may hold a shared lock, but - /// none may hold an exclusive lock at the same time. + /// This acquires a shared lock; more than one file handle may hold a shared lock, but none may + /// hold an exclusive lock at the same time. + /// + /// This lock may be advisory or mandatory. This lock is meant to interact with [`lock`], + /// [`try_lock`], [`lock_shared`], [`try_lock_shared`], and [`unlock`]. Its interactions with + /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not + /// cause non-lockholders to block. /// - /// If this file handle, or a clone of it, already holds an advisory lock, the exact behavior is + /// If this file handle, or a clone of it, already holds an lock, the exact behavior is /// unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns `Ok(true)`, then it has acquired a shared lock. /// - /// Note, this is an advisory lock meant to interact with [`lock`], [`try_lock`], - /// [`try_lock`], and [`unlock`]. Its interactions with other methods, such as [`read`] - /// and [`write`] are platform specific, and it may or may not cause non-lockholders to block. - /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. /// @@ -803,11 +813,15 @@ impl File { /// `LOCKFILE_FAIL_IMMEDIATELY` flag. Note that, this /// [may change in the future][changes]. /// + /// On Windows, locking a file will fail if the file is opened only for append. To lock a file, + /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`. + /// /// [changes]: io#platform-specific-behavior /// /// [`lock`]: File::lock /// [`lock_shared`]: File::lock_shared /// [`try_lock`]: File::try_lock + /// [`try_lock_shared`]: File::try_lock_shared /// [`unlock`]: File::unlock /// [`read`]: Read::read /// [`write`]: Write::write @@ -815,7 +829,6 @@ impl File { /// # Examples /// /// ```no_run - /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -824,7 +837,7 @@ impl File { /// Ok(()) /// } /// ``` - #[unstable(feature = "file_lock", issue = "130994")] + #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] pub fn try_lock_shared(&self) -> io::Result { self.inner.try_lock_shared() } @@ -844,12 +857,14 @@ impl File { /// and the `UnlockFile` function on Windows. Note that, this /// [may change in the future][changes]. /// + /// On Windows, locking a file will fail if the file is opened only for append. To lock a file, + /// open it with one of `.read(true)`, `.read(true).append(true)`, or `.write(true)`. + /// /// [changes]: io#platform-specific-behavior /// /// # Examples /// /// ```no_run - /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -859,7 +874,7 @@ impl File { /// Ok(()) /// } /// ``` - #[unstable(feature = "file_lock", issue = "130994")] + #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] pub fn unlock(&self) -> io::Result<()> { self.inner.unlock() } @@ -1229,6 +1244,9 @@ impl Seek for &File { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.inner.seek(pos) } + fn stream_position(&mut self) -> io::Result { + self.inner.tell() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1275,6 +1293,9 @@ impl Seek for File { fn seek(&mut self, pos: SeekFrom) -> io::Result { (&*self).seek(pos) } + fn stream_position(&mut self) -> io::Result { + (&*self).stream_position() + } } #[stable(feature = "io_traits_arc", since = "1.73.0")] @@ -2505,6 +2526,7 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// * `from` does not exist. /// * The current process does not have the permission rights to read /// `from` or write `to`. +/// * The parent directory of `to` doesn't exist. /// /// # Examples /// diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 8e307f57cf9d2..c7833c7dc7133 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1,5 +1,6 @@ use rand::RngCore; +use crate::char::MAX_LEN_UTF8; use crate::fs::{self, File, FileTimes, OpenOptions}; use crate::io::prelude::*; use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; @@ -155,7 +156,7 @@ fn file_test_io_non_positional_read() { #[test] fn file_test_io_seek_and_tell_smoke_test() { let message = "ten-four"; - let mut read_mem = [0; 4]; + let mut read_mem = [0; MAX_LEN_UTF8]; let set_cursor = 4 as u64; let tell_pos_pre_read; let tell_pos_post_read; @@ -356,7 +357,7 @@ fn file_test_io_seek_shakedown() { let chunk_one: &str = "qwer"; let chunk_two: &str = "asdf"; let chunk_three: &str = "zxcv"; - let mut read_mem = [0; 4]; + let mut read_mem = [0; MAX_LEN_UTF8]; let tmpdir = tmpdir(); let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt"); { @@ -621,7 +622,7 @@ fn file_test_directoryinfo_readdir() { check!(w.write(msg)); } let files = check!(fs::read_dir(dir)); - let mut mem = [0; 4]; + let mut mem = [0; MAX_LEN_UTF8]; for f in files { let f = f.unwrap().path(); { @@ -1913,8 +1914,11 @@ fn test_hidden_file_truncation() { assert_eq!(metadata.len(), 0); } +// See https://github.com/rust-lang/rust/pull/131072 for more details about why +// these two tests are disabled under Windows 7 here. #[cfg(windows)] #[test] +#[cfg_attr(target_vendor = "win7", ignore = "Unsupported under Windows 7.")] fn test_rename_file_over_open_file() { // Make sure that std::fs::rename works if the target file is already opened with FILE_SHARE_DELETE. See #123985. let tmpdir = tmpdir(); @@ -1939,6 +1943,7 @@ fn test_rename_file_over_open_file() { #[test] #[cfg(windows)] +#[cfg_attr(target_vendor = "win7", ignore = "Unsupported under Windows 7.")] fn test_rename_directory_to_non_empty_directory() { // Renaming a directory over a non-empty existing directory should fail on Windows. let tmpdir: TempDir = tmpdir(); diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 606099c8bc67a..08832bbc1e3d1 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -153,7 +153,7 @@ impl Cursor { /// let reference = buff.get_mut(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_mut_cursor", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] pub const fn get_mut(&mut self) -> &mut T { &mut self.inner } @@ -201,7 +201,7 @@ impl Cursor { /// assert_eq!(buff.position(), 4); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_mut_cursor", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_mut_cursor", since = "1.86.0")] pub const fn set_position(&mut self, pos: u64) { self.pos = pos; } diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 318c350822168..017862c7f3aac 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -20,7 +20,7 @@ type LocalStream = Arc>>; thread_local! { /// Used by the test crate to capture the output of the print macros and panics. - static OUTPUT_CAPTURE: Cell> = { + static OUTPUT_CAPTURE: Cell> = const { Cell::new(None) } } @@ -239,6 +239,7 @@ fn handle_ebadf_lazy(r: io::Result, default: impl FnOnce() -> T) -> io::Re /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Stdin")] pub struct Stdin { inner: &'static Mutex>, } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 750116c6269dd..938b8c6e4f41b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -274,7 +274,6 @@ // tidy-alphabetical-start // stabilization was reverted after it hit beta -#![cfg_attr(not(bootstrap), feature(extended_varargs_abi_support))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] @@ -284,6 +283,7 @@ #![feature(cfg_sanitizer_cfi)] #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] +#![feature(char_max_len)] #![feature(concat_idents)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] @@ -292,6 +292,7 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] +#![feature(extended_varargs_abi_support)] #![feature(f128)] #![feature(f16)] #![feature(formatting_options)] diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 42aada131dadc..34f0e89f2f1ee 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -162,13 +162,6 @@ pub trait FileExt { Ok(()) } - /// Returns the current position within the file. - /// - /// This corresponds to the `fd_tell` syscall and is similar to - /// `seek` where you offset 0 bytes from the current position. - #[doc(alias = "fd_tell")] - fn tell(&self) -> io::Result; - /// Adjusts the flags associated with this file. /// /// This corresponds to the `fd_fdstat_set_flags` syscall. @@ -240,10 +233,6 @@ impl FileExt for fs::File { self.as_inner().as_inner().pwrite(bufs, offset) } - fn tell(&self) -> io::Result { - self.as_inner().as_inner().tell() - } - fn fdstat_set_flags(&self, flags: u16) -> io::Result<()> { self.as_inner().as_inner().set_flags(flags) } diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 61801db072a0e..22776ae2bc4a7 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -255,6 +255,7 @@ pub use crate::panicking::{set_hook, take_hook}; #[stable(feature = "panic_any", since = "1.51.0")] #[inline] #[track_caller] +#[cfg_attr(not(test), rustc_diagnostic_item = "panic_any")] pub fn panic_any(msg: M) -> ! { crate::panicking::begin_panic(msg); } diff --git a/library/std/src/process.rs b/library/std/src/process.rs index fd0fd1cb755e0..bdd4844b6511a 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -217,6 +217,7 @@ use crate::{fmt, fs, str}; /// /// [`wait`]: Child::wait #[stable(feature = "process", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Child")] pub struct Child { pub(crate) handle: imp::Process, @@ -2115,6 +2116,7 @@ impl Child { /// [`ErrorKind`]: io::ErrorKind /// [`InvalidInput`]: io::ErrorKind::InvalidInput #[stable(feature = "process", since = "1.0.0")] + #[cfg_attr(not(test), rustc_diagnostic_item = "child_kill")] pub fn kill(&mut self) -> io::Result<()> { self.handle.kill() } @@ -2135,6 +2137,7 @@ impl Child { /// ``` #[must_use] #[stable(feature = "process_id", since = "1.3.0")] + #[cfg_attr(not(test), rustc_diagnostic_item = "child_id")] pub fn id(&self) -> u32 { self.handle.id() } @@ -2375,6 +2378,7 @@ pub fn exit(code: i32) -> ! { /// [panic hook]: crate::panic::set_hook #[stable(feature = "process_abort", since = "1.17.0")] #[cold] +#[cfg_attr(not(test), rustc_diagnostic_item = "process_abort")] pub fn abort() -> ! { crate::sys::abort_internal(); } diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index 8caa2dcfad99c..8712332dd2767 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -1382,3 +1382,6 @@ impl fmt::Debug for Receiver { f.pad("Receiver { .. }") } } + +#[cfg(test)] +mod tests; diff --git a/library/std/src/sync/mpmc/tests.rs b/library/std/src/sync/mpmc/tests.rs new file mode 100644 index 0000000000000..6deb4dc2fe0cc --- /dev/null +++ b/library/std/src/sync/mpmc/tests.rs @@ -0,0 +1,14 @@ +// Ensure that thread_local init with `const { 0 }` still has unique address at run-time +#[test] +fn waker_current_thread_id() { + let first = super::waker::current_thread_id(); + let t = crate::thread::spawn(move || { + let second = super::waker::current_thread_id(); + assert_ne!(first, second); + assert_eq!(second, super::waker::current_thread_id()); + }); + + assert_eq!(first, super::waker::current_thread_id()); + t.join().unwrap(); + assert_eq!(first, super::waker::current_thread_id()); +} diff --git a/library/std/src/sync/mpmc/waker.rs b/library/std/src/sync/mpmc/waker.rs index 1895466f95d45..f5e764e69bd6e 100644 --- a/library/std/src/sync/mpmc/waker.rs +++ b/library/std/src/sync/mpmc/waker.rs @@ -204,6 +204,6 @@ impl Drop for SyncWaker { pub fn current_thread_id() -> usize { // `u8` is not drop so this variable will be available during thread destruction, // whereas `thread::current()` would not be - thread_local! { static DUMMY: u8 = 0 } + thread_local! { static DUMMY: u8 = const { 0 } } DUMMY.with(|x| (x as *const u8).addr()) } diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 21e6b65a744f8..ffb90b1469584 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -191,7 +191,7 @@ impl OnceLock { /// }) /// ``` #[inline] - #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "once_wait", since = "1.86.0")] pub fn wait(&self) -> &T { self.once.wait_force(); diff --git a/library/std/src/sync/poison/once.rs b/library/std/src/sync/poison/once.rs index d2938b7a0c12e..103e519540795 100644 --- a/library/std/src/sync/poison/once.rs +++ b/library/std/src/sync/poison/once.rs @@ -284,7 +284,7 @@ impl Once { /// If this [`Once`] has been poisoned because an initialization closure has /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force) /// if this behavior is not desired. - #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "once_wait", since = "1.86.0")] pub fn wait(&self) { if !self.inner.is_completed() { self.inner.wait(false); @@ -293,7 +293,7 @@ impl Once { /// Blocks the current thread until initialization has completed, ignoring /// poisoning. - #[stable(feature = "once_wait", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "once_wait", since = "1.86.0")] pub fn wait_force(&self) { if !self.inner.is_completed() { self.inner.wait(true); diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket.rs index b4f0a7836803e..ddd74b426158d 100644 --- a/library/std/src/sys/net/connection/socket.rs +++ b/library/std/src/sys/net/connection/socket.rs @@ -557,10 +557,13 @@ impl TcpListener { } pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() }; + // The `accept` function will fill in the storage with the address, + // so we don't need to zero it here. + // reference: https://linux.die.net/man/2/accept4 + let mut storage: mem::MaybeUninit = mem::MaybeUninit::uninit(); let mut len = mem::size_of_val(&storage) as c::socklen_t; - let sock = self.inner.accept((&raw mut storage) as *mut _, &mut len)?; - let addr = unsafe { socket_addr_from_c(&storage, len as usize)? }; + let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?; + let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? }; Ok((TcpStream { inner: sock }, addr)) } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 34ab26bc117af..29fb47ddca3b9 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -322,7 +322,10 @@ impl Socket { buf: &mut [u8], flags: c_int, ) -> io::Result<(usize, SocketAddr)> { - let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() }; + // The `recvfrom` function will fill in the storage with the address, + // so we don't need to zero it here. + // reference: https://linux.die.net/man/2/recvfrom + let mut storage: mem::MaybeUninit = mem::MaybeUninit::uninit(); let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t; let n = cvt(unsafe { @@ -335,7 +338,7 @@ impl Socket { &mut addrlen, ) })?; - Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })) + Ok((n as usize, unsafe { socket_addr_from_c(storage.as_ptr(), addrlen as usize)? })) } pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 5b65d862be102..1d337694944bc 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -8,7 +8,7 @@ use crate::collections::TryReserveError; use crate::fmt::Write; use crate::rc::Rc; use crate::sync::Arc; -use crate::sys_common::{AsInner, IntoInner}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem, str}; #[cfg(test)] @@ -25,6 +25,37 @@ pub struct Slice { pub inner: [u8], } +impl IntoInner> for Buf { + fn into_inner(self) -> Vec { + self.inner + } +} + +impl FromInner> for Buf { + fn from_inner(inner: Vec) -> Self { + Buf { inner } + } +} + +impl AsInner<[u8]> for Buf { + #[inline] + fn as_inner(&self) -> &[u8] { + &self.inner + } +} + +impl fmt::Debug for Buf { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), f) + } +} + +impl fmt::Display for Buf { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), f) + } +} + impl fmt::Debug for Slice { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f) @@ -55,18 +86,6 @@ impl fmt::Display for Slice { } } -impl fmt::Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_slice(), formatter) - } -} - -impl fmt::Display for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_slice(), formatter) - } -} - impl Clone for Buf { #[inline] fn clone(&self) -> Self { @@ -79,19 +98,6 @@ impl Clone for Buf { } } -impl IntoInner> for Buf { - fn into_inner(self) -> Vec { - self.inner - } -} - -impl AsInner<[u8]> for Buf { - #[inline] - fn as_inner(&self) -> &[u8] { - &self.inner - } -} - impl Buf { #[inline] pub fn into_encoded_bytes(self) -> Vec { @@ -103,6 +109,12 @@ impl Buf { Self { inner: s } } + #[inline] + pub fn into_string(self) -> Result { + String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() }) + } + + #[inline] pub fn from_string(s: String) -> Buf { Buf { inner: s.into_bytes() } } @@ -122,6 +134,11 @@ impl Buf { self.inner.capacity() } + #[inline] + pub fn push_slice(&mut self, s: &Slice) { + self.inner.extend_from_slice(&s.inner) + } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) @@ -157,7 +174,7 @@ impl Buf { // SAFETY: Slice just wraps [u8], // and &*self.inner is &[u8], therefore // transmuting &[u8] to &Slice is safe. - unsafe { mem::transmute(&*self.inner) } + unsafe { mem::transmute(self.inner.as_slice()) } } #[inline] @@ -165,15 +182,7 @@ impl Buf { // SAFETY: Slice just wraps [u8], // and &mut *self.inner is &mut [u8], therefore // transmuting &mut [u8] to &mut Slice is safe. - unsafe { mem::transmute(&mut *self.inner) } - } - - pub fn into_string(self) -> Result { - String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() }) - } - - pub fn push_slice(&mut self, s: &Slice) { - self.inner.extend_from_slice(&s.inner) + unsafe { mem::transmute(self.inner.as_mut_slice()) } } #[inline] @@ -278,18 +287,22 @@ impl Slice { unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) } } + #[inline] pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { str::from_utf8(&self.inner) } + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { String::from_utf8_lossy(&self.inner) } + #[inline] pub fn to_owned(&self) -> Buf { Buf { inner: self.inner.to_vec() } } + #[inline] pub fn clone_into(&self, buf: &mut Buf) { self.inner.clone_into(&mut buf.inner) } @@ -300,6 +313,7 @@ impl Slice { unsafe { mem::transmute(boxed) } } + #[inline] pub fn empty_box() -> Box { let boxed: Box<[u8]> = Default::default(); unsafe { mem::transmute(boxed) } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index a4ad5966afe57..19728d33990ac 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -10,11 +10,16 @@ use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::{fmt, mem}; -#[derive(Clone, Hash)] +#[derive(Hash)] pub struct Buf { pub inner: Wtf8Buf, } +#[repr(transparent)] +pub struct Slice { + pub inner: Wtf8, +} + impl IntoInner for Buf { fn into_inner(self) -> Wtf8Buf { self.inner @@ -35,31 +40,38 @@ impl AsInner for Buf { } impl fmt::Debug for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_slice(), formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self.as_slice(), f) } } impl fmt::Display for Buf { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_slice(), formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_slice(), f) } } -#[repr(transparent)] -pub struct Slice { - pub inner: Wtf8, -} - impl fmt::Debug for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.inner, formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.inner, f) } } impl fmt::Display for Slice { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.inner, formatter) + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.inner, f) + } +} + +impl Clone for Buf { + #[inline] + fn clone(&self) -> Self { + Buf { inner: self.inner.clone() } + } + + #[inline] + fn clone_from(&mut self, source: &Self) { + self.inner.clone_from(&source.inner) } } @@ -74,62 +86,57 @@ impl Buf { unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } } } - pub fn with_capacity(capacity: usize) -> Buf { - Buf { inner: Wtf8Buf::with_capacity(capacity) } - } - - pub fn clear(&mut self) { - self.inner.clear() - } - - pub fn capacity(&self) -> usize { - self.inner.capacity() + #[inline] + pub fn into_string(self) -> Result { + self.inner.into_string().map_err(|buf| Buf { inner: buf }) } + #[inline] pub fn from_string(s: String) -> Buf { Buf { inner: Wtf8Buf::from_string(s) } } - pub fn as_slice(&self) -> &Slice { - // SAFETY: Slice is just a wrapper for Wtf8, - // and self.inner.as_slice() returns &Wtf8. - // Therefore, transmuting &Wtf8 to &Slice is safe. - unsafe { mem::transmute(self.inner.as_slice()) } + #[inline] + pub fn with_capacity(capacity: usize) -> Buf { + Buf { inner: Wtf8Buf::with_capacity(capacity) } } - pub fn as_mut_slice(&mut self) -> &mut Slice { - // SAFETY: Slice is just a wrapper for Wtf8, - // and self.inner.as_mut_slice() returns &mut Wtf8. - // Therefore, transmuting &mut Wtf8 to &mut Slice is safe. - // Additionally, care should be taken to ensure the slice - // is always valid Wtf8. - unsafe { mem::transmute(self.inner.as_mut_slice()) } + #[inline] + pub fn clear(&mut self) { + self.inner.clear() } - pub fn into_string(self) -> Result { - self.inner.into_string().map_err(|buf| Buf { inner: buf }) + #[inline] + pub fn capacity(&self) -> usize { + self.inner.capacity() } + #[inline] pub fn push_slice(&mut self, s: &Slice) { self.inner.push_wtf8(&s.inner) } + #[inline] pub fn reserve(&mut self, additional: usize) { self.inner.reserve(additional) } + #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.inner.try_reserve(additional) } + #[inline] pub fn reserve_exact(&mut self, additional: usize) { self.inner.reserve_exact(additional) } + #[inline] pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { self.inner.try_reserve_exact(additional) } + #[inline] pub fn shrink_to_fit(&mut self) { self.inner.shrink_to_fit() } @@ -139,6 +146,24 @@ impl Buf { self.inner.shrink_to(min_capacity) } + #[inline] + pub fn as_slice(&self) -> &Slice { + // SAFETY: Slice is just a wrapper for Wtf8, + // and self.inner.as_slice() returns &Wtf8. + // Therefore, transmuting &Wtf8 to &Slice is safe. + unsafe { mem::transmute(self.inner.as_slice()) } + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut Slice { + // SAFETY: Slice is just a wrapper for Wtf8, + // and self.inner.as_mut_slice() returns &mut Wtf8. + // Therefore, transmuting &mut Wtf8 to &mut Slice is safe. + // Additionally, care should be taken to ensure the slice + // is always valid Wtf8. + unsafe { mem::transmute(self.inner.as_mut_slice()) } + } + #[inline] pub fn leak<'a>(self) -> &'a mut Slice { unsafe { mem::transmute(self.inner.leak()) } @@ -194,6 +219,7 @@ impl Slice { } #[track_caller] + #[inline] pub fn check_public_boundary(&self, index: usize) { check_utf8_boundary(&self.inner, index); } @@ -203,18 +229,22 @@ impl Slice { unsafe { mem::transmute(Wtf8::from_str(s)) } } + #[inline] pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> { self.inner.as_str() } + #[inline] pub fn to_string_lossy(&self) -> Cow<'_, str> { self.inner.to_string_lossy() } + #[inline] pub fn to_owned(&self) -> Buf { Buf { inner: self.inner.to_owned() } } + #[inline] pub fn clone_into(&self, buf: &mut Buf) { self.inner.clone_into(&mut buf.inner) } @@ -224,6 +254,7 @@ impl Slice { unsafe { mem::transmute(self.inner.into_box()) } } + #[inline] pub fn empty_box() -> Box { unsafe { mem::transmute(Wtf8::empty_box()) } } diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs index 7bc36717f34d3..d4bf84dc1854c 100644 --- a/library/std/src/sys/pal/hermit/fs.rs +++ b/library/std/src/sys/pal/hermit/fs.rs @@ -421,6 +421,10 @@ impl File { Err(Error::from_raw_os_error(22)) } + pub fn tell(&self) -> io::Result { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result { Err(Error::from_raw_os_error(22)) } diff --git a/library/std/src/sys/pal/solid/fs.rs b/library/std/src/sys/pal/solid/fs.rs index c87a63fde8958..4e741943283d0 100644 --- a/library/std/src/sys/pal/solid/fs.rs +++ b/library/std/src/sys/pal/solid/fs.rs @@ -452,8 +452,11 @@ impl File { abi::SOLID_FS_Lseek(self.fd.raw(), pos, whence) }) .map_err(|e| e.as_io_error())?; - // Get the new offset + self.tell() + } + + pub fn tell(&self) -> io::Result { unsafe { let mut out_offset = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Ftell( diff --git a/library/std/src/sys/pal/uefi/fs.rs b/library/std/src/sys/pal/uefi/fs.rs index 9585ec24f687d..45e93deffa3a4 100644 --- a/library/std/src/sys/pal/uefi/fs.rs +++ b/library/std/src/sys/pal/uefi/fs.rs @@ -258,6 +258,10 @@ impl File { self.0 } + pub fn tell(&self) -> io::Result { + self.0 + } + pub fn duplicate(&self) -> io::Result { self.0 } diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs index 9efe9a314f2e9..c73a6350357a4 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/pal/uefi/process.rs @@ -388,7 +388,7 @@ mod uefi_command_internal { } } - pub fn start_image(&mut self) -> io::Result { + pub(crate) fn start_image(&mut self) -> io::Result { self.update_st_crc32()?; // Use our system table instead of the default one diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs index 495ff2dc930ed..c4ff3015ac60d 100644 --- a/library/std/src/sys/pal/uefi/time.rs +++ b/library/std/src/sys/pal/uefi/time.rs @@ -84,7 +84,7 @@ pub(crate) mod system_time_internal { // This algorithm is based on the one described in the post // https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html - pub const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration { + pub(crate) const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration { assert!(t.month <= 12); assert!(t.month != 0); diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 16fb207298dbd..3df460e38b72e 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -1437,6 +1437,10 @@ impl File { Ok(n as u64) } + pub fn tell(&self) -> io::Result { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result { self.0.duplicate().map(File) } diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index db5c6bd3a1c32..43ece63457fe6 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -319,21 +319,27 @@ mod imp { ))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut ret = None; - let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); + let mut attr: mem::MaybeUninit = mem::MaybeUninit::uninit(); + if !cfg!(target_os = "freebsd") { + attr = mem::MaybeUninit::zeroed(); + } #[cfg(target_os = "freebsd")] - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr()); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr()); if e == 0 { let mut stackaddr = crate::ptr::null_mut(); let mut stacksize = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0); + assert_eq!( + libc::pthread_attr_getstack(attr.as_ptr(), &mut stackaddr, &mut stacksize), + 0 + ); ret = Some(stackaddr); } if e == 0 || cfg!(target_os = "freebsd") { - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); } ret } @@ -509,16 +515,20 @@ mod imp { // FIXME: I am probably not unsafe. unsafe fn current_guard() -> Option> { let mut ret = None; - let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); + + let mut attr: mem::MaybeUninit = mem::MaybeUninit::uninit(); + if !cfg!(target_os = "freebsd") { + attr = mem::MaybeUninit::zeroed(); + } #[cfg(target_os = "freebsd")] - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), attr.as_mut_ptr()); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), attr.as_mut_ptr()); if e == 0 { let mut guardsize = 0; - assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0); + assert_eq!(libc::pthread_attr_getguardsize(attr.as_ptr(), &mut guardsize), 0); if guardsize == 0 { if cfg!(all(target_os = "linux", target_env = "musl")) { // musl versions before 1.1.19 always reported guard @@ -531,7 +541,7 @@ mod imp { } let mut stackptr = crate::ptr::null_mut::(); let mut size = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0); + assert_eq!(libc::pthread_attr_getstack(attr.as_ptr(), &mut stackptr, &mut size), 0); let stackaddr = stackptr.addr(); ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd", target_os = "hurd")) { @@ -552,7 +562,7 @@ mod imp { }; } if e == 0 || cfg!(target_os = "freebsd") { - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); } ret } diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 69c99782f0bf6..37d5e01790a0b 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -49,24 +49,27 @@ impl Thread { pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); let mut native: libc::pthread_t = mem::zeroed(); - let mut attr: libc::pthread_attr_t = mem::zeroed(); - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + let mut attr: mem::MaybeUninit = mem::MaybeUninit::uninit(); + assert_eq!(libc::pthread_attr_init(attr.as_mut_ptr()), 0); #[cfg(target_os = "espidf")] if stack > 0 { // Only set the stack if a non-zero value is passed // 0 is used as an indication that the default stack size configured in the ESP-IDF menuconfig system should be used assert_eq!( - libc::pthread_attr_setstacksize(&mut attr, cmp::max(stack, min_stack_size(&attr))), + libc::pthread_attr_setstacksize( + attr.as_mut_ptr(), + cmp::max(stack, min_stack_size(&attr)) + ), 0 ); } #[cfg(not(target_os = "espidf"))] { - let stack_size = cmp::max(stack, min_stack_size(&attr)); + let stack_size = cmp::max(stack, min_stack_size(attr.as_ptr())); - match libc::pthread_attr_setstacksize(&mut attr, stack_size) { + match libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size) { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -77,16 +80,16 @@ impl Thread { let page_size = os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); + assert_eq!(libc::pthread_attr_setstacksize(attr.as_mut_ptr(), stack_size), 0); } }; } - let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _); + let ret = libc::pthread_create(&mut native, attr.as_ptr(), thread_start, p as *mut _); // Note: if the thread creation fails and this assert fails, then p will // be leaked. However, an alternative design could cause double-free // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(libc::pthread_attr_destroy(attr.as_mut_ptr()), 0); return if ret != 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is diff --git a/library/std/src/sys/pal/unsupported/fs.rs b/library/std/src/sys/pal/unsupported/fs.rs index 9585ec24f687d..45e93deffa3a4 100644 --- a/library/std/src/sys/pal/unsupported/fs.rs +++ b/library/std/src/sys/pal/unsupported/fs.rs @@ -258,6 +258,10 @@ impl File { self.0 } + pub fn tell(&self) -> io::Result { + self.0 + } + pub fn duplicate(&self) -> io::Result { self.0 } diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs index 11002406d2ba2..39978346d7382 100644 --- a/library/std/src/sys/pal/wasi/fs.rs +++ b/library/std/src/sys/pal/wasi/fs.rs @@ -517,6 +517,10 @@ impl File { self.fd.seek(pos) } + pub fn tell(&self) -> io::Result { + self.fd.tell() + } + pub fn duplicate(&self) -> io::Result { // https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-rationale.md#why-no-dup unsupported() diff --git a/library/std/src/sys/pal/wasi/stdio.rs b/library/std/src/sys/pal/wasi/stdio.rs index d08b772e5fc7d..fb21cb4d393d0 100644 --- a/library/std/src/sys/pal/wasi/stdio.rs +++ b/library/std/src/sys/pal/wasi/stdio.rs @@ -1,7 +1,7 @@ #![forbid(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::os::raw; use crate::os::wasi::io::{AsRawFd, FromRawFd}; @@ -28,6 +28,10 @@ impl io::Read for Stdin { self.read_vectored(&mut [IoSliceMut::new(data)]) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).read_buf(buf) + } + fn read_vectored(&mut self, data: &mut [IoSliceMut<'_>]) -> io::Result { ManuallyDrop::new(unsafe { WasiFd::from_raw_fd(self.as_raw_fd()) }).read(data) } @@ -64,6 +68,7 @@ impl io::Write for Stdout { fn is_write_vectored(&self) -> bool { true } + fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 8dc61edb603f4..4fbdc839939c9 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -204,7 +204,7 @@ compat_fn_with_fallback! { pub fn NtReleaseKeyedEvent( EventHandle: HANDLE, Key: *const c_void, - Alertable: BOOLEAN, + Alertable: bool, Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") @@ -213,7 +213,7 @@ compat_fn_with_fallback! { pub fn NtWaitForKeyedEvent( EventHandle: HANDLE, Key: *const c_void, - Alertable: BOOLEAN, + Alertable: bool, Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index ff02737dcf827..0ddce30cf8e44 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -631,6 +631,10 @@ impl File { Ok(newpos as u64) } + pub fn tell(&self) -> io::Result { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result { Ok(Self { handle: self.handle.try_clone()? }) } diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index fd3f559ba1901..1b245991aa797 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -1,5 +1,6 @@ #![unstable(issue = "none", feature = "windows_stdio")] +use core::char::MAX_LEN_UTF8; use core::str::utf8_char_width; use super::api::{self, WinError}; @@ -426,7 +427,7 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { impl IncompleteUtf8 { pub const fn new() -> IncompleteUtf8 { - IncompleteUtf8 { bytes: [0; 4], len: 0 } + IncompleteUtf8 { bytes: [0; MAX_LEN_UTF8], len: 0 } } } diff --git a/library/std/src/sys/random/windows.rs b/library/std/src/sys/random/windows.rs index 7566000f9e6ff..f5da637f56ca9 100644 --- a/library/std/src/sys/random/windows.rs +++ b/library/std/src/sys/random/windows.rs @@ -14,7 +14,7 @@ pub fn fill_bytes(mut bytes: &mut [u8]) { while !bytes.is_empty() { let len = bytes.len().try_into().unwrap_or(u32::MAX); let ret = unsafe { c::RtlGenRandom(bytes.as_mut_ptr().cast(), len) }; - assert_ne!(ret, 0, "failed to generate random data"); + assert!(ret, "failed to generate random data"); bytes = &mut bytes[len as usize..]; } } diff --git a/library/std/src/sys/sync/mutex/windows7.rs b/library/std/src/sys/sync/mutex/windows7.rs index 689dba10f01ed..0b57de78ba6dd 100644 --- a/library/std/src/sys/sync/mutex/windows7.rs +++ b/library/std/src/sys/sync/mutex/windows7.rs @@ -44,7 +44,7 @@ impl Mutex { #[inline] pub fn try_lock(&self) -> bool { - unsafe { c::TryAcquireSRWLockExclusive(raw(self)) != 0 } + unsafe { c::TryAcquireSRWLockExclusive(raw(self)) } } #[inline] diff --git a/library/std/src/sys/sync/thread_parking/windows7.rs b/library/std/src/sys/sync/thread_parking/windows7.rs index f7585e882f055..a1a0f8427cd83 100644 --- a/library/std/src/sys/sync/thread_parking/windows7.rs +++ b/library/std/src/sys/sync/thread_parking/windows7.rs @@ -195,7 +195,7 @@ mod keyed_events { pub unsafe fn park(parker: Pin<&Parker>) { // Wait for unpark() to produce this event. - c::NtWaitForKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut()); + c::NtWaitForKeyedEvent(keyed_event_handle(), parker.ptr(), false, ptr::null_mut()); // Set the state back to EMPTY (from either PARKED or NOTIFIED). // Note that we don't just write EMPTY, but use swap() to also // include an acquire-ordered read to synchronize with unpark()'s @@ -218,7 +218,7 @@ mod keyed_events { // Wait for unpark() to produce this event. let unparked = - c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, &mut timeout) == c::STATUS_SUCCESS; + c::NtWaitForKeyedEvent(handle, parker.ptr(), false, &mut timeout) == c::STATUS_SUCCESS; // Set the state back to EMPTY (from either PARKED or NOTIFIED). let prev_state = parker.state.swap(EMPTY, Acquire); @@ -228,7 +228,7 @@ mod keyed_events { // was set to NOTIFIED, which means we *just* missed an // unpark(), which is now blocked on us to wait for it. // Wait for it to consume the event and unblock that thread. - c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, ptr::null_mut()); + c::NtWaitForKeyedEvent(handle, parker.ptr(), false, ptr::null_mut()); } } pub unsafe fn unpark(parker: Pin<&Parker>) { @@ -239,7 +239,7 @@ mod keyed_events { // To prevent this thread from blocking indefinitely in that case, // park_impl() will, after seeing the state set to NOTIFIED after // waking up, call NtWaitForKeyedEvent again to unblock us. - c::NtReleaseKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut()); + c::NtReleaseKeyedEvent(keyed_event_handle(), parker.ptr(), false, ptr::null_mut()); } fn keyed_event_handle() -> c::HANDLE { diff --git a/library/std/src/sys/thread_local/os.rs b/library/std/src/sys/thread_local/os.rs index 00d2e30bd6036..fe6af27db3a17 100644 --- a/library/std/src/sys/thread_local/os.rs +++ b/library/std/src/sys/thread_local/os.rs @@ -28,9 +28,7 @@ pub macro thread_local_inner { // user provided type or type alias with a matching name. Please update the shadowing test // in `tests/thread.rs` if these types are renamed. unsafe { - // Inlining does not work on windows-gnu due to linking errors around - // dllimports. See https://github.com/rust-lang/rust/issues/109797. - $crate::thread::LocalKey::new(#[cfg_attr(windows, inline(never))] |init| { + $crate::thread::LocalKey::new(|init| { static VAL: $crate::thread::local_impl::Storage<$t> = $crate::thread::local_impl::Storage::new(); VAL.get(init, __init) diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 6c60d901ee904..952c39132b056 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -18,7 +18,7 @@ #[cfg(test)] mod tests; -use core::char::{encode_utf8_raw, encode_utf16_raw}; +use core::char::{MAX_LEN_UTF8, MAX_LEN_UTF16, encode_utf8_raw, encode_utf16_raw}; use core::clone::CloneToUninit; use core::str::next_code_point; @@ -156,9 +156,12 @@ impl ops::DerefMut for Wtf8Buf { } } -/// Format the string with double quotes, -/// and surrogates as `\u` followed by four hexadecimal digits. -/// Example: `"a\u{D800}"` for a string with code points [U+0061, U+D800] +/// Formats the string in double quotes, with characters escaped according to +/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`, +/// where each `x` is a hexadecimal digit. +/// +/// For example, the code units [U+0061, U+D800, U+000A] are formatted as +/// `"a\u{D800}\n"`. impl fmt::Debug for Wtf8Buf { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -181,7 +184,7 @@ impl Wtf8Buf { /// Creates a WTF-8 string from a WTF-8 byte vec. /// - /// Since the byte vec is not checked for valid WTF-8, this functions is + /// Since the byte vec is not checked for valid WTF-8, this function is /// marked unsafe. #[inline] pub unsafe fn from_bytes_unchecked(value: Vec) -> Wtf8Buf { @@ -205,7 +208,7 @@ impl Wtf8Buf { /// Since WTF-8 is a superset of UTF-8, this always succeeds. #[inline] pub fn from_str(s: &str) -> Wtf8Buf { - Wtf8Buf { bytes: <[_]>::to_vec(s.as_bytes()), is_known_utf8: true } + Wtf8Buf { bytes: s.as_bytes().to_vec(), is_known_utf8: true } } pub fn clear(&mut self) { @@ -237,10 +240,11 @@ impl Wtf8Buf { string } - /// Copied from String::push + /// Appends the given `char` to the end of this string. /// This does **not** include the WTF-8 concatenation check or `is_known_utf8` check. + /// Copied from String::push. fn push_code_point_unchecked(&mut self, code_point: CodePoint) { - let mut bytes = [0; 4]; + let mut bytes = [0; MAX_LEN_UTF8]; let bytes = encode_utf8_raw(code_point.value, &mut bytes); self.bytes.extend_from_slice(bytes) } @@ -264,16 +268,16 @@ impl Wtf8Buf { /// /// # Panics /// - /// Panics if the new capacity overflows `usize`. + /// Panics if the new capacity exceeds `isize::MAX` bytes. #[inline] pub fn reserve(&mut self, additional: usize) { self.bytes.reserve(additional) } - /// Tries to reserve capacity for at least `additional` more length units - /// in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to avoid - /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if + /// Tries to reserve capacity for at least `additional` more bytes to be + /// inserted in the given `Wtf8Buf`. The `Wtf8Buf` may reserve more space to + /// avoid frequent reallocations. After calling `try_reserve`, capacity will + /// be greater than or equal to `self.len() + additional`. Does nothing if /// capacity is already sufficient. This method preserves the contents even /// if an error occurs. /// @@ -291,8 +295,8 @@ impl Wtf8Buf { self.bytes.reserve_exact(additional) } - /// Tries to reserve the minimum capacity for exactly `additional` - /// length units in the given `Wtf8Buf`. After calling + /// Tries to reserve the minimum capacity for exactly `additional` more + /// bytes to be inserted in the given `Wtf8Buf`. After calling /// `try_reserve_exact`, capacity will be greater than or equal to /// `self.len() + additional` if it returns `Ok(())`. /// Does nothing if the capacity is already sufficient. @@ -440,22 +444,17 @@ impl Wtf8Buf { /// /// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”) pub fn into_string_lossy(mut self) -> String { - // Fast path: If we already have UTF-8, we can return it immediately. - if self.is_known_utf8 { - return unsafe { String::from_utf8_unchecked(self.bytes) }; - } - - let mut pos = 0; - loop { - match self.next_surrogate(pos) { - Some((surrogate_pos, _)) => { - pos = surrogate_pos + 3; - self.bytes[surrogate_pos..pos] - .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes()); - } - None => return unsafe { String::from_utf8_unchecked(self.bytes) }, + if !self.is_known_utf8 { + let mut pos = 0; + while let Some((surrogate_pos, _)) = self.next_surrogate(pos) { + pos = surrogate_pos + 3; + // Surrogates and the replacement character are all 3 bytes, so + // they can substituted in-place. + self.bytes[surrogate_pos..pos] + .copy_from_slice(UTF8_REPLACEMENT_CHARACTER.as_bytes()); } } + unsafe { String::from_utf8_unchecked(self.bytes) } } /// Converts this `Wtf8Buf` into a boxed `Wtf8`. @@ -535,9 +534,9 @@ impl AsInner<[u8]> for Wtf8 { } } -/// Format the slice with double quotes, -/// and surrogates as `\u` followed by four hexadecimal digits. -/// Example: `"a\u{D800}"` for a slice with code points [U+0061, U+D800] +/// Formats the string in double quotes, with characters escaped according to +/// [`char::escape_debug`] and unpaired surrogates represented as `\u{xxxx}`, +/// where each `x` is a hexadecimal digit. impl fmt::Debug for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { fn write_str_escaped(f: &mut fmt::Formatter<'_>, s: &str) -> fmt::Result { @@ -562,6 +561,8 @@ impl fmt::Debug for Wtf8 { } } +/// Formats the string with unpaired surrogates substituted with the replacement +/// character, U+FFFD. impl fmt::Display for Wtf8 { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let wtf8_bytes = &self.bytes; @@ -672,9 +673,8 @@ impl Wtf8 { /// /// This only copies the data if necessary (if it contains any surrogate). pub fn to_string_lossy(&self) -> Cow<'_, str> { - let surrogate_pos = match self.next_surrogate(0) { - None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }), - Some((pos, _)) => pos, + let Some((surrogate_pos, _)) = self.next_surrogate(0) else { + return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }); }; let wtf8_bytes = &self.bytes; let mut utf8_bytes = Vec::with_capacity(self.len()); @@ -964,7 +964,7 @@ pub struct Wtf8CodePoints<'a> { bytes: slice::Iter<'a, u8>, } -impl<'a> Iterator for Wtf8CodePoints<'a> { +impl Iterator for Wtf8CodePoints<'_> { type Item = CodePoint; #[inline] @@ -990,7 +990,7 @@ pub struct EncodeWide<'a> { // Copied from libunicode/u_str.rs #[stable(feature = "rust1", since = "1.0.0")] -impl<'a> Iterator for EncodeWide<'a> { +impl Iterator for EncodeWide<'_> { type Item = u16; #[inline] @@ -1001,7 +1001,7 @@ impl<'a> Iterator for EncodeWide<'a> { return Some(tmp); } - let mut buf = [0; 2]; + let mut buf = [0; MAX_LEN_UTF16]; self.code_points.next().map(|code_point| { let n = encode_utf16_raw(code_point.value, &mut buf).len(); if n == 2 { diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index ca04aa4ada497..d5a5d10205dd8 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -50,7 +50,8 @@ use crate::fmt; /// use std::cell::Cell; /// use std::thread; /// -/// thread_local!(static FOO: Cell = Cell::new(1)); +/// // explicit `const {}` block enables more efficient initialization +/// thread_local!(static FOO: Cell = const { Cell::new(1) }); /// /// assert_eq!(FOO.get(), 1); /// FOO.set(2); @@ -138,7 +139,7 @@ impl fmt::Debug for LocalKey { /// use std::cell::{Cell, RefCell}; /// /// thread_local! { -/// pub static FOO: Cell = Cell::new(1); +/// pub static FOO: Cell = const { Cell::new(1) }; /// /// static BAR: RefCell> = RefCell::new(vec![1.0, 2.0]); /// } @@ -394,7 +395,7 @@ impl LocalKey> { /// use std::cell::Cell; /// /// thread_local! { - /// static X: Cell = Cell::new(1); + /// static X: Cell = const { Cell::new(1) }; /// } /// /// assert_eq!(X.get(), 1); @@ -423,7 +424,7 @@ impl LocalKey> { /// use std::cell::Cell; /// /// thread_local! { - /// static X: Cell> = Cell::new(Some(1)); + /// static X: Cell> = const { Cell::new(Some(1)) }; /// } /// /// assert_eq!(X.take(), Some(1)); @@ -453,7 +454,7 @@ impl LocalKey> { /// use std::cell::Cell; /// /// thread_local! { - /// static X: Cell = Cell::new(1); + /// static X: Cell = const { Cell::new(1) }; /// } /// /// assert_eq!(X.replace(2), 1); diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 88b3e9e0ceba0..5ab71413586dc 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -93,11 +93,17 @@ use crate::sys_common::{FromInner, IntoInner}; /// use std::time::{Instant, Duration}; /// /// let now = Instant::now(); -/// let max_seconds = u64::MAX / 1_000_000_000; -/// let duration = Duration::new(max_seconds, 0); +/// let days_per_10_millennia = 365_2425; +/// let solar_seconds_per_day = 60 * 60 * 24; +/// let millenium_in_solar_seconds = 31_556_952_000; +/// assert_eq!(millenium_in_solar_seconds, days_per_10_millennia * solar_seconds_per_day / 10); +/// +/// let duration = Duration::new(millenium_in_solar_seconds, 0); /// println!("{:?}", now + duration); /// ``` /// +/// For cross-platform code, you can comfortably use durations of up to around one hundred years. +/// /// # Underlying System calls /// /// The following system calls are [currently] being used by `now()` to find out diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index aa6c3dc32e2ba..0f6fa2d291ab3 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["public-dependency"] + [package] name = "sysroot" version = "0.0.0" @@ -5,10 +7,10 @@ edition = "2021" # this is a dummy crate to ensure that all required crates appear in the sysroot [dependencies] -proc_macro = { path = "../proc_macro" } +proc_macro = { path = "../proc_macro", public = true } profiler_builtins = { path = "../profiler_builtins", optional = true } -std = { path = "../std" } -test = { path = "../test" } +std = { path = "../std", public = true } +test = { path = "../test", public = true } # Forward features to the `std` crate as necessary [features] @@ -19,11 +21,13 @@ compiler-builtins-mem = ["std/compiler-builtins-mem"] compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] compiler-builtins-no-f16-f128 = ["std/compiler-builtins-no-f16-f128"] compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] +debug_refcell = ["std/debug_refcell"] +debug_typeid = ["std/debug_typeid"] llvm-libunwind = ["std/llvm-libunwind"] system-llvm-libunwind = ["std/system-llvm-libunwind"] +optimize_for_size = ["std/optimize_for_size"] panic-unwind = ["std/panic_unwind"] panic_immediate_abort = ["std/panic_immediate_abort"] -optimize_for_size = ["std/optimize_for_size"] profiler = ["dep:profiler_builtins"] std_detect_file_io = ["std/std_detect_file_io"] std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 75cc7c00e389c..241ef324b0088 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["public-dependency"] + [package] name = "test" version = "0.0.0" @@ -5,8 +7,8 @@ edition = "2021" [dependencies] getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } -std = { path = "../std" } -core = { path = "../core" } +std = { path = "../std", public = true } +core = { path = "../core", public = true } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] libc = { version = "0.2.150", default-features = false } diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 761f924844620..5451a38a674ca 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -1,5 +1,6 @@ #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] +#![feature(cfg_emscripten_wasm_eh)] #![feature(link_cfg)] #![feature(staged_api)] #![cfg_attr(not(target_env = "msvc"), feature(libc))] @@ -8,7 +9,6 @@ feature(simd_wasm64, wasm_exception_handling_intrinsics) )] #![allow(internal_features)] -#![cfg_attr(not(bootstrap), feature(cfg_emscripten_wasm_eh))] #![deny(unsafe_op_in_unsafe_fn)] // Force libc to be included even if unused. This is required by many platforms. diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml index 64097320caba7..57c2706f60a56 100644 --- a/src/bootstrap/defaults/config.tools.toml +++ b/src/bootstrap/defaults/config.tools.toml @@ -8,6 +8,8 @@ incremental = true download-rustc = "if-unchanged" [build] +# cargo and clippy tests don't pass on stage 1 +test-stage = 2 # Document with the in-tree rustdoc by default, since `download-rustc` makes it quick to compile. doc-stage = 2 # Contributors working on tools will probably expect compiler docs to be generated, so they can figure out how to use the API. diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 21afb0312033a..b8bbe1eb5f8a6 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -69,7 +69,7 @@ impl Step for Std { ); std_cargo(builder, target, compiler.stage, &mut cargo); - if matches!(builder.config.cmd, Subcommand::Fix { .. }) { + if matches!(builder.config.cmd, Subcommand::Fix) { // By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot. cargo.arg("--lib"); } diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index c62c36390eaeb..9d3d07c83d25a 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1174,9 +1174,15 @@ pub fn rustc_cargo( // We want to link against registerEnzyme and in the future we want to use additional // functionality from Enzyme core. For that we need to link against Enzyme. if builder.config.llvm_enzyme { - let llvm_config = builder.llvm_config(builder.config.build).unwrap(); - let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); - cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); + let arch = builder.build.build; + let enzyme_dir = builder.build.out.join(arch).join("enzyme").join("lib"); + cargo.rustflag("-L").rustflag(enzyme_dir.to_str().expect("Invalid path")); + + if !builder.config.dry_run() { + let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); + cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}")); + } } // Building with protected visibility reduces the number of dynamic relocations needed, giving @@ -1341,7 +1347,7 @@ pub fn rustc_cargo_env( // Build jemalloc on AArch64 with support for page sizes up to 64K // See: https://github.com/rust-lang/rust/pull/135081 - if builder.config.jemalloc + if builder.config.jemalloc(target) && target.starts_with("aarch64") && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() { @@ -1977,13 +1983,14 @@ impl Step for Assemble { let maybe_install_llvm_bitcode_linker = |compiler| { if builder.config.llvm_bitcode_linker_enabled { trace!("llvm-bitcode-linker enabled, installing"); - let src_path = builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { - compiler, - target: target_compiler.host, - extra_features: vec![], - }); + let llvm_bitcode_linker = + builder.ensure(crate::core::build_steps::tool::LlvmBitcodeLinker { + compiler, + target: target_compiler.host, + extra_features: vec![], + }); let tool_exe = exe("llvm-bitcode-linker", target_compiler.host); - builder.copy_link(&src_path, &libdir_bin.join(tool_exe)); + builder.copy_link(&llvm_bitcode_linker.tool_path, &libdir_bin.join(tool_exe)); } }; @@ -2028,16 +2035,20 @@ impl Step for Assemble { let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build); // Build enzyme - if builder.config.llvm_enzyme { + if builder.config.llvm_enzyme && !builder.config.dry_run() { debug!("`llvm_enzyme` requested"); let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host }); + let llvm_config = builder.llvm_config(builder.config.build).unwrap(); + let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config); let lib_ext = std::env::consts::DLL_EXTENSION; - let src_lib = enzyme_install.join("build/Enzyme/libEnzyme-19").with_extension(lib_ext); + let libenzyme = format!("libEnzyme-{llvm_version_major}"); + let src_lib = + enzyme_install.join("build/Enzyme").join(&libenzyme).with_extension(lib_ext); let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host); let target_libdir = builder.sysroot_target_libdir(target_compiler, target_compiler.host); - let dst_lib = libdir.join("libEnzyme-19").with_extension(lib_ext); - let target_dst_lib = target_libdir.join("libEnzyme-19").with_extension(lib_ext); + let dst_lib = libdir.join(&libenzyme).with_extension(lib_ext); + let target_dst_lib = target_libdir.join(&libenzyme).with_extension(lib_ext); builder.copy_link(&src_lib, &dst_lib); builder.copy_link(&src_lib, &target_dst_lib); } @@ -2171,14 +2182,13 @@ impl Step for Assemble { // logic to create the final binary. This is used by the // `wasm32-wasip2` target of Rust. if builder.tool_enabled("wasm-component-ld") { - let wasm_component_ld_exe = - builder.ensure(crate::core::build_steps::tool::WasmComponentLd { - compiler: build_compiler, - target: target_compiler.host, - }); + let wasm_component = builder.ensure(crate::core::build_steps::tool::WasmComponentLd { + compiler: build_compiler, + target: target_compiler.host, + }); builder.copy_link( - &wasm_component_ld_exe, - &libdir_bin.join(wasm_component_ld_exe.file_name().unwrap()), + &wasm_component.tool_path, + &libdir_bin.join(wasm_component.tool_path.file_name().unwrap()), ); } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 509ee9e1acf07..26b3e0b701c4b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -21,7 +21,7 @@ use tracing::instrument; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::tool::{self, Tool}; -use crate::core::build_steps::vendor::default_paths_to_vendor; +use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; @@ -421,16 +421,12 @@ impl Step for Rustc { if let Some(ra_proc_macro_srv) = builder.ensure_if_default( tool::RustAnalyzerProcMacroSrv { - compiler: builder.compiler_for( - compiler.stage, - builder.config.build, - compiler.host, - ), + compiler: builder.compiler(compiler.stage, builder.config.build), target: compiler.host, }, builder.kind, ) { - builder.install(&ra_proc_macro_srv, &image.join("libexec"), 0o755); + builder.install(&ra_proc_macro_srv.tool_path, &image.join("libexec"), 0o755); } let libdir_relative = builder.libdir_relative(compiler); @@ -775,11 +771,7 @@ impl Step for Analysis { // Find the actual compiler (handling the full bootstrap option) which // produced the save-analysis data because that data isn't copied // through the sysroot uplifting. - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1029,6 +1021,17 @@ impl Step for PlainSourceTarball { ], plain_dst_src, ); + // We keep something in src/gcc because it is a registered submodule, + // and if it misses completely it can cause issues elsewhere + // (see https://github.com/rust-lang/rust/issues/137332). + // We can also let others know why is the source code missing. + if !builder.config.dry_run() { + builder.create_dir(&plain_dst_src.join("src/gcc")); + t!(std::fs::write( + plain_dst_src.join("src/gcc/notice.txt"), + "The GCC source code is not included due to unclear licensing implications\n" + )); + } // Copy the files normally for item in &src_files { @@ -1052,19 +1055,6 @@ impl Step for PlainSourceTarball { if builder.config.dist_vendor { builder.require_and_update_all_submodules(); - // Vendor all Cargo dependencies - let mut cmd = command(&builder.initial_cargo); - cmd.arg("vendor").arg("--versioned-dirs"); - - for (p, _) in default_paths_to_vendor(builder) { - cmd.arg("--sync").arg(p); - } - - cmd - // Will read the libstd Cargo.toml which uses the unstable `public-dependency` feature. - .env("RUSTC_BOOTSTRAP", "1") - .current_dir(plain_dst_src); - // Vendor packages that are required by opt-dist to collect PGO profiles. let pkgs_for_pgo_training = build_helper::LLVM_PGO_CRATES .iter() @@ -1076,15 +1066,18 @@ impl Step for PlainSourceTarball { manifest_path.push("Cargo.toml"); manifest_path }); - for manifest_path in pkgs_for_pgo_training { - cmd.arg("--sync").arg(manifest_path); - } - let config = cmd.run_capture(builder).stdout(); + // Vendor all Cargo dependencies + let vendor = builder.ensure(Vendor { + sync_args: pkgs_for_pgo_training.collect(), + versioned_dirs: true, + root_dir: plain_dst_src.into(), + output_dir: VENDOR_DIR.into(), + }); let cargo_config_dir = plain_dst_src.join(".cargo"); builder.create_dir(&cargo_config_dir); - builder.create(&cargo_config_dir.join("config.toml"), &config); + builder.create(&cargo_config_dir.join("config.toml"), &vendor.config); } // Delete extraneous directories @@ -1123,11 +1116,7 @@ impl Step for Cargo { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Cargo { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1144,7 +1133,7 @@ impl Step for Cargo { let mut tarball = Tarball::new(builder, "cargo", &target.triple); tarball.set_overlay(OverlayKind::Cargo); - tarball.add_file(cargo, "bin", 0o755); + tarball.add_file(cargo.tool_path, "bin", 0o755); tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644); tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo"); tarball.add_dir(etc.join("man"), "share/man/man1"); @@ -1172,11 +1161,7 @@ impl Step for Rls { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rls { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1190,7 +1175,7 @@ impl Step for Rls { let mut tarball = Tarball::new(builder, "rls", &target.triple); tarball.set_overlay(OverlayKind::Rls); tarball.is_preview(true); - tarball.add_file(rls, "bin", 0o755); + tarball.add_file(rls.tool_path, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/rls"); Some(tarball.generate()) } @@ -1214,11 +1199,7 @@ impl Step for RustAnalyzer { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzer { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1232,7 +1213,7 @@ impl Step for RustAnalyzer { let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); tarball.set_overlay(OverlayKind::RustAnalyzer); tarball.is_preview(true); - tarball.add_file(rust_analyzer, "bin", 0o755); + tarball.add_file(rust_analyzer.tool_path, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/rust-analyzer"); Some(tarball.generate()) } @@ -1256,11 +1237,7 @@ impl Step for Clippy { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Clippy { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1278,8 +1255,8 @@ impl Step for Clippy { let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); tarball.is_preview(true); - tarball.add_file(clippy, "bin", 0o755); - tarball.add_file(cargoclippy, "bin", 0o755); + tarball.add_file(clippy.tool_path, "bin", 0o755); + tarball.add_file(cargoclippy.tool_path, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/clippy"); Some(tarball.generate()) } @@ -1303,11 +1280,7 @@ impl Step for Miri { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Miri { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1328,8 +1301,8 @@ impl Step for Miri { let mut tarball = Tarball::new(builder, "miri", &target.triple); tarball.set_overlay(OverlayKind::Miri); tarball.is_preview(true); - tarball.add_file(miri, "bin", 0o755); - tarball.add_file(cargomiri, "bin", 0o755); + tarball.add_file(miri.tool_path, "bin", 0o755); + tarball.add_file(cargomiri.tool_path, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/miri"); Some(tarball.generate()) } @@ -1441,11 +1414,7 @@ impl Step for Rustfmt { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rustfmt { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -1459,8 +1428,8 @@ impl Step for Rustfmt { let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); tarball.set_overlay(OverlayKind::Rustfmt); tarball.is_preview(true); - tarball.add_file(rustfmt, "bin", 0o755); - tarball.add_file(cargofmt, "bin", 0o755); + tarball.add_file(rustfmt.tool_path, "bin", 0o755); + tarball.add_file(cargofmt.tool_path, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/rustfmt"); Some(tarball.generate()) } @@ -1495,7 +1464,7 @@ impl Step for Extended { fn run(self, builder: &Builder<'_>) { let target = self.target; let stage = self.stage; - let compiler = builder.compiler_for(self.stage, self.host, self.target); + let compiler = builder.compiler(self.stage, self.host); builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target)); @@ -2259,11 +2228,7 @@ impl Step for LlvmBitcodeLinker { fn make_run(run: RunConfig<'_>) { run.builder.ensure(LlvmBitcodeLinker { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), target: run.target, }); } @@ -2282,7 +2247,7 @@ impl Step for LlvmBitcodeLinker { tarball.set_overlay(OverlayKind::LlvmBitcodeLinker); tarball.is_preview(true); - tarball.add_file(llbc_linker, self_contained_bin_dir, 0o755); + tarball.add_file(llbc_linker.tool_path, self_contained_bin_dir, 0o755); Some(tarball.generate()) } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 23bb47dcc5863..aee56fe78e21f 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -577,6 +577,10 @@ impl Step for Std { fn make_run(run: RunConfig<'_>) { let crates = compile::std_crates_for_run_make(&run); + let target_is_no_std = run.builder.no_std(run.target).unwrap_or(false); + if crates.is_empty() && target_is_no_std { + return; + } run.builder.ensure(Std { stage: run.builder.top_stage, target: run.target, diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 3025f95566070..40d701f22c137 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -996,13 +996,11 @@ impl Step for Enzyme { .config .update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap()); let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/")); - // FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds - //cfg.profile("Debug"); - //cfg.define("CMAKE_BUILD_TYPE", "Debug"); configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]); // Re-use the same flags as llvm to control the level of debug information - // generated for lld. + // generated by Enzyme. + // FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds. let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { (false, _) => "Debug", (true, false) => "Release", @@ -1015,7 +1013,6 @@ impl Step for Enzyme { .env("LLVM_CONFIG_REAL", &llvm_config) .define("LLVM_ENABLE_ASSERTIONS", "ON") .define("ENZYME_EXTERNAL_SHARED_LIB", "ON") - .define("ENZYME_RUNPASS", "ON") .define("LLVM_DIR", builder.llvm_out(target)); cfg.build(); diff --git a/src/bootstrap/src/core/build_steps/perf.rs b/src/bootstrap/src/core/build_steps/perf.rs index 98c63a41e768b..6962001fdc240 100644 --- a/src/bootstrap/src/core/build_steps/perf.rs +++ b/src/bootstrap/src/core/build_steps/perf.rs @@ -166,7 +166,7 @@ Consider setting `rust.debuginfo-level = 1` in `config.toml`."#); let results_dir = rustc_perf_dir.join("results"); builder.create_dir(&results_dir); - let mut cmd = command(collector); + let mut cmd = command(collector.tool_path); // We need to set the working directory to `src/tools/rustc-perf`, so that it can find the directory // with compile-time benchmarks. diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 167b8a5b168c9..fea8232296eca 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -9,6 +9,7 @@ use crate::Mode; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; use crate::core::build_steps::tool::{self, SourceType, Tool}; +use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; use crate::core::config::flags::get_completion; @@ -125,11 +126,7 @@ impl Step for Miri { // This compiler runs on the host, we'll just use it for the target. let target_compiler = builder.compiler(stage, host); - // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise - // we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage - // compilers, which isn't what we want. Rustdoc should be linked in the same way as the - // rustc compiler it's paired with, so it must be built with the previous stage compiler. - let host_compiler = builder.compiler(stage - 1, host); + let host_compiler = tool::get_tool_rustc_compiler(builder, target_compiler); // Get a target sysroot for Miri. let miri_sysroot = test::Miri::build_miri_sysroot(builder, target_compiler, target); @@ -212,11 +209,39 @@ impl Step for GenerateCopyright { let dest = builder.out.join("COPYRIGHT.html"); let dest_libstd = builder.out.join("COPYRIGHT-library.html"); + let paths_to_vendor = default_paths_to_vendor(builder); + for (_, submodules) in &paths_to_vendor { + for submodule in submodules { + builder.build.require_submodule(submodule, None); + } + } + let cargo_manifests = paths_to_vendor + .into_iter() + .map(|(path, _submodules)| path.to_str().unwrap().to_string()) + .inspect(|path| assert!(!path.contains(','), "{path} contains a comma in its name")) + .collect::>() + .join(","); + + let vendored_sources = if let Some(path) = builder.vendored_crates_path() { + path + } else { + let cache_dir = builder.out.join("tmp").join("generate-copyright-vendor"); + builder.ensure(Vendor { + sync_args: Vec::new(), + versioned_dirs: true, + root_dir: builder.src.clone(), + output_dir: cache_dir.clone(), + }); + cache_dir + }; + let mut cmd = builder.tool_cmd(Tool::GenerateCopyright); + cmd.env("CARGO_MANIFESTS", &cargo_manifests); cmd.env("LICENSE_METADATA", &license_metadata); cmd.env("DEST", &dest); cmd.env("DEST_LIBSTD", &dest_libstd); - cmd.env("OUT_DIR", &builder.out); + cmd.env("SRC_DIR", &builder.src); + cmd.env("VENDOR_DIR", &vendored_sources); cmd.env("CARGO", &builder.initial_cargo); // it is important that generate-copyright runs from the root of the // source tree, because it uses relative paths diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index fbd0dc3ec3021..f25dfaab0f115 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -523,19 +523,31 @@ undesirable, simply delete the `pre-push` file from .git/hooks." /// Handles editor-specific setup differences #[derive(Clone, Debug, Eq, PartialEq)] enum EditorKind { - Vscode, - Vim, Emacs, Helix, + Vim, + VsCode, + Zed, } impl EditorKind { + // Used in `./tests.rs`. + #[allow(dead_code)] + pub const ALL: &[EditorKind] = &[ + EditorKind::Emacs, + EditorKind::Helix, + EditorKind::Vim, + EditorKind::VsCode, + EditorKind::Zed, + ]; + fn prompt_user() -> io::Result> { let prompt_str = "Available editors: -1. vscode -2. vim -3. emacs -4. helix +1. Emacs +2. Helix +3. Vim +4. VS Code +5. Zed Select which editor you would like to set up [default: None]: "; @@ -543,28 +555,41 @@ Select which editor you would like to set up [default: None]: "; loop { print!("{}", prompt_str); io::stdout().flush()?; - input.clear(); io::stdin().read_line(&mut input)?; - match input.trim().to_lowercase().as_str() { - "1" | "vscode" => return Ok(Some(EditorKind::Vscode)), - "2" | "vim" => return Ok(Some(EditorKind::Vim)), - "3" | "emacs" => return Ok(Some(EditorKind::Emacs)), - "4" | "helix" => return Ok(Some(EditorKind::Helix)), - "" => return Ok(None), + + let mut modified_input = input.to_lowercase(); + modified_input.retain(|ch| !ch.is_whitespace()); + match modified_input.as_str() { + "1" | "emacs" => return Ok(Some(EditorKind::Emacs)), + "2" | "helix" => return Ok(Some(EditorKind::Helix)), + "3" | "vim" => return Ok(Some(EditorKind::Vim)), + "4" | "vscode" => return Ok(Some(EditorKind::VsCode)), + "5" | "zed" => return Ok(Some(EditorKind::Zed)), + "" | "none" => return Ok(None), _ => { eprintln!("ERROR: unrecognized option '{}'", input.trim()); eprintln!("NOTE: press Ctrl+C to exit"); } - }; + } + + input.clear(); } } /// A list of historical hashes of each LSP settings file /// New entries should be appended whenever this is updated so we can detect /// outdated vs. user-modified settings files. - fn hashes(&self) -> Vec<&str> { + fn hashes(&self) -> &'static [&'static str] { match self { - EditorKind::Vscode | EditorKind::Vim => vec![ + EditorKind::Emacs => &[ + "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", + "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", + ], + EditorKind::Helix => &[ + "2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233", + "6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040", + ], + EditorKind::Vim | EditorKind::VsCode => &[ "ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8", "56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922", "af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0", @@ -576,12 +601,8 @@ Select which editor you would like to set up [default: None]: "; "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", "c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d", ], - EditorKind::Emacs => vec![ - "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", - "d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45", - ], - EditorKind::Helix => { - vec!["2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233"] + EditorKind::Zed => { + &["bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c"] } } } @@ -592,29 +613,31 @@ Select which editor you would like to set up [default: None]: "; fn settings_short_path(&self) -> PathBuf { self.settings_folder().join(match self { - EditorKind::Vscode => "settings.json", - EditorKind::Vim => "coc-settings.json", EditorKind::Emacs => ".dir-locals.el", EditorKind::Helix => "languages.toml", + EditorKind::Vim => "coc-settings.json", + EditorKind::VsCode | EditorKind::Zed => "settings.json", }) } fn settings_folder(&self) -> PathBuf { match self { - EditorKind::Vscode => PathBuf::from(".vscode"), - EditorKind::Vim => PathBuf::from(".vim"), EditorKind::Emacs => PathBuf::new(), EditorKind::Helix => PathBuf::from(".helix"), + EditorKind::Vim => PathBuf::from(".vim"), + EditorKind::VsCode => PathBuf::from(".vscode"), + EditorKind::Zed => PathBuf::from(".zed"), } } - fn settings_template(&self) -> &str { + fn settings_template(&self) -> &'static str { match self { - EditorKind::Vscode | EditorKind::Vim => { - include_str!("../../../../etc/rust_analyzer_settings.json") - } EditorKind::Emacs => include_str!("../../../../etc/rust_analyzer_eglot.el"), EditorKind::Helix => include_str!("../../../../etc/rust_analyzer_helix.toml"), + EditorKind::Vim | EditorKind::VsCode => { + include_str!("../../../../etc/rust_analyzer_settings.json") + } + EditorKind::Zed => include_str!("../../../../etc/rust_analyzer_zed.json"), } } diff --git a/src/bootstrap/src/core/build_steps/setup/tests.rs b/src/bootstrap/src/core/build_steps/setup/tests.rs index f3d4b6aa4db6e..e8f83ff75e404 100644 --- a/src/bootstrap/src/core/build_steps/setup/tests.rs +++ b/src/bootstrap/src/core/build_steps/setup/tests.rs @@ -5,13 +5,16 @@ use crate::utils::helpers::hex_encode; #[test] fn check_matching_settings_hash() { - let editor = EditorKind::Vscode; - let mut hasher = sha2::Sha256::new(); - hasher.update(&editor.settings_template()); - let hash = hex_encode(hasher.finalize().as_slice()); - assert_eq!( - &hash, - editor.hashes().last().unwrap(), - "Update `EditorKind::hashes()` with the new hash of `src/etc/rust_analyzer_settings.json`" - ); + for editor in EditorKind::ALL { + let mut hasher = sha2::Sha256::new(); + hasher.update(&editor.settings_template()); + let hash = hex_encode(hasher.finalize().as_slice()); + assert_eq!( + &hash, + editor.hashes().last().unwrap(), + "Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`", + editor.settings_template(), + editor, + ); + } } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index b3f4a7bad99c2..d335ce65ad53c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -263,7 +263,7 @@ impl Step for Cargotest { let _time = helpers::timeit(builder); let mut cmd = builder.tool_cmd(Tool::CargoTest); - cmd.arg(&cargo) + cmd.arg(&cargo.tool_path) .arg(&out_dir) .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) @@ -298,9 +298,16 @@ impl Step for Cargo { /// Runs `cargo test` for `cargo` packaged with Rust. fn run(self, builder: &Builder<'_>) { + if self.stage < 2 { + eprintln!("WARNING: cargo tests on stage {} may not behave well.", self.stage); + eprintln!("HELP: consider using stage 2"); + } + let compiler = builder.compiler(self.stage, self.host); - builder.ensure(tool::Cargo { compiler, target: self.host }); + let cargo = builder.ensure(tool::Cargo { compiler, target: self.host }); + let compiler = cargo.build_compiler; + let cargo = tool::prepare_tool_cargo( builder, compiler, @@ -367,6 +374,7 @@ impl Step for RustAnalyzer { let stage = self.stage; let host = self.host; let compiler = builder.compiler(stage, host); + let compiler = tool::get_tool_rustc_compiler(builder, compiler); // We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite, // but we do need the standard library to be present. @@ -427,7 +435,8 @@ impl Step for Rustfmt { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Rustfmt { compiler, target: self.host }); + let tool_result = builder.ensure(tool::Rustfmt { compiler, target: self.host }); + let compiler = tool_result.build_compiler; let mut cargo = tool::prepare_tool_cargo( builder, @@ -522,16 +531,11 @@ impl Step for Miri { // This compiler runs on the host, we'll just use it for the target. let target_compiler = builder.compiler(stage, host); - // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise - // we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage - // compilers, which isn't what we want. Rustdoc should be linked in the same way as the - // rustc compiler it's paired with, so it must be built with the previous stage compiler. - let host_compiler = builder.compiler(stage - 1, host); // Build our tools. - let miri = builder.ensure(tool::Miri { compiler: host_compiler, target: host }); + let miri = builder.ensure(tool::Miri { compiler: target_compiler, target: host }); // the ui tests also assume cargo-miri has been built - builder.ensure(tool::CargoMiri { compiler: host_compiler, target: host }); + builder.ensure(tool::CargoMiri { compiler: target_compiler, target: host }); // We also need sysroots, for Miri and for the host (the latter for build scripts). // This is for the tests so everything is done with the target compiler. @@ -542,7 +546,8 @@ impl Step for Miri { // Miri has its own "target dir" for ui test dependencies. Make sure it gets cleared when // the sysroot gets rebuilt, to avoid "found possibly newer version of crate `std`" errors. if !builder.config.dry_run() { - let ui_test_dep_dir = builder.stage_out(host_compiler, Mode::ToolStd).join("miri_ui"); + let ui_test_dep_dir = + builder.stage_out(miri.build_compiler, Mode::ToolStd).join("miri_ui"); // The mtime of `miri_sysroot` changes when the sysroot gets rebuilt (also see // ). // We can hence use that directly as a signal to clear the ui test dir. @@ -553,7 +558,7 @@ impl Step for Miri { // This is with the Miri crate, so it uses the host compiler. let mut cargo = tool::prepare_tool_cargo( builder, - host_compiler, + miri.build_compiler, Mode::ToolRustc, host, Kind::Test, @@ -571,7 +576,7 @@ impl Step for Miri { // miri tests need to know about the stage sysroot cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", &host_sysroot); - cargo.env("MIRI", &miri); + cargo.env("MIRI", &miri.tool_path); // Set the target. cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg()); @@ -743,7 +748,13 @@ impl Step for Clippy { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Clippy { compiler, target: self.host }); + if stage < 2 { + eprintln!("WARNING: clippy tests on stage {stage} may not behave well."); + eprintln!("HELP: consider using stage 2"); + } + + let tool_result = builder.ensure(tool::Clippy { compiler, target: self.host }); + let compiler = tool_result.build_compiler; let mut cargo = tool::prepare_tool_cargo( builder, compiler, @@ -1234,6 +1245,14 @@ impl Step for RunMakeSupport { &[], ); + let _guard = builder.msg_tool( + Kind::Build, + Mode::ToolStd, + "run-make-support", + self.compiler.stage, + &self.compiler.host, + &self.target, + ); cargo.into_cmd().run(builder); let lib_name = "librun_make_support.rlib"; @@ -1720,18 +1739,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // If we're using `--stage 0`, we should provide the bootstrap cargo. builder.initial_cargo.clone() } else { - // We need to properly build cargo using the suitable stage compiler. - - let compiler = builder.download_rustc().then_some(compiler).unwrap_or_else(|| - // HACK: currently tool stages are off-by-one compared to compiler stages, i.e. if - // you give `tool::Cargo` a stage 1 rustc, it will cause stage 2 rustc to be built - // and produce a cargo built with stage 2 rustc. To fix this, we need to chop off - // the compiler stage by 1 to align with expected `./x test run-make --stage N` - // behavior, i.e. we need to pass `N - 1` compiler stage to cargo. See also Miri - // which does a similar hack. - builder.compiler(builder.top_stage - 1, compiler.host)); - - builder.ensure(tool::Cargo { compiler, target: compiler.host }) + builder.ensure(tool::Cargo { compiler, target: compiler.host }).tool_path }; cmd.arg("--cargo-path").arg(cargo_path); @@ -1752,9 +1760,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // Use the beta compiler for jsondocck let json_compiler = compiler.with_stage(0); cmd.arg("--jsondocck-path") - .arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target })); - cmd.arg("--jsondoclint-path") - .arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target })); + .arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target }).tool_path); + cmd.arg("--jsondoclint-path").arg( + builder.ensure(tool::JsonDocLint { compiler: json_compiler, target }).tool_path, + ); } if matches!(mode, "coverage-map" | "coverage-run") { @@ -1762,7 +1771,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--coverage-dump-path").arg(coverage_dump); } - cmd.arg("--src-base").arg(builder.src.join("tests").join(suite)); + cmd.arg("--src-root").arg(&builder.src); + cmd.arg("--src-test-suite-root").arg(builder.src.join("tests").join(suite)); + cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); // When top stage is 0, that means that we're testing an externally provided compiler. @@ -1847,10 +1858,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } // FIXME(136096): on macOS, we get linker warnings about duplicate `-lm` flags. - // NOTE: `stage > 1` here because `test --stage 1 ui-fulldeps` is a hack that compiles - // with stage 0, but links the tests against stage 1. - // cfg(bootstrap) - remove only the `stage > 1` check, leave everything else. - if suite == "ui-fulldeps" && compiler.stage > 1 && target.ends_with("darwin") { + if suite == "ui-fulldeps" && target.ends_with("darwin") { flags.push("-Alinker_messages".into()); } @@ -2989,12 +2997,15 @@ impl Step for RemoteCopyLibs { builder.info(&format!("REMOTE copy libs to emulator ({target})")); - let server = builder.ensure(tool::RemoteTestServer { compiler, target }); + let remote_test_server = builder.ensure(tool::RemoteTestServer { compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); let mut cmd = command(&tool); - cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.tempdir()); + cmd.arg("spawn-emulator") + .arg(target.triple) + .arg(&remote_test_server.tool_path) + .arg(builder.tempdir()); if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); } @@ -3622,7 +3633,7 @@ impl Step for TestFloatParse { let bootstrap_host = builder.config.build; let compiler = builder.compiler(builder.top_stage, bootstrap_host); let path = self.path.to_str().unwrap(); - let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap(); + let crate_name = self.path.iter().next_back().unwrap().to_str().unwrap(); builder.ensure(tool::TestFloatParse { host: self.host }); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a54db9d781573..39acb646dff4d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1,3 +1,14 @@ +//! This module handles building and managing various tools in bootstrap +//! build system. +//! +//! **What It Does** +//! - Defines how tools are built, configured and installed. +//! - Manages tool dependencies and build steps. +//! - Copies built tool binaries to the correct locations. +//! +//! Each Rust tool **MUST** utilize `ToolBuild` inside their `Step` logic, +//! return `ToolBuildResult` and should never prepare `cargo` invocations manually. + use std::path::PathBuf; use std::{env, fs}; @@ -64,8 +75,21 @@ impl Builder<'_> { } } +/// Result of the tool build process. Each `Step` in this module is responsible +/// for using this type as `type Output = ToolBuildResult;` +#[derive(Clone)] +pub struct ToolBuildResult { + /// Executable path of the corresponding tool that was built. + pub tool_path: PathBuf, + /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`. + /// For `ToolRustc` this is one stage before of the `target_compiler`. + pub build_compiler: Compiler, + /// Target compiler passed to `Step`. + pub target_compiler: Compiler, +} + impl Step for ToolBuild { - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.never() @@ -75,25 +99,31 @@ impl Step for ToolBuild { /// /// This will build the specified tool with the specified `host` compiler in /// `stage` into the normal cargo output directory. - fn run(self, builder: &Builder<'_>) -> PathBuf { - let compiler = self.compiler; + fn run(mut self, builder: &Builder<'_>) -> ToolBuildResult { let target = self.target; let mut tool = self.tool; let path = self.path; + let target_compiler = self.compiler; + self.compiler = if self.mode == Mode::ToolRustc { + get_tool_rustc_compiler(builder, self.compiler) + } else { + self.compiler + }; + match self.mode { Mode::ToolRustc => { - builder.ensure(compile::Std::new(compiler, compiler.host)); - builder.ensure(compile::Rustc::new(compiler, target)); + builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); + builder.ensure(compile::Rustc::new(self.compiler, target)); } - Mode::ToolStd => builder.ensure(compile::Std::new(compiler, target)), + Mode::ToolStd => builder.ensure(compile::Std::new(self.compiler, target)), Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs _ => panic!("unexpected Mode for tool build"), } let mut cargo = prepare_tool_cargo( builder, - compiler, + self.compiler, self.mode, target, Kind::Build, @@ -101,10 +131,28 @@ impl Step for ToolBuild { self.source_type, &self.extra_features, ); + + if path.ends_with("/rustdoc") && + // rustdoc is performance sensitive, so apply LTO to it. + is_lto_stage(&self.compiler) + { + let lto = match builder.config.rust_lto { + RustcLto::Off => Some("off"), + RustcLto::Thin => Some("thin"), + RustcLto::Fat => Some("fat"), + RustcLto::ThinLocal => None, + }; + if let Some(lto) = lto { + cargo.env(cargo_profile_var("LTO", &builder.config), lto); + } + } + if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } + cargo.args(self.cargo_args); + let _guard = builder.msg_tool( Kind::Build, self.mode, @@ -131,7 +179,10 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool) + let tool_path = + copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool); + + ToolBuildResult { tool_path, build_compiler: self.compiler, target_compiler } } } } @@ -240,6 +291,23 @@ pub fn prepare_tool_cargo( cargo } +/// Handle stage-off logic for `ToolRustc` tools when necessary. +pub(crate) fn get_tool_rustc_compiler( + builder: &Builder<'_>, + target_compiler: Compiler, +) -> Compiler { + if builder.download_rustc() && target_compiler.stage == 1 { + // We already have the stage 1 compiler, we don't need to cut the stage. + builder.compiler(target_compiler.stage, builder.config.build) + } else { + // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise + // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage + // compilers, which isn't what we want. Rustc tools should be linked in the same way as the + // compiler it's paired with, so it must be built with the previous stage compiler. + builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.build) + } +} + /// Links a built tool binary with the given `name` from the build directory to the /// tools directory. fn copy_link_tool_bin( @@ -279,7 +347,7 @@ macro_rules! bootstrap_tool { self.ensure($name { compiler: self.compiler(0, self.config.build), target: self.config.build, - }), + }).tool_path, )+ } } @@ -293,7 +361,7 @@ macro_rules! bootstrap_tool { } impl Step for $name { - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path($path) @@ -315,7 +383,7 @@ macro_rules! bootstrap_tool { skip_all, ), )] - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { $( for submodule in $submodules { builder.require_submodule(submodule, None); @@ -390,7 +458,7 @@ pub struct OptimizedDist { } impl Step for OptimizedDist { - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/tools/opt-dist") @@ -403,7 +471,7 @@ impl Step for OptimizedDist { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { // We need to ensure the rustc-perf submodule is initialized when building opt-dist since // the tool requires it to be in place to run. builder.require_submodule("src/tools/rustc-perf", None); @@ -432,7 +500,7 @@ pub struct RustcPerf { impl Step for RustcPerf { /// Path to the built `collector` binary. - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/tools/rustc-perf") @@ -445,7 +513,7 @@ impl Step for RustcPerf { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { // We need to ensure the rustc-perf submodule is initialized. builder.require_submodule("src/tools/rustc-perf", None); @@ -462,12 +530,12 @@ impl Step for RustcPerf { // a CLI. cargo_args: vec!["-p".to_string(), "collector".to_string()], }; - let collector_bin = builder.ensure(tool.clone()); + let res = builder.ensure(tool.clone()); // We also need to symlink the `rustc-fake` binary to the corresponding directory, // because `collector` expects it in the same directory. copy_link_tool_bin(builder, tool.compiler, tool.target, tool.mode, "rustc-fake"); - collector_bin + res } } @@ -482,7 +550,7 @@ impl ErrorIndex { // for rustc_private and libLLVM.so, and `sysroot_lib` for libstd, etc. let host = builder.config.build; let compiler = builder.compiler_for(builder.top_stage, host, host); - let mut cmd = command(builder.ensure(ErrorIndex { compiler })); + let mut cmd = command(builder.ensure(ErrorIndex { compiler }).tool_path); let mut dylib_paths = builder.rustc_lib_paths(compiler); dylib_paths.push(PathBuf::from(&builder.sysroot_target_libdir(compiler, compiler.host))); add_dylib_path(dylib_paths, &mut cmd); @@ -491,27 +559,23 @@ impl ErrorIndex { } impl Step for ErrorIndex { - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/tools/error_index_generator") } fn make_run(run: RunConfig<'_>) { - // Compile the error-index in the same stage as rustdoc to avoid - // recompiling rustdoc twice if we can. - // // NOTE: This `make_run` isn't used in normal situations, only if you // manually build the tool with `x.py build // src/tools/error-index-generator` which almost nobody does. // Normally, `x.py test` or `x.py doc` will use the // `ErrorIndex::command` function instead. - let compiler = - run.builder.compiler(run.builder.top_stage.saturating_sub(1), run.builder.config.build); + let compiler = run.builder.compiler(run.builder.top_stage, run.builder.config.build); run.builder.ensure(ErrorIndex { compiler }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { builder.ensure(ToolBuild { compiler: self.compiler, target: self.compiler.host, @@ -533,7 +597,7 @@ pub struct RemoteTestServer { } impl Step for RemoteTestServer { - type Output = PathBuf; + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/tools/remote-test-server") @@ -546,7 +610,7 @@ impl Step for RemoteTestServer { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -569,7 +633,7 @@ pub struct Rustdoc { } impl Step for Rustdoc { - type Output = PathBuf; + type Output = ToolBuildResult; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -578,24 +642,25 @@ impl Step for Rustdoc { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustdoc { - // NOTE: this is somewhat unique in that we actually want a *target* - // compiler here, because rustdoc *is* a compiler. We won't be using - // this as the compiler to build with, but rather this is "what - // compiler are we producing"? - compiler: run.builder.compiler(run.builder.top_stage, run.target), - }); + run.builder + .ensure(Rustdoc { compiler: run.builder.compiler(run.builder.top_stage, run.target) }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { let target_compiler = self.compiler; + let target = target_compiler.host; + if target_compiler.stage == 0 { if !target_compiler.is_snapshot(builder) { panic!("rustdoc in stage 0 must be snapshot rustdoc"); } - return builder.initial_rustdoc.clone(); + + return ToolBuildResult { + tool_path: builder.initial_rustdoc.clone(), + build_compiler: target_compiler, + target_compiler, + }; } - let target = target_compiler.host; let bin_rustdoc = || { let sysroot = builder.sysroot(target_compiler); @@ -625,27 +690,15 @@ impl Step for Rustdoc { let bin_rustdoc = bin_rustdoc(); builder.copy_link(&precompiled_rustdoc, &bin_rustdoc); - return bin_rustdoc; + + return ToolBuildResult { + tool_path: bin_rustdoc, + build_compiler: target_compiler, + target_compiler, + }; } } - let build_compiler = if builder.download_rustc() && target_compiler.stage == 1 { - // We already have the stage 1 compiler, we don't need to cut the stage. - builder.compiler(target_compiler.stage, builder.config.build) - } else { - // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise - // we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage - // compilers, which isn't what we want. Rustdoc should be linked in the same way as the - // rustc compiler it's paired with, so it must be built with the previous stage compiler. - builder.compiler(target_compiler.stage - 1, builder.config.build) - }; - - // When using `download-rustc` and a stage0 build_compiler, copying rustc doesn't actually - // build stage0 libstd (because the libstd in sysroot has the wrong ABI). Explicitly build - // it. - builder.ensure(compile::Std::new(build_compiler, target_compiler.host)); - builder.ensure(compile::Rustc::new(build_compiler, target_compiler.host)); - // The presence of `target_compiler` ensures that the necessary libraries (codegen backends, // compiler libraries, ...) are built. Rustdoc does not require the presence of any // libraries within sysroot_libdir (i.e., rustlib), though doctests may want it (since @@ -653,65 +706,39 @@ impl Step for Rustdoc { // libraries here. The intuition here is that If we've built a compiler, we should be able // to build rustdoc. // - let mut features = Vec::new(); - if builder.config.jemalloc { - features.push("jemalloc".to_string()); + let mut extra_features = Vec::new(); + if builder.config.jemalloc(target) { + extra_features.push("jemalloc".to_string()); } - // NOTE: Never modify the rustflags here, it breaks the build cache for other tools! - let mut cargo = prepare_tool_cargo( - builder, - build_compiler, - Mode::ToolRustc, - target, - Kind::Build, - "src/tools/rustdoc", - SourceType::InTree, - features.as_slice(), - ); - - // rustdoc is performance sensitive, so apply LTO to it. - if is_lto_stage(&build_compiler) { - let lto = match builder.config.rust_lto { - RustcLto::Off => Some("off"), - RustcLto::Thin => Some("thin"), - RustcLto::Fat => Some("fat"), - RustcLto::ThinLocal => None, - }; - if let Some(lto) = lto { - cargo.env(cargo_profile_var("LTO", &builder.config), lto); - } - } - - let _guard = builder.msg_tool( - Kind::Build, - Mode::ToolRustc, - "rustdoc", - build_compiler.stage, - &self.compiler.host, - &target, - ); - cargo.into_cmd().run(builder); - - // Cargo adds a number of paths to the dylib search path on windows, which results in - // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" - // rustdoc a different name. - let tool_rustdoc = builder - .cargo_out(build_compiler, Mode::ToolRustc, target) - .join(exe("rustdoc_tool_binary", target_compiler.host)); + let ToolBuildResult { tool_path, build_compiler, target_compiler } = + builder.ensure(ToolBuild { + compiler: target_compiler, + target, + // Cargo adds a number of paths to the dylib search path on windows, which results in + // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" + // rustdoc a different name. + tool: "rustdoc_tool_binary", + mode: Mode::ToolRustc, + path: "src/tools/rustdoc", + source_type: SourceType::InTree, + extra_features, + allow_features: "", + cargo_args: Vec::new(), + }); // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into // our final binaries - compile::strip_debug(builder, target, &tool_rustdoc); + compile::strip_debug(builder, target, &tool_path); } let bin_rustdoc = bin_rustdoc(); - builder.copy_link(&tool_rustdoc, &bin_rustdoc); - bin_rustdoc + builder.copy_link(&tool_path, &bin_rustdoc); + ToolBuildResult { tool_path: bin_rustdoc, build_compiler, target_compiler } } else { - tool_rustdoc + ToolBuildResult { tool_path, build_compiler, target_compiler } } } } @@ -723,7 +750,7 @@ pub struct Cargo { } impl Step for Cargo { - type Output = PathBuf; + type Output = ToolBuildResult; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -739,7 +766,7 @@ impl Step for Cargo { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { builder.build.require_submodule("src/tools/cargo", None); builder.ensure(ToolBuild { @@ -763,7 +790,7 @@ pub struct LldWrapper { } impl Step for LldWrapper { - type Output = (); + type Output = ToolBuildResult; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.never() @@ -778,14 +805,19 @@ impl Step for LldWrapper { fields(build_compiler = ?self.build_compiler, target_compiler = ?self.target_compiler), ), )] - fn run(self, builder: &Builder<'_>) { + + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { if builder.config.dry_run() { - return; + return ToolBuildResult { + tool_path: Default::default(), + build_compiler: self.build_compiler, + target_compiler: self.target_compiler, + }; } let target = self.target_compiler.host; - let executable = builder.ensure(ToolBuild { + let tool_result = builder.ensure(ToolBuild { compiler: self.build_compiler, target, tool: "lld-wrapper", @@ -809,8 +841,11 @@ impl Step for LldWrapper { t!(fs::create_dir_all(&self_contained_lld_dir)); for name in crate::LLD_FILE_NAMES { - builder.copy_link(&executable, &self_contained_lld_dir.join(exe(name, target))); + builder + .copy_link(&tool_result.tool_path, &self_contained_lld_dir.join(exe(name, target))); } + + tool_result } } @@ -825,7 +860,7 @@ impl RustAnalyzer { } impl Step for RustAnalyzer { - type Output = PathBuf; + type Output = ToolBuildResult; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -841,7 +876,7 @@ impl Step for RustAnalyzer { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -863,7 +898,7 @@ pub struct RustAnalyzerProcMacroSrv { } impl Step for RustAnalyzerProcMacroSrv { - type Output = Option; + type Output = Option; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -885,8 +920,8 @@ impl Step for RustAnalyzerProcMacroSrv { }); } - fn run(self, builder: &Builder<'_>) -> Option { - let path = builder.ensure(ToolBuild { + fn run(self, builder: &Builder<'_>) -> Option { + let tool_result = builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, tool: "rust-analyzer-proc-macro-srv", @@ -902,9 +937,10 @@ impl Step for RustAnalyzerProcMacroSrv { // so that r-a can use it. let libexec_path = builder.sysroot(self.compiler).join("libexec"); t!(fs::create_dir_all(&libexec_path)); - builder.copy_link(&path, &libexec_path.join("rust-analyzer-proc-macro-srv")); + builder + .copy_link(&tool_result.tool_path, &libexec_path.join("rust-analyzer-proc-macro-srv")); - Some(path) + Some(tool_result) } } @@ -916,7 +952,7 @@ pub struct LlvmBitcodeLinker { } impl Step for LlvmBitcodeLinker { - type Output = PathBuf; + type Output = ToolBuildResult; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -938,51 +974,34 @@ impl Step for LlvmBitcodeLinker { feature = "tracing", instrument(level = "debug", name = "LlvmBitcodeLinker::run", skip_all) )] - fn run(self, builder: &Builder<'_>) -> PathBuf { - let bin_name = "llvm-bitcode-linker"; - - // If enabled, use ci-rustc and skip building the in-tree compiler. - if !builder.download_rustc() { - builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); - builder.ensure(compile::Rustc::new(self.compiler, self.target)); - } - - let cargo = prepare_tool_cargo( - builder, - self.compiler, - Mode::ToolRustc, - self.target, - Kind::Build, - "src/tools/llvm-bitcode-linker", - SourceType::InTree, - &self.extra_features, - ); - - let _guard = builder.msg_tool( - Kind::Build, - Mode::ToolRustc, - bin_name, - self.compiler.stage, - &self.compiler.host, - &self.target, - ); - - cargo.into_cmd().run(builder); - - let tool_out = builder - .cargo_out(self.compiler, Mode::ToolRustc, self.target) - .join(exe(bin_name, self.compiler.host)); + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { + let tool_result = builder.ensure(ToolBuild { + compiler: self.compiler, + target: self.target, + tool: "llvm-bitcode-linker", + mode: Mode::ToolRustc, + path: "src/tools/llvm-bitcode-linker", + source_type: SourceType::InTree, + extra_features: self.extra_features, + allow_features: "", + cargo_args: Vec::new(), + }); - if self.compiler.stage > 0 { + if tool_result.target_compiler.stage > 0 { let bindir_self_contained = builder - .sysroot(self.compiler) + .sysroot(tool_result.target_compiler) .join(format!("lib/rustlib/{}/bin/self-contained", self.target.triple)); t!(fs::create_dir_all(&bindir_self_contained)); - let bin_destination = bindir_self_contained.join(exe(bin_name, self.compiler.host)); - builder.copy_link(&tool_out, &bin_destination); - bin_destination + let bin_destination = bindir_self_contained + .join(exe("llvm-bitcode-linker", tool_result.target_compiler.host)); + builder.copy_link(&tool_result.tool_path, &bin_destination); + ToolBuildResult { + tool_path: bin_destination, + build_compiler: tool_result.build_compiler, + target_compiler: tool_result.target_compiler, + } } else { - tool_out + tool_result } } } @@ -1067,7 +1086,7 @@ macro_rules! tool_extended { } impl Step for $name { - type Output = PathBuf; + type Output = ToolBuildResult; const DEFAULT: bool = true; // Overridden by `should_run_tool_build_step` const ONLY_HOSTS: bool = true; @@ -1087,7 +1106,7 @@ macro_rules! tool_extended { }); } - fn run(self, builder: &Builder<'_>) -> PathBuf { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { let Self { compiler, target } = self; run_tool_build_step( builder, @@ -1133,38 +1152,37 @@ fn run_tool_build_step( tool_name: &'static str, path: &'static str, add_bins_to_sysroot: Option<&[&str]>, -) -> PathBuf { - let tool = builder.ensure(ToolBuild { - compiler, - target, - tool: tool_name, - mode: Mode::ToolRustc, - path, - extra_features: vec![], - source_type: SourceType::InTree, - allow_features: "", - cargo_args: vec![], - }); +) -> ToolBuildResult { + let ToolBuildResult { tool_path, build_compiler, target_compiler } = + builder.ensure(ToolBuild { + compiler, + target, + tool: tool_name, + mode: Mode::ToolRustc, + path, + extra_features: vec![], + source_type: SourceType::InTree, + allow_features: "", + cargo_args: vec![], + }); // FIXME: This should just be an if-let-chain, but those are unstable. if let Some(add_bins_to_sysroot) = - add_bins_to_sysroot.filter(|bins| !bins.is_empty() && compiler.stage > 0) + add_bins_to_sysroot.filter(|bins| !bins.is_empty() && target_compiler.stage > 0) { - let bindir = builder.sysroot(compiler).join("bin"); + let bindir = builder.sysroot(target_compiler).join("bin"); t!(fs::create_dir_all(&bindir)); - let tools_out = builder.cargo_out(compiler, Mode::ToolRustc, target); - for add_bin in add_bins_to_sysroot { - let bin_source = tools_out.join(exe(add_bin, target)); - let bin_destination = bindir.join(exe(add_bin, compiler.host)); - builder.copy_link(&bin_source, &bin_destination); + let bin_destination = bindir.join(exe(add_bin, target_compiler.host)); + builder.copy_link(&tool_path, &bin_destination); } // Return a path into the bin dir. - bindir.join(exe(tool_name, compiler.host)) + let path = bindir.join(exe(tool_name, target_compiler.host)); + ToolBuildResult { tool_path: path, build_compiler, target_compiler } } else { - tool + ToolBuildResult { tool_path, build_compiler, target_compiler } } } @@ -1202,7 +1220,7 @@ pub struct TestFloatParse { } impl Step for TestFloatParse { - type Output = (); + type Output = ToolBuildResult; const ONLY_HOSTS: bool = true; const DEFAULT: bool = false; @@ -1210,7 +1228,7 @@ impl Step for TestFloatParse { run.path("src/etc/test-float-parse") } - fn run(self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { let bootstrap_host = builder.config.build; let compiler = builder.compiler(builder.top_stage, bootstrap_host); @@ -1224,7 +1242,7 @@ impl Step for TestFloatParse { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), - }); + }) } } diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index 668133f05cb35..a65623de95a3f 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -354,12 +354,12 @@ fn read_old_toolstate() -> Vec { /// 1. Generate a new Personal access token: /// /// * Login to the bot account, and go to Settings -> Developer settings -> -/// Personal access tokens +/// Personal access tokens /// * Click "Generate new token" /// * Enable the "public_repo" permission, then click "Generate token" /// * Copy the generated token (should be a 40-digit hexadecimal number). -/// Save it somewhere secure, as the token would be gone once you leave -/// the page. +/// Save it somewhere secure, as the token would be gone once you leave +/// the page. /// /// 2. Update the variable group in Azure Pipelines /// @@ -368,7 +368,7 @@ fn read_old_toolstate() -> Vec { /// 4. Replace the email address below if the bot account identity is changed /// /// * See -/// if a private email by GitHub is wanted. +/// if a private email by GitHub is wanted. fn commit_toolstate_change(builder: &Builder<'_>, current_toolstate: &ToolstateData) { let message = format!("({} CI update)", OS.expect("linux/windows only")); let mut success = false; diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 26d0f100ffd52..984c70955d7da 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,9 +1,16 @@ +//! Handles the vendoring process for the bootstrap system. +//! +//! This module ensures that all required Cargo dependencies are gathered +//! and stored in the `/` directory. use std::path::PathBuf; use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::utils::exec::command; +/// The name of the directory where vendored dependencies are stored. +pub const VENDOR_DIR: &str = "vendor"; + /// Returns the cargo workspaces to vendor for `x vendor` and dist tarballs. /// /// Returns a `Vec` of `(path_to_manifest, submodules_required)` where @@ -27,15 +34,24 @@ pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<(PathBuf, Vec<&'sta .collect() } +/// Defines the vendoring step in the bootstrap process. +/// +/// This step executes `cargo vendor` to collect all dependencies +/// and store them in the `/` directory. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub(crate) struct Vendor { - sync_args: Vec, - versioned_dirs: bool, - root_dir: PathBuf, + /// Additional paths to synchronize during vendoring. + pub(crate) sync_args: Vec, + /// Determines whether vendored dependencies use versioned directories. + pub(crate) versioned_dirs: bool, + /// The root directory of the source code. + pub(crate) root_dir: PathBuf, + /// The target directory for storing vendored dependencies. + pub(crate) output_dir: PathBuf, } impl Step for Vendor { - type Output = (); + type Output = VendorOutput; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -48,10 +64,17 @@ impl Step for Vendor { sync_args: run.builder.config.cmd.vendor_sync_args(), versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(), root_dir: run.builder.src.clone(), + output_dir: run.builder.src.join(VENDOR_DIR), }); } + /// Executes the vendoring process. + /// + /// This function runs `cargo vendor` and ensures all required submodules + /// are initialized before vendoring begins. fn run(self, builder: &Builder<'_>) -> Self::Output { + builder.info(&format!("Vendoring sources to {:?}", self.root_dir)); + let mut cmd = command(&builder.initial_cargo); cmd.arg("vendor"); @@ -81,8 +104,15 @@ impl Step for Vendor { // which uses the unstable `public-dependency` feature. cmd.env("RUSTC_BOOTSTRAP", "1"); - cmd.current_dir(self.root_dir); + cmd.current_dir(self.root_dir).arg(&self.output_dir); - cmd.run(builder); + let config = cmd.run_capture_stdout(builder); + VendorOutput { config: config.stdout() } } } + +/// Stores the result of the vendoring step. +#[derive(Debug, Clone)] +pub(crate) struct VendorOutput { + pub(crate) config: String, +} diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 59680af00622f..f08d229c76d5f 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -285,10 +285,7 @@ impl Cargo { // Ignore linker warnings for now. These are complicated to fix and don't affect the build. // FIXME: we should really investigate these... - // cfg(bootstrap) - if compiler.stage != 0 { - self.rustflags.arg("-Alinker-messages"); - } + self.rustflags.arg("-Alinker-messages"); // Throughout the build Cargo can execute a number of build scripts // compiling C/C++ code and we need to pass compilers, archivers, flags, etc @@ -924,8 +921,7 @@ impl Builder<'_> { if self.config.rust_remap_debuginfo { let mut env_var = OsString::new(); - if self.config.vendor { - let vendor = self.build.src.join("vendor"); + if let Some(vendor) = self.build.vendored_crates_path() { env_var.push(vendor); env_var.push("=/rust/deps"); } else { @@ -1072,10 +1068,7 @@ impl Builder<'_> { if mode == Mode::Rustc { rustflags.arg("-Wrustc::internal"); - // cfg(bootstrap) - remove this check when lint is in bootstrap compiler - if stage != 0 { - rustflags.arg("-Drustc::symbol_intern_string_literal"); - } + rustflags.arg("-Drustc::symbol_intern_string_literal"); // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all // of the individual lints are satisfied. rustflags.arg("-Wkeyword_idents_2024"); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index daef8fa3c8a34..9c04f097bee27 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1262,6 +1262,9 @@ impl<'a> Builder<'a> { ), ), )] + + /// FIXME: This function is unnecessary (and dangerous, see ). + /// We already have uplifting logic for the compiler, so remove this. pub fn compiler_for( &self, stage: u32, @@ -1392,7 +1395,7 @@ impl<'a> Builder<'a> { } pub fn rustdoc(&self, compiler: Compiler) -> PathBuf { - self.ensure(tool::Rustdoc { compiler }) + self.ensure(tool::Rustdoc { compiler }).tool_path } pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { @@ -1408,14 +1411,13 @@ impl<'a> Builder<'a> { return cmd; } - let build_compiler = self.compiler(run_compiler.stage - 1, self.build.build); - self.ensure(tool::Clippy { compiler: build_compiler, target: self.build.build }); + let _ = self.ensure(tool::Clippy { compiler: run_compiler, target: self.build.build }); let cargo_clippy = - self.ensure(tool::CargoClippy { compiler: build_compiler, target: self.build.build }); + self.ensure(tool::CargoClippy { compiler: run_compiler, target: self.build.build }); let mut dylib_path = helpers::dylib_path(); dylib_path.insert(0, self.sysroot(run_compiler).join("lib")); - let mut cmd = command(cargo_clippy); + let mut cmd = command(cargo_clippy.tool_path); cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); cmd.env("CARGO", &self.initial_cargo); cmd @@ -1423,23 +1425,21 @@ impl<'a> Builder<'a> { pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0"); - let build_compiler = self.compiler(run_compiler.stage - 1, self.build.build); - // Prepare the tools - let miri = self.ensure(tool::Miri { compiler: build_compiler, target: self.build.build }); + let miri = self.ensure(tool::Miri { compiler: run_compiler, target: self.build.build }); let cargo_miri = - self.ensure(tool::CargoMiri { compiler: build_compiler, target: self.build.build }); + self.ensure(tool::CargoMiri { compiler: run_compiler, target: self.build.build }); // Invoke cargo-miri, make sure it can find miri and cargo. - let mut cmd = command(cargo_miri); - cmd.env("MIRI", &miri); + let mut cmd = command(cargo_miri.tool_path); + cmd.env("MIRI", &miri.tool_path); cmd.env("CARGO", &self.initial_cargo); - // Need to add the `run_compiler` libs. Those are the libs produces *by* `build_compiler`, - // so they match the Miri we just built. However this means they are actually living one - // stage up, i.e. we are running `stage0-tools-bin/miri` with the libraries in `stage1/lib`. - // This is an unfortunate off-by-1 caused (possibly) by the fact that Miri doesn't have an - // "assemble" step like rustc does that would cross the stage boundary. We can't use - // `add_rustc_lib_path` as that's a NOP on Windows but we do need these libraries added to - // the PATH due to the stage mismatch. + // Need to add the `run_compiler` libs. Those are the libs produces *by* `build_compiler` + // in `tool::ToolBuild` step, so they match the Miri we just built. However this means they + // are actually living one stage up, i.e. we are running `stage0-tools-bin/miri` with the + // libraries in `stage1/lib`. This is an unfortunate off-by-1 caused (possibly) by the fact + // that Miri doesn't have an "assemble" step like rustc does that would cross the stage boundary. + // We can't use `add_rustc_lib_path` as that's a NOP on Windows but we do need these libraries + // added to the PATH due to the stage mismatch. // Also see https://github.com/rust-lang/rust/pull/123192#issuecomment-2028901503. add_dylib_path(self.rustc_lib_paths(run_compiler), &mut cmd); cmd diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 445b5dfbeab22..0eaa89792bd97 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -525,6 +525,7 @@ mod dist { first(cache.all::()), &[ rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0), + rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1), rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1), ] ); @@ -1084,3 +1085,33 @@ fn test_is_builder_target() { assert!(!builder.is_builder_target(target2)); } } + +#[test] +fn test_get_tool_rustc_compiler() { + let mut config = configure("build", &[], &[]); + config.download_rustc_commit = None; + let build = Build::new(config); + let builder = Builder::new(&build); + + let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); + + let compiler = Compiler { stage: 2, host: target_triple_1 }; + let expected = Compiler { stage: 1, host: target_triple_1 }; + let actual = tool::get_tool_rustc_compiler(&builder, compiler); + assert_eq!(expected, actual); + + let compiler = Compiler { stage: 1, host: target_triple_1 }; + let expected = Compiler { stage: 0, host: target_triple_1 }; + let actual = tool::get_tool_rustc_compiler(&builder, compiler); + assert_eq!(expected, actual); + + let mut config = configure("build", &[], &[]); + config.download_rustc_commit = Some("".to_owned()); + let build = Build::new(config); + let builder = Builder::new(&build); + + let compiler = Compiler { stage: 1, host: target_triple_1 }; + let expected = Compiler { stage: 1, host: target_triple_1 }; + let actual = tool::get_tool_rustc_compiler(&builder, compiler); + assert_eq!(expected, actual); +} diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index d27a8b155df73..d4b72ead045eb 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -325,6 +325,9 @@ pub struct Config { pub hosts: Vec, pub targets: Vec, pub local_rebuild: bool, + #[cfg(not(test))] + jemalloc: bool, + #[cfg(test)] pub jemalloc: bool, pub control_flow_guard: bool, pub ehcont_guard: bool, @@ -643,6 +646,7 @@ pub struct Target { pub no_std: bool, pub codegen_backends: Option>, pub optimized_compiler_builtins: Option, + pub jemalloc: Option, } impl Target { @@ -1234,6 +1238,7 @@ define_config! { codegen_backends: Option> = "codegen-backends", runner: Option = "runner", optimized_compiler_builtins: Option = "optimized-compiler-builtins", + jemalloc: Option = "jemalloc", } } @@ -2161,6 +2166,7 @@ impl Config { target.profiler = cfg.profiler; target.rpath = cfg.rpath; target.optimized_compiler_builtins = cfg.optimized_compiler_builtins; + target.jemalloc = cfg.jemalloc; if let Some(ref backends) = cfg.codegen_backends { let available_backends = ["llvm", "cranelift", "gcc"]; @@ -2324,21 +2330,21 @@ impl Config { Subcommand::Doc { .. } => { flags.stage.or(doc_stage).unwrap_or(if download_rustc { 2 } else { 0 }) } - Subcommand::Build { .. } => { + Subcommand::Build => { flags.stage.or(build_stage).unwrap_or(if download_rustc { 2 } else { 1 }) } Subcommand::Test { .. } | Subcommand::Miri { .. } => { flags.stage.or(test_stage).unwrap_or(if download_rustc { 2 } else { 1 }) } Subcommand::Bench { .. } => flags.stage.or(bench_stage).unwrap_or(2), - Subcommand::Dist { .. } => flags.stage.or(dist_stage).unwrap_or(2), - Subcommand::Install { .. } => flags.stage.or(install_stage).unwrap_or(2), + Subcommand::Dist => flags.stage.or(dist_stage).unwrap_or(2), + Subcommand::Install => flags.stage.or(install_stage).unwrap_or(2), Subcommand::Perf { .. } => flags.stage.unwrap_or(1), // These are all bootstrap tools, which don't depend on the compiler. // The stage we pass shouldn't matter, but use 0 just in case. Subcommand::Clean { .. } | Subcommand::Clippy { .. } - | Subcommand::Fix { .. } + | Subcommand::Fix | Subcommand::Run { .. } | Subcommand::Setup { .. } | Subcommand::Format { .. } @@ -2353,10 +2359,10 @@ impl Config { Subcommand::Test { .. } | Subcommand::Miri { .. } | Subcommand::Doc { .. } - | Subcommand::Build { .. } + | Subcommand::Build | Subcommand::Bench { .. } - | Subcommand::Dist { .. } - | Subcommand::Install { .. } => { + | Subcommand::Dist + | Subcommand::Install => { assert_eq!( config.stage, 2, "x.py should be run with `--stage 2` on CI, but was run with `--stage {}`", @@ -2366,7 +2372,7 @@ impl Config { Subcommand::Clean { .. } | Subcommand::Check { .. } | Subcommand::Clippy { .. } - | Subcommand::Fix { .. } + | Subcommand::Fix | Subcommand::Run { .. } | Subcommand::Setup { .. } | Subcommand::Format { .. } @@ -2726,6 +2732,10 @@ impl Config { .unwrap_or(&self.rust_codegen_backends) } + pub fn jemalloc(&self, target: TargetSelection) -> bool { + self.target_config.get(&target).and_then(|cfg| cfg.jemalloc).unwrap_or(self.jemalloc) + } + pub fn default_codegen_backend(&self, target: TargetSelection) -> Option { self.codegen_backends(target).first().cloned() } @@ -2757,7 +2767,7 @@ impl Config { ), )] pub(crate) fn update_submodule(&self, relative_path: &str) { - if !self.submodules() { + if self.rust_info.is_from_tarball() || !self.submodules() { return; } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index c08a041ebcd3f..3bb62bbe38082 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -490,17 +490,17 @@ impl Subcommand { pub fn kind(&self) -> Kind { match self { Subcommand::Bench { .. } => Kind::Bench, - Subcommand::Build { .. } => Kind::Build, + Subcommand::Build => Kind::Build, Subcommand::Check { .. } => Kind::Check, Subcommand::Clippy { .. } => Kind::Clippy, Subcommand::Doc { .. } => Kind::Doc, - Subcommand::Fix { .. } => Kind::Fix, + Subcommand::Fix => Kind::Fix, Subcommand::Format { .. } => Kind::Format, Subcommand::Test { .. } => Kind::Test, Subcommand::Miri { .. } => Kind::Miri, Subcommand::Clean { .. } => Kind::Clean, - Subcommand::Dist { .. } => Kind::Dist, - Subcommand::Install { .. } => Kind::Install, + Subcommand::Dist => Kind::Dist, + Subcommand::Install => Kind::Install, Subcommand::Run { .. } => Kind::Run, Subcommand::Setup { .. } => Kind::Setup, Subcommand::Suggest { .. } => Kind::Suggest, diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 983674d2c6835..01cbf6629408d 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -1,3 +1,10 @@ +//! This module interacts with Cargo metadata to collect and store information about +//! the packages in the Rust workspace. +//! +//! It runs `cargo metadata` to gather details about each package, including its name, +//! source, dependencies, targets, and available features. The collected metadata is then +//! used to update the `Build` structure, ensuring proper dependency resolution and +//! compilation flow. use std::collections::BTreeMap; use std::path::PathBuf; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 241b7386d18c5..fdac7f3cb179d 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,10 +34,6 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined - "aarch64-unknown-nto-qnx710_iosock", - "x86_64-pc-nto-qnx710_iosock", - "x86_64-pc-nto-qnx800", - "aarch64-unknown-nto-qnx800", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 62ddc7d682ee8..351e67f6702d1 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -50,6 +50,8 @@ pub use utils::change_tracker::{ CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes, }; +use crate::core::build_steps::vendor::VENDOR_DIR; + const LLVM_TOOLS: &[&str] = &[ "llvm-cov", // used to generate coverage report "llvm-nm", // used to inspect binaries; it shows symbol names, their sizes and visibility @@ -479,6 +481,10 @@ impl Build { ), )] pub fn require_submodule(&self, submodule: &str, err_hint: Option<&str>) { + if self.rust_info().is_from_tarball() { + return; + } + // When testing bootstrap itself, it is much faster to ignore // submodules. Almost all Steps work fine without their submodules. if cfg!(test) && !self.config.submodules() { @@ -486,7 +492,7 @@ impl Build { } self.config.update_submodule(submodule); let absolute_path = self.config.src.join(submodule); - if dir_is_empty(&absolute_path) { + if !absolute_path.exists() || dir_is_empty(&absolute_path) { let maybe_enable = if !self.config.submodules() && self.config.rust_info.is_managed_git_subrepository() { @@ -631,7 +637,7 @@ impl Build { // Check for postponed failures from `test --no-fail-fast`. let failures = self.delayed_failures.borrow(); - if failures.len() > 0 { + if !failures.is_empty() { eprintln!("\n{} command(s) did not execute successfully:\n", failures.len()); for failure in failures.iter() { eprintln!(" - {failure}\n"); @@ -686,7 +692,7 @@ impl Build { crates.is_empty() || possible_features_by_crates.contains(feature) }; let mut features = vec![]; - if self.config.jemalloc && check("jemalloc") { + if self.config.jemalloc(target) && check("jemalloc") { features.push("jemalloc"); } if (self.config.llvm_enabled(target) || kind == Kind::Check) && check("llvm") { @@ -791,6 +797,11 @@ impl Build { self.out.join(target).join("md-doc") } + /// Path to the vendored Rust crates. + fn vendored_crates_path(&self) -> Option { + if self.config.vendor { Some(self.src.join(VENDOR_DIR)) } else { None } + } + /// Returns `true` if this is an external version of LLVM not managed by bootstrap. /// In particular, we expect llvm sources to be available when this is false. /// diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 9b23cf1843ef5..8dfe0d3a35ef6 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -350,4 +350,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "The llvm.ccache option has moved to build.ccache. llvm.ccache is now deprecated.", }, + ChangeInfo { + change_id: 137170, + severity: ChangeSeverity::Info, + summary: "It is now possible to configure `jemalloc` for each target", + }, + ChangeInfo { + change_id: 137215, + severity: ChangeSeverity::Info, + summary: "Added `build.test-stage = 2` to 'tools' profile defaults", + }, ]; diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs index dbfd6f47dc67f..34bf6bb7013ff 100644 --- a/src/bootstrap/src/utils/proc_macro_deps.rs +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -6,25 +6,18 @@ pub static CRATES: &[&str] = &[ "annotate-snippets", "anstyle", "basic-toml", - "block-buffer", "bumpalo", - "cfg-if", - "cpufeatures", - "crypto-common", "darling", "darling_core", "derive_builder_core", - "digest", "fluent-bundle", "fluent-langneg", "fluent-syntax", "fnv", - "generic-array", "heck", "ident_case", "intl-memoizer", "intl_pluralrules", - "libc", "log", "memchr", "mime", @@ -32,17 +25,12 @@ pub static CRATES: &[&str] = &[ "minimal-lexical", "nom", "num-conv", - "once_cell", - "pest", - "pest_generator", - "pest_meta", "proc-macro2", "quote", "rinja_parser", "rustc-hash", "self_cell", "serde", - "sha2", "smallvec", "stable_deref_trait", "strsim", @@ -52,15 +40,12 @@ pub static CRATES: &[&str] = &[ "time-core", "tinystr", "type-map", - "typenum", - "ucd-trie", "unic-langid", "unic-langid-impl", "unic-langid-macros", "unicase", "unicode-ident", "unicode-width", - "version_check", "wasm-bindgen-backend", "wasm-bindgen-macro-support", "wasm-bindgen-shared", diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig index 576f3631cd53f..aa33f72268e4e 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/loongarch64-unknown-linux-gnu.defconfig @@ -7,6 +7,8 @@ CT_ARCH_LOONGARCH=y # CT_DEMULTILIB is not set CT_ARCH_USE_MMU=y CT_ARCH_ARCH="loongarch64" +CT_TARGET_CFLAGS="-mcmodel=medium" +CT_TARGET_LDFLAGS="-mcmodel=medium" CT_KERNEL_LINUX=y CT_LINUX_V_5_19=y CT_GLIBC_V_2_36=y diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig index 3ab676ed9717a..3ccbc583c1bd2 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig @@ -7,6 +7,8 @@ CT_ARCH_LOONGARCH=y # CT_DEMULTILIB is not set CT_ARCH_USE_MMU=y CT_ARCH_ARCH="loongarch64" +CT_TARGET_CFLAGS="-mcmodel=medium" +CT_TARGET_LDFLAGS="-mcmodel=medium" CT_KERNEL_LINUX=y CT_LINUX_V_5_19=y CT_LIBC_MUSL=y diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index d2697ac27ab7a..6658b83efc8d2 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -236,9 +236,15 @@ args= if [ "$SCCACHE_BUCKET" != "" ]; then args="$args --env SCCACHE_BUCKET" args="$args --env SCCACHE_REGION" - args="$args --env AWS_ACCESS_KEY_ID" - args="$args --env AWS_SECRET_ACCESS_KEY" args="$args --env AWS_REGION" + + # Disable S3 authentication for PR builds, because the access keys are missing + if [ "$PR_CI_JOB" != "" ]; then + args="$args --env SCCACHE_S3_NO_CREDENTIALS=1" + else + args="$args --env AWS_ACCESS_KEY_ID" + args="$args --env AWS_SECRET_ACCESS_KEY" + fi else mkdir -p $HOME/.cache/sccache args="$args --env SCCACHE_DIR=/sccache --volume $HOME/.cache/sccache:/sccache" diff --git a/src/ci/docker/scripts/build-clang.sh b/src/ci/docker/scripts/build-clang.sh index 841a0adb2ab8c..536991cc06b7d 100755 --- a/src/ci/docker/scripts/build-clang.sh +++ b/src/ci/docker/scripts/build-clang.sh @@ -5,7 +5,7 @@ set -ex source shared.sh # Try to keep the LLVM version here in sync with src/ci/scripts/install-clang.sh -LLVM=llvmorg-19.1.0-rc3 +LLVM=llvmorg-20.1.0-rc2 mkdir llvm-project cd llvm-project diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 3eb85ab215e0b..573821c3e59cd 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,7 +2,7 @@ set -euo pipefail -LINUX_VERSION=50e57739141b41f731ab31f8380821c7969f9dc4 +LINUX_VERSION=v6.14-rc3 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt @@ -28,7 +28,7 @@ rm -rf linux || true # Download Linux at a specific commit mkdir -p linux git -C linux init -git -C linux remote add origin https://github.com/Darksonn/linux.git +git -C linux remote add origin https://github.com/Rust-for-Linux/linux.git git -C linux fetch --depth 1 origin ${LINUX_VERSION} git -C linux checkout FETCH_HEAD diff --git a/src/ci/docker/scripts/sccache.sh b/src/ci/docker/scripts/sccache.sh index 6c713e1f8611f..f66671c64d25c 100644 --- a/src/ci/docker/scripts/sccache.sh +++ b/src/ci/docker/scripts/sccache.sh @@ -6,10 +6,10 @@ set -ex case "$(uname -m)" in x86_64) - url="https://ci-mirrors.rust-lang.org/rustc/2021-08-24-sccache-v0.2.15-x86_64-unknown-linux-musl" + url="https://ci-mirrors.rust-lang.org/rustc/2025-01-07-sccache-v0.9.1-x86_64-unknown-linux-musl" ;; aarch64) - url="https://ci-mirrors.rust-lang.org/rustc/2021-08-25-sccache-v0.2.15-aarch64-unknown-linux-musl" + url="https://ci-mirrors.rust-lang.org/rustc/2025-01-07-sccache-v0.9.1-aarch64-unknown-linux-musl" ;; *) echo "unsupported architecture: $(uname -m)" diff --git a/src/ci/run.sh b/src/ci/run.sh index b874f71832d73..536754f12bc6d 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -279,5 +279,5 @@ if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then fi echo "::group::sccache stats" -sccache --show-stats || true +sccache --show-adv-stats || true echo "::endgroup::" diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 91eab2e7a0816..c8c501e646a9d 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -32,6 +32,12 @@ if isWindows && isKnownToBeMingwBuild; then ;; esac + # Stop /msys64/bin from being prepended to PATH by adding the bin directory manually. + # Note that this intentionally uses a Windows style path instead of the msys2 path to + # avoid being auto-translated into `/usr/bin`, which will not have the desired effect. + msys2Path="c:/msys64" + ciCommandAddPath "${msys2Path}/usr/bin" + mingw_dir="mingw${bits}" curl -o mingw.7z "${MIRRORS_BASE}/${mingw_archive}" diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md index 91c4aeacbd749..106db508ebbc7 100644 --- a/src/doc/rustc-dev-guide/src/SUMMARY.md +++ b/src/doc/rustc-dev-guide/src/SUMMARY.md @@ -75,6 +75,7 @@ - [Prologue](./building/bootstrapping/intro.md) - [What Bootstrapping does](./building/bootstrapping/what-bootstrapping-does.md) - [How Bootstrap does it](./building/bootstrapping/how-bootstrap-does-it.md) +- [Writing tools in Bootstrap](./building/bootstrapping/writing-tools-in-bootstrap.md) - [Debugging bootstrap](./building/bootstrapping/debugging-bootstrap.md) # High-level Compiler Architecture diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md new file mode 100644 index 0000000000000..6046d5b133d7d --- /dev/null +++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md @@ -0,0 +1,23 @@ +# Writing tools in Bootstrap + +There are three types of tools you can write in bootstrap: + +- **`Mode::ToolBootstrap`** + Use this for tools that don’t need anything from the in-tree compiler and can run with the stage0 `rustc`. + The output is placed in the "stage0-bootstrap-tools" directory. This mode is for general-purpose tools built + entirely with the stage0 compiler, including target libraries and only works for stage 0. + +- **`Mode::ToolStd`** + Use this for tools that rely on the locally built std. The output goes into the "stageN-tools" directory. + This mode is rarely used, mainly for `compiletest` which requires `libtest`. + +- **`Mode::ToolRustc`** + Use this for tools that depend on both the locally built `rustc` and the target `std`. This is more complex than + the other modes because the tool must be built with the same compiler used for `rustc` and placed in the "stageN-tools" + directory. When you choose `Mode::ToolRustc`, `ToolBuild` implementation takes care of this automatically. + If you need to use the builder’s compiler for something specific, you can get it from `ToolBuildResult`, which is + returned by the tool's [`Step`]. + +Regardless of the tool type you must return `ToolBuildResult` from the tool’s [`Step`] implementation and use `ToolBuild` inside it. + +[`Step`]: https://doc.rust-lang.org/nightly/nightly-rustc/bootstrap/core/builder/trait.Step.html diff --git a/src/doc/rustc-dev-guide/src/building/suggested.md b/src/doc/rustc-dev-guide/src/building/suggested.md index 2c6c3fe1df84b..5c041d6cb70f9 100644 --- a/src/doc/rustc-dev-guide/src/building/suggested.md +++ b/src/doc/rustc-dev-guide/src/building/suggested.md @@ -154,6 +154,16 @@ You can run `./x setup editor` and select `helix`, which will prompt you to create `languages.toml` with the recommended configuration for Helix. The recommended settings live at [`src/etc/rust_analyzer_helix.toml`]. +### Zed + +Zed comes with built-in LSP and rust-analyzer support. +It can be configured through `.zed/settings.json`, as described +[here](https://zed.dev/docs/configuring-languages). Selecting `zed` +in `./x setup editor` will prompt you to create a `.zed/settings.json` +file which will configure Zed with the recommended configuration. The +recommended `rust-analyzer` settings live +at [`src/etc/rust_analyzer_zed.json`]. + ## Check, check, and check again When doing simple refactoring, it can be useful to run `./x check` @@ -381,4 +391,5 @@ load this completion. [`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json [`src/etc/rust_analyzer_eglot.el`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el [`src/etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml +[`src/etc/rust_analyzer_zed.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json [`src/etc/pre-push.sh`]: https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh diff --git a/src/doc/rustc-dev-guide/src/implementing_new_features.md b/src/doc/rustc-dev-guide/src/implementing_new_features.md index 5b67ccd7f4c5e..fda38ef4fc01a 100644 --- a/src/doc/rustc-dev-guide/src/implementing_new_features.md +++ b/src/doc/rustc-dev-guide/src/implementing_new_features.md @@ -167,9 +167,7 @@ a new unstable feature: 1. Prevent usage of the new feature unless the feature gate is set. You can check it in most places in the compiler using the - expression `tcx.features().$feature_name` (or - `sess.features_untracked().$feature_name` if the - tcx is unavailable) + expression `tcx.features().$feature_name()` If the feature gate is not set, you should either maintain the pre-feature behavior or raise an error, depending on diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index b5cd3864620d3..c4e5c1aac2f5d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -301,7 +301,7 @@ target | std | host | notes [`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Bare Armv8-R, hardfloat [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat -`avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` +`avr-none` | * | | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) @@ -309,10 +309,10 @@ target | std | host | notes [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 [`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS (Penryn) [^x86_32-floats-return-ABI] -[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86 (original Pentium) [^x86_32-floats-x87] [`i586-unknown-redox`](platform-support/redox.md) | ✓ | | 32-bit x86 Redox OS (PentiumPro) [^x86_32-floats-x87] [`i686-apple-darwin`](platform-support/apple-darwin.md) | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+, Penryn) [^x86_32-floats-return-ABI] +[`i686-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS (Pentium 4) [^x86_32-floats-return-ABI] `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd (Pentium 4) [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 (Pentium 4) [^x86_32-floats-return-ABI] diff --git a/src/doc/rustc/src/platform-support/avr-none.md b/src/doc/rustc/src/platform-support/avr-none.md new file mode 100644 index 0000000000000..9c1836222c103 --- /dev/null +++ b/src/doc/rustc/src/platform-support/avr-none.md @@ -0,0 +1,81 @@ +# `avr-none` + +Series of microcontrollers from Atmel: ATmega8, ATmega328p etc. + +**Tier: 3** + +## Target maintainers + +- [Patryk Wychowaniec](https://github.com/Patryk27) + +## Requirements + +This target is only cross-compiled; x86-64 Linux, x86-64 macOS and aarch64 macOS +hosts are confirmed to work, but in principle any machine able to run rustc and +avr-gcc should be good. + +Compiling for this target requires `avr-gcc` installed, because a couple of +intrinsics (like 32-bit multiplication) rely on [`libgcc`](https://github.com/gcc-mirror/gcc/blob/3269a722b7a03613e9c4e2862bc5088c4a17cc11/libgcc/config/avr/lib1funcs.S) +and can't be provided through `compiler-builtins` yet. This is a limitation that +[we hope to lift in the future](https://github.com/rust-lang/compiler-builtins/issues/711). + +You'll also need to setup the `.cargo/config` file - see below for details. + +## Building the target + +Rust comes with AVR support enabled, you don't have to rebuild the compiler. + +## Building Rust programs + +Install `avr-gcc`: + +```console +# Ubuntu: +$ sudo apt-get install gcc-avr + +# Mac: +$ brew tap osx-cross/avr && brew install avr-gcc + +# NixOS (takes a couple of minutes, since it's not provided through Hydra): +$ nix shell nixpkgs#pkgsCross.avr.buildPackages.gcc11 +``` + +... setup `.cargo/config` for your project: + +```toml +[build] +target = "avr-none" +rustflags = ["-C", "target-cpu=atmega328p"] + +[unstable] +build-std = ["core"] +``` + +... and then simply run: + +```console +$ cargo build --release +``` + +The final binary will be placed into +`./target/avr-none/release/your-project.elf`. + +Note that since AVRs have rather small amounts of registers, ROM and RAM, it's +recommended to always use `--release` to avoid running out of space. + +Also, please note that specifying `-C target-cpu` is required - here's a list of +the possible variants: + +https://github.com/llvm/llvm-project/blob/093d4db2f3c874d4683fb01194b00dbb20e5c713/clang/lib/Basic/Targets/AVR.cpp#L32 + +## Testing + +You can use [`simavr`](https://github.com/buserror/simavr) to emulate the +resulting firmware on your machine: + +```console +$ simavr -m atmega328p ./target/avr-none/release/your-project.elf +``` + +Alternatively, if you want to write a couple of actual `#[test]`s, you can use +[`avr-tester`](https://github.com/Patryk27/avr-tester). diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index 110a7cc3424d4..bafa85c26e290 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -32,7 +32,7 @@ By default, code generated with the soft-float target should run on any LoongArch64 hardware, with the hard-float target additionally requiring an FPU; enabling additional target features may raise this baseline. -Code generated with the targets will use the `small` code model by default. +Code generated with the targets will use the `medium` code model by default. You can change this using the `-C code-model=` option to rustc. On `loongarch64-unknown-none*`, `extern "C"` uses the [architecture's standard calling convention][lapcs]. diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 339741f14727d..77e8caaee4cdc 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -31,7 +31,7 @@ Currently, the following QNX versions and compilation targets are supported: | `aarch64-unknown-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | AArch64 | ? | ✓ | | `x86_64-pc-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | x86_64 | ? | ✓ | | `aarch64-unknown-nto-qnx700` | QNX Neutrino 7.0 | AArch64 | ? | ✓ | -| `i586-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | +| `i686-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | On QNX Neutrino 7.0 and 7.1, `io-pkt` is used as network stack by default. QNX Neutrino 7.1 includes the optional network stack `io-sock`. diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md index 73264aba85809..ba95ab7af6d1a 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md @@ -129,6 +129,8 @@ As of the time of this writing the proposals that are enabled by default (the * `mutable-globals` * `reference-types` * `sign-ext` +* `nontrapping-fptoint` (Rust 1.87.0+, LLVM 20+) +* `bulk-memory` (Rust 1.87.0+, LLVM 20+) If you're compiling WebAssembly code for an engine that does not support a feature in LLVM's default feature set then the feature must be disabled at diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 1af5e2b0e1d4f..872592d669d6d 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -100,7 +100,8 @@ mod private { // this item is private and will not be documented } ``` -`--document-private-items` documents all items, even if they're not public. +`--document-private-items` includes all non-public items in the generated documentation except for `#[doc(hidden)]` items. Private items will be shown with a 🔒 icon. + ## `-L`/`--library-path`: where to look for dependencies diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3abd538d372c4..d4ff69a99338b 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -262,6 +262,25 @@ themselves marked as unstable. To use any of these options, pass `-Z unstable-op the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the `RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. +### `--document-hidden-items`: Show items that are `#[doc(hidden)]` + + +By default, `rustdoc` does not document items that are annotated with +[`#[doc(hidden)]`](write-documentation/the-doc-attribute.html#hidden). + +`--document-hidden-items` causes all items to be documented as if they did not have `#[doc(hidden)]`, except that hidden items will be shown with a 👻 icon. + +Here is a table that fully describes which items are documented with each combination of `--document-hidden-items` and `--document-private-items`: + + +| rustdoc flags | items that will be documented | +|---------------------------------|---------------------------------------| +| neither flag | only public items that are not hidden | +| only `--document-hidden-items` | all public items | +| only `--document-private-items` | all items that are not hidden | +| both flags | all items | + + ### `--markdown-before-content`: include rendered Markdown before the content * Tracking issue: [#44027](https://github.com/rust-lang/rust/issues/44027) diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md index ff033aa14b821..45146993371f9 100644 --- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md +++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md @@ -230,9 +230,8 @@ If you want to know more about inlining rules, take a look at the -Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless -the `strip-hidden` pass is removed. Re-exported items where one of its ancestors has -`#[doc(hidden)]` will be considered the same as private. +Any item annotated with `#[doc(hidden)]` will not appear in the documentation, +unless the [`--document-hidden-items`](../unstable-features.md#document-hidden-items) flag is used. You can find more information in the [`re-exports` chapter](./re-exports.md). diff --git a/src/doc/unstable-book/src/compiler-flags/autodiff.md b/src/doc/unstable-book/src/compiler-flags/autodiff.md index 4e55be0ad95a0..95c188d1f3b29 100644 --- a/src/doc/unstable-book/src/compiler-flags/autodiff.md +++ b/src/doc/unstable-book/src/compiler-flags/autodiff.md @@ -8,16 +8,13 @@ This feature allows you to differentiate functions using automatic differentiati Set the `-Zautodiff=` compiler flag to adjust the behaviour of the autodiff feature. Multiple options can be separated with a comma. Valid options are: +`Enable` - Required flag to enable autodiff `PrintTA` - print Type Analysis Information `PrintAA` - print Activity Analysis Information `PrintPerf` - print Performance Warnings from Enzyme -`Print` - prints all intermediate transformations +`PrintSteps` - prints all intermediate transformations `PrintModBefore` - print the whole module, before running opts -`PrintModAfterOpts` - print the whole module just before we pass it to Enzyme -`PrintModAfterEnzyme` - print the module after Enzyme differentiated everything +`PrintModAfter` - print the module after Enzyme differentiated everything `LooseTypes` - Enzyme's loose type debug helper (can cause incorrect gradients) `Inline` - runs Enzyme specific Inlining -`NoModOptAfter` - do not optimize the module after Enzyme is done -`EnableFncOpt` - tell Enzyme to run LLVM Opts on each function it generated -`NoVecUnroll` - do not unroll vectorized loops `RuntimeActivity` - allow specifying activity at runtime diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md index bc58768611175..bfdb579cd3523 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md @@ -10,10 +10,11 @@ This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust. -For more information, see the corresponding typing rules for [Editions 2024 and later]. -On earlier Editions, the current behavior is unspecified. +For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md). +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md index 43de1849a5ebb..0c90cec0dbddb 100644 --- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md +++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md @@ -10,10 +10,11 @@ This feature is incomplete and not yet intended for general use. This implements experimental, Edition-dependent match ergonomics under consideration for inclusion in Rust. -For more information, see the corresponding typing rules for [Editions 2024 and later]. -On earlier Editions, the current behavior is unspecified. +For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for +[Editions 2024 and later]. For alternative experimental match ergonomics, see the feature [`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md). +[Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands index ef0c3740f0326..508296c3a5aec 100644 --- a/src/etc/lldb_commands +++ b/src/etc/lldb_commands @@ -1,43 +1,80 @@ -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)String$" --category Rust +# Forces test-compliant formatting to all other types +type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust +type summary add -F _ -e -x -h "^.*$" --category Rust +# Std String +type synthetic add -l lldb_lookup.StdStringSyntheticProvider -x "^(alloc::([a-z_]+::)+)String$" --category Rust +type summary add -F lldb_lookup.StdStringSummaryProvider -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust +# Std str type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?str$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust +## MSVC +type synthetic add -l lldb_lookup.MSVCStrSyntheticProvider -x "^ref(_mut)?\$$" --category Rust +type summary add -F lldb_lookup.StdStrSummaryProvider -e -h -x "^ref(_mut)?\$$" --category Rust +# Array type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?\\[.+\\]$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust +# Slice +## MSVC +type synthetic add -l lldb_lookup.MSVCStdSliceSyntheticProvider -x "^ref(_mut)?\$ >" --category Rust +type summary add -F lldb_lookup.StdSliceSummaryProvider -e -x -h "^ref(_mut)?\$ >" --category Rust +# OsString type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust +# Vec type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust +# VecDeque type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust +# BTreeSet type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust +# BTreeMap type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust +# HashMap type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust +# HashSet type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust +# Rc type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust +# Arc type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust +# Cell type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust +# RefCell type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^core::num::([a-z_]+::)*NonZero.+$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::([a-z_]+::)+)PathBuf$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust -type synthetic add -l lldb_lookup.synthetic_lookup -x "^(.*)$" --category Rust -type summary add -F _ -e -x -h "^.*$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeSet<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)BTreeMap<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashMap<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::collections::([a-z_]+::)+)HashSet<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Rc<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Arc<.+>$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Cell<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)Ref<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefMut<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)RefCell<.+>$" --category Rust +# NonZero +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust +type synthetic add -l lldb_lookup.synthetic_lookup -x "^core::num::([a-z_]+::)*NonZero.+$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(core::([a-z_]+::)+)NonZero<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^core::num::([a-z_]+::)*NonZero.+$" --category Rust +# PathBuf +type synthetic add -l lldb_lookup.synthetic_lookup -x "^(std::([a-z_]+::)+)PathBuf$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::([a-z_]+::)+)PathBuf$" --category Rust +# Path +type synthetic add -l lldb_lookup.synthetic_lookup -x "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?(std::([a-z_]+::)+)Path$" --category Rust +# Enum +## MSVC +type synthetic add -l lldb_lookup.MSVCEnumSyntheticProvider -x "^enum2\$<.+>$" --category Rust +type summary add -F lldb_lookup.MSVCEnumSummaryProvider -e -x -h "^enum2\$<.+>$" --category Rust +## MSVC Variants +type synthetic add -l lldb_lookup.synthetic_lookup -x "^enum2\$<.+>::.*$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^enum2\$<.+>::.*$" --category Rust +# Tuple +type synthetic add -l lldb_lookup.synthetic_lookup -x "^\(.*\)$" --category Rust +## MSVC +type synthetic add -l lldb_lookup.MSVCTupleSyntheticProvider -x "^tuple\$<.+>$" --category Rust +type summary add -F lldb_lookup.TupleSummaryProvider -e -x -h "^tuple\$<.+>$" --category Rust type category enable Rust diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 2f32ed833af1e..98426e4242398 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -1,14 +1,19 @@ +from __future__ import annotations import sys +from typing import List, TYPE_CHECKING from lldb import ( SBData, SBError, - SBValue, eBasicTypeLong, eBasicTypeUnsignedLong, eBasicTypeUnsignedChar, + eFormatChar, ) +if TYPE_CHECKING: + from lldb import SBValue, SBType, SBTypeStaticField + # from lldb.formatters import Logger #################################################################################################### @@ -127,6 +132,36 @@ def has_children(self) -> bool: return False +def get_template_args(type_name: str) -> list[str]: + """ + Takes a type name `T, D>` and returns a list of its generic args + `["A", "tuple$", "D"]`. + + String-based replacement for LLDB's `SBType.template_args`, as LLDB is currently unable to + populate this field for targets with PDB debug info. Also useful for manually altering the type + name of generics (e.g. `Vec` -> `Vec<&str>`). + + Each element of the returned list can be looked up for its `SBType` value via + `SBTarget.FindFirstType()` + """ + params = [] + level = 0 + start = 0 + for i, c in enumerate(type_name): + if c == "<": + level += 1 + if level == 1: + start = i + 1 + elif c == ">": + level -= 1 + if level == 0: + params.append(type_name[start:i].strip()) + elif c == "," and level == 1: + params.append(type_name[start:i].strip()) + start = i + 1 + return params + + def SizeSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: return "size=" + str(valobj.GetNumChildren()) @@ -141,11 +176,32 @@ def vec_to_string(vec: SBValue) -> str: ) -def StdStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: - # logger = Logger.Logger() - # logger >> "[StdStringSummaryProvider] for " + str(valobj.GetName()) - vec = valobj.GetChildAtIndex(0) - return '"%s"' % vec_to_string(vec) +def StdStringSummaryProvider(valobj, dict): + inner_vec = ( + valobj.GetNonSyntheticValue() + .GetChildMemberWithName("vec") + .GetNonSyntheticValue() + ) + + pointer = ( + inner_vec.GetChildMemberWithName("buf") + .GetChildMemberWithName("inner") + .GetChildMemberWithName("ptr") + .GetChildMemberWithName("pointer") + .GetChildMemberWithName("pointer") + ) + + length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned() + + if length <= 0: + return '""' + error = SBError() + process = pointer.GetProcess() + data = process.ReadMemory(pointer.GetValueAsUnsigned(), length, error) + if error.Success(): + return '"' + data.decode("utf8", "replace") + '"' + else: + raise Exception("ReadMemory error: %s", error.GetCString()) def StdOsStringSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: @@ -205,6 +261,31 @@ def StdPathSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: return '"%s"' % data +def sequence_formatter(output: str, valobj: SBValue, _dict: LLDBOpaque): + length: int = valobj.GetNumChildren() + + long: bool = False + for i in range(0, length): + if len(output) > 32: + long = True + break + + child: SBValue = valobj.GetChildAtIndex(i) + + summary = child.summary + if summary is None: + summary = child.value + if summary is None: + summary = "{...}" + output += f"{summary}, " + if long: + output = f"(len: {length}) " + output + "..." + else: + output = output[:-2] + + return output + + class StructSyntheticProvider: """Pretty-printer for structs and struct enum variants""" @@ -246,6 +327,89 @@ def has_children(self) -> bool: return True +class StdStringSyntheticProvider: + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + self.update() + + def update(self): + inner_vec = self.valobj.GetChildMemberWithName("vec").GetNonSyntheticValue() + self.data_ptr = ( + inner_vec.GetChildMemberWithName("buf") + .GetChildMemberWithName("inner") + .GetChildMemberWithName("ptr") + .GetChildMemberWithName("pointer") + .GetChildMemberWithName("pointer") + ) + self.length = inner_vec.GetChildMemberWithName("len").GetValueAsUnsigned() + self.element_type = self.data_ptr.GetType().GetPointeeType() + + def has_children(self) -> bool: + return True + + def num_children(self) -> int: + return self.length + + def get_child_index(self, name: str) -> int: + index = name.lstrip("[").rstrip("]") + if index.isdigit(): + return int(index) + + return -1 + + def get_child_at_index(self, index: int) -> SBValue: + if not 0 <= index < self.length: + return None + start = self.data_ptr.GetValueAsUnsigned() + address = start + index + element = self.data_ptr.CreateValueFromAddress( + f"[{index}]", address, self.element_type + ) + element.SetFormat(eFormatChar) + return element + + +class MSVCStrSyntheticProvider: + __slots__ = ["valobj", "data_ptr", "length"] + + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + self.update() + + def update(self): + self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr") + self.length = self.valobj.GetChildMemberWithName("length").GetValueAsUnsigned() + + def has_children(self) -> bool: + return True + + def num_children(self) -> int: + return self.length + + def get_child_index(self, name: str) -> int: + index = name.lstrip("[").rstrip("]") + if index.isdigit(): + return int(index) + + return -1 + + def get_child_at_index(self, index: int) -> SBValue: + if not 0 <= index < self.length: + return None + start = self.data_ptr.GetValueAsUnsigned() + address = start + index + element = self.data_ptr.CreateValueFromAddress( + f"[{index}]", address, self.data_ptr.GetType().GetPointeeType() + ) + return element + + def get_type_name(self): + if self.valobj.GetTypeName().startswith("ref_mut"): + return "&mut str" + else: + return "&str" + + class ClangEncodedEnumProvider: """Pretty-printer for 'clang-encoded' enums support implemented in LLDB""" @@ -308,6 +472,242 @@ def _getCurrentVariantIndex(self, all_variants: SBValue) -> int: return default_index +class MSVCEnumSyntheticProvider: + """ + Synthetic provider for sum-type enums on MSVC. For a detailed explanation of the internals, + see: + + https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs + """ + + __slots__ = ["valobj", "variant", "value"] + + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + self.variant: SBValue + self.value: SBValue + self.update() + + def update(self): + tag: SBValue = self.valobj.GetChildMemberWithName("tag") + + if tag.IsValid(): + tag: int = tag.GetValueAsUnsigned() + for child in self.valobj.GetNonSyntheticValue().children: + if not child.name.startswith("variant"): + continue + + variant_type: SBType = child.GetType() + try: + exact: SBTypeStaticField = variant_type.GetStaticFieldWithName( + "DISCR_EXACT" + ) + except AttributeError: + # LLDB versions prior to 19.0.0 do not have the `SBTypeGetStaticField` API. + # With current DI generation there's not a great way to provide a "best effort" + # evaluation either, so we just return the object itself with no further + # attempts to inspect the type information + self.variant = self.valobj + self.value = self.valobj + return + + if exact.IsValid(): + discr: int = exact.GetConstantValue( + self.valobj.target + ).GetValueAsUnsigned() + if tag == discr: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + else: # if invalid, DISCR must be a range + begin: int = ( + variant_type.GetStaticFieldWithName("DISCR_BEGIN") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + end: int = ( + variant_type.GetStaticFieldWithName("DISCR_END") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + + # begin isn't necessarily smaller than end, so we must test for both cases + if begin < end: + if begin <= tag <= end: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + else: + if tag >= begin or tag <= end: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + else: # if invalid, tag is a 128 bit value + tag_lo: int = self.valobj.GetChildMemberWithName( + "tag128_lo" + ).GetValueAsUnsigned() + tag_hi: int = self.valobj.GetChildMemberWithName( + "tag128_hi" + ).GetValueAsUnsigned() + + tag: int = (tag_hi << 64) | tag_lo + + for child in self.valobj.GetNonSyntheticValue().children: + if not child.name.startswith("variant"): + continue + + variant_type: SBType = child.GetType() + exact_lo: SBTypeStaticField = variant_type.GetStaticFieldWithName( + "DISCR128_EXACT_LO" + ) + + if exact_lo.IsValid(): + exact_lo: int = exact_lo.GetConstantValue( + self.valobj.target + ).GetValueAsUnsigned() + exact_hi: int = ( + variant_type.GetStaticFieldWithName("DISCR128_EXACT_HI") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + + discr: int = (exact_hi << 64) | exact_lo + if tag == discr: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + else: # if invalid, DISCR must be a range + begin_lo: int = ( + variant_type.GetStaticFieldWithName("DISCR128_BEGIN_LO") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + begin_hi: int = ( + variant_type.GetStaticFieldWithName("DISCR128_BEGIN_HI") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + + end_lo: int = ( + variant_type.GetStaticFieldWithName("DISCR128_END_LO") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + end_hi: int = ( + variant_type.GetStaticFieldWithName("DISCR128_END_HI") + .GetConstantValue(self.valobj.target) + .GetValueAsUnsigned() + ) + + begin = (begin_hi << 64) | begin_lo + end = (end_hi << 64) | end_lo + + # begin isn't necessarily smaller than end, so we must test for both cases + if begin < end: + if begin <= tag <= end: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + else: + if tag >= begin or tag <= end: + self.variant = child + self.value = child.GetChildMemberWithName( + "value" + ).GetSyntheticValue() + return + + def num_children(self) -> int: + return self.value.GetNumChildren() + + def get_child_index(self, name: str) -> int: + return self.value.GetIndexOfChildWithName(name) + + def get_child_at_index(self, index: int) -> SBValue: + return self.value.GetChildAtIndex(index) + + def has_children(self) -> bool: + return self.value.MightHaveChildren() + + def get_type_name(self) -> str: + name = self.valobj.GetTypeName() + # remove "enum2$<", str.removeprefix() is python 3.9+ + name = name[7:] + + # MSVC misinterprets ">>" as a shift operator, so spaces are inserted by rust to + # avoid that + if name.endswith(" >"): + name = name[:-2] + elif name.endswith(">"): + name = name[:-1] + + return name + + +def MSVCEnumSummaryProvider(valobj: SBValue, _dict: LLDBOpaque) -> str: + enum_synth = MSVCEnumSyntheticProvider(valobj.GetNonSyntheticValue(), _dict) + variant_names: SBType = valobj.target.FindFirstType( + f"{enum_synth.valobj.GetTypeName()}::VariantNames" + ) + try: + name_idx = ( + enum_synth.variant.GetType() + .GetStaticFieldWithName("NAME") + .GetConstantValue(valobj.target) + .GetValueAsUnsigned() + ) + except AttributeError: + # LLDB versions prior to 19 do not have the `SBTypeGetStaticField` API, and have no way + # to determine the value based on the tag field. + tag: SBValue = valobj.GetChildMemberWithName("tag") + + if tag.IsValid(): + discr: int = tag.GetValueAsUnsigned() + return "".join(["{tag = ", str(tag.unsigned), "}"]) + else: + tag_lo: int = valobj.GetChildMemberWithName( + "tag128_lo" + ).GetValueAsUnsigned() + tag_hi: int = valobj.GetChildMemberWithName( + "tag128_hi" + ).GetValueAsUnsigned() + + discr: int = (tag_hi << 64) | tag_lo + + return "".join(["{tag = ", str(discr), "}"]) + + name: str = variant_names.enum_members[name_idx].name + + if enum_synth.num_children() == 0: + return name + + child_name: str = enum_synth.value.GetChildAtIndex(0).name + if child_name == "0" or child_name == "__0": + # enum variant is a tuple struct + return name + TupleSummaryProvider(enum_synth.value, _dict) + else: + # enum variant is a regular struct + var_list = ( + str(enum_synth.value.GetNonSyntheticValue()).split("= ", 1)[1].splitlines() + ) + vars = [x.strip() for x in var_list if x not in ("{", "}")] + if vars[0][0] == "(": + vars[0] = vars[0][1:] + if vars[-1][-1] == ")": + vars[-1] = vars[-1][:-1] + + return f"{name}{{{', '.join(vars)}}}" + + class TupleSyntheticProvider: """Pretty-printer for tuples and tuple enum variants""" @@ -348,6 +748,50 @@ def has_children(self) -> bool: return True +class MSVCTupleSyntheticProvider: + __slots__ = ["valobj"] + + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): + self.valobj = valobj + + def num_children(self) -> int: + return self.valobj.GetNumChildren() + + def get_child_index(self, name: str) -> int: + return self.valobj.GetIndexOfChildWithName(name) + + def get_child_at_index(self, index: int) -> SBValue: + child: SBValue = self.valobj.GetChildAtIndex(index) + return child.CreateChildAtOffset(str(index), 0, child.GetType()) + + def update(self): + pass + + def has_children(self) -> bool: + return self.valobj.MightHaveChildren() + + def get_type_name(self) -> str: + name = self.valobj.GetTypeName() + # remove "tuple$<" and ">", str.removeprefix and str.removesuffix require python 3.9+ + name = name[7:-1] + return "(" + name + ")" + + +def TupleSummaryProvider(valobj: SBValue, _dict: LLDBOpaque): + output: List[str] = [] + + for i in range(0, valobj.GetNumChildren()): + child: SBValue = valobj.GetChildAtIndex(i) + summary = child.summary + if summary is None: + summary = child.value + if summary is None: + summary = "{...}" + output.append(summary) + + return "(" + ", ".join(output) + ")" + + class StdVecSyntheticProvider: """Pretty-printer for alloc::vec::Vec @@ -396,6 +840,11 @@ def update(self): ) self.element_type = self.valobj.GetType().GetTemplateArgumentType(0) + + if not self.element_type.IsValid(): + element_name = get_template_args(self.valobj.GetTypeName())[0] + self.element_type = self.valobj.target.FindFirstType(element_name) + self.element_type_size = self.element_type.GetByteSize() def has_children(self) -> bool: @@ -403,6 +852,8 @@ def has_children(self) -> bool: class StdSliceSyntheticProvider: + __slots__ = ["valobj", "length", "data_ptr", "element_type", "element_size"] + def __init__(self, valobj: SBValue, _dict: LLDBOpaque): self.valobj = valobj self.update() @@ -419,7 +870,7 @@ def get_child_index(self, name: str) -> int: def get_child_at_index(self, index: int) -> SBValue: start = self.data_ptr.GetValueAsUnsigned() - address = start + index * self.element_type_size + address = start + index * self.element_size element = self.data_ptr.CreateValueFromAddress( "[%s]" % index, address, self.element_type ) @@ -430,12 +881,34 @@ def update(self): self.data_ptr = self.valobj.GetChildMemberWithName("data_ptr") self.element_type = self.data_ptr.GetType().GetPointeeType() - self.element_type_size = self.element_type.GetByteSize() + self.element_size = self.element_type.GetByteSize() def has_children(self) -> bool: return True +class MSVCStdSliceSyntheticProvider(StdSliceSyntheticProvider): + def get_type_name(self) -> str: + name = self.valobj.GetTypeName() + + if name.startswith("ref_mut"): + # remove "ref_mut$ >" + name = name[17:-3] + ref = "&mut " + else: + # remove "ref$ >" + name = name[13:-3] + ref = "&" + + return "".join([ref, "[", name, "]"]) + + +def StdSliceSummaryProvider(valobj, dict): + output = sequence_formatter("[", valobj, dict) + output += "]" + return output + + class StdVecDequeSyntheticProvider: """Pretty-printer for alloc::collections::vec_deque::VecDeque @@ -627,7 +1100,16 @@ def update(self): ctrl = inner_table.GetChildMemberWithName("ctrl").GetChildAtIndex(0) self.size = inner_table.GetChildMemberWithName("items").GetValueAsUnsigned() - self.pair_type = table.type.template_args[0] + + template_args = table.type.template_args + + if template_args is None: + type_name = table.GetTypeName() + args = get_template_args(type_name) + self.pair_type = self.valobj.target.FindFirstType(args[0]) + else: + self.pair_type = template_args[0] + if self.pair_type.IsTypedefType(): self.pair_type = self.pair_type.GetTypedefedType() self.pair_type_size = self.pair_type.GetByteSize() diff --git a/src/etc/rust_analyzer_zed.json b/src/etc/rust_analyzer_zed.json new file mode 100644 index 0000000000000..469ea0506218f --- /dev/null +++ b/src/etc/rust_analyzer_zed.json @@ -0,0 +1,52 @@ +{ + "lsp": { + "rust-analyzer": { + "initialization_options": { + "cargo": { + "buildScripts": { + "enable": true, + "invocationLocation": "root", + "invocationStrategy": "once", + "overrideCommand": ["python3", "x.py", "check", "--json-output"] + }, + "extraEnv": { + "RUSTC_BOOTSTRAP": "1" + }, + "sysrootSrc": "./library" + }, + "check": { + "invocationLocation": "root", + "invocationStrategy": "once", + "overrideCommand": ["python3", "x.py", "check", "--json-output"] + }, + "linkedProjects": [ + "Cargo.toml", + "library/Cargo.toml", + "src/tools/x/Cargo.toml", + "src/bootstrap/Cargo.toml", + "src/tools/rust-analyzer/Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml" + ], + "procMacro": { + "enable": true, + "server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv" + }, + "rustc": { + "source": "./Cargo.toml" + }, + "rustfmt": { + "overrideCommand": [ + "${workspaceFolder}/build/host/rustfmt/bin/rustfmt", + "--edition=2021" + ] + }, + "server": { + "extraEnv": { + "RUSTUP_TOOLCHAIN": "nightly" + } + } + } + } + } +} diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index c593cdcbcd225..c07cc4dc347aa 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -13,7 +13,7 @@ rinja = { version = "0.3", default-features = false, features = ["config"] } base64 = "0.21.7" itertools = "0.12" indexmap = "2" -minifier = { version = "0.3.4", default-features = false } +minifier = { version = "0.3.5", default-features = false } pulldown-cmark-old = { version = "0.9.6", package = "pulldown-cmark", default-features = false } regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 92ef3ab7a1d47..dcc5fd12d81bf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1150,9 +1150,9 @@ fn clean_args_from_types_and_body_id<'tcx>( Arguments { values: types .iter() - .enumerate() - .map(|(i, ty)| Argument { - name: name_from_pat(body.params[i].pat), + .zip(body.params) + .map(|(ty, param)| Argument { + name: name_from_pat(param.pat), type_: clean_ty(ty, cx), is_const: false, }) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8b424499724b8..fc7c4b42047db 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2121,7 +2121,7 @@ impl Discriminant { /// simplified pub(crate) fn expr(&self, tcx: TyCtxt<'_>) -> Option { self.expr - .map(|body| rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body))) + .map(|body| rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body))) } pub(crate) fn value(&self, tcx: TyCtxt<'_>, with_underscores: bool) -> String { print_evaluated_const(tcx, self.value, with_underscores, false).unwrap() @@ -2417,7 +2417,7 @@ impl ConstantKind { ConstantKind::Path { ref path } => path.to_string(), ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id), ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => { - rendered_const(tcx, tcx.hir_body(body), tcx.hir().body_owner_def_id(body)) + rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body)) } ConstantKind::Infer { .. } => "_".to_string(), } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 8a7d140bb1a69..34656b26ce28c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -1,5 +1,5 @@ use std::assert_matches::debug_assert_matches; -use std::fmt::Write as _; +use std::fmt::{self, Display, Write as _}; use std::mem; use std::sync::LazyLock as Lazy; @@ -24,6 +24,7 @@ use crate::clean::{ clean_middle_ty, inline, }; use crate::core::DocContext; +use crate::display::Joined as _; #[cfg(test)] mod tests; @@ -250,16 +251,20 @@ pub(crate) fn qpath_to_string(p: &hir::QPath<'_>) -> String { hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(), }; - let mut s = String::new(); - for (i, seg) in segments.iter().enumerate() { - if i > 0 { - s.push_str("::"); - } - if seg.ident.name != kw::PathRoot { - s.push_str(seg.ident.as_str()); - } - } - s + fmt::from_fn(|f| { + segments + .iter() + .map(|seg| { + fmt::from_fn(|f| { + if seg.ident.name != kw::PathRoot { + write!(f, "{}", seg.ident)?; + } + Ok(()) + }) + }) + .joined("::", f) + }) + .to_string() } pub(crate) fn build_deref_target_impls( @@ -299,35 +304,49 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { Symbol::intern(&match p.kind { // FIXME(never_patterns): does this make sense? - PatKind::Wild | PatKind::Err(_) | PatKind::Never | PatKind::Struct(..) => { + PatKind::Wild + | PatKind::Err(_) + | PatKind::Never + | PatKind::Struct(..) + | PatKind::Range(..) => { return kw::Underscore; } PatKind::Binding(_, _, ident, _) => return ident.name, + PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), PatKind::TupleStruct(ref p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), PatKind::Or(pats) => { - pats.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(" | ") + fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string() + } + PatKind::Tuple(elts, _) => { + format!("({})", fmt::from_fn(|f| elts.iter().map(|p| name_from_pat(p)).joined(", ", f))) } - PatKind::Tuple(elts, _) => format!( - "({})", - elts.iter().map(|p| name_from_pat(p).to_string()).collect::>().join(", ") - ), - PatKind::Box(p) => return name_from_pat(p), PatKind::Deref(p) => format!("deref!({})", name_from_pat(p)), - PatKind::Ref(p, _) => return name_from_pat(p), PatKind::Expr(..) => { warn!( "tried to get argument name from PatKind::Expr, which is silly in function arguments" ); return Symbol::intern("()"); } - PatKind::Guard(p, _) => return name_from_pat(p), - PatKind::Range(..) => return kw::Underscore, - PatKind::Slice(begin, ref mid, end) => { - let begin = begin.iter().map(|p| name_from_pat(p).to_string()); - let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(p))).into_iter(); - let end = end.iter().map(|p| name_from_pat(p).to_string()); - format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) + PatKind::Slice(begin, mid, end) => { + fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { + fmt::from_fn(move |f| { + if wild { + f.write_str("..")?; + } + name_from_pat(pat).fmt(f) + }) + } + + format!( + "[{}]", + fmt::from_fn(|f| { + let begin = begin.iter().map(|p| print_pat(p, false)); + let mid = mid.map(|p| print_pat(p, true)); + let end = end.iter().map(|p| print_pat(p, false)); + begin.chain(mid).chain(end).joined(", ", f) + }) + ) } }) } @@ -336,7 +355,7 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { - rendered_const(cx.tcx, cx.tcx.hir().body_owned_by(def), def) + rendered_const(cx.tcx, cx.tcx.hir_body_owned_by(def), def) } else { inline::print_inlined_const(cx.tcx, def) }; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1ead87fd69da2..757a2a6e0dd06 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -304,8 +304,7 @@ pub(crate) fn create_config( return tcx.typeck(typeck_root_def_id); } - let hir = tcx.hir(); - let body = hir.body_owned_by(def_id); + let body = tcx.hir_body_owned_by(def_id); debug!("visiting body for {def_id:?}"); EmitIgnoredResolutionErrors::new(tcx).visit_body(body); (rustc_interface::DEFAULT_QUERY_PROVIDERS.typeck)(tcx, def_id) @@ -335,14 +334,14 @@ pub(crate) fn run_global_ctxt( // NOTE: These are copy/pasted from typeck/lib.rs and should be kept in sync with those changes. let _ = tcx.sess.time("wf_checking", || { - tcx.hir().try_par_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module)) + tcx.try_par_hir_for_each_module(|module| tcx.ensure_ok().check_mod_type_wf(module)) }); tcx.dcx().abort_if_errors(); tcx.sess.time("missing_docs", || rustc_lint::check_crate(tcx)); tcx.sess.time("check_mod_attrs", || { - tcx.hir().for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module)) + tcx.hir_for_each_module(|module| tcx.ensure_ok().check_mod_attrs(module)) }); rustc_passes::stability::check_unused_or_stable_features(tcx); diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index d89caabefe3e0..4792bc525a592 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -1,6 +1,7 @@ //! Logic for transforming the raw code given by the user into something actually //! runnable, e.g. by adding a `main` function if it doesn't already exist. +use std::fmt::{self, Write as _}; use std::io; use std::sync::Arc; @@ -17,6 +18,7 @@ use rustc_span::symbol::sym; use tracing::debug; use super::GlobalTestOptions; +use crate::display::Joined as _; use crate::html::markdown::LangString; /// This struct contains information about the doctest itself which is then used to generate @@ -232,13 +234,15 @@ impl DocTestBuilder { // add extra 4 spaces for each line to offset the code block if opts.insert_indent_space { - prog.push_str( - &everything_else + write!( + prog, + "{}", + fmt::from_fn(|f| everything_else .lines() - .map(|line| format!(" {}", line)) - .collect::>() - .join("\n"), - ); + .map(|line| fmt::from_fn(move |f| write!(f, " {line}"))) + .joined("\n", f)) + ) + .unwrap(); } else { prog.push_str(everything_else); }; diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index 0d52e21419fcf..1ac3c040b5918 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -81,7 +81,7 @@ impl<'tcx> HirCollector<'tcx> { pub fn collect_crate(mut self) -> Vec { let tcx = self.tcx; self.visit_testable("".to_string(), CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID), |this| { - tcx.hir().walk_toplevel_module(this) + tcx.hir_walk_toplevel_module(this) }); self.collector.tests } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d2d7415261b9f..f320114703996 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -2,7 +2,6 @@ use std::cmp::Ordering; use std::fmt; use std::fmt::Display; -use itertools::Itertools; use rinja::Template; use rustc_abi::VariantIdx; use rustc_data_structures::captures::Captures; @@ -514,11 +513,7 @@ fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[cl class = myitem.type_(), unsafety_flag = unsafety_flag, href = item_path(myitem.type_(), myitem.name.unwrap().as_str()), - title = [myitem.type_().to_string(), full_path(cx, myitem)] - .iter() - .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) - .collect::>() - .join(" "), + title = format_args!("{} {}", myitem.type_(), full_path(cx, myitem)), ), ); } @@ -915,7 +910,7 @@ fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w, format_args!( "
At least one of the `{}` methods is required.
", - list.iter().join("`, `") + fmt::from_fn(|f| list.iter().joined("`, `", f)) ), ); } @@ -1168,17 +1163,18 @@ fn item_trait(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra js_src_path.extend(cx.current.iter().copied()); js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); } - let extern_crates = extern_crates - .into_iter() - .map(|cnum| tcx.crate_name(cnum).to_string()) - .collect::>() - .join(","); - let (extern_before, extern_after) = - if extern_crates.is_empty() { ("", "") } else { (" data-ignore-extern-crates=\"", "\"") }; + let extern_crates = fmt::from_fn(|f| { + if !extern_crates.is_empty() { + f.write_str(" data-ignore-extern-crates=\"")?; + extern_crates.iter().map(|&cnum| tcx.crate_name(cnum)).joined(",", f)?; + f.write_str("\"")?; + } + Ok(()) + }); write_str( w, format_args!( - "", + "", src = js_src_path.finish() ), ); @@ -1400,7 +1396,7 @@ fn item_type_alias(w: &mut String, cx: &Context<'_>, it: &clean::Item, t: &clean .collect(); js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied()); js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap())); - let self_path = self_fqp.iter().map(Symbol::as_str).collect::>().join("::"); + let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f)); write_str( w, format_args!( diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 50c09b98db441..64dbaf9083e70 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::cmp::Ordering; use rinja::Template; use rustc_data_structures::fx::FxHashSet; @@ -12,6 +13,7 @@ use crate::clean; use crate::formats::Impl; use crate::formats::item_type::ItemType; use crate::html::markdown::{IdMap, MarkdownWithToc}; +use crate::html::render::print_item::compare_names; #[derive(Clone, Copy)] pub(crate) enum ModuleLike { @@ -77,7 +79,7 @@ impl<'a> LinkBlock<'a> { } /// A link to an item. Content should not be escaped. -#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)] +#[derive(Ord, PartialEq, Eq, Hash, Clone)] pub(crate) struct Link<'a> { /// The content for the anchor tag and title attr name: Cow<'a, str>, @@ -89,6 +91,20 @@ pub(crate) struct Link<'a> { children: Vec>, } +impl PartialOrd for Link<'_> { + fn partial_cmp(&self, other: &Link<'_>) -> Option { + match compare_names(&self.name, &other.name) { + Ordering::Equal => (), + result => return Some(result), + } + (&self.name_html, &self.href, &self.children).partial_cmp(&( + &other.name_html, + &other.href, + &other.children, + )) + } +} + impl<'a> Link<'a> { pub fn new(href: impl Into>, name: impl Into>) -> Self { Self { href: href.into(), name: name.into(), children: vec![], name_html: None } diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index fa2465c1926e0..ce9c42c01cc73 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -51,7 +51,7 @@ pub(crate) fn collect_spans_and_sources( let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() }; if generate_link_to_definition { - tcx.hir().walk_toplevel_module(&mut visitor); + tcx.hir_walk_toplevel_module(&mut visitor); } let sources = sources::collect_local_sources(tcx, src_root, krate); (sources, visitor.matches) @@ -173,18 +173,18 @@ impl SpanMapVisitor<'_> { } fn infer_id(&mut self, hir_id: HirId, expr_hir_id: Option, span: Span) { - let hir = self.tcx.hir(); - let body_id = hir.enclosing_body_owner(hir_id); + let tcx = self.tcx; + let body_id = tcx.hir_enclosing_body_owner(hir_id); // FIXME: this is showing error messages for parts of the code that are not // compiled (because of cfg)! // // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 - let typeck_results = self.tcx.typeck_body(hir.body_owned_by(body_id).id()); + let typeck_results = tcx.typeck_body(tcx.hir_body_owned_by(body_id).id()); // Interestingly enough, for method calls, we need the whole expression whereas for static // method/function calls, we need the call expression specifically. if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) { let link = if def_id.as_local().is_some() { - LinkFromSrc::Local(rustc_span(def_id, self.tcx)) + LinkFromSrc::Local(rustc_span(def_id, tcx)) } else { LinkFromSrc::External(def_id) }; @@ -288,7 +288,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { | ItemKind::Use(_, _) | ItemKind::ExternCrate(_) | ItemKind::ForeignMod { .. } - | ItemKind::GlobalAsm(_) + | ItemKind::GlobalAsm { .. } // We already have "visit_mod" above so no need to check it here. | ItemKind::Mod(_) => {} } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index bef59469179cc..9606ba76991a7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -846,7 +846,7 @@ fn convert_static( is_unsafe: safety.is_unsafe(), expr: stat .expr - .map(|e| rendered_const(tcx, tcx.hir_body(e), tcx.hir().body_owner_def_id(e))) + .map(|e| rendered_const(tcx, tcx.hir_body(e), tcx.hir_body_owner_def_id(e))) .unwrap_or_default(), } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e4acbcf2c626f..1f2f8f7d33a4a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -13,7 +13,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] -#![feature(os_str_display)] #![feature(round_char_boundary)] #![feature(test)] #![feature(type_alias_impl_trait)] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 9fe8b99e8af87..97e6d3146427c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1983,7 +1983,7 @@ fn resolution_failure( .tcx .resolutions(()) .all_macro_rules - .contains_key(&Symbol::intern(path_str)) + .contains(&Symbol::intern(path_str)) { diag.note(format!( "`macro_rules` named `{path_str}` exists in this crate, \ diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index dd9dbd7170e50..44551d75903da 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -135,8 +135,7 @@ where // If we visit an item that contains an expression outside a function body, // then we need to exit before calling typeck (which will panic). See // test/run-make/rustdoc-scrape-examples-invalid-expr for an example. - let hir = tcx.hir(); - if hir.maybe_body_owned_by(ex.hir_id.owner.def_id).is_none() { + if tcx.hir_maybe_body_owned_by(ex.hir_id.owner.def_id).is_none() { return; } @@ -178,7 +177,7 @@ where // If the enclosing item has a span coming from a proc macro, then we also don't want to // include the example. let enclosing_item_span = - tcx.hir().span_with_body(tcx.hir().get_parent_item(ex.hir_id).into()); + tcx.hir().span_with_body(tcx.hir_get_parent_item(ex.hir_id).into()); if enclosing_item_span.from_expansion() { trace!("Rejecting expr ({call_span:?}) from macro item: {enclosing_item_span:?}"); return; @@ -302,7 +301,7 @@ pub(crate) fn run( // Run call-finder on all items let mut calls = FxIndexMap::default(); let mut finder = FindCalls { calls: &mut calls, cx, target_crates, bin_crate }; - tcx.hir().visit_all_item_likes_in_crate(&mut finder); + tcx.hir_visit_all_item_likes_in_crate(&mut finder); // The visitor might have found a type error, which we need to // promote to a fatal error diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f606a3d8a9270..7b6921afa0808 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } // If we're inlining, skip private items. _ if self.inlining && !is_pub => {} - hir::ItemKind::GlobalAsm(..) => {} + hir::ItemKind::GlobalAsm { .. } => {} hir::ItemKind::Use(_, hir::UseKind::ListStem) => {} hir::ItemKind::Use(path, kind) => { for &res in &path.res { diff --git a/src/llvm-project b/src/llvm-project index 7e8c93c87c611..92e80685d0d5d 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 7e8c93c87c611f21d9bd95100563392f4c18bfe7 +Subproject commit 92e80685d0d5dcea3ccf321995c43b72338639c6 diff --git a/src/stage0 b/src/stage0 index 5c3e3a7cebcc7..9d6a08d378d8e 100644 --- a/src/stage0 +++ b/src/stage0 @@ -13,469 +13,469 @@ nightly_branch=master # # All changes below this comment will be overridden the next time the # tool is executed. - -compiler_date=2025-02-08 + +compiler_date=2025-02-18 compiler_version=beta -rustfmt_date=2025-02-08 +rustfmt_date=2025-02-18 rustfmt_version=nightly -dist/2025-02-08/rustc-beta-aarch64-apple-darwin.tar.gz=ca5440402ebfd3ba7ce3b30ecbcdc3e9341861996a5dd51601de3131d62d0bc2 -dist/2025-02-08/rustc-beta-aarch64-apple-darwin.tar.xz=bb7c79e5adb6998ac3a57ae7434a247029777bf3e1687c51ff3fdca938b72b3d -dist/2025-02-08/rustc-beta-aarch64-pc-windows-msvc.tar.gz=596a586332d87beaf3d52fead6e6c286a1da6abc89b53da5f6874f5da134cded -dist/2025-02-08/rustc-beta-aarch64-pc-windows-msvc.tar.xz=6828f88d3d576cdea838d975e0dc61ae2daf32746d7dbefce07f12684f5c0d97 -dist/2025-02-08/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=86943f595d3ad4b4ee5b7c9db63df9addf9c5e50e25267f64daa504dc4bb63b6 -dist/2025-02-08/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=13449944b13c4a8ef9aae649e1edf0bfbedc9816f7f32445ce9623098a21e51d -dist/2025-02-08/rustc-beta-aarch64-unknown-linux-musl.tar.gz=ce7fc3bed538a938f11b1cc15da20dc7d68097cf7d68a37ecc969c225bf5dcaf -dist/2025-02-08/rustc-beta-aarch64-unknown-linux-musl.tar.xz=a3b77720f7ff2a4707ecf44cab11ef088c3903ed6e123de14237b2149858f1a0 -dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a9f02a5eb65c85f98b73dfd88ef4eb48e6782455b3ccb77032b2df5bbfa39e84 -dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=93c5ad3bcb8473a7ec0dcc81b788436c9881c9d9c276906dc09bada56b45180c -dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=90f46141b9590ad69f60ffabdceb262e0940081994bda97a74692b76fd5cf8c0 -dist/2025-02-08/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=364a0b19dd91fe47c7152bd5a495d5ebf10170e4e5896859b02aef81225fc72e -dist/2025-02-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=977901c4eaf17b2acc8f7b7dd4e2efe5c45b45f5763f94b2ca36beadcc1544fc -dist/2025-02-08/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=4f60ec3e8a48c97a98567338be479499dbfb48db328d3d208763a8e6ad36e80d -dist/2025-02-08/rustc-beta-i686-pc-windows-gnu.tar.gz=ab1f6cf30ac8abf6dd130144355b79510633b24b06b416d82ba1fbccd318c2e5 -dist/2025-02-08/rustc-beta-i686-pc-windows-gnu.tar.xz=68327052940d99080217450553c42f3df81507385b5b90734c9b41a57e601ec6 -dist/2025-02-08/rustc-beta-i686-pc-windows-msvc.tar.gz=479053067ce64241d06a09d88b23cfb3da6dbcff46b5e8e33c2c1797ecdefb19 -dist/2025-02-08/rustc-beta-i686-pc-windows-msvc.tar.xz=12a4286b430fdd49e8806aa98a4395fc2ded6eae5ca254fb2cddc2c6db2cd893 -dist/2025-02-08/rustc-beta-i686-unknown-linux-gnu.tar.gz=865d88d2a9bb177851e901a56c5b3a295aa4ecdec8f73c72d4f9914b2e4aac60 -dist/2025-02-08/rustc-beta-i686-unknown-linux-gnu.tar.xz=3f17f91cd666e59efd5a47c2db28af8eee0d89d4ebbc6263f005e1d8d7d5b839 -dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=a1c42bc975d9ccd10771aa83874d0ea382780a8a925016d966d50084fb45c267 -dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=5452b62e9cccb5dac1cd36b01d31b11ac97c85bf4f82a559a15a08c278061d78 -dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=eb9d9ac867835710ef4dd301aed0afbfeb4221c818ef4d7f70f4bb2b5bc02790 -dist/2025-02-08/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=0afbff667ada4671511c48d6c5558009f395f3c2f3ad3d10c716882f6c9860f6 -dist/2025-02-08/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=db77ef515643b4ced71ab9ffce80338fe99b03abd6b7672f627f38e33e6642d9 -dist/2025-02-08/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=cac3b683fb606be111d5788b1a4194ec0ea77e0226350454cb7d1904d6f2f78e -dist/2025-02-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=a86bb2a0cd6f2c25f6f6c55b070a3f841c0a006588f759d0aa7c8d6b3401d904 -dist/2025-02-08/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=050e07098291a659baa3fb31e2a83c7e6e203614139dab3f3eb2c486c20b9f8b -dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=c20d1b649bb28b8abba4a5dd8e881a03061ebe091e5cdbc44310706fc76b55b0 -dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=24c742968242e5bb3d81b865c0fdfdb021772a40fe4d25f3b83fdcf8ccb087bd -dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=2aa9e78148c44ae2c01f554449811993e592aa9c428de37fbdb42dead53eb60c -dist/2025-02-08/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=2e6751dacf4ce4a60c61e1fa8afb746ac38285c62e567df78f2de27ce25e5770 -dist/2025-02-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=d0d365fdba806bda1263767d40365da7b5c2e5d01cfe6e9e4c5a2fd66ad4608a -dist/2025-02-08/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fef429294c81caa19fc0dac00eda00d55c087e94c7235e032b17c2b4f5556850 -dist/2025-02-08/rustc-beta-s390x-unknown-linux-gnu.tar.gz=75ea2ad9e2377d09c9517a932126f876eaf377ff0f38a382187bb4a8c31be34e -dist/2025-02-08/rustc-beta-s390x-unknown-linux-gnu.tar.xz=908e6fff603ef6d0721efc24e8faf014f5cafa71fc0220da4dac5c870b974c04 -dist/2025-02-08/rustc-beta-x86_64-apple-darwin.tar.gz=ccea051b3787d3682258edcfa6a35f2d7a44ac5c3d8117fcd55cc0a97e7b9b92 -dist/2025-02-08/rustc-beta-x86_64-apple-darwin.tar.xz=3555ff1e179da6a249861086c8986039ab7dcdcf581beb1f27246f987da436f6 -dist/2025-02-08/rustc-beta-x86_64-pc-windows-gnu.tar.gz=227da932cd028d2c2415f4df4c14daf225e2a917a0879e1debcee2b8ebbfc790 -dist/2025-02-08/rustc-beta-x86_64-pc-windows-gnu.tar.xz=231c0fb2989746424f8ad394e9015ef13a6b991a50f62009e7bca3e010e9320e -dist/2025-02-08/rustc-beta-x86_64-pc-windows-msvc.tar.gz=b75be89ce511758f7b9ab6b5701155349e5675e4b85975c33a91483d78666927 -dist/2025-02-08/rustc-beta-x86_64-pc-windows-msvc.tar.xz=bf529ca4409fefe3d38e2b0ee6b3102e9f8b7ace4352bea7e6d3148a84e98767 -dist/2025-02-08/rustc-beta-x86_64-unknown-freebsd.tar.gz=e2dcaf33887031f8d169ab734f3b3eb6858e5247097e46293c11ba1a2887a919 -dist/2025-02-08/rustc-beta-x86_64-unknown-freebsd.tar.xz=2cf5c49c04e57bcc34ada76ff22dd149c4d643b5af5766267663f2e0e4031d17 -dist/2025-02-08/rustc-beta-x86_64-unknown-illumos.tar.gz=c7572379985941a513b7b9e750043a74097655600cb34cb0460a34a5587b7e0d -dist/2025-02-08/rustc-beta-x86_64-unknown-illumos.tar.xz=4e98bbcbae02618c3f95a21fdb22b4e067ce0bacd8370076a1bf8107964d2896 -dist/2025-02-08/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=bcc22d77b53b54bcb95a5b92b19af7cf5d3e4b4418c3c9ed1d5ab9db3cd6c3a0 -dist/2025-02-08/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=8f3eb1b74e06bbdbf1d09e5df205677db6f6ff78e94f80fc1fd1441deed86f80 -dist/2025-02-08/rustc-beta-x86_64-unknown-linux-musl.tar.gz=ccd5ba2c7c7d8c8eeaae2f7c7b462945d7c7ac552d6175dd33c0b77ee3d6730b -dist/2025-02-08/rustc-beta-x86_64-unknown-linux-musl.tar.xz=ab198284a035b8b5ef584a925b5f7ef08228d1eeb43b17a33dab8c7ae93cbc96 -dist/2025-02-08/rustc-beta-x86_64-unknown-netbsd.tar.gz=5b52a1e3f591e6f65ac50d885cfa38e2bb655abc3db7f09ea860450b4b95d6e0 -dist/2025-02-08/rustc-beta-x86_64-unknown-netbsd.tar.xz=fad94b63a75e789df1e5d25e0bf44d1fc29146dea862006d5b1ffb5c20fdfc8d -dist/2025-02-08/rust-std-beta-aarch64-apple-darwin.tar.gz=19c355276bb12522f3c8e94e843e6e54434c66c4e2e49bf68e084d43e1c83350 -dist/2025-02-08/rust-std-beta-aarch64-apple-darwin.tar.xz=c05a1e3e86e2846c4322df02f9b02a1bf16edbf39d3394da56e1a8b3b36d9a60 -dist/2025-02-08/rust-std-beta-aarch64-apple-ios.tar.gz=ade5b194bd6b7737f505d201f6560ec3aeb41345ea692b2d262317fe0a3bfc38 -dist/2025-02-08/rust-std-beta-aarch64-apple-ios.tar.xz=026a233fab1b27e70dd1455a9a9a0f097d0617b720f82549a413bc4b2d9a2755 -dist/2025-02-08/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=fe743c3895565a7e641b8727a0e96172e0a735bb77f9ced18e201f54d5bab19e -dist/2025-02-08/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=66fd5b769ae7f0e4dd587fdf81ac31cb780cd20eadd082ef0252d7346354bfdb -dist/2025-02-08/rust-std-beta-aarch64-apple-ios-sim.tar.gz=ccc55643bde9f89be185b560e44d379ef85a0cc7f087f2f2bf7738d523b7a32d -dist/2025-02-08/rust-std-beta-aarch64-apple-ios-sim.tar.xz=b1d4c3de214fa207e987742ab73d316537ad9856eb3499d046f6aea4e9d3bc0c -dist/2025-02-08/rust-std-beta-aarch64-linux-android.tar.gz=b17466c9da602c1c282826bdd878e6ba4592906f74b0e8bbe3df302c2358ede4 -dist/2025-02-08/rust-std-beta-aarch64-linux-android.tar.xz=4addf9a4ed3ae4c80b097027fef7237261d2e9ada641e549cc91595c83614d6e -dist/2025-02-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=391f0b460feb164d29ed222b322380586743b19ab03c217690e8053e22903d3e -dist/2025-02-08/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=d81567dc4e204f7080854d0a3a7e7e16424758ff122dfc14448fa9da630932aa -dist/2025-02-08/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=91ff95f6a56ee5db99e72b293ea2048be0fd5ac3788bd32d9fc97337e7ee8b68 -dist/2025-02-08/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d6eb64cdaa12fcc469687f99d03a30329847e89bf802361bb6acd61f65b0547e -dist/2025-02-08/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c9f43315d352ecddbc18a9034723c58d5d8ec77fffa9e0e82322743d162e3db7 -dist/2025-02-08/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=2356a2902f91323d1492ef12fa2f17d1e4934748cec03d6621d6ecfe272f1c3e -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=ccc8c1777dc8d2e04d4d0640ece7b7820a8fea60a0fe371efcaa055972dcd7b3 -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=4208ef48af14c5feee97c16fe7e894777a479492760dc0eb838febf2eb92ece7 -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=b67e319c5e447e9ebf4b9a7e51800e7d7aec3564f0829fa23df953d8ee714131 -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=432ea33a49f0010125c960d7b93b585e7b4c91b34f9d07989cf1664bf7e71fe5 -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=53bbbc52c4f99733c7b4a1038fa014867c0d6ca8f1d7eccba651fab4f794247e -dist/2025-02-08/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=6df101f4d5416cba695be66b975a4e4dcab2a3041d079f0a454f342a6d24d7db -dist/2025-02-08/rust-std-beta-aarch64-unknown-none.tar.gz=f1ef3141ac9c634e7e6686cf3c13b83323eb168a249f596b1490f874372c1423 -dist/2025-02-08/rust-std-beta-aarch64-unknown-none.tar.xz=a709c52f479c73ed15709b3cb0b8e7641606cf86375a4c9a60b1c9d381c70183 -dist/2025-02-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=31b8fec1cd20dd1809bdf733209288d60de0f096fbd0cc2955982ce119703772 -dist/2025-02-08/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=afb3872ffa8ab3c79d08f713aeb76c658ea00a3b9d79d5516d89aa78ec1eab8e -dist/2025-02-08/rust-std-beta-aarch64-unknown-uefi.tar.gz=d73b90fa9d3a330274b2004ec535d396f90a82ac5b10fb8688f82472bd2c5ac1 -dist/2025-02-08/rust-std-beta-aarch64-unknown-uefi.tar.xz=ae05fa6bf0638b0e26fcb8bcac5973835aa965a56507588fa3d43981f20eee89 -dist/2025-02-08/rust-std-beta-arm-linux-androideabi.tar.gz=c18354734b678f0665dd60bb8765df00bca5d3fb7bb6e6a4b83e3cde971c26cf -dist/2025-02-08/rust-std-beta-arm-linux-androideabi.tar.xz=5f6bc44bbe3b24140fecad715cc5528249906bacf98fc3a0618a9c0cc92913e0 -dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=d9a2ab83df4240431479fe27600ab1098333699e14103b8a627dc09a3dad6976 -dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=4f95a441ff45c16fb8aa37432cffeef60f2e0711c9cb1015cf440f4da51d5425 -dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=dacdeceea6625041f75c3f2fad4382d2c957b9511666987695fed8e3a2216c88 -dist/2025-02-08/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=e338c1d2cef57e4c4ef613e6b080371751b874f94a246ab32e872a008e9166ab -dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=8bd4174934e5d0e4dd8e757db494a238c95024be5336e6062923b479c0275b6a -dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=1637b8d23bc8052803d785f15031a75594860f2263808c9dee68dead29bcd37e -dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=db6eb6a2af3395e1eee0060d0c022c74c0741c765009f081c0646d696bd0b873 -dist/2025-02-08/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ca21a4af4de66abf9d31ae6b3fbc33df152656feef7a269bf7d039d2766176ee -dist/2025-02-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=118c52dfa7142c0ee281b126da5b043b2357b78e7e110000f490b20e6a1e7eed -dist/2025-02-08/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=558fbb7453a2e633630ed33ad150dce87fa515b5b443ae66c5f85ee27e0e771f -dist/2025-02-08/rust-std-beta-armebv7r-none-eabi.tar.gz=96ff6441b0577b25b83540dc803d692d3444bcd0b4f6128a7743970726facce9 -dist/2025-02-08/rust-std-beta-armebv7r-none-eabi.tar.xz=2621a9f82f73a3a2a2a0c6a7446549c5ad29a430a3e0b961909fe68da21b8491 -dist/2025-02-08/rust-std-beta-armebv7r-none-eabihf.tar.gz=0ef78d66dea96d1a6565fb3469bdcb3368f9e61a55a59a5d2508c54c091484e9 -dist/2025-02-08/rust-std-beta-armebv7r-none-eabihf.tar.xz=1c586301ae2a20ed1caaf0d62d985f9fd95bf2b937ebe7b6d738ca5812713722 -dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=aaeb690b0a08e8f6546ac5608fade5852bb029db9189d6d036c69c4895c6ce32 -dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=1d6ae672d5ebcd302a654c4347a386fabc3bf53aec9664cdf76b9c5a061d4eb1 -dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=5557c7444e72eb29c904436f0221cb40c3156c5289c39b7e8c1a057dfd56c394 -dist/2025-02-08/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=ae9abe3580b1751854305200bd6a5dbf98aeef396e163534ac5521d04d7bfa7c -dist/2025-02-08/rust-std-beta-armv7-linux-androideabi.tar.gz=c466403dfb8e15cd674859fad24e2e0dd1ba100946c662a9bf29f2440f02a938 -dist/2025-02-08/rust-std-beta-armv7-linux-androideabi.tar.xz=83ad7b8237ae7ab0ddd6f43b604b27677ec9e83453f3127c356936af12140ee2 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=12489ebd742dd611937c2942c6f897608d1c4acb0fcb103a2a18f70b9b2d0596 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=54231b6c641736b29317682be9d1de9463e23478a892c16e083bc1bf20c9c925 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=e41b6582cc6eb2340208a3473d54d441e13fab87bfee3091a513da4039c224c6 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=9ca2df0ba2afd630a94a3bac08f8c412fdb6f905333c8978ac9b6bb5be777774 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=dd9f6f6d930d18dc5e1764691acd2e33cdd032ef757d534ea70202fcdc18e461 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=9d0e4864ecb7e33b231dedd10b54ad7707d79c61ff455256fd693a46a4ecddb5 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=b508af76bcabed45442fc1587ea1c74bbbf85d75fbd2fb64d7078cd799485ae6 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=3f9916a37ac0b79586756f09986516ba08e1c24b4d4675bd17d66058e42494cd -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=a80bdd0178f0b9c98c2fe80e59a1b936115a509d9b1be0202bea09d275b4c5d0 -dist/2025-02-08/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=6cb0340d4633e52f7a6f3419a0f18a9d0b75f604fbfe99ce5886186f81204264 -dist/2025-02-08/rust-std-beta-armv7a-none-eabi.tar.gz=f9ac794582c73c7e0a36990daa6c2e2d637213dc16a0063aed330bf68cf04d4d -dist/2025-02-08/rust-std-beta-armv7a-none-eabi.tar.xz=7463c6f6e9ba1bc056ab528e00017db0d6ac2b0e06812f0b1d7b569a8a7e51ab -dist/2025-02-08/rust-std-beta-armv7r-none-eabi.tar.gz=c676cfbcaae8c7686a231693b923f98e23ed3dfa174ecf42aab57d94e2bddd85 -dist/2025-02-08/rust-std-beta-armv7r-none-eabi.tar.xz=93b2802c8f555fdf03cd309539eabfa2f8e434114f8f750b89ec3005249e9b91 -dist/2025-02-08/rust-std-beta-armv7r-none-eabihf.tar.gz=077cf1bbe4fdb0c011bd625a59ebc4b3d2876a50b544b76934523504c59042b9 -dist/2025-02-08/rust-std-beta-armv7r-none-eabihf.tar.xz=3be6d9e04ad155e78be5ecce391b57b285c7675cd9a4f86e2ddb388c934c21f8 -dist/2025-02-08/rust-std-beta-i586-pc-windows-msvc.tar.gz=2e705d5660544cec738cda300b059dcc1d730f7ff3cb029980a1ac9c1f9e6831 -dist/2025-02-08/rust-std-beta-i586-pc-windows-msvc.tar.xz=4cc0760e20f53648ae5b171c6948af3950cda4c468f2bb437016d92a2eeb2465 -dist/2025-02-08/rust-std-beta-i586-unknown-linux-gnu.tar.gz=3a516cf5c265899c9a548f6b9305b78069cc03864dcf1b3fa0e247adfa978cb8 -dist/2025-02-08/rust-std-beta-i586-unknown-linux-gnu.tar.xz=25144f4fb500ab9ba438042dd24796b25660fc3d16d3e04b64561bd35f84e46b -dist/2025-02-08/rust-std-beta-i586-unknown-linux-musl.tar.gz=70bf9429de2e11fe9e14216d3c1cc61a3923e1a7c7bc17d5b0d63785716a9e26 -dist/2025-02-08/rust-std-beta-i586-unknown-linux-musl.tar.xz=35cfef70aa5c59ecbe0d563959c62ec0162a8943d32cdc45dd0207b6ad3d16eb -dist/2025-02-08/rust-std-beta-i686-linux-android.tar.gz=a17f82a5f41e38c5c9ccaf1b2cf5182ed2e3c459e87c841497f0594cda7f71bf -dist/2025-02-08/rust-std-beta-i686-linux-android.tar.xz=06565daae363ed88f579f261a89f75d126785c894e439976ae47870cedd56378 -dist/2025-02-08/rust-std-beta-i686-pc-windows-gnu.tar.gz=986595d50c1c5799f67bd04575b248c5cd81dc03f318bd137b46248f75b2727f -dist/2025-02-08/rust-std-beta-i686-pc-windows-gnu.tar.xz=9daf96aa939ec6ed4ac8ff6119da06fca827a7f160e5c7db658653d5839846af -dist/2025-02-08/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=f793d7a5ce20392287a7d178a2403d1d72dec2437401c447a7c5e3168c25bcf6 -dist/2025-02-08/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=039a361f65fd610b14142f0d654895f4ac271cfb03918f7fcd8b2e9c5ffc3c98 -dist/2025-02-08/rust-std-beta-i686-pc-windows-msvc.tar.gz=6cdd125eafa981da12bff2a7e519866cfe40b7d6d7b6debabbd2415759fd9dc8 -dist/2025-02-08/rust-std-beta-i686-pc-windows-msvc.tar.xz=7f1a722bc007efe77dbd099ff36f2c682ec4bcdb7e8b60d6ad868e9d08a9a367 -dist/2025-02-08/rust-std-beta-i686-unknown-freebsd.tar.gz=b7dc78d6d4e6ce343ce90a7153082575a991eebd8acbc3cdfbcb56d1cc281b83 -dist/2025-02-08/rust-std-beta-i686-unknown-freebsd.tar.xz=91d19c3086de738b3d11a2bd0f0ad31c9f6a9c39ef800fdb2040638fc91c69ac -dist/2025-02-08/rust-std-beta-i686-unknown-linux-gnu.tar.gz=fdd0f12816d4bfc15c441cd26c7ef0f9ac05f19b03f471f162e8781f04bfc392 -dist/2025-02-08/rust-std-beta-i686-unknown-linux-gnu.tar.xz=a1ba9ce61110a1a64cba2bad7274865979d8d10cf30dba44137cd0acd4b49bf1 -dist/2025-02-08/rust-std-beta-i686-unknown-linux-musl.tar.gz=3774b47f5d6748c32d634f0414391121f2a68d7e3e15162cce62ca42bfce1db3 -dist/2025-02-08/rust-std-beta-i686-unknown-linux-musl.tar.xz=fb0203eb986554773288b732feb65a76aa7e4510b30acf60a9a879614332f0e1 -dist/2025-02-08/rust-std-beta-i686-unknown-uefi.tar.gz=a388f43900f4ac040e2263f06e89ef92c3d630f2631b37147eb1234e3ff5555b -dist/2025-02-08/rust-std-beta-i686-unknown-uefi.tar.xz=5fcc43194705468d31fc07ea2cca780fef717adc2d46bd9508d006adcd237c23 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=c1d25f88813fb558bf47478a7e2a43e735f2e7ceba87f3ab8e658200825ac6a5 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=66ae16763fba1c9e54519a34b70811f4b54c2a3985bd0faab4ae1a454f837556 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=0cf97c80c7dc0e760d9aa2f6a6d6b82ecceed06b0c0e7f56b2f3fee98f558d3e -dist/2025-02-08/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=7b8284890d5c90e9a3d2cee73ee6b77ed0f023321a547a9add7d25e64886c9b9 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-none.tar.gz=67f97000b8786928eb7ff7f060fdaa2fa9e3805c23e5f3fc24350c6ab0954c17 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-none.tar.xz=5660100854fbe9fd87c0854b560a91dd5b653f07a0c374ba6349c44ff54b3b76 -dist/2025-02-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=a885c29e4eea19ada52cc22bfe395eb0f2e884932885c3978187a44405d5873a -dist/2025-02-08/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=acbfef3c94943ebc1a44e662a5eeffea6c3c0f8b2518568b03d2e1c5baf323ea -dist/2025-02-08/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=2bb3f9493afdd89c52bd62e2597c8687335e0d4fbe5a486782335a614881a516 -dist/2025-02-08/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=0702664eceb39c21390e3ee8dbfc0a7a181877449642b1b47dc74e1f463d8ebc -dist/2025-02-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=788b46512726f8350f8266f4dc7e3bd4108ea96b2c257876d42d6c62cef71507 -dist/2025-02-08/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=a746eeeb6c41696c95144068e348237bc7a3b254b1c3db626797dd2947194999 -dist/2025-02-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=48f11a2d3aee9b3cb8d9e7f6480c8859427f446ebde617e2575a17dda6605fc7 -dist/2025-02-08/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=5a3933b2465cfe93daab1b5d339a0da17bc364d5621d85e192283250b337e38f -dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=50bddd9780ebcb5bc081b41c071c6059618881e1cc384f30787caa6fd2f28127 -dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=4630d67082a6c2211a8c59a6da45d260616bd026d7cf7d2bbee5ae6d24b218c1 -dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=4a0bcf103df6febd7b3e04bb24d54b30b6a2f4ffaf150f6774811c149f450588 -dist/2025-02-08/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=6a37963463641ddc14e03c0f9d8b037cd62afe3af89aeaa73f1f1d3aea1a6f93 -dist/2025-02-08/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=7e2c0f7ea78086cc2b8674aacf350b6de737ca68a51778a8a66c75932161a8a8 -dist/2025-02-08/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=a575b31731a910d2db684a931ced914b4286b942ce878fde94f08bafae92903c -dist/2025-02-08/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=096407f438062be73bdd4f2efb6e06ddcb6c6c8e08b3c2db76388a4f4c4a731f -dist/2025-02-08/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=38b771d01c0a56330d9547692c424e92b243d3f2448c13b29873cb2e4fe70b17 -dist/2025-02-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=218d5db0b8427fcc0a81612134d830e6807db8d66eaa4365c4b101f29ab75ae2 -dist/2025-02-08/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=1227b4dbfe7f3a0c7715904d3ed1e9f9846c49e522bb579d7dd76de370ab83a2 -dist/2025-02-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=8e5ad6f6116b0fef61650f2a3788cc9a9e6da1cd76dd0dc300d81060ef42ee6b -dist/2025-02-08/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=777cc9ec22cb9b92ea3569d6835770f45ea7793397be670edeafa65660d411eb -dist/2025-02-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=16d6414fcbfd0356206cccb10f0d5ec1391300c8bd92029d9457fc3030cf3cff -dist/2025-02-08/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bd4ffe303e7b6a9031eae2dca7b4af4c7095e06961a55a6eff01db57178c1635 -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=facbe91da7b765e03b058682a1353153b89632f5f60692b25077ba4152105faf -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=e130dbd1aa2f19c308ca3e72e0456769ab0898a9bacdc667261396d786a22fca -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=3849880a18e3176c4acb895dcee7f5befa64ad3413ac8476325d97a9a2bbc542 -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=8a14b3cb0c9e20ec84ab686e6eca5acd201e71364ab5007c96b884feb4b59340 -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=f5f58c50d793cb26103f812bb32b2d3623c57319a141e151201764f20032262b -dist/2025-02-08/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=db7ea697f41b8dc2610c6d71ded8dc0b80ec848c002cb6af8faa3105023ec424 -dist/2025-02-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=b081a9b131703cbc11658eb84e54e495fca021bdc6487d902c7aeb8126629437 -dist/2025-02-08/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=2a3327ffdd3bfb9b4ce6d1aa13202958587d0819dc49ce08e635970d8e608b6c -dist/2025-02-08/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=3b0abfeb0a6bda721e1faad0fe4ed2db072ae04beaef53d895f3902a26387522 -dist/2025-02-08/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=5d6314a99746c5fd7f1d0eb0ac426848b4baafb9e2f4e08b7ce361091909a485 -dist/2025-02-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=01f85bdc840f6d354fbc765b2574cbf039a97e7a8cd4345f31d4a93f41ea2936 -dist/2025-02-08/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=350aa8e77ce705d04d996ae3911121c14213fed5db6d179ae4efeb54e64d5554 -dist/2025-02-08/rust-std-beta-sparcv9-sun-solaris.tar.gz=4cdb48054bcd8c596657c466145e1ec9d9a513d6019694895b7b1218183d7ed1 -dist/2025-02-08/rust-std-beta-sparcv9-sun-solaris.tar.xz=abda0bf8356c63fcf50fafb196c86a6c2275f3155362fe6b9eb63c8a145e07dc -dist/2025-02-08/rust-std-beta-thumbv6m-none-eabi.tar.gz=87ce4c701797be511509773e6121d69470d604f143c4e46e18866105193d503e -dist/2025-02-08/rust-std-beta-thumbv6m-none-eabi.tar.xz=d0af4c523a37df6ef2519d2abd680e2abc21e8806904cbbfa2bad3ddebc55252 -dist/2025-02-08/rust-std-beta-thumbv7em-none-eabi.tar.gz=9c183442ae8a7bf18303331e23c2263d180157a4fa9d000735b57f54f894fbf3 -dist/2025-02-08/rust-std-beta-thumbv7em-none-eabi.tar.xz=c9278b82123969a4f9c8536f6d27ceb6b6cae182335cee4cfc1ba8f297d503c7 -dist/2025-02-08/rust-std-beta-thumbv7em-none-eabihf.tar.gz=cda7f615c006369dea46c6d00660d596459d2ca809b27802c15a9e71e741f806 -dist/2025-02-08/rust-std-beta-thumbv7em-none-eabihf.tar.xz=7b2bf45033d1849ced101c696641a3e0037dc65029bea06fcedf3b11af1b21b8 -dist/2025-02-08/rust-std-beta-thumbv7m-none-eabi.tar.gz=bbe3db6ddb17830708086940294a8931054c09d781968f69c810a5a17cb4299d -dist/2025-02-08/rust-std-beta-thumbv7m-none-eabi.tar.xz=4cf28e2656f8927cbb75c007aded9d0fcac8d8d34841e9ac5486ba8ad3a75a58 -dist/2025-02-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=6021afefa8b06c99e09e63c07a8d4580ef7a6d9e004205d85f8fea47fb7c77d7 -dist/2025-02-08/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=7fb5c89a7605b0b377fd3e11d3ac5e33dc59667557b690b02df5c852109cefe8 -dist/2025-02-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=f1cbb573556272077f7a119e019ee4c1f8c533cfcbdb2b12c858c7d72c05212a -dist/2025-02-08/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=2d7c0f7ece15f6ad5de053a4b0292113efd8b45457a7ea4ac4a84534985a6e7c -dist/2025-02-08/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=fb5c1d99eeedb48edac78bce237351bb2a04b3ce1e028b47c488a28a0f5b258d -dist/2025-02-08/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=301ced2f4ca8766183cfbd84b94ca09f21c9c2fee62b3e1afca440f5872ec6f0 -dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=c720cd1896d201ecee177381386cf37ff58a0ad2e153efa8752dc11358489774 -dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f2e14c2a08777200dcec2c18677a1bd68c57a7caaed8751e17d4a82af0f61e9c -dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=146bfeecf574cab3bc15396c2523f27cc463ba9030d9a8c9a07118781a78227c -dist/2025-02-08/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=093364007abdcb942a1d095bba6b3f6a63cb891e3897764923828db5aa44f970 -dist/2025-02-08/rust-std-beta-wasm32-unknown-emscripten.tar.gz=f2e4ef8637a02510dc3edf78f7117dc16671946e1eebf3ee8911160bde53f3a2 -dist/2025-02-08/rust-std-beta-wasm32-unknown-emscripten.tar.xz=d30b8b9a7607de4cee24b144452439726eb8b4a436f53c058c2b0c21b686a391 -dist/2025-02-08/rust-std-beta-wasm32-unknown-unknown.tar.gz=242403cc6e3df3d47c566c63fccfb40e6a95d2f2295630bb13f4875c9e28ae62 -dist/2025-02-08/rust-std-beta-wasm32-unknown-unknown.tar.xz=8ba08c010e49593d417feb05f3efe407200421bc26d40b51a8d92ae6cbc46200 -dist/2025-02-08/rust-std-beta-wasm32-wasip1.tar.gz=25cdad2de0d599c5e90373765acba871e2facc7656ea1362b3e0d1132fe8805b -dist/2025-02-08/rust-std-beta-wasm32-wasip1.tar.xz=0eb3ae579124a47f7e8b63e6933e703d00c535f8369c614678e35c431a5480ff -dist/2025-02-08/rust-std-beta-wasm32-wasip1-threads.tar.gz=08d400d8ad036c2b240f4044adc6cf484cf996b5f1cca5e9c0fe81814a71635e -dist/2025-02-08/rust-std-beta-wasm32-wasip1-threads.tar.xz=46aeb5066e5fe4bc613a704c760292a85d2cd5ae10d135412adf5cb42de24015 -dist/2025-02-08/rust-std-beta-wasm32-wasip2.tar.gz=9df47e7c8280b8780ca41ed3dac9326375c76955560491ade1c2fdc8682b70d4 -dist/2025-02-08/rust-std-beta-wasm32-wasip2.tar.xz=275cc332f6d29c685ecfc308e143edccf58fce0359f632b038733a7759ae7389 -dist/2025-02-08/rust-std-beta-wasm32v1-none.tar.gz=96ee2faa07796474ea348b83b626cfa0bd07d108ffd05aed8051b63960315ee5 -dist/2025-02-08/rust-std-beta-wasm32v1-none.tar.xz=965650429f8129c65a6180025fdb69c0890f5c6f9c1fc16566c08b055e4ed93c -dist/2025-02-08/rust-std-beta-x86_64-apple-darwin.tar.gz=92ebd93de4f4da8267e13824db8455dbcb7bb95ffda8ae480c648c2eb8f820da -dist/2025-02-08/rust-std-beta-x86_64-apple-darwin.tar.xz=00e4b5a44f69a2c9235e522eee91e972624c75e3ce773928b09e9ee20d2d51ba -dist/2025-02-08/rust-std-beta-x86_64-apple-ios.tar.gz=dfb3d88798ff9b490c1a517d57e459a77cf2bb2e8b427493a3a612405534ebb3 -dist/2025-02-08/rust-std-beta-x86_64-apple-ios.tar.xz=7091bae8ccf328336261c2b096d1565c0dc9dca02b03d4e228a7c3f4c412a6df -dist/2025-02-08/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=79628c744d12c1bc5514801a530d903ec539efd16e82d0c871adfaa168b7f55b -dist/2025-02-08/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=2b12ae64c94a4f11591de8484998391d2825bc68535257dd305d31a1c51a7210 -dist/2025-02-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=54f4caf75ac93676fd61fec65e2ea6b73774d5de7d7abe8d47d9c2d8030d8fe0 -dist/2025-02-08/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=abc1feb82d4449c0d098a1ee0861ad991e79911cf0d5cc9ed9b5ca1e134248e6 -dist/2025-02-08/rust-std-beta-x86_64-linux-android.tar.gz=fdc1afd6334f725cfd913faf0915da711cdbcc45c05ec2672fae34d97e73ca60 -dist/2025-02-08/rust-std-beta-x86_64-linux-android.tar.xz=9451c74b695dce762d56354fac148263b0a7de75209c127bc7126da54ede7114 -dist/2025-02-08/rust-std-beta-x86_64-pc-solaris.tar.gz=d32731be8a9d3c5e8279a1b4971d105fe457717acbdfcfd720bc0ae55a34df26 -dist/2025-02-08/rust-std-beta-x86_64-pc-solaris.tar.xz=a5a08cfaae7eb3d77c137bf0d436beb7a84a19e351f529fe459861a8841df44c -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=7c41f46506f93132c5f90184d7ad1577edec98d47be17c6330f24cd172c673d5 -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=e439c8a7368e70685b239ab7b84bffcd8081ddc80c2d9f6d2b686485316aed68 -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=128c7e526e37551ba3b6a347cb870c4ceefb272d964512fa10635c8f1f6e239c -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=660409184e81625419b91a4fb5d84572abb0505d9bc11bacbed50121f9230790 -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=10b37018a254f81e55f555628fcc535a54b0eae0097f02a148c443a3d7e762f9 -dist/2025-02-08/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=d61e44948d2ea70b44c8d3f958a3657dae9eb8a551aedb3ef90327da0124d9d5 -dist/2025-02-08/rust-std-beta-x86_64-unknown-freebsd.tar.gz=7ed5b948a50946b518040170be16cba1b5ec0c02f823436c973e5afbd335d26b -dist/2025-02-08/rust-std-beta-x86_64-unknown-freebsd.tar.xz=0bdce5b2f88448dbbe101f4ef48231763739533b52c32ab6ef858b6b37d98a50 -dist/2025-02-08/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=49676d645ef9c49a421f3fa1d908830b61542541f1ea12c2d240ceaac3b977d4 -dist/2025-02-08/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=1c0854c619e2a0dd7e508513fb68c22352ddc170572bfe6535d2f759de069c53 -dist/2025-02-08/rust-std-beta-x86_64-unknown-illumos.tar.gz=8ded61102c481e7c000292a8c6d39d84c016f81b00618947ac7357a7c72fb142 -dist/2025-02-08/rust-std-beta-x86_64-unknown-illumos.tar.xz=b76ed9b0896cfe863fd2aff88fd6d075e6091a651cb0d5fa65307948316f7ebd -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=1cbcf5ae9dd2c61212b82bf27bf1b1b7d9504f077119c1fa04a978fa0ef3b2e6 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=86f236dc4222f5f93f160ca847f43f364e1659b6d4c9f68a31c202f5346f2221 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=2225ae88e8cf954b7eef8fc2e4f391c0194fd7be6433928dbc8aa6e2235ac479 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=6017a3197b7a103a4444b81f8fa4f790a2b11bf1c3db0af297e2ed0c97f78172 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=e7b3c4d8efb8f56fa76c3cfe51eb0683fc41308691ac194b9eb70e13b1b2e976 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=f0ad48db569e21b8fa1053de3320d766cbb10962ebbd69ed56f170bdaf76fe45 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=f1baa7f02c0969d74cd0ba420ae0a8d5e761cd5545c04fd2e432c889db8cb655 -dist/2025-02-08/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e572e1a7db7e0127bf7072e5361b91dac84c019afa6433538b40dc984957f1d7 -dist/2025-02-08/rust-std-beta-x86_64-unknown-netbsd.tar.gz=c714b5f4a61041b5c68abc532203c88d65a852a813b7af8e11ab3207804886fc -dist/2025-02-08/rust-std-beta-x86_64-unknown-netbsd.tar.xz=61d6c87b146f114d14fe637257b9feccbb1d787958a7291f7800c7541bd8e21b -dist/2025-02-08/rust-std-beta-x86_64-unknown-none.tar.gz=5ab7c9985beb3f07520cecbb60c2fcb8bf60b3079b253267fb55d2139619331a -dist/2025-02-08/rust-std-beta-x86_64-unknown-none.tar.xz=992257d8f922654977d1c1fdad2b57654b4ea7fd2c27d6a4bcb8f85b9a75fc5a -dist/2025-02-08/rust-std-beta-x86_64-unknown-redox.tar.gz=e5090b881329fd94e4250cef92464bf3fc42ae6566ab3bf461e1f3c843d3d1fe -dist/2025-02-08/rust-std-beta-x86_64-unknown-redox.tar.xz=89cc1ad229a453c15d4a88137646d6824c572eed602c9c131982e3ddc62abd75 -dist/2025-02-08/rust-std-beta-x86_64-unknown-uefi.tar.gz=f42383deea91ab9dfdffede178b4411d751772a482811058dfc0bcc33da2fab6 -dist/2025-02-08/rust-std-beta-x86_64-unknown-uefi.tar.xz=3b4e67edf9785c0eff0fd83e357fbd4c0840620d1b7380ba5d270729f751e4b1 -dist/2025-02-08/cargo-beta-aarch64-apple-darwin.tar.gz=f197e428af3ea3d409a43b54372c9f0f7f8f70ef8d048e066b5c609364211e35 -dist/2025-02-08/cargo-beta-aarch64-apple-darwin.tar.xz=e84b8ec6f87512fbf31c823703b94ebee8531675430224331845158b8997121f -dist/2025-02-08/cargo-beta-aarch64-pc-windows-msvc.tar.gz=16b73927483117d158a3f3aa36d9cd14d74dce707071345fab9e6c359b68665b -dist/2025-02-08/cargo-beta-aarch64-pc-windows-msvc.tar.xz=3fb1381b750a1ccf386602394af21130e9cc6384b962bd008ffb2e11bcac4c1b -dist/2025-02-08/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=2b0d90694987ee10a0f0e5b40c1f95c65c9bbeae6c921556b85067a1920f5988 -dist/2025-02-08/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=b47667e97225ce7542c6e9a137adbc7c002ee1e4b1e0c1255b5dcb87743d886f -dist/2025-02-08/cargo-beta-aarch64-unknown-linux-musl.tar.gz=843bea38aaeaf6629060a046e6654fde6f4a73221a996e56ea9a1f35466cc6cb -dist/2025-02-08/cargo-beta-aarch64-unknown-linux-musl.tar.xz=147827cb32d5ff3628f347800a9202eb0b3caaa142d363dffde94bc6bf821352 -dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=0dd6585f3e93a60d4084a4f7f6c58748e82c03ea38fee164828d3911d024459b -dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=2e8240d79a86de26e7782265bd6551c6357a025b7084a3ba88161c84e2fee54b -dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=323095df9d5c9f47463c5b05729960ee0db5f910619050ed548adb2b8c59fc35 -dist/2025-02-08/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=8f5be63da1f8e9a7d90116c9793e03021855dde170a356002f306180d4ba7ff7 -dist/2025-02-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=63dfca05df7a8d14c27070ce882a96defa2e5c3134fe17e848273694b42b3c88 -dist/2025-02-08/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=3881f42ce8e69953804cb0c566fe08f44ab8763cefe8c0d6a4461645dd44f518 -dist/2025-02-08/cargo-beta-i686-pc-windows-gnu.tar.gz=70aabf19aa3db89599131fc09fc005a9c8c0974d3f04267df0e41007f5bc46d7 -dist/2025-02-08/cargo-beta-i686-pc-windows-gnu.tar.xz=c57bfddc9285dd7c1151c3bfbde4f92da394fe6c8d0239c1f9ee8eceeb15e29c -dist/2025-02-08/cargo-beta-i686-pc-windows-msvc.tar.gz=056e750115574ab4e008d76d1bda67aa30f3818a9f46cc88d7ad13bb4238d772 -dist/2025-02-08/cargo-beta-i686-pc-windows-msvc.tar.xz=663a9ec0ba07807ce289bd61c66e196262e991046da44dd583fdc1414759f5e8 -dist/2025-02-08/cargo-beta-i686-unknown-linux-gnu.tar.gz=95dee9910674196f2bf655e91a8443be5b46e36747bf1e980e1585fa3789375b -dist/2025-02-08/cargo-beta-i686-unknown-linux-gnu.tar.xz=09af49a00e181084e7f766c9008c2d3446ff1cb801780feb79d0b7cc31a038b6 -dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=ab1ac3686ed7b3b50ace61efe20ea6848370de691cf0f287337113d7ca52c61b -dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=bee237e641da0d804f2002d33910bfb199127c5006af39dd06d877ca5fd1ff82 -dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=9beb2a39f1ef7630f03ed1da5e1e68964a4b198fe7f18d0db9efb4f10d70b35f -dist/2025-02-08/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=f1528e4aec2095d55b98e3421d2310f3aa3fcf7c2493f83e75d3cbc80e18f923 -dist/2025-02-08/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=2ee460d198339449e85ff8c7e522c47f33677e90f8b215c0a13514fe5f05cdb1 -dist/2025-02-08/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=4a9fc5e31abfe582b580e395ada8d59a1aecf65b07b09b8ce526a84fdf61830b -dist/2025-02-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=9e471ec06debbe078b8c92773a1c4380969e92dbbd9f20884986b2cc7e942106 -dist/2025-02-08/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=1cc6e9e448f036af3bd6f8e597ee242edc65811835e20545e84ab917744b50ca -dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=08fb88ea0a4d904b28ef7a51275ccfd1f8480f1d33c7a5a83461d322143e81be -dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=0809a5f718157763bbf67e8c3a3b9b868a6694bd88b87277b542fc3207c1f1d7 -dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=dcbf18b645016eee37a23dce4126d0ad61f8886e8997b480609e8f8fffe0191a -dist/2025-02-08/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=f4f9350ec459016cc0fe54414d75fee119b0051e3ae1b839971ec5b569be97ce -dist/2025-02-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=dbeee82ff5cec6c16ba873b40f986e85b55f831efbd4d09d0107b2e66037db87 -dist/2025-02-08/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=2974493a708fd5c793b9f1920a11b66aa5ad6aaffecb0b9c597416b7200e411a -dist/2025-02-08/cargo-beta-s390x-unknown-linux-gnu.tar.gz=ca157ff6dac3d680f63c99fc2efbc30376eb6ae54682f40369c4d2aa8647b77c -dist/2025-02-08/cargo-beta-s390x-unknown-linux-gnu.tar.xz=ea5ebe153fbe3d1fdf514ebc050f46776b075268aaf7e7e3ef308f13d0ad545f -dist/2025-02-08/cargo-beta-x86_64-apple-darwin.tar.gz=dd19dc295a1c430a52c223478a01610b359e2e0b40abce7111c9a02a51d4d313 -dist/2025-02-08/cargo-beta-x86_64-apple-darwin.tar.xz=f729d46cb4ca8945657671d5d0c0a55792a2ac9f5ea21b3e2991843004fc23ae -dist/2025-02-08/cargo-beta-x86_64-pc-windows-gnu.tar.gz=9a7dbfaaafd177a725aef60ec6c4fe3c5b732bcbd69a2e25a91ad7461a76ef4c -dist/2025-02-08/cargo-beta-x86_64-pc-windows-gnu.tar.xz=ef585bc9e5f23368fbb960959f80fd34961909e62cd65bb847db06a7178b174a -dist/2025-02-08/cargo-beta-x86_64-pc-windows-msvc.tar.gz=5e396a15cc63f084467d9afcb30cb374c070856b0aa3fcf209d88bcccfc6436b -dist/2025-02-08/cargo-beta-x86_64-pc-windows-msvc.tar.xz=78cdbf2cf0d7fec4d24308853e96a39bf5c417905abfcad34de4d1b2d498a617 -dist/2025-02-08/cargo-beta-x86_64-unknown-freebsd.tar.gz=1e485ce036055c7b3e1949d9e34e7d3dca436438b3f09bd75d36e49217d53d44 -dist/2025-02-08/cargo-beta-x86_64-unknown-freebsd.tar.xz=80c5d0d5860eebbb807a2e5cf8ccba8ed4461f932825439ec8182f6f0c8939c4 -dist/2025-02-08/cargo-beta-x86_64-unknown-illumos.tar.gz=5681331e1d29b476c4f458fee453f73efc86856caf1d30c49df9dec3e147f4b1 -dist/2025-02-08/cargo-beta-x86_64-unknown-illumos.tar.xz=9f7d97045851bb1ab334761cddb38cd8bf3bb0b26f2fca4903c09301c70fbca4 -dist/2025-02-08/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=24bda5749883e133ac58ddcfdbd8dbeeb660c3b33d613852dd1d993cc13f6e8f -dist/2025-02-08/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=2304e5cde3efdb5c6e7319d8239bca7d1c69306846cc3eba84d70d49b8c24e51 -dist/2025-02-08/cargo-beta-x86_64-unknown-linux-musl.tar.gz=825a42ae4bab8be081c7320f06fc7ce6d0c0c31f2224fb0c13af4d01e04c3626 -dist/2025-02-08/cargo-beta-x86_64-unknown-linux-musl.tar.xz=656d148e383896d06483297d785d62c8e235020081acb4110a8bf698a3d6d6e5 -dist/2025-02-08/cargo-beta-x86_64-unknown-netbsd.tar.gz=1e6a750acd6c1f44e37b3d1b1dceef7e8a0d2b0806e1577b667573a6340e7cf9 -dist/2025-02-08/cargo-beta-x86_64-unknown-netbsd.tar.xz=c45bd23fd1004cea41f133a40bd102e55e9f7ed29c9e8cec83dcacc4653da7c7 -dist/2025-02-08/clippy-beta-aarch64-apple-darwin.tar.gz=cd22d4191ca0fb9d8ec3d627805f297ca4528018e34c4f627e7e4fc05d6b0954 -dist/2025-02-08/clippy-beta-aarch64-apple-darwin.tar.xz=0c408799a742b00dce013553a597e62d8f84232ede6883632dade6b3d024904f -dist/2025-02-08/clippy-beta-aarch64-pc-windows-msvc.tar.gz=b4d902d9a096cdc6eb655ae2a0960db6fe4b83ccb681cc5bb5124dcfc5e1fdc0 -dist/2025-02-08/clippy-beta-aarch64-pc-windows-msvc.tar.xz=9e2514d7f304e3253e7205cec8189b8f9b1d49da5b14b2c03e69b8bb0223a65c -dist/2025-02-08/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=1496cc4bbd0edc18ce05bc2ca76d9ed78934f1d1c4749ff830dff7d1acc2535f -dist/2025-02-08/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=4577dce94261cdf07064f43404ade755a8906ed0b1a39a148333d9309e011916 -dist/2025-02-08/clippy-beta-aarch64-unknown-linux-musl.tar.gz=d28217818fb6c1a13456684bfdbf9caa687dcc257fadffcde2d2fd94dfbb228a -dist/2025-02-08/clippy-beta-aarch64-unknown-linux-musl.tar.xz=bae2f1841776e321f5f950678516bb31c05dea8f825fda23f3a3cd423dc00249 -dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=e1698a07ab47d02954bdb67034de33a8414731e3d12a8937cdea97004d98e45f -dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=631499b2ee136c428f1c6045eb6aefee3e6c765dec1baeb0c3e4da056d540d71 -dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=248a15737924d07afee2108e6545cb4bd5cce91878dedb5368c358c16a0b016d -dist/2025-02-08/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=6581c968d48e37baf99addf17baf8b4fdda1417c201da311959c62a51783209a -dist/2025-02-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=8ff9d93ea49d805ffd3534c6aa03692fa7dc8bf0460bba7c22259257dae863d1 -dist/2025-02-08/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=b267e928b9708cc168d84c005036d155547274e8fe03f23b14232609b780d219 -dist/2025-02-08/clippy-beta-i686-pc-windows-gnu.tar.gz=957e8d14451557ce11de7303be61a50c68af7b90293a46e48c9a1bb3db05d154 -dist/2025-02-08/clippy-beta-i686-pc-windows-gnu.tar.xz=576732c661cd0998f7b47e99fe84c3dbcb919e787e3222e1c27b5377361083aa -dist/2025-02-08/clippy-beta-i686-pc-windows-msvc.tar.gz=5a4ea7d3fd79823b2342ec9069e865000dc5ab58be0fcf3655bcb161cb195858 -dist/2025-02-08/clippy-beta-i686-pc-windows-msvc.tar.xz=fbe4f93a9f1ab718a5dd3995ce67b7b0768f7f211f8fc3f1e6b181c4e4f1f467 -dist/2025-02-08/clippy-beta-i686-unknown-linux-gnu.tar.gz=0c013dba1ac3db5ec21e672f357c6a86c379c29f7cac0d43df4857e0332abe22 -dist/2025-02-08/clippy-beta-i686-unknown-linux-gnu.tar.xz=0e585010d88a8f04f9e031fcef623a12da7f82ed9f0d827157b10f6be80eb920 -dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=2716e252361ac72dfebc8521b3f2c0edaa6e0a0bb0b9a3ea3b9b888a5d747104 -dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=3d400fda76fbc8a830e12f5f71e40d4993019e9e53d58434ca23e3d8761d530f -dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=8d7cd64c2ec8ee5f25bbd6aa01ba22001a4ab2eae6ca481583f736a1da07dc31 -dist/2025-02-08/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=f60bca644d441e36e537e896d4b122ca0f8cde0fbd886f12c3a312efd5225997 -dist/2025-02-08/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=a3fc359554026ae39c7cc46c53c6928de0522387ad2327444745eefd0fdcc43b -dist/2025-02-08/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=8344b79f4a2a61cf68e526c144bbe797f1c60dec047845fc731f4c47a58b7be6 -dist/2025-02-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=05c2cd6e95a7c8ef36703b9bc39cedb8e5eb5b3c93a66a16deef2e18e96be489 -dist/2025-02-08/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2a0c36d392c3b69fc437c8ab8358f87c6c50380e8c5ced6690c9a7d0be9c95e8 -dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=c9c6975ec5ef1e206a917d03841db90e1f4a3562b0afec32a4753134752454d3 -dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=efe920b25316d84c08693f28d0593d227ca18456be2dd9b426c8cbf49d81a352 -dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=b133cb9709d11da1710b3b833a3e15d3fc216cacfd37e6e1c7c8fe1dbc202067 -dist/2025-02-08/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=7db8db7300b87bc7841ef59111c8f83fc6e6ffedbb6dd8fbb79431edb821e017 -dist/2025-02-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=2fea1f879ca90478a2fb75566da4cbed2f2afec31af6d18160fe183772241658 -dist/2025-02-08/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=668ef736714909588cae0bc77c30c3063d2911b0e1c28fc77678081099d38a83 -dist/2025-02-08/clippy-beta-s390x-unknown-linux-gnu.tar.gz=a05eb2ea42fc2ed7df974610b076adae42ec456bb80eaf9191521dda5c0cf12b -dist/2025-02-08/clippy-beta-s390x-unknown-linux-gnu.tar.xz=5874e0cfa3b7f7c3b8d9d0c84a519b98908b6228fcd9f29d971b9c36d639a998 -dist/2025-02-08/clippy-beta-x86_64-apple-darwin.tar.gz=e259a0e7776430f1697153505f937c92e942fb5c436c00dd9da3b160ef9a7856 -dist/2025-02-08/clippy-beta-x86_64-apple-darwin.tar.xz=a311ec69770a431837a26e63591dba11dedbad411b688ee69e457bb7a4596c50 -dist/2025-02-08/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2b8278419633f83ca22e2d1c54a170e04775d903076935ce13e91575d6122715 -dist/2025-02-08/clippy-beta-x86_64-pc-windows-gnu.tar.xz=13190a1e83debb9483abc7b0e4e3a4b8d53895542ffa56ebc012dbd72b8e7637 -dist/2025-02-08/clippy-beta-x86_64-pc-windows-msvc.tar.gz=9c8c8de0bd646bb0284e47b6adc1db6443d9da7c06ed6d237c421339a446fd83 -dist/2025-02-08/clippy-beta-x86_64-pc-windows-msvc.tar.xz=32dbce4ca3f3abf6da249e33297efea856b3b0ff39b3571531d71e1d0f90a46c -dist/2025-02-08/clippy-beta-x86_64-unknown-freebsd.tar.gz=55b22726920214e2ca9c4e552b50401fb3eef872c63de554623aaeebf9e11e75 -dist/2025-02-08/clippy-beta-x86_64-unknown-freebsd.tar.xz=b67e699d65462020333c037f206287e609f35e448cffeed6ecaec6874ccb2233 -dist/2025-02-08/clippy-beta-x86_64-unknown-illumos.tar.gz=6bf570aa87c05050e5dffcc191db07b1b0abf18bce160637a1be39e5caa130e6 -dist/2025-02-08/clippy-beta-x86_64-unknown-illumos.tar.xz=52ae7e8906f27c020df67beae61c1c1faf6458a0ccb3e904b909841b2b504d89 -dist/2025-02-08/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=fadc4ff0f2acc6d44a5a29d01101152c8570dcca69ea4fd60e8ca6cc2cfac1e9 -dist/2025-02-08/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=fd8472509ffdb81ff5ce786784274f654eb213ce963caf6e5cb90baa9e641c3b -dist/2025-02-08/clippy-beta-x86_64-unknown-linux-musl.tar.gz=c94e847aae4aa7a04981a4be424cdb2a1eae81a808858a5fc14a20134b7575e3 -dist/2025-02-08/clippy-beta-x86_64-unknown-linux-musl.tar.xz=b1f2a240069cda55c7c49afda6137822d7aee855557cf7269ac4f440d54a0ca9 -dist/2025-02-08/clippy-beta-x86_64-unknown-netbsd.tar.gz=86ada6c1406ff381a81624da25e65f415380da01252e6016bffe50ef7ca5b49d -dist/2025-02-08/clippy-beta-x86_64-unknown-netbsd.tar.xz=2b24a66215cd93b84065cd35d00bb3e7c9482b118eaeaf089bb2a128450add88 -dist/2025-02-08/rustfmt-nightly-aarch64-apple-darwin.tar.gz=0e6740aa70ccffed1e2649619990b75586638b8eb34747aab58ba4cccfb09f29 -dist/2025-02-08/rustfmt-nightly-aarch64-apple-darwin.tar.xz=c5c166763202c35bb7844f0866f05cfb7e2666fe9416776a092372362e7bd8e3 -dist/2025-02-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=cf025264c087d9339787db6f8cd4c76aaa9c3118b7875de7413dc1894b660fcd -dist/2025-02-08/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=f788a44b9542ddda3a88e3000c31644e1b9ee874ce523798b6638f7f181b8df0 -dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=0a7d236cd45ef4f3f12e4516b202cf9b5190e70a19044c8b17c5eef16c45032e -dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=80cf271c8adc2192b212d1b40992d90aa21fcc695375774c17a4f70468c82c11 -dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=58d0eef426f8f0c4bf191118161db008db378ee3e77d973d7e15e39e88c3f7ea -dist/2025-02-08/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=7eedaef7100f7272f38fbc3cc14a1f4fee7deddd31a59f7db71c2a6f2f03f946 -dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=df5190ea7d9bb84d5ffdda74cec7591388d3501c2a4084c667e0f29ca0a0ba9d -dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=96334a22d0534adc8521b6a000f422f1727f80235303137eac32f4e76e85194b -dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=2944da8dab479b4892f512711ed6bb3b242602ab11c81c6b22352a467c898165 -dist/2025-02-08/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=5aa59c9ded50503a2f05d5330ef41ae888254887559b31c4304422aa4ba9e73f -dist/2025-02-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bf17c1d62ae3f59b595c6536add64453d5584135e1d238bae55216c428416767 -dist/2025-02-08/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c60925816b01596b846e56efa7cd0e186391e212da077b36d781b926799704ad -dist/2025-02-08/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=5c73dce13f7e0ad408f39f49ae647b0fbda00416027ba43228a443f311b33fb1 -dist/2025-02-08/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=df005321b30d82854f97a3e68a702c64ded7f4cde18edc69c3b1d7c8927b53e0 -dist/2025-02-08/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=2483fe75cd360607f29fc5f7cfc6d55074047291544f398946b5c263eef6b164 -dist/2025-02-08/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=f2553f96bb513e999597c89d0655bf1b28a338d6510f9a146b3e47674c83c550 -dist/2025-02-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=9cbc32383a8b6025ab9b7d75bf95b831cba32826f2732597cc3749b1a44278d6 -dist/2025-02-08/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=07f16dcf8340feaa8ac400eb54833017d501f78f11f699c095febec148f35aef -dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=03f7b562d15fb47e8e3ad244b127ed170c6296fbf5bf822fddd51eb5ab2a4f1d -dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=834186eb75bff0e05f1a7d9ea63382c7b96a18519aa6815060554b06f3d7b90e -dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=45c7db895ae3751fe07dc7483d0c1ae6dae989ec0b3507eabdfaaf9b1f24af04 -dist/2025-02-08/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=8aef8265279fca165e1627639d64c1f980877744cbd8a927c6c6f3f1e9ef2fd8 -dist/2025-02-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=4f85245ee5c997a7d821ea3c397c5bc7315c8cb07605f2b5a4746f254ef567aa -dist/2025-02-08/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=ec1326a520eb4bac792bce1e260b261e3cd638c123dc2da962bf2f25bf3a89a6 -dist/2025-02-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=dd473534cd897998f6dd361f18a61ea12ed38bbb323c3d602b3124e832ce37fb -dist/2025-02-08/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=a3523178a5186ebd3847b1b0fbdf91f300b29f780fc7910fa867ccddaecbab73 -dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=625777f6ccf6ede941a88252bea183f8f285f6d282f95a78153e5d45e63edaad -dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=7c57c7c0163c74beaa80378974cfbe222f70057e44a025e042989f3816cf02e0 -dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=b431d8683230d783641bbacf7fee8102ecccf527485e8a753781b49906cdfb56 -dist/2025-02-08/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=637801af10b564fa8b2bc8b3075b3fc26efd69237702bdd95b60f6d55e7a92ea -dist/2025-02-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=2532bededd1512c36f97ad91d065ccf681b4df47db86dc382635cbd55e6f1aaa -dist/2025-02-08/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=16eb4fcdc66b86d45af649905b33eb1a9cb9a859eaf4becae10b443a747b790f -dist/2025-02-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=2c29615e4de5f4f9aac64102afee2f7775e961037c2b044ff5ea4690564a0af5 -dist/2025-02-08/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=0f88b8da8d50b7bc1fef09a53c5cedb79d24b3a63b8ab8cc6960285acb7fde7a -dist/2025-02-08/rustfmt-nightly-x86_64-apple-darwin.tar.gz=f46c2a065cf61ba644062b20efbbd6cfd0dcba5b15bc8f333c35e32dd4640e03 -dist/2025-02-08/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9bd81b4ec3625d959f96d7b6b17d6c548673c10f7246b712f99fe40e8dcb4844 -dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2d37451b9314b525d41817c432e3bff5e90028cb020f0331f39490975376bf82 -dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=e8ad4c33272708ba094a2a14e1a69d9071345351921b357ebd0df7d32ccfdcd3 -dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=1d8e24202a8b2111b78531e5313446c6d2e3be083aef77cbd95c09b909b7c49b -dist/2025-02-08/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=9217ed18bb34379079aa529e3ef2fcc899db75780db942b1b6a45cb8f9b317eb -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=f82fdf61057bae8a38daa767f72c74efefaa6043ef48229bed9d8a86787387be -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=60857a9f3518fa6e1a0b8f17a0391672af55bf37bf5fc965b18079060086f946 -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=67384f76d40cb80dc79bf0221a4c021e33f11f283e793404421bd5391d75f0af -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=e1238f9c47666b623feca48243e88ad40ba70d3d762e5e0326dd29eef41f8c83 -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=cdf48fd39c450219ecbc0801aab198c74e31e543b663030bcff9d6df8829f7b0 -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=a5a461c01b8709335c7e2dfef9378ee49aee5f9491f4bf6173142ab87bee3d31 -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=d9881dac0e6d10758cc5e28d3c63be557d596336685b5d095cb77f69853ad978 -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=beec700c0c6829c8975abbd26f7330a3ddc21040a8f2d531f1991f99ac11363f -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=188004d4990d1ca6f8fa7b00dfab510b0cbe840fda4e7318942bc2664c03588a -dist/2025-02-08/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=ff25e65591a638072362122059d71888ddef0b9b81f0b0d7b2fc285fe82192f9 -dist/2025-02-08/rustc-nightly-aarch64-apple-darwin.tar.gz=c97c0921c6749ab5eebb2fcc65cc7fc98af43d1504fa1cf4ef360e299c74fdde -dist/2025-02-08/rustc-nightly-aarch64-apple-darwin.tar.xz=51e12e1a1bb60b65145a5742899f0ba3c60840c60962c424351dd337de7b2906 -dist/2025-02-08/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=469e68dc2e1546ca27117cb3d282a77bd783e84c351d911a2e45c91916fc5944 -dist/2025-02-08/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=ca16024d975f6c4835d53a47cc12e728380ed9e9126f4f523854b5c8af148499 -dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=75e9f08ced58ed868a1c5e727b632c1ea9ed8f483cadc68d30d7394ab3f60215 -dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=c5d3906481bed31bfa563f216e8c17e8be971cf64d0a5d66820025900aa82893 -dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=a6dab5d9fd0ddb5fd83f5332e3608df71b62891c1bc02f73479cf0aa344c4d1a -dist/2025-02-08/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9b4412cb694f46774b5642b972b0c149b5ba8d4081069cf078ee83e7f7ab1c45 -dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=cda11234e3e2370fb2a9ae7d4f50a7c44c646c5ea9dee4d4a576383785ae993d -dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=bd6cece56d6559ae261d5494af10d665bb7293f439287f1d190cd959c598ab15 -dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=c29c0ace7fe5b160e9399813848e70865d4eb90536169d9c6089a90b74e4e0b7 -dist/2025-02-08/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=bea382931c0b9804ab6ea0f3666679493c1c4390a2f732ad367b6540d4279614 -dist/2025-02-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c83086892fb1ce1b4ca0c778e9efe57334bd18d74a961fccca78125d58f185b0 -dist/2025-02-08/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=30ac3e64449a919ccb70dd30350086bcd5e8f4d12e0da6851f685fb60cdb871b -dist/2025-02-08/rustc-nightly-i686-pc-windows-gnu.tar.gz=f51df0f5c9a8a89fabfb347f1164000a99485bd85dd67ca7bc84e2a48f9c80e6 -dist/2025-02-08/rustc-nightly-i686-pc-windows-gnu.tar.xz=153a564d7930f3c217b25f8573f79b279af82b8ea5ad7ccf09f8c127d4cb6c33 -dist/2025-02-08/rustc-nightly-i686-pc-windows-msvc.tar.gz=2d9c05cb1d60804cfca6076f231ac03081d3b2072cdb87e5f1d9f036325a17a1 -dist/2025-02-08/rustc-nightly-i686-pc-windows-msvc.tar.xz=fbb95c6c97a5e4389b761a1ba712f111f808113ef30abbbf0e95bedc5344708a -dist/2025-02-08/rustc-nightly-i686-unknown-linux-gnu.tar.gz=df09eea18c7be163abd768ede37cfdec306563d0b33219ae040d8f9eef263154 -dist/2025-02-08/rustc-nightly-i686-unknown-linux-gnu.tar.xz=3ba7cab1234713f4fffade6344b62fc6b89d264e3b8b993799e5e0051d869e08 -dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=ae94de4d5bcd8c265fb0297078d446fd84bb5ca7f9e61f87e956330d2c439ccd -dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=be81df065f92bd25825af0935b3188418c97e377ed7ce05ae287f576ff2eec9c -dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=96ccf45347235ac893cb61aa0d61aedcc46ae7c93d26f3ad964a73ddd1c274f9 -dist/2025-02-08/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=1e19c00ef298e5cd1334aa60df8873c0925304bb2a996d0ca590d363443f2f20 -dist/2025-02-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=3e44c93e6be85dfcd8031fce279b1d1604859d149a979d91144272ed4da920fd -dist/2025-02-08/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=c3651fdbfec98c155159d799a895917c0df3599dcda71a79bdcedee3c9cb616d -dist/2025-02-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=4875368f83906c9f447657ed70b0d53ae75ff563e6bd9b75110defbaf44ba134 -dist/2025-02-08/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=069716dd18791fea69df0b97627bba5fc83ee466883080ef934f4cb6b6342ee7 -dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=0aa826fe16a9245091b84972be39aae113f62c1a254b82ec91df81a2c2c2da82 -dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2324bf8323d784cd37ca9546295e252a0327e25386ba406409e5c4172412d356 -dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=2b5debffe5fd870828cf54365b21b1cb989bc5223b76a911299208c5ec105c2c -dist/2025-02-08/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=34342b7ac92698d15b53afa13897fa37401e33b591e2a9ebb00ea17bf2ad7741 -dist/2025-02-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=e189c8be0a75ebc0c65e1b467476c510415231c5bb67d742719b39c425ee98a6 -dist/2025-02-08/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=2407a0e42ff8280a16e944f430d2724bed6765295a64a53f463e341d35f9fb0b -dist/2025-02-08/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=ffbaaee6cb11d1cbed985601a58fa5e9d796161b0435b9a8ef547148f042200a -dist/2025-02-08/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=3c6dcdea50189f815b16033dfc8524687d7101eafb266be8f16681fcf348dbd5 -dist/2025-02-08/rustc-nightly-x86_64-apple-darwin.tar.gz=43b2f1b7d16b46419d8fcede2b5b354ab778a1f2c3f59e691b71db8cfa00d727 -dist/2025-02-08/rustc-nightly-x86_64-apple-darwin.tar.xz=6f18083854625d41b5ace4aa8b33f9c1aadfba764a6cb8ce1d5986f745ddfe3c -dist/2025-02-08/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=eba376122f9f9439aa2f6f08a08d496e07fd3e5ac99c82a69eab279e44755b8f -dist/2025-02-08/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=e5b67e358ae1068482f6e09cdacb6f212b6b6c5e87056909b54182d21c6ba5bb -dist/2025-02-08/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=310f2fc7bf1d32926d78e264638d2795718a1406209238c8c18ba76680c58fca -dist/2025-02-08/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=f8915c772b352fd7f25a7f1be36c94f7b383b813d9dae139831c9f7f2b960de8 -dist/2025-02-08/rustc-nightly-x86_64-unknown-freebsd.tar.gz=05bd6715082b006f6d43c369f37c262732e4bb1c44cabe50a201ceb8556ce651 -dist/2025-02-08/rustc-nightly-x86_64-unknown-freebsd.tar.xz=d03c251f78273d4a3de99e650634d30287c4868031ddd3cc929cef8d7cb5d215 -dist/2025-02-08/rustc-nightly-x86_64-unknown-illumos.tar.gz=16804058f8c88358ae2ab0a8302acb092c27a459ca7217d30fde504746be14f9 -dist/2025-02-08/rustc-nightly-x86_64-unknown-illumos.tar.xz=b76535703edb204daf577e42b0a1ae2a41bfa18e0e3205fb5773e7ec12ec9fc7 -dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=5a63f9f4ee7c5a91252ae8b235780ed6349641c9b6593e9038021c3a3927374d -dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=0a53b3706ab2981fadb020362dd497917f8361cc778a11d9a7fa05a3b329eea2 -dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=ab4e3c5a4eaabf0f227b160efcf2f8d0e9a572d079ece83c6313fca9865a5dc3 -dist/2025-02-08/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=dcd74640d883aa75df93b86b041f98ef99178d5f39e78de3ff6801077703da32 -dist/2025-02-08/rustc-nightly-x86_64-unknown-netbsd.tar.gz=cdb3d9ac0651e3d44dbb50b3e341e609e228cbc4c358b126547a2909b807901a -dist/2025-02-08/rustc-nightly-x86_64-unknown-netbsd.tar.xz=f4227393819e678dd67c579fc00b52fc1a3974e270f10593d8b550f7362b5a63 \ No newline at end of file +dist/2025-02-18/rustc-beta-aarch64-apple-darwin.tar.gz=1b51ca064350d8b15c7ab6c8ec996a497e912dc237cafc2c205066fc6416e0ff +dist/2025-02-18/rustc-beta-aarch64-apple-darwin.tar.xz=e4b71f6456d9e62ada6909254606da7f6681f3da0f5bc7d2c3d5c387fea35743 +dist/2025-02-18/rustc-beta-aarch64-pc-windows-msvc.tar.gz=1ff70a5bd238d959d806c3b471a5b03c6cde784944a96a585e0ae0837d2a9c92 +dist/2025-02-18/rustc-beta-aarch64-pc-windows-msvc.tar.xz=5017b351bb90a08041757eae61386b224ec0161c5734293184a87d8903f30098 +dist/2025-02-18/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=8a58b6cc4577615efc76bb9472229098d6f938c1f051ea540409e9dc812dbd8f +dist/2025-02-18/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=330e217dbd1c507c8706aef5fbd0baf9584495445743f38668cdc962adfb125e +dist/2025-02-18/rustc-beta-aarch64-unknown-linux-musl.tar.gz=4060ec54281975880a9819b815120d6a450e4c31ddf1136ecce348e28875d50d +dist/2025-02-18/rustc-beta-aarch64-unknown-linux-musl.tar.xz=0f92b9267a55ac0c764cde63b8cbc8a0a317f7e0817185d380fc2aa35a933687 +dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=4e989e00725e7cfb08ea834c74ec6dd352eda74c13218f7da423ed598af9f9df +dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=b06181daf8842c2e544e5d54169f9bbfc70ee76115495de033ac4e341617a588 +dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=93fe2efcde1032ad636ef509a73168f0ab7fadbca699a27e2882b3832539e8fa +dist/2025-02-18/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=b49d0256381c928785035578e5b7624c37ba732ea7aefca37dbb66b5162c8090 +dist/2025-02-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=56fd36c20d78085f39f0df40f15f7694e8744714104539865b9c3d7b06d47e2f +dist/2025-02-18/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=86587bea60c2b8a114ab33fe65a7152fcf8e1dcca14550712dca72af9fd65674 +dist/2025-02-18/rustc-beta-i686-pc-windows-gnu.tar.gz=32c95c78b223efea2ee8e02fbe3a58ac753ce9284e792bc87feaa051fcff5687 +dist/2025-02-18/rustc-beta-i686-pc-windows-gnu.tar.xz=d2e623f11aee7e81eceb6947e3f7150bfd727eb2f527e4abc6b10d3322959802 +dist/2025-02-18/rustc-beta-i686-pc-windows-msvc.tar.gz=f7ffd07eb2b5e83df513c6a313e28003e3ce923778583e78da9efbb5e62405dc +dist/2025-02-18/rustc-beta-i686-pc-windows-msvc.tar.xz=cd2e61b548a6849b17183fcacb2ac8f94955d893be439793580c39080feb28be +dist/2025-02-18/rustc-beta-i686-unknown-linux-gnu.tar.gz=fedeca202c1651fe4b15cfc411365ecf016376b3cc7c772d2e0d739e0ec02dc6 +dist/2025-02-18/rustc-beta-i686-unknown-linux-gnu.tar.xz=6389f10e2328bdfa81ef1f34406bb4ec8bcb6dcf64d39c95946d32c9fee7f0b7 +dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=21b565bbaacc2be5d066c5d0c49b7c0f5b0bd24690ca35e9c88e6ec91846f744 +dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=4a728e3ec41834775f0b288cdca5ae152314edcaf20d7ea46ea62fab1b9ef327 +dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=0a72f650aa70708f9a72886ea33b7a2e3ffe2a6e2cbcb1d2248f3d9eca74a9d4 +dist/2025-02-18/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=877c3c447f4c25068f70bd7d6dd5078d75b0c194777b2f8a9311a66fc6eda701 +dist/2025-02-18/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=67af5e05ab0a367d3f76c0656823b530a23fb26d9c86db2b433684b9191b8881 +dist/2025-02-18/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=2da086d39eaa000ba629ee15bec740db57039ca3e5c7c55feb9cb9ca6d39c785 +dist/2025-02-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=b079df9a3e5be95a755d22f5ecf3ddeb43f94d96eaa3985770ae98ad0e7e15bb +dist/2025-02-18/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=916fe3b67094bb351320371de9587f01bb65f9b9aed2c7aff7930e499822b660 +dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=356e3173c960aadfb91dcb607a26647895fb1ae11a7cb596b019c71c6dd808e7 +dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=9115c4c85d8c4b5254df41a5d3f55733648ba282711e18a692ee100ed13fb550 +dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.gz=b8a267f9ca2d23385c529924782f633b6b9f66b50cda5986eff91c223d715307 +dist/2025-02-18/rustc-beta-powerpc64le-unknown-linux-musl.tar.xz=84e65fc1d4282d737b6d0b1aaa1c2abd395af215983eb5b3700e925ca6ba3bc3 +dist/2025-02-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=19b1d8618edb5d3a6cf620c814f6b76a462bc965f4aac2cde7aca5849b92cac9 +dist/2025-02-18/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=9914408b5590fe7c43b2aa10c261bb5162b024e396c625b06546564a5eaddb89 +dist/2025-02-18/rustc-beta-s390x-unknown-linux-gnu.tar.gz=37ac73ea85f43a4859d8c4526cb9480e69bcaa778e842128852c8b21c6db6b45 +dist/2025-02-18/rustc-beta-s390x-unknown-linux-gnu.tar.xz=af1cab661b26cab1ade53f12ec08d13d60a74c2f370d9d3617154e0f01cb3719 +dist/2025-02-18/rustc-beta-x86_64-apple-darwin.tar.gz=aa9999ad56f8968e3e0f5417661ff42fbd1bd482a649d1a8c01d6ba5a6e78a72 +dist/2025-02-18/rustc-beta-x86_64-apple-darwin.tar.xz=bfd09bf8db9bbd7557df3f206207631cc4b10d59d0cf6b072e610646b5c7fa4a +dist/2025-02-18/rustc-beta-x86_64-pc-windows-gnu.tar.gz=dabab346a003a5b13265da6bab96fc703c34f728c852092bec4cf08d13daeadc +dist/2025-02-18/rustc-beta-x86_64-pc-windows-gnu.tar.xz=c2252dea69c8dcf6ba0213da8b05b8d9173676fb7448cde684da7b56d2c52577 +dist/2025-02-18/rustc-beta-x86_64-pc-windows-msvc.tar.gz=9ae9c3cb963872b2ef02650bcec15906e0b5e89cc6d3bee0aadfffcec7a1e6df +dist/2025-02-18/rustc-beta-x86_64-pc-windows-msvc.tar.xz=bcbf75c92e9afe6b25bbde275bd38c3cdeda6324baf5b8c99173ca5738760a7f +dist/2025-02-18/rustc-beta-x86_64-unknown-freebsd.tar.gz=5313d0780f6a9587e809da0f1ffc973721afad88a0ef8fb83005c383d79229d8 +dist/2025-02-18/rustc-beta-x86_64-unknown-freebsd.tar.xz=52ab3212d64b56a8da207fe976cbc8d266e962a61c742e6069137b10ff25c3c1 +dist/2025-02-18/rustc-beta-x86_64-unknown-illumos.tar.gz=527f839ddedc7bdff48527a276d3d7f64d475dd815b81c6664f1ce25668e0ce4 +dist/2025-02-18/rustc-beta-x86_64-unknown-illumos.tar.xz=3861d9928983a415cd44e5dc50a99af948fac392adfb6c2147b14fb98dd08890 +dist/2025-02-18/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=0054d14cf00b25cfbcb2a1560887c825f703223312ca9cdd0ad51076bf54a3cc +dist/2025-02-18/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=75a9d69d13e50bb22ec721f9c64d08282d76f285482b285bb61bacabeecd710c +dist/2025-02-18/rustc-beta-x86_64-unknown-linux-musl.tar.gz=305765ca6a413ea86360b970bd062a19f6bc52756551af43d74920fc2a021d95 +dist/2025-02-18/rustc-beta-x86_64-unknown-linux-musl.tar.xz=c7230b578a97fb234ac106c7333615074b9a7a8abc1422f149ad613c2af28134 +dist/2025-02-18/rustc-beta-x86_64-unknown-netbsd.tar.gz=881bd9b260b2c7838ea1b4de2cd6baf2ff4d317e0c159faba1a683c4c32ba267 +dist/2025-02-18/rustc-beta-x86_64-unknown-netbsd.tar.xz=0c4f2cc0bafbf8b41b257e851870b64d3b5fc112f02227f561c645dc439c96db +dist/2025-02-18/rust-std-beta-aarch64-apple-darwin.tar.gz=958434edfc07bf6d10da3d41f01d1511b28d1178423a78bff2f60cd10046dbca +dist/2025-02-18/rust-std-beta-aarch64-apple-darwin.tar.xz=80043af05fb96c497bce55063f2733e37f243f85084f9aa60ab504d7c15c5cce +dist/2025-02-18/rust-std-beta-aarch64-apple-ios.tar.gz=509aa8803b29ccbb97a1a8c12e2ca6b27310d5af313650c7afff45ab1843106a +dist/2025-02-18/rust-std-beta-aarch64-apple-ios.tar.xz=f0f05dafc9a3277b075023bb449675946706307f769590c065cb53ae615708d9 +dist/2025-02-18/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=c37c0aee56c5858f91fb5aa60df28cc92649d4884d5edde57eb6690f494ba5f5 +dist/2025-02-18/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=e5120697e4a118824fdebf6d2a644f8f338bb83e209303fc684095b8f6b4ab1c +dist/2025-02-18/rust-std-beta-aarch64-apple-ios-sim.tar.gz=d5b851917a3f57703378596828e92068c28e00fe0b02331891737c2fc697b5ff +dist/2025-02-18/rust-std-beta-aarch64-apple-ios-sim.tar.xz=ef33164320931007db65f4915b533e5078a7279a7a134fc80045751a5198834a +dist/2025-02-18/rust-std-beta-aarch64-linux-android.tar.gz=4b94607d7c09b4f0f85236fb2237f1859150e12745ee2020cb134db904c1e05b +dist/2025-02-18/rust-std-beta-aarch64-linux-android.tar.xz=3aa7807ef9da83e1a4deebe4a7085e4df1b60edd4e9f237870f827073100d09c +dist/2025-02-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=2d4c8a5a400c35443228087f8203f320253299a5018c1b92526f99023581c3e9 +dist/2025-02-18/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=df8741055b3d4f7eeedec9e0101a1c184a37ffb75b2d4474bfbca577300355f2 +dist/2025-02-18/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=8db9c07d4b68018cd3c67be1e7bc496078dfa8a6852a35c449db5ba19f6bf0df +dist/2025-02-18/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=f112e3d51013ceff37e8c05d80c3605b76ddec8e55474d55815b4860f96febc8 +dist/2025-02-18/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=2bb6d934225823c2dcdb86dca91dd8e488f69b238b283607f75abe9b5de46486 +dist/2025-02-18/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=99036fde94fe0cb3ab2d2f48cd9f9bbb4d2fa784f1bd21afaa71b032cd95b069 +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=c49fee34a02f5d3fe4e03ed7da90e045f7967c3e2e8f7a30804f4da5d535225c +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=88170a13f9448b9671d252f0315aed94b6324716230db7307061d4890cfda70a +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=a5e7442d722f6742fd0436d3c7d75738bc6cbd936f3399190086a88ef311e34e +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=5d07a95e3203ebe98eed1b271a2e6ae44bead53e7bda019a8d256c8553c21bd1 +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=0af6b8fc7f46641d4de61ada9bc9ff01af7775d727121267177fa4c43cc9ed7b +dist/2025-02-18/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=fd68b34e7aba25d8a834c018febbde6c3de7d967e014a738681642f41ec61603 +dist/2025-02-18/rust-std-beta-aarch64-unknown-none.tar.gz=46025b0892498de8e311be7bd6df261065f80a70720cb9285062161a30af5d76 +dist/2025-02-18/rust-std-beta-aarch64-unknown-none.tar.xz=b4cbf42364270c158d801ac7d4b6cfd7bf1f5f9e74a3044e6d959f1971f5bc34 +dist/2025-02-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=ae2a5c63cce6ce237c81ae78cabc6e1e0634c956789c2e2f39e3a6c0d864636f +dist/2025-02-18/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=6bba5069c89d9a0d9a2013715814fb55ebcd77b342ed0dfc72115a18367c5e8c +dist/2025-02-18/rust-std-beta-aarch64-unknown-uefi.tar.gz=0bef07ceece7523d6f41f1d640569c52ebe8a6b97b35da84240d873fd68250da +dist/2025-02-18/rust-std-beta-aarch64-unknown-uefi.tar.xz=cff8b58e158786cee1a719552fb97cb2cd3a12b541641437809428a65eed42fa +dist/2025-02-18/rust-std-beta-arm-linux-androideabi.tar.gz=a34fbf0d01cea60876a6d0aa4ee96587a5e31b6d4f84aa7c1ba5b7fed261b639 +dist/2025-02-18/rust-std-beta-arm-linux-androideabi.tar.xz=7d72d638f5984726fb4a61e81671d9557d0a9a876bf5bbf39b2df3c9983d2962 +dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=9ef3aa1bcbe1a18658bd16359cbf3e94ae1b07f65bd5c69ffbfa964ad845baf5 +dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=93020195c2ce07204179e2d2f900953707e341a71d9371551c4a727afc58378e +dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=5b0a4c4831534de85a5ba5b0149bbd824ca83648bf66babe5dbf13291b06e03d +dist/2025-02-18/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=60f1ff95cc88330b6c9741520c02ec845e7b14943f2927091a9110b7fb1c4305 +dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=0f254a943b6e56873d2ab84e8a93fa7a3ab723df5a7926faeadae4696ed06121 +dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=0c682e7cbba8463682a0a20785ff7fd331d2bc7a32c0cf86b8159897fc5c5ee7 +dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=6c5be45f79035f57ac41fd209f6e7d4439cab5acaa766f7bf001b24196411b1e +dist/2025-02-18/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=bf25eb6650ad27377414d53af6857133a539530c841cf96e3cae4406bf4ad485 +dist/2025-02-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=39ec7fd0ecf47b36c6badc1fc71f1290e99d2edfa9d7cfa72446fbb32ba9c8b0 +dist/2025-02-18/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=f1d578e9251d95c94c20e3ee7888993ec7ea3d967a880f89963df7bea0bbe93b +dist/2025-02-18/rust-std-beta-armebv7r-none-eabi.tar.gz=3990bce70402da79a27fd0f4adb169e4e9faf617bdbca2676bc41d9f85845dd7 +dist/2025-02-18/rust-std-beta-armebv7r-none-eabi.tar.xz=ac944400a3da94e32d7010e10b30879bbb5da456d3d54dfd0efc792884b035de +dist/2025-02-18/rust-std-beta-armebv7r-none-eabihf.tar.gz=1196e2ae338b325ceb89edaab8b165478ec481270a7ce4c65f47f45d76e7b33b +dist/2025-02-18/rust-std-beta-armebv7r-none-eabihf.tar.xz=fead57620d21252c958020e340fc793102d177f76fd90b3936eaf3a22a3b87c9 +dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=e5e81e1501554c2b28745c4d905bbe50f909dce3b7806f6010a9d48cc528304e +dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=d3c9513cdb058685848de3d7864a7fa5a9b1e45f779a7ecf447ac7faae652772 +dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=6ca5598fbdbf77bcf971e62d5b3f486e25d01e95773670bdc600448f29b68a09 +dist/2025-02-18/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=7e0a8798586538c4b322b58b9e1ac90e27dea4a0b5b750873f90b8ec9dcdbe2e +dist/2025-02-18/rust-std-beta-armv7-linux-androideabi.tar.gz=cbd81d4f949248c0c48a60545648a384aa321ee5f590f52d50e8d3639a649745 +dist/2025-02-18/rust-std-beta-armv7-linux-androideabi.tar.xz=75216a970ba5a023717dbbd45b5a1a90ff9533f25deca241c11ebce80dc6229e +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=5acf37dc6035d3d83d003d70d3db3c196b20d461a70385e8e5d545be1f4392b4 +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=8c75b0c815465126d6c7516883c478c78fc83cfb294bd5b9387d5bad65c9810f +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=733fca96e3d6dd232c746a6034bd7cc864f06bfce3d5da3bfd72c5ca4cea221d +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=e9ef142105d0073bf070a6de74e7173fbc09f3f22fd50eef0fea8ab6cf0ab4d7 +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=13f2b55f297628bea201f3caaae0178f0d898c67a696d4b60a37c3ba5af0582b +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=455605ff7e88d69052a4b3798ba27a673807ac1be197a8ac9e57497b5bac1661 +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=5b4b8eae2d86baeb470ad2a143f5d91f0dedeb225607189d9d0f8c8115e5251f +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=fd36a0f0a001436195eacdb52baee2462c43a1f9899b2e01ed60019f8285a95d +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=093900dfc07c4c4f59bd84aa8e9b505890cd8736a994798da8cfd7fb6210ab5b +dist/2025-02-18/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=e5cef28308348a378835ced449affa965f49d9b7382d28cbf32337ae94ebc9cd +dist/2025-02-18/rust-std-beta-armv7a-none-eabi.tar.gz=210229d27f6d574670e9406b98748869212e66713a8ad37f2e5b67ebf27e43ab +dist/2025-02-18/rust-std-beta-armv7a-none-eabi.tar.xz=323197f1dc3fe70e0a540df8a5f5d9475dcb390f1685bef54ba355ad3b48f316 +dist/2025-02-18/rust-std-beta-armv7r-none-eabi.tar.gz=f66d3a794ea7ea0df73b5df389738e6b3e1790b27c06187de2ed1888743ecb57 +dist/2025-02-18/rust-std-beta-armv7r-none-eabi.tar.xz=ae1465d82ea49e5ed33ac95dc0ece4c8fd0ce3df20b21a6a44ed93f33d131aca +dist/2025-02-18/rust-std-beta-armv7r-none-eabihf.tar.gz=fa0d84655bfb7488c9c378ecf833edbde08c652d25fbc9092ed2707b320f657a +dist/2025-02-18/rust-std-beta-armv7r-none-eabihf.tar.xz=251ba3b71c4a0bbdc327a84ee1b3c3deeeed3917fe55aadff9a52a44063f6270 +dist/2025-02-18/rust-std-beta-i586-pc-windows-msvc.tar.gz=9d9d89b206dc85323a7ee765447d1cafc2fab9189be88e1558709d94c51f2298 +dist/2025-02-18/rust-std-beta-i586-pc-windows-msvc.tar.xz=b124483bdffbb41b5c806f6bcc1003ba15d031cf5fe02eaead555abe15da20a6 +dist/2025-02-18/rust-std-beta-i586-unknown-linux-gnu.tar.gz=914925fb75c45cd9939c8692b02efd337b814040ca9bce369d812b97698a4c3e +dist/2025-02-18/rust-std-beta-i586-unknown-linux-gnu.tar.xz=eefceae8f0d42a5e3524ac134afa9a13e938f1680edf605cca2e2d9dfbd33682 +dist/2025-02-18/rust-std-beta-i586-unknown-linux-musl.tar.gz=4baafd6924c5ab59c0c4dfd30272c08328ea1f31b70e8a9a3dababb94c1dee03 +dist/2025-02-18/rust-std-beta-i586-unknown-linux-musl.tar.xz=c75b6e4b50cd731d7f955956ce0afc02f04e2adc4268a1bec8b076eb1733ad28 +dist/2025-02-18/rust-std-beta-i686-linux-android.tar.gz=e067c5483336195763c2f1e9625644075fd93cc86180e6d24bee63aa26b22e99 +dist/2025-02-18/rust-std-beta-i686-linux-android.tar.xz=d4892feae881cc914b94b8bfd66b5e75cc4d62cbb697b8faa3f29d1d70d15f5f +dist/2025-02-18/rust-std-beta-i686-pc-windows-gnu.tar.gz=ff6f43c40e2f8edc9ca21df771c3c28ab77bcb0e254adaa09d8c9433bd56fa97 +dist/2025-02-18/rust-std-beta-i686-pc-windows-gnu.tar.xz=8d6088d7ef7f13bbf576fe238e8a032091359a773845f35e3329b5d8273d1fcc +dist/2025-02-18/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cc62a0e5c529bb041455ed15f646e5c9c918f20a644ed7306ad8beb1abf07c1d +dist/2025-02-18/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=9cdcd32f73d9839c5e6322f8b1e18e3abf825ddbbe9bb498616f0c058c5fb061 +dist/2025-02-18/rust-std-beta-i686-pc-windows-msvc.tar.gz=fecfb22d75b38e9c92c64790833c8ed8b4ea70c40d3d9c67a23277216c1246bb +dist/2025-02-18/rust-std-beta-i686-pc-windows-msvc.tar.xz=a592d638118b0b95e8ef0e174b94c1825d0e3a3aab87d03737eb7415d1b32076 +dist/2025-02-18/rust-std-beta-i686-unknown-freebsd.tar.gz=e8546b2f4fe5746706d2b0d56fe174ee5993bd61a9fe451fd233236d7af0feee +dist/2025-02-18/rust-std-beta-i686-unknown-freebsd.tar.xz=09efaf8f4f26ce6d466c1e20758901dc64348cdf390f4b878b4ee9542f50dbae +dist/2025-02-18/rust-std-beta-i686-unknown-linux-gnu.tar.gz=e173f1ac1662deba8c719965d5d4c77e711cc0eac732d933b6c8ac021a44de5c +dist/2025-02-18/rust-std-beta-i686-unknown-linux-gnu.tar.xz=600aa6b6ed1b49afdcc4978c897cd1e1f801193b804b0d1723319464c8378c88 +dist/2025-02-18/rust-std-beta-i686-unknown-linux-musl.tar.gz=38f7ee73e7067df2b98064b9f0ed00b8aa7c7eeae5955719fa0e2cf1f126ed19 +dist/2025-02-18/rust-std-beta-i686-unknown-linux-musl.tar.xz=6e639d9c45eda6b43ce0ce52e3213172df1875adfa0c13e52385b5aa9fa05da1 +dist/2025-02-18/rust-std-beta-i686-unknown-uefi.tar.gz=2ae2a44ad2610bbe3a97d176bbfd3e43efa22b5713c9591b9f3bcd7609f3a30b +dist/2025-02-18/rust-std-beta-i686-unknown-uefi.tar.xz=d8fcf03e16ce9ada0253a2f8899ee9193083e1638d9e0da6cc76886b6ee14c91 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=cb0f09f7d81b1e49a761a94396dcb4e999dbbea7d70e044785992da9a2aa38e2 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=1cecfc8d91f5f3cb7bc67f49795d5e2c74638df0f7d66a3051a851522dae2860 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=0369af7a8b56dac39448a22f1ad27df42c72ccdcb43cb96e7eaecf0c0d8b94e2 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=a395fd16ea741c72b39db5d398a46a90cae8531be620a3468d0dc13f8a9979f0 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-none.tar.gz=e2ce2c57ad140b9088052009efae96ed04ce14c258cd954ee049dfc9146242a7 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-none.tar.xz=a055dd6cc47dad744fe9343d100750ea013cbe3a5bf4fcdac54e80809352a6d3 +dist/2025-02-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=26f8ba1c9594f7336ad530eef0076f2d30752d2edcf96d944cc962dde3d3caff +dist/2025-02-18/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=32c80782a30c7bf300510e4fa29dad76d9a40bed2d5746c4d55b17fb261d788c +dist/2025-02-18/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=2cd25291aa0c7610f10ab04cdf4ba4d214e0c684bed73d2ef31ae84af2da0eaf +dist/2025-02-18/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=a7f02677a5c35388593142ef95cf56ffe1632df7fd42ff35bff89dafb34a0bdf +dist/2025-02-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=64ee7c6fb36ea45490911ae5557f6a051728a05a7c88b1476489be87456be4bb +dist/2025-02-18/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=250993b5a1915a8970d91f7a10f3f50c907cc9508d71d3b2c8e20914f90254a6 +dist/2025-02-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=deb267998a725fb0288432a51aeac3004d6430fce8683c91d102b6708e5b99ea +dist/2025-02-18/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=49ba80f0a2970948699b78fc60ac09f77dda94e56931399c57c2c81fce8df9e4 +dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=06ff5073e946ed2a5f80f9a5befd7b0c27e9a959cebf26b6cefc5762a0fcdb03 +dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=27f12f5835f564b03f55d85121c9474b9fc93d3084c5b5d0fc63d33c8c9dcc64 +dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.gz=78aff087bbef054b5a6a8d2a1649dd59f69b7f98635eb0c130c4ba87b3018850 +dist/2025-02-18/rust-std-beta-powerpc64le-unknown-linux-musl.tar.xz=e82b6bdfed001c91f8f88f6c37e31ef35f2f25cdca6fe8adfd90d024cc068e15 +dist/2025-02-18/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=8dd6fdb684882ce4087bb96ec2d982c0d808c93c053c774b49cfc705959b4309 +dist/2025-02-18/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=4d6db36241c3d8735e7c2ee84a37ae0cfbc2fc79c6fd259ca4b74e7edb68b8f0 +dist/2025-02-18/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=32e8a2eb316b2a82f80e7268a318df89f732d7cbaba779debe10664aec7d40de +dist/2025-02-18/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=562030f1bdc1307bc0261a2e66c12a6f21fed0ed21fdb2140b1b1d55664aab00 +dist/2025-02-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=52e8c7ab87f5d2cbb712fb54ad8394b50a7f95961e1a7e5ffce981a962899a2c +dist/2025-02-18/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=74f13bf5f0ff428c323c3041771b653d3ccf5a999105869378bf09a6ce6ca040 +dist/2025-02-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=e2b8a784b4c6826d00a69de8e1891a40619f4b17c6e54c5cbed349fedefbd8f1 +dist/2025-02-18/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=a231848519003a9ea1306a7da2139675516c0d94e5cbd8af140bb1a37515d7fa +dist/2025-02-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=82d33d6527db7adaff8bec04c6edb4f3f7a1609fb5e5a91011a3b48dd47af93e +dist/2025-02-18/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bfe440ce80c4547afef2c6b8379bccde9f7206a5406c5a7ed5c06ab460ad8ba1 +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=728c559f432bf8487c345967a2ebc9e4eada676a6d56a68ec32d26ee9775857e +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=51e7990ff209c27a15d40a684d634e5cad26d55913b897c2be6d92fcb849b7d8 +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=ea66ba0e6af1fc7ce741c0838bc005abc04c6ad85c6831d2e05d04f30066281b +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=7429a295ccda168e41e9717647ba4639eceb81a73d66ad7ba01c9e7f1ca19c03 +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=01824c3ca49cfb433de4508282f0395bae8053866691869fb804a3058a403b02 +dist/2025-02-18/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=67e324c82c6a5c9fd279b9bf5ebabaecf35374c741e5728c2db3fbbb6eab1fd9 +dist/2025-02-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=466d4e5c1912937481fbd22d739987d663f3c771ff0efd676b34fc34e9266f87 +dist/2025-02-18/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=409c2870098222c09abcb1c89c7394633222bef2cba9756638e8cad058e3c524 +dist/2025-02-18/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=b31e3389756f78bf680982d6c6415c3712567e5050beddae10d2df52de560e61 +dist/2025-02-18/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=729b7433746947b88b8d4f488e2831bff1a92911b8c25f16a1208542e38d5834 +dist/2025-02-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=56caed9608e88e9ed6dec56ec3265d6464633ed57b14a455c626983defc87411 +dist/2025-02-18/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=9c9d16cac691185cf055117d6888a25f14c72cd110e3bc699c6e78b5d0dc70d8 +dist/2025-02-18/rust-std-beta-sparcv9-sun-solaris.tar.gz=6963215ffa1d2cf9650db8bc36f1eb5c97fb4d824a010c2a65f842fa00b4b4c0 +dist/2025-02-18/rust-std-beta-sparcv9-sun-solaris.tar.xz=9077823bd323a251347336f3c656c6847d5fefb90efed0cacadd510f42afbb74 +dist/2025-02-18/rust-std-beta-thumbv6m-none-eabi.tar.gz=f6d1b17e822403428a6ddf254caf78c75c2d91c208e035590779b51d45b7e081 +dist/2025-02-18/rust-std-beta-thumbv6m-none-eabi.tar.xz=1eb4e8ca0d8a52ddf754aec64b70e7a1f91d2746eef7e3c6d4580a0794cbfae3 +dist/2025-02-18/rust-std-beta-thumbv7em-none-eabi.tar.gz=7793950c2a0016ae90ee8fb70e881047a1f85c82f087fb02532009d6419ba6a8 +dist/2025-02-18/rust-std-beta-thumbv7em-none-eabi.tar.xz=14464141719b2b2c5d4a4b29685f3a2e336c2542ea33af01cfaec2ed7511baba +dist/2025-02-18/rust-std-beta-thumbv7em-none-eabihf.tar.gz=62612b4da1872950af31bf3d9f0a595f019e6c4074874f4cdfa9166c5ff39434 +dist/2025-02-18/rust-std-beta-thumbv7em-none-eabihf.tar.xz=07ab29714f76693f69273a5567408307186b272061501a9ac83eebe944f66d31 +dist/2025-02-18/rust-std-beta-thumbv7m-none-eabi.tar.gz=b2da60ea5d746b607c505279b84aa2a8f3bac3e258ca867f6aeca958e50691c8 +dist/2025-02-18/rust-std-beta-thumbv7m-none-eabi.tar.xz=3eee9280fdd35f30ee9b4a2e5d8614ee916f36cd08629a574f6450721a1fe05b +dist/2025-02-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=c5be169574de4fcd550b67d19834e064b81084e673764390b9f177631f3fb0ed +dist/2025-02-18/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=bcd6ddf6493cbe17236a74c26da7e16a9a752fd39ab453866ae3301cff0c8375 +dist/2025-02-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=e52c2e8272a9ff9442ae6bafb7526cac424d15d4d6d1d8d210fe981b42da9b73 +dist/2025-02-18/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=81adef669c6f8f08b941b0befc6af30eb78b2717c3aacd52a1526d9545548c53 +dist/2025-02-18/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=1036f47867b7d29ae468a040c50da016e20a6a3a291714df4193895234591c00 +dist/2025-02-18/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=508b4f1e307d0b033eab345ab5106eb83ad8dad212f491f1ba92b9680f699bc6 +dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=41c806851db8e59dc9ad8a756c8efde7dc14e8ef5dc4feb81be9351d267b6157 +dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=f3bb9c783f4350e491fd683d057521f497314e85576b26808f4edc7d1d8612c6 +dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=36a3e0675cc972fe6f4f860da47c9d4e0ac175191622c651fbb002207506b627 +dist/2025-02-18/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=c3287e3ebd4583a576f4bbdcfaa77fc21f6165b18573cbfdeb28593494ec14dc +dist/2025-02-18/rust-std-beta-wasm32-unknown-emscripten.tar.gz=4a7128b50478a05d4fdad69715a0a7c9dcc745aab33cbc2e137cb670c6265001 +dist/2025-02-18/rust-std-beta-wasm32-unknown-emscripten.tar.xz=6e3b5981cca095c2414ad4d23f3e69a942a12c1d51dc9e055ad8409c5edbdcf9 +dist/2025-02-18/rust-std-beta-wasm32-unknown-unknown.tar.gz=3b0cbbb35daf13711e8f211da8e2ed4ade96f728be5e5ad3ca02e4d3e32b7262 +dist/2025-02-18/rust-std-beta-wasm32-unknown-unknown.tar.xz=4e50db69d0917f205a16fa3c4ee5e4012c000194ff75641ddeb49bbec9a2ec49 +dist/2025-02-18/rust-std-beta-wasm32-wasip1.tar.gz=d382d7f9787018480329518035fc4ce3247775633423e0f2940c3670cbdd4705 +dist/2025-02-18/rust-std-beta-wasm32-wasip1.tar.xz=e1d9c800db62bf606d9be9a75dd00ac7190acf3fd3592cbdeba67170ddb092aa +dist/2025-02-18/rust-std-beta-wasm32-wasip1-threads.tar.gz=cc7cd664a483eace96710d341132de4f9cf2113f358722425ddcf84cfe821116 +dist/2025-02-18/rust-std-beta-wasm32-wasip1-threads.tar.xz=17156e3e57e304ab3ab10f8191a9952400182d2a46ebcd39d1cfde97b94c0756 +dist/2025-02-18/rust-std-beta-wasm32-wasip2.tar.gz=7ab89b39693bd1bc3f344dce6ad1c127ef38f64591c7be769d07603b2422800d +dist/2025-02-18/rust-std-beta-wasm32-wasip2.tar.xz=2f53c60d0c0388ff644c17e341368e8b15d4c41b2827b03507d4efee100a1841 +dist/2025-02-18/rust-std-beta-wasm32v1-none.tar.gz=3277ec65149e708925ca7fc062cde92953d01569d2700d2831e6ff68768e5b30 +dist/2025-02-18/rust-std-beta-wasm32v1-none.tar.xz=24df037c2c4bcb3d593033d93b6e26aa1dc38161452220d7a73a23a696dc93bc +dist/2025-02-18/rust-std-beta-x86_64-apple-darwin.tar.gz=3878e1506ee4642fdd1bd5e10025c9c289f8d03b7cea876d2348fabc2675b721 +dist/2025-02-18/rust-std-beta-x86_64-apple-darwin.tar.xz=46bdd522559b61848cfcbc8c55d95b190a134f2a0ac19e3c7ebfaea867f9780b +dist/2025-02-18/rust-std-beta-x86_64-apple-ios.tar.gz=e914a0a4a2824f12764b0b91b0dd97a25416686839f35dea2aabde41c011f850 +dist/2025-02-18/rust-std-beta-x86_64-apple-ios.tar.xz=b44ac0cc8cab86ba9d000d2164786b5bdc115ace7990ead57aaba2b0e02750aa +dist/2025-02-18/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=497c75ec8b5f99a625d898b406d437b8902b8ad42ee1d629a0efd27cfee96e44 +dist/2025-02-18/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=a53ed7bfd16d62a7f51509d32fb6cc6b1f3af331f4c4867cbc1eb57da5c3d521 +dist/2025-02-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=3cec5b6714f156e43c85b4b15377475bc38f65325f61de020bddfc2708b25a7b +dist/2025-02-18/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=ea2cc73a03644647dec905100154a3238dd819fd0421f770dbc433cd6dc49f33 +dist/2025-02-18/rust-std-beta-x86_64-linux-android.tar.gz=2eaebfe572503b69e34674ed414357c514bcfbf013e6a2a7bb3fb14f501872e8 +dist/2025-02-18/rust-std-beta-x86_64-linux-android.tar.xz=66c4f03b907515831f9a48c8f5036d4c3115e814507a27abe1e423ef4a7e7c0b +dist/2025-02-18/rust-std-beta-x86_64-pc-solaris.tar.gz=4c8f54f1709908a9edabd9e60d8492cda771db4b51fe766f2a2323a10f184e1e +dist/2025-02-18/rust-std-beta-x86_64-pc-solaris.tar.xz=60d74169e80b3e1297b010501fa5a46a29a7541c84ceeff304b4c2ace7631540 +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=9d043fbcd7e180052b903180114d50c71a2ccbeb22fff7020514b4b0a11a8123 +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=f08905c0b8192f23f214465d757d93e30aee0250dda279d648e948961e0745ca +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=e35a42a9a6eccc4b738b389fdff24ba01ef23ff8d00fbd34100acafffb9c3763 +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=a1fd2d1b1bb1fe9593df7835b5fb81e5c9453c0bbbc17b9ee5deb0512ad12550 +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=feada263ce77cd0ec635ae78c8ce34099385a1f89d1eb680576a85a8adf0d75e +dist/2025-02-18/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=ee8def01984eba376773f7a055a18a4096750d26f96ab9150326dc60ece9fbe5 +dist/2025-02-18/rust-std-beta-x86_64-unknown-freebsd.tar.gz=7791a0155a0a3464d07b176383a4b61dcfaef4bf0247c58d447402fac3123186 +dist/2025-02-18/rust-std-beta-x86_64-unknown-freebsd.tar.xz=11bae401884cce0306b415bb1202c2c63f81395677057fbbe12e9302951a9d3d +dist/2025-02-18/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=4d05cd943f4e4250d50a5f732a64f32431a6cfef59b38bc087b1dbe1aa4b9561 +dist/2025-02-18/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=7bdc7161d66b6c330f027f53b15f164c9ad4d55debe77b7c34971a877bf82caa +dist/2025-02-18/rust-std-beta-x86_64-unknown-illumos.tar.gz=01edf8fdab00df25cfea2ade367dc4f66a1d08d11bfd9a7e56b65a723e14b517 +dist/2025-02-18/rust-std-beta-x86_64-unknown-illumos.tar.xz=9efccf8ba6fc68997123924cddd7008b15f1a57170d03597a370346fdc6c83d6 +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=9dbfabe77853e672d576e70332e07727882cd6af14dee9a00d5186b43763ce82 +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=04e31482a3ff18d8fdff40c4e95b22bc667bc0dd1ba06fadbe2479bae5d97288 +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=ebb6e0c56d905ef064fa15449a72746daa9e3998f5aba5c6a3c132bc676228cd +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=818fc179c8380f0fb70c46e04086926a69b026591ab62cfbc1051abc5c80012a +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=c0a1c692a334821d61a9b92cd1332f047175d4335336db3e2129687ba96ce5bc +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=2c71b87db4cec49e3c620e6b4e0e07f1aaaffe69020b07c87546232ed1ad3b20 +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=c1bbf445dd0b187904af5871bf48a720151ef75fdd3dd13161dad01ef5e87bbc +dist/2025-02-18/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=19963165ec2c35c15024869c16a707bdc90e72032ebf6e203cc67411ec8ba7c7 +dist/2025-02-18/rust-std-beta-x86_64-unknown-netbsd.tar.gz=63fbbd51047125fe30f1954ea19a05d6f051d2a77929952bab326c8ded6db8d3 +dist/2025-02-18/rust-std-beta-x86_64-unknown-netbsd.tar.xz=1c255d1de9c2629210575b862600bf369499a0eb8873178ceff4a337ba9dccfe +dist/2025-02-18/rust-std-beta-x86_64-unknown-none.tar.gz=781f14a54c5e68acde1e68042905a48f687294e2bc61450f422a6e15bf6ab509 +dist/2025-02-18/rust-std-beta-x86_64-unknown-none.tar.xz=d45921b98740f3cce5833bc4fb1e36816f34b81e96c3ca2c76deff4744134c6c +dist/2025-02-18/rust-std-beta-x86_64-unknown-redox.tar.gz=0cd76d3c5b051b0b2015cb08079ea3b5ecbb9b0b68779eb35946721b24c07008 +dist/2025-02-18/rust-std-beta-x86_64-unknown-redox.tar.xz=6dec719cdb7f35f6eafd901414525b40f030566bdf3fb55e3b05de162dbf0741 +dist/2025-02-18/rust-std-beta-x86_64-unknown-uefi.tar.gz=aad1e2cfd4f428acb67d9dac1fab4450eccfe9212f52f99f06c09899285b6b1e +dist/2025-02-18/rust-std-beta-x86_64-unknown-uefi.tar.xz=4252b618ffc906949756ad28a5437d11b0353fe1d755ee1d23502a208bdee74c +dist/2025-02-18/cargo-beta-aarch64-apple-darwin.tar.gz=2f7f459d2595d3f60bcef4ccbd3c72095a3ec54fa3f2221a647ae892c308d5b2 +dist/2025-02-18/cargo-beta-aarch64-apple-darwin.tar.xz=501feb9138f3c11a13fd649d6573924ead10f5e6fb1e759d880684bff11c12be +dist/2025-02-18/cargo-beta-aarch64-pc-windows-msvc.tar.gz=b589177b0287a42ce17939dbbee92d883dfec88ebad33bf9a719a3cb2f446533 +dist/2025-02-18/cargo-beta-aarch64-pc-windows-msvc.tar.xz=d795082d304ecdde233a4b6bb3aa558392b2c5a1553fab213ee99648c49f7a51 +dist/2025-02-18/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=8444d938514ad2d55769cf614774dfb4e5a27c34f8ba8b49329a2bcf0b000162 +dist/2025-02-18/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=02e52fc13ae52066031ac40dad039ad752b83582e5f9e74ecef206aa9206ac16 +dist/2025-02-18/cargo-beta-aarch64-unknown-linux-musl.tar.gz=e89709bb552e7ee73de02b08c6d8820b07bccdc09777eff9716efabb2bdd50cd +dist/2025-02-18/cargo-beta-aarch64-unknown-linux-musl.tar.xz=50944f0e51190f9db065764afc7a41a3a1e39767bd1ef5ec659c98fe9243cc98 +dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=0343dfc2f015d476b3aca59b33dd75f907f595bc24715e6c518194ab1a5dfec1 +dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=3dd6c378c10172b1abfdd1db2fa764d1b48153ac1b5065cf124399941d036e56 +dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6eac5ffb9adaf2591d3b1872249f4a959c04afdf6694e62dc850936aa8d35972 +dist/2025-02-18/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=484510e6b9519c2b047864584253c8c1f725ce843e8dd3117349032314737462 +dist/2025-02-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=fcf4d4b2d401ea689ee32f38b4a61c77b52ff4d3d114b23d0262bd02c3d1ab5d +dist/2025-02-18/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=1a75296c42d6cf93a5e51ecb2b2bfbf0cdea350668d610e8b0c90937163b4f33 +dist/2025-02-18/cargo-beta-i686-pc-windows-gnu.tar.gz=d1b5147ec79466ab9441825b4761e89cebe57ad21a3199b0eca0779683c45ed6 +dist/2025-02-18/cargo-beta-i686-pc-windows-gnu.tar.xz=980850e06ccd90512baebbfe3baaa65b5c089edbae8146fd940c708fd7556abc +dist/2025-02-18/cargo-beta-i686-pc-windows-msvc.tar.gz=78c67ba481cc7b855b54a2edc0297bfb5eadcd83d5a028b05291415417bc6947 +dist/2025-02-18/cargo-beta-i686-pc-windows-msvc.tar.xz=6ea74c750e6e0a794965c6616e5b1a82dee295815b0c24a3898952b1a5a02c8a +dist/2025-02-18/cargo-beta-i686-unknown-linux-gnu.tar.gz=a0c8f67fe77b94674698b4816c081e2ef08500990c0f9eb069d0190df9c4f129 +dist/2025-02-18/cargo-beta-i686-unknown-linux-gnu.tar.xz=9b13f958ec4edff194858e90c54866a129e88769a76fe22582b07e17540708c3 +dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=f4d2f1c8a7bec6d2b8378aa87a324c42f0f414962174b40b6f0d1dc21d0cacf4 +dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=f25659ef3be1a28da8821eb178e02108f41cd5c0b87aa01a052a3a90e7a9da50 +dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=b687a7c3fac08680818804e034af6689f1bbcf8fc0e406c99b2a49ddae1e900d +dist/2025-02-18/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=e33818d2f94e8ba148dbf8cd53d6396e370157acba6d0865a5ac71d292939a0a +dist/2025-02-18/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=9cdc2115bd2022cb0b0ac4f1c71142c064957137decc028dde7585acabb8b780 +dist/2025-02-18/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=f722447494f0a7af9c31b71364aa4a2fde79a9887440d8281e4561f7d71620d3 +dist/2025-02-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=d8a30f9e48e89cb1d18532fd7fbef8eeceef6bc602ffaf9e730c635e2fdbb156 +dist/2025-02-18/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=ec6b3b1595c5761b8092a04a412e79534c28910ed78ed792c9af7ddc4d92a389 +dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=4bf9c73173199fd3ca952d33702288deb483c7fd392179352135b64e7e8fadb4 +dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=12aa06644e07344a77d0c16dc1ed96bfba63de02df1f432d57b82f8a1e2282b6 +dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.gz=eab362146d449dcdd10740c8e6f9dec6e640ffcca162eb51febbc835e34acdfd +dist/2025-02-18/cargo-beta-powerpc64le-unknown-linux-musl.tar.xz=867b716eae9225c66c0ab4642e4e497055ad2effd24343bdf80354ce2845d6f9 +dist/2025-02-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=0503ba2e4b1d668fa3a3174f96ec3fcc12ff767574a7af8ef5fc824ca86dc965 +dist/2025-02-18/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=478b9f1d4f517f93f15530d27a7d55ea29cdd06eccf01176ffd08c0ee3204c1f +dist/2025-02-18/cargo-beta-s390x-unknown-linux-gnu.tar.gz=419a679aaf6e164649538916daf28081a063bd56c7b86ff0e2df58072f334fdc +dist/2025-02-18/cargo-beta-s390x-unknown-linux-gnu.tar.xz=31b39e242035036c1101412b7c86387e1183063ff5f6ce67d311d0764435a588 +dist/2025-02-18/cargo-beta-x86_64-apple-darwin.tar.gz=d6d5224228dd54b6d16be30271111620c02fd88e656b8bbd22452b66b0d5cb56 +dist/2025-02-18/cargo-beta-x86_64-apple-darwin.tar.xz=cbeff7c031b4ab4732207b90ee8849b27f03cb28d3e085bf4d70444347dbfc99 +dist/2025-02-18/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ae5922955ec579732aacd8112bc53bf5333438eb81d0f81dc5f387888ac979a3 +dist/2025-02-18/cargo-beta-x86_64-pc-windows-gnu.tar.xz=553c55a2bc8eae2c8ba831823a97f2232808af1f753642ec4cdd09c33dd3f6ae +dist/2025-02-18/cargo-beta-x86_64-pc-windows-msvc.tar.gz=d9b2cf14565478429fba6266f0c86a58f3bbd1ce11a63268828b33ccb55759cf +dist/2025-02-18/cargo-beta-x86_64-pc-windows-msvc.tar.xz=2e8c0560355d11a038219072d2503860f5c5b3cd137b89ad931f54d9bba60499 +dist/2025-02-18/cargo-beta-x86_64-unknown-freebsd.tar.gz=4b528361607845e6f8ece403bbdb8d77c6159ec137396319562ea2772502792f +dist/2025-02-18/cargo-beta-x86_64-unknown-freebsd.tar.xz=c244ec4f97420c29c690e32bd6d8f14994bf1d990747f31a3dc0f2b37644493e +dist/2025-02-18/cargo-beta-x86_64-unknown-illumos.tar.gz=7d3b49df93e87322a9e99e36c6df020d3311c5538ad2298d8b5d8f2d9ad3e0d3 +dist/2025-02-18/cargo-beta-x86_64-unknown-illumos.tar.xz=136ce90487448ee770472d4bd2c0d9c96200f0ec762419feb42fefa26ba36b58 +dist/2025-02-18/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=510538965ea142405925d3f4f03a87783516407989b8aa7be07fb84c0680e9fa +dist/2025-02-18/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=a8c569398d71cab0b90c809b1d869a2e3c5037407b5af804df08c205775981c2 +dist/2025-02-18/cargo-beta-x86_64-unknown-linux-musl.tar.gz=1493f66e5cb12e8b955841804e7df745e26daea2278144aa57670192c4c62cef +dist/2025-02-18/cargo-beta-x86_64-unknown-linux-musl.tar.xz=472bbe49415557b75b572879d0c33750731c1fe9e56cc6ef3b0fd5532e56446c +dist/2025-02-18/cargo-beta-x86_64-unknown-netbsd.tar.gz=d3baa6019e13449c01fbeebebce42027ce4ba70841cf28733f6849e7c6ce5d89 +dist/2025-02-18/cargo-beta-x86_64-unknown-netbsd.tar.xz=0db9af42e9ad914a99db4924721c895cdf490bc5351bc8c2d8993e3569e952e4 +dist/2025-02-18/clippy-beta-aarch64-apple-darwin.tar.gz=6ce3b464744082131c99a213454225e5702564c83032e11dd0f3d95530a4e0af +dist/2025-02-18/clippy-beta-aarch64-apple-darwin.tar.xz=925baff0d91b959a99c989a4ada70973baf3da03e1d7e7e8be1fa334c3acbc50 +dist/2025-02-18/clippy-beta-aarch64-pc-windows-msvc.tar.gz=76d265c2fb6280eb8ed399501964f301a50e09e548cee708ebacc978d8db538c +dist/2025-02-18/clippy-beta-aarch64-pc-windows-msvc.tar.xz=e3d1d69cbc838ab639b2e41537b10266f1b6998a228882d4041f35cbb8984909 +dist/2025-02-18/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=918191cad727d795b51f892abb6e4fc87ed735bfcb51433cfb4371cb8be8690c +dist/2025-02-18/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=157d6eb9e7dd80dda7daae5584d095a5e68d13ba8b1d1229e90b5b51f6670e8d +dist/2025-02-18/clippy-beta-aarch64-unknown-linux-musl.tar.gz=fd4de290450e3d3c9188263d9506167e298f4c2d4c781fb3573806694b5ca1ba +dist/2025-02-18/clippy-beta-aarch64-unknown-linux-musl.tar.xz=335c5fd24d1c118e4d1d8abc43d3529dafc9b30af39f6b009924cd0fea676182 +dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=209cdd2042e293d1061b149d97333515821dda0ffeb9b30f24dd2dbb4c1ad548 +dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=57dbfdc34ff4e74aaa8776b80d35aaf0317fdc314ee4b0f3bf58fc672963cf38 +dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=a89a2562fe9ac6492a5de220c395f433b0e53a8b29c72b3a8d4843f996649ca6 +dist/2025-02-18/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=0e6ff6453df1397e7b12e7e356e7c7300cfb1f85bc3a6705735067128d2a8135 +dist/2025-02-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=7764c2dbaf217f4b1d8ca4ed2ceaacbb91e8010d26ae1bb10b808afd5dc6a798 +dist/2025-02-18/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=b7a042eb6830653a623c6299ef57492ae6c9b51a9cd8480f0a6fc2fb6d378bbb +dist/2025-02-18/clippy-beta-i686-pc-windows-gnu.tar.gz=ff41e5b666b3531ccdc0ee836dceb270179d6a849e47024eedc6ea309d36791a +dist/2025-02-18/clippy-beta-i686-pc-windows-gnu.tar.xz=98c6386b63ed89dd96beea223f4c720320b6ca460f11b77c46427e128034cbbb +dist/2025-02-18/clippy-beta-i686-pc-windows-msvc.tar.gz=12bd371402e4d3251f60fa29b3b3aca88b4480229088b68791dffbb4ae1554ce +dist/2025-02-18/clippy-beta-i686-pc-windows-msvc.tar.xz=62a22d1e9b4fdba254e549f5edb276bef5252754ba67a76526d5aeca85515646 +dist/2025-02-18/clippy-beta-i686-unknown-linux-gnu.tar.gz=04179b3a20a68ae2fd8444832ea4edd8155dc9296c7a1edf101053e3ff934891 +dist/2025-02-18/clippy-beta-i686-unknown-linux-gnu.tar.xz=c955e464e99097025fc7d0e42bf90342f74f475c5148526df2f51ca46ce8db4d +dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=6f58d326a1f2a35246384640b999f95a961a9fe1e5a3c4a3e67d7f96e1ef43fb +dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=583b1d55a38fdd473a3f3f3cc0fbeac808fbeb593b8b45c7a6b8a09dec0d68cf +dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=80d73fe94ecbbcdb14b35e1616d52e0bb9b1f04dcdd4fc384e7103cc36325014 +dist/2025-02-18/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=1bae908e4d3931eb4dc71ac1524f990bbccaadd9d30897bf516899baebd4c5d5 +dist/2025-02-18/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=b882e7ea97e0d36b289a46ef84b14b2b44ccea93ebdc77b2ab3430361ad15b1f +dist/2025-02-18/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=91e52dc398dccbafd040e401f155c204f2a14d5f62aecfc24912910d5e45008d +dist/2025-02-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=c81497f2b2d2670b9dea2e35804e10780c1631a8761d4bc3331767c1ccaad6b9 +dist/2025-02-18/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=6236e129f3e551a3126fa07662cc8ad512ad5fcf436a8da9e27a915ad4c234cf +dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=1b031f055ea4ab4a9da0c8bfb0037e92b493caf7879351f8b404a96c447ec92c +dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=2f07224e49f7cab10d673116d9dee9f964b4c44ac3db336e7ddbab9e0b1bc698 +dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.gz=84a8295a7066d258404c87d2269a01d89cc7efd0f143ab53689597f3fb351417 +dist/2025-02-18/clippy-beta-powerpc64le-unknown-linux-musl.tar.xz=019460a6b0e1c5c1331d5a54f3e45306ba0d1b1c2206e2e69f38c1c3501cf741 +dist/2025-02-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=aba8f7bd0a89205961f9803418cdf9bb63a7d72bab4a1ff937f4a142921f4833 +dist/2025-02-18/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=4607503ba131ca655dab86ad48c1737f216f8ec25ba6dfddbf1f0807e5a6dd2a +dist/2025-02-18/clippy-beta-s390x-unknown-linux-gnu.tar.gz=b0170f9b9e13d4f6e016124fd40c858e00155479fb4f96c1edc896130bb76dcd +dist/2025-02-18/clippy-beta-s390x-unknown-linux-gnu.tar.xz=397f0a8944beffb87c74717bd0f422836b3daccfa848d91c0a65875031bf12fa +dist/2025-02-18/clippy-beta-x86_64-apple-darwin.tar.gz=11be90b9b09f4e24e56df2a602ed8161023314514121d9f76e424fb628df468c +dist/2025-02-18/clippy-beta-x86_64-apple-darwin.tar.xz=16d313798f12d0e74f888b627e079606958de58eb2ca4c70d5f7de8cce72620c +dist/2025-02-18/clippy-beta-x86_64-pc-windows-gnu.tar.gz=41ed081e4a7b205cde3fe958db18ffe1c1ac5a9c336f965a03fe89499a3eddbd +dist/2025-02-18/clippy-beta-x86_64-pc-windows-gnu.tar.xz=daaa3267dcbb3daa0cae47861683f29da5b7419214ec5949e242aa93e3f87148 +dist/2025-02-18/clippy-beta-x86_64-pc-windows-msvc.tar.gz=6d9b8f549e34d8fb65987b39c01c27fbb0e18e8950a07ec6fd1888d01e253971 +dist/2025-02-18/clippy-beta-x86_64-pc-windows-msvc.tar.xz=1c26b51c484f5b10ee693212e258fb86c63a2b59e631542918799d480a3587d4 +dist/2025-02-18/clippy-beta-x86_64-unknown-freebsd.tar.gz=a42777c542773a4262ac9fcb07ed13f769957f58a795160441241ad4e4f5258a +dist/2025-02-18/clippy-beta-x86_64-unknown-freebsd.tar.xz=9e809fa141ac68557f203aec2a6cc02a4ddd22169595c40ed4a964801ccadb1d +dist/2025-02-18/clippy-beta-x86_64-unknown-illumos.tar.gz=4e65b5db249a18e73247029506f619393be7042f2c91a00301962effb76a18ea +dist/2025-02-18/clippy-beta-x86_64-unknown-illumos.tar.xz=6714018d069fbce271c177f1941a6b77f18b67af462596aff273f7db1970ef4a +dist/2025-02-18/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=72a8ee3bad3d638af0cc3ba6c0c0ed1594abe609573de71d9c7a884a8ac7645c +dist/2025-02-18/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=f622befd60c3695d3d62642b953deabc3e3f04b32cae8a7cc228cb534244adbc +dist/2025-02-18/clippy-beta-x86_64-unknown-linux-musl.tar.gz=8946e02ab98281b6949c4d725a5fe3fb1bfc86651a675e451f126fec8d053762 +dist/2025-02-18/clippy-beta-x86_64-unknown-linux-musl.tar.xz=425907bd4320c516647e5dd6df6154746d64854fe2e78f27283b7fcb27164de7 +dist/2025-02-18/clippy-beta-x86_64-unknown-netbsd.tar.gz=505208d2d73ed7278e5b29d8450c382a89e4c0992d6199243e07c8640c611b85 +dist/2025-02-18/clippy-beta-x86_64-unknown-netbsd.tar.xz=d4b0306e7d7db5cb7da977a7ca72fff2070f102ac385c3b35286da25033582af +dist/2025-02-18/rustfmt-nightly-aarch64-apple-darwin.tar.gz=13854358645915af29d9337bb87301aa1a5e76ecc86a934dd640d02af3255ea2 +dist/2025-02-18/rustfmt-nightly-aarch64-apple-darwin.tar.xz=0cd190bd5a064235f9cd6f6e7eae4725b3b53ae36493b3ea54b8f190372ba3ee +dist/2025-02-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=20b3f8c4c7b02158181970804d419b16f85a1083943e1c384e0bcef441f32aff +dist/2025-02-18/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=1ace0f10060d2fc35a1f05a1d61adebf95212e8b46a2234c2e78030481c1b3e9 +dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=e5ad64d67931df49f6b7d3448e9860699d6549c2b4a96abda1a03069b45f339b +dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=e8112ae80c8fd43452612b79dabf471be561b7e828c9a2141c698429d761a49b +dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=8ad36bbe888e61b6d7e540ba4a2478652f14c1b28dbbcaab732003293b7c985b +dist/2025-02-18/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=1794af320a273f4a951942ff0cd73a359fd82a971c572af1ab7ff2961340791c +dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=67b9d1d3c46bcce0aa94d6cb4155cdf7376677caf2e19685553266f781eb7cc1 +dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=9d7b97a85b1368cfc78f1df42afb08aa04eb17fbb91ceb3c379d59fab4294890 +dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=42396c7bd206d0fa07f3b44fcb894ac074e2af07eb158c1ef630bb5467151c8f +dist/2025-02-18/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=6881c9681342f1430fd9cc8c9786cee40522be3dcd0fc4dcf2b3957d9d53f03e +dist/2025-02-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=6cb8973ac4215d67aad9bb56521024626d7883a6e00748623a728dd9107698db +dist/2025-02-18/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=920d877e04260be6ccf9963bea12220e886df673cbc48b55925650f8f5b21d9f +dist/2025-02-18/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=ec5c7105f2c2a2055f704435fff9edbbee0a234e63050676c034f983d4e341ee +dist/2025-02-18/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ab408b64db4bd47abf8e24c0f611f2c67a3c9ce7e2138a92772e0510c6dce5f9 +dist/2025-02-18/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=d04250bc2e57fcb03f1d80722f2ac1117f797d768262d7630c9b53af808a8c9d +dist/2025-02-18/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=6d7be9f04a46040f068544e32eb84c98afc1f81b750beb229def84a7513150fb +dist/2025-02-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=94f585a7c666dc9c95c3ae14744e614a3fbe37b3e31b476b48bc4ef3289bdd46 +dist/2025-02-18/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=83e82932245b3c1d3c275126184f942b9cb8bf20f0d40c7cb1efb6f918327b9d +dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=9c8cb5a14294c48f8ee972d5f460751a8bae5b541bff3d872c85812b621c39d8 +dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=4f616740bef30599e6950ae2d8ae694513003e14122f6002a9d60bdc64f77cfc +dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=a668e7be7946f6a9099486a40256f17832288322c9237d931f172ed76caf678d +dist/2025-02-18/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=b02c57c217f358ff4344ee2afcbb8353cffc0a012f970d9520ad233d188d59e2 +dist/2025-02-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=9baf04e268999020372b21484ecc4f5aa001b3bcee05619ae5b0a11571a3a45f +dist/2025-02-18/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=b2c2c3a0eecca7b4c35eabf09e215158c48eb426899e365db1c91c1c560ad255 +dist/2025-02-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=c42df8e575a24a5edbc58b5b46a89a226188d2aafc59da89d568acbb6e9cceb6 +dist/2025-02-18/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=fee7c373bb8fee5c7d4e43d7a7046d3bb156d3e496ed21cddf20c21ffdef3e69 +dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=a0ae21a3b56e20e667c72d92ad4bacd4abb77d1fea32949d7dd62a56d6b531d3 +dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=fc7e21cbd61169b37e81c73d4d5353d7e54ca322fd01491d9f37ff3666557e7e +dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.gz=e08ceaa9241c2e53041b107af09674ca4fbc4e12b1371254869e3d80d5c907ab +dist/2025-02-18/rustfmt-nightly-powerpc64le-unknown-linux-musl.tar.xz=9f208dc6e5938a128174263349345e9fe7f587689f6a53fe5d026ae3c6fbed2c +dist/2025-02-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=44abe49dfc0492cb3ab28f0aae0d784c982063399a38f8f13016f3dde123948a +dist/2025-02-18/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=72fa294f92ab244608c384d6ad6eea0e540e6fc58181fd65a4fce0c5029c39fd +dist/2025-02-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=556dcf393856c6d9c9c6731b02e34146f9f956f588025b6a614b8802032d125a +dist/2025-02-18/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=93906364910891f71e13e0ecb07f02b707e42e11a0f1b117c590804dfa16a9d1 +dist/2025-02-18/rustfmt-nightly-x86_64-apple-darwin.tar.gz=7022c760f457075fb353e59984dcb551600581a315fd17ea1320b892b1d99a55 +dist/2025-02-18/rustfmt-nightly-x86_64-apple-darwin.tar.xz=e085ee261acbaa41361a0263dd8f13644f8a4e3679eca6bb0851b03c647b80e8 +dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2436e18fefae02554e620a1131455d923c1b67e00e878c75a941a6eedb4eae28 +dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=9f6e37b5973925d07115e517e6a3e490a221218f48fd101a20670da2c3d01add +dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=78f492a26981e7a6f9f3e8bbd1e880682e55cede081f3cfb13a2ec5f736edbb2 +dist/2025-02-18/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=d4d788fa3e3b9a598aa7baec47af3b56362224533be85dd68a411f35f8800b2d +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=8922186dedf0b12e9aa2bb041b76be8fccd43b9322c3496c688355f34bbd7a59 +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=6325e43f2c28118a9525f5c5fc09de9fb9a09ffb4aaad31f28d394c233ee8398 +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=7f317107f8319c650973cef52f745c2a8e57ea6a087910b6979404f2cb2f1cff +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=b273be4897e83f786020bce1dc5dd1caf01e2ea43f085391c0031277718feba0 +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=0373011266a9ab62f45fa137a4bfdb970ccad8bbbb74bf776466d203f28d226b +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=62748525678370dbda7f1cbd12a384e95d4af76103de998785278f6d1f076177 +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=30eeb980720d8c22bc45c012c4fd212e118195206b8b993630f074e526e6693a +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=2f3843d9544fa56dc87f1d13ef79c68c1e68d84bec007f0345159a7448368dfe +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=a86eaeab8f5f45d16eaf355a46d8b19afcd8c46db732432091156e381aa79cb6 +dist/2025-02-18/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=144cd28da601c331f6501c634ad89286be213a69cf521435e35657c5f6fe2afd +dist/2025-02-18/rustc-nightly-aarch64-apple-darwin.tar.gz=21101db859a550ab39de1ecdec75f4f058934ed8e0ab7dfadbb2efab57bc5e0a +dist/2025-02-18/rustc-nightly-aarch64-apple-darwin.tar.xz=a40da26e908810701112b9d3f9ab83515c8e2f4b33219f8f773c5459366d37e1 +dist/2025-02-18/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=5391bc993b7208c10a6f4256417c9f76a4a33d167b2fd547b57af614d3fc8458 +dist/2025-02-18/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=d72a205f52173b1726d8341a9436e62439b1987fe0cd4d2bbff740e38f629b41 +dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=185e052bf2ba1cda4b6ad1c49a9f65b906899ad1ca09cd864d6041941ad344dc +dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=640f7af3fef5f0abacdaa292ce17255433ee16f12bfc2d2e81d70afcf9fcdd8f +dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=8cdee468a90606b21a8cc3305f2b6b3eb7e3d687263f4ca8319c709cda2a324f +dist/2025-02-18/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=358bbfb24816c781e07d5480a5606dce27068f856c0a606873ceba05c9540c3c +dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=b220757cc8ed39c429c49b55e293ded3e07239d2e2bab8a9054ce55581393c47 +dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=18d3cbc49e44b7810b498517d21390e39bee7ca8351c8b321592e83301ad79e9 +dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=77ac127bae48859f57d9bd8337ac4a0bda95b1190e451abeaf7e77f1a240a647 +dist/2025-02-18/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=79009bbf0325f9db0c905d74cb0f139c92478a0b2fb5edaf383366b0e654a172 +dist/2025-02-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=8264c7ed7bc47953ae76cf87236655562a55846abb195bc9281833a0da168db6 +dist/2025-02-18/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=c6a85e7f2a469fb05f0a84ceaea25dc0d95b57bd4d68dcee447918162cb36b2a +dist/2025-02-18/rustc-nightly-i686-pc-windows-gnu.tar.gz=0f31c9ed4ba7e942806fc2927d305f9d3ad676cf81e53e0f7c4123aef375fedc +dist/2025-02-18/rustc-nightly-i686-pc-windows-gnu.tar.xz=350f4b46dee2aa6ebfc31912cfae5c7c1db99b298c52834308e95c504cadbe7d +dist/2025-02-18/rustc-nightly-i686-pc-windows-msvc.tar.gz=e12a40b7178995ac223eb7fa317e1114a988256d99fe615f70d64cf3f2891fa7 +dist/2025-02-18/rustc-nightly-i686-pc-windows-msvc.tar.xz=09fb4a4744a55bf8fd6371e5496f6a9c00b119ddf20b19855653d66d9a618214 +dist/2025-02-18/rustc-nightly-i686-unknown-linux-gnu.tar.gz=52361a34730f8bf14eefad7e51f66fc3ba3be405a364d4520103208fe8fdc056 +dist/2025-02-18/rustc-nightly-i686-unknown-linux-gnu.tar.xz=ea81964fc8bcb8b43968acb6a4f7fdec2ddea9f75a8be5446fb01b4267d0d75f +dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=11e7a143112b6abf818652e425b6f092464cc9d8f5286e90180c7af8d5939643 +dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=86f5d40eecccb623ff744bbc1fb40458949db9b2f8501cadc6be9bca95f6c693 +dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=1be7ecdf609958fb0ef945203b22a600f1e343ee7fc581f6451eecd39f1e0b7e +dist/2025-02-18/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=03d3b67092da64f7b7be7ba4e115cfad4071c0bea3abb5e60ac166127713b169 +dist/2025-02-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=4e33311490c2dcf79a16307e1141ce37574ec3829a1e93d0f5b06ff68ad5c861 +dist/2025-02-18/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=504c102fa1c8dc5042cb354a60b87c0f6d47f9adab341f496af723f3ea8bd548 +dist/2025-02-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=c559971ae42a5e0e999e2fe119033bffbfe8c64b767e697e0b95f5dfc271d13e +dist/2025-02-18/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=51159ab0ade5a62e128b6c794da5c9815324470c468e5808b50663c3a0df6d39 +dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=a8134f8f7ea4531d54ab5c0a0894f140ce5182a384c57395edbe06ed551970ab +dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=8f2f5d88ba9f4ee946db5f00d56c4852213dcb0b46ce2793966af6c96d934dc6 +dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.gz=7bfc6666757b57fa6160d076a9eb52852dcb5bf788bd12c0f014bbd552b8a7ef +dist/2025-02-18/rustc-nightly-powerpc64le-unknown-linux-musl.tar.xz=e2c3293e2a90012ad48bbc2b6f285adf20f356ff1f4146b3f11543511bbb3c44 +dist/2025-02-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=f582a59b5a6cbe6d58400c69f1cad4f34d0f1541c1ffb9df3ce71846edd828fe +dist/2025-02-18/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=244384bd94f7c3606a086abc8be9d36a855faf09d9bb6b121f42e168c526e717 +dist/2025-02-18/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=327e29662140cb76b1ff362fe51f9a12fb4ec304929317ed8de7295fdb9c5b9f +dist/2025-02-18/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=a2c4e19b3a8dabd5c8fe72edd60d1925947cad5971c77c62f12fca764c6e4e7a +dist/2025-02-18/rustc-nightly-x86_64-apple-darwin.tar.gz=b6812f92e08cff1b706380637fdd553b04b9cea746ffb69e6488fbec70680136 +dist/2025-02-18/rustc-nightly-x86_64-apple-darwin.tar.xz=f2502b2a810938c41e2302a9112c97d04998ada16583373e6488bcca00595761 +dist/2025-02-18/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=9159f7323718c6a8b98f7de5186ed507b3dca1bfcce9bdfa6437313bd630a989 +dist/2025-02-18/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=10d54c9b80570b6729d0e68f017d862c5126f09b42f150d004aa8fd5382b165c +dist/2025-02-18/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=1f29c1aef1dcc3ff9f2e3013b7ea0521829e6e474f9058cb70fea65180230b41 +dist/2025-02-18/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=18cddaf7653f146dcc8a44ca0cc33c6dd3c24f28fff87aedca01fe3beaaa9915 +dist/2025-02-18/rustc-nightly-x86_64-unknown-freebsd.tar.gz=e57c1477cf9b75e727db48b8b75435d65aa0a6ef0eb566ac1890b576c330f64f +dist/2025-02-18/rustc-nightly-x86_64-unknown-freebsd.tar.xz=725f9e9d25b7ad6f60d5596684964b0c3a63d98a62a2aeda6a134b9f02fdb681 +dist/2025-02-18/rustc-nightly-x86_64-unknown-illumos.tar.gz=86a9034fa275c0fc73d639fe6437fc4d2621bf12897c9f83a81ab6056173a95f +dist/2025-02-18/rustc-nightly-x86_64-unknown-illumos.tar.xz=4aeef66ad8a908589ddf0d89581a6ca809b7c2a57f06bbda6fd3927b531fe07b +dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=907aa282fb9f3d96c9fb03dadd62f4ea766e1242fe19106ae331a4f49a9b20f0 +dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=e63d13a6acd596ebfd7bf65b292eedd2a5e260b536ca11517a3fe1d8e6a6241f +dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=b7bee098c32b321551f68e96e002f85e3a0323c864aa7f65641a58ae24f4238e +dist/2025-02-18/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=e5c22c2fab89c7ba548b11104c54e8f82cafb1979ba73a318682bb10ed9e4fb9 +dist/2025-02-18/rustc-nightly-x86_64-unknown-netbsd.tar.gz=7bf40bffe95437244f6f8a5fde69499f42d2b716e166115530fbcdbdcd837887 +dist/2025-02-18/rustc-nightly-x86_64-unknown-netbsd.tar.xz=0adeaa382f289233ffc9229e116a340ac03a861f0fdbb5bd35aaf5d0d7370877 \ No newline at end of file diff --git a/src/tools/cargo b/src/tools/cargo index ce948f4616e3d..1d1d646c06a84 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit ce948f4616e3d4277e30c75c8bb01e094910df39 +Subproject commit 1d1d646c06a84c1aa53967b394b7f1218f85db82 diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index aff40fa846be2..c0ae4960e10d9 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -362,7 +362,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { } } else if let ItemKind::ForeignMod { .. } = item.kind { continue; - } else if let ItemKind::GlobalAsm(_) = item.kind { + } else if let ItemKind::GlobalAsm { .. } = item.kind { continue; } else if let ItemKind::Use(path, use_kind) = item.kind { if path.segments.is_empty() { @@ -467,7 +467,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte ItemKind::Macro(..) => Macro, ItemKind::Mod(..) => Mod, ItemKind::ForeignMod { .. } => ForeignMod, - ItemKind::GlobalAsm(..) => GlobalAsm, + ItemKind::GlobalAsm { .. } => GlobalAsm, ItemKind::TyAlias(..) => TyAlias, ItemKind::Enum(..) => Enum, ItemKind::Struct(..) => Struct, diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs index c01155ca86e01..348495f97a27b 100644 --- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs +++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs @@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones { && !cx.tcx.is_builtin_derived(resolved_impl) // Don't suggest calling a function we're implementing. && resolved_impl.as_local().is_none_or(|block_id| { - cx.tcx.hir().parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id) + cx.tcx.hir_parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id) }) && let resolved_assoc_items = cx.tcx.associated_items(resolved_impl) // Only suggest if `clone_from`/`clone_into` is explicitly implemented diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index 772268e7899ef..784214c29af9f 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -52,11 +52,10 @@ declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]); impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback { fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { - let hir = cx.tcx.hir(); // NOTE: this is different from `clippy_utils::is_inside_always_const_context`. // Inline const supports type inference. let is_parent_const = matches!( - hir.body_const_context(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_const_context(cx.tcx.hir_body_owner_def_id(body.id())), Some(ConstContext::Const { inline: false } | ConstContext::Static(_)) ); let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const); diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs index d1ffbb6ffe251..e8638595c4b26 100644 --- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs +++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs @@ -24,8 +24,7 @@ pub fn check( if !check_private_items && cx .tcx - .hir() - .parent_iter(owner_id.into()) + .hir_parent_iter(owner_id.into()) .any(|(id, _node)| is_doc_hidden(cx.tcx.hir().attrs(id))) { return; diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index 93c2b7a2d1823..713d62a8801d8 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -1057,7 +1057,7 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> { "assert" | "assert_eq" | "assert_ne" ) { - self.is_const = self.cx.tcx.hir().is_inside_const_context(expr.hir_id); + self.is_const = self.cx.tcx.hir_is_inside_const_context(expr.hir_id); self.panic_span = Some(macro_call.span); } } diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index a090a987d4fc3..2e1f8ac615a23 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -41,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { if let ItemKind::Enum(def, _) = &item.kind { for var in def.variants { if let Some(anon_const) = &var.disr_expr { - let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); + let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body); let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity(); let constant = cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index c55d4387d6961..0c06c9117d737 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -80,8 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { let parent_id = cx .tcx - .hir() - .get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id)) + .hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id)) .def_id; let mut trait_self_ty = None; diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs index e6ddcd107d9d3..cc8e4d7d9e281 100644 --- a/src/tools/clippy/clippy_lints/src/exit.rs +++ b/src/tools/clippy/clippy_lints/src/exit.rs @@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit { && let ExprKind::Path(ref path) = path_expr.kind && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::process_exit, def_id) - && let parent = cx.tcx.hir().get_parent_item(e.hir_id) + && let parent = cx.tcx.hir_get_parent_item(e.hir_id) && let OwnerNode::Item(Item{kind: ItemKind::Fn{ .. }, ..}) = cx.tcx.hir_owner_node(parent) // If the next item up is a function we check if it is an entry point // and only then emit a linter warning diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs index 6d1c55d069380..cb83b1395d260 100644 --- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs @@ -39,7 +39,7 @@ fn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) { if let FnKind::ItemFn(_, generics, _) = kind - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, hir_id) { for param in generics.params { @@ -57,7 +57,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) { && let hir::Impl { of_trait, .. } = *impl_ && of_trait.is_none() && let body = cx.tcx.hir_body(body_id) - && cx.tcx.visibility(cx.tcx.hir().body_owner_def_id(body.id())).is_public() + && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public() && !is_in_test(cx.tcx, impl_item.hir_id()) { for param in impl_item.generics.params { diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs index ac2e866e4ff7e..5ad83f886e2ec 100644 --- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs +++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs @@ -22,7 +22,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id) && !is_from_ignored_trait(trait_ref, ignored_traits) { - let mut param_idents_iter = cx.tcx.hir().body_param_names(body_id); + let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id); let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied(); let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter); diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs index f666ed0a440bf..33431385c7de3 100644 --- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs @@ -112,7 +112,7 @@ impl IndexingSlicing { impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let ExprKind::Index(array, index, _) = &expr.kind - && (!self.suppress_restriction_lint_in_const || !cx.tcx.hir().is_inside_const_context(expr.hir_id)) + && (!self.suppress_restriction_lint_in_const || !cx.tcx.hir_is_inside_const_context(expr.hir_id)) && let expr_ty = cx.typeck_results().expr_ty(array) && let mut deref = deref_chain(cx, expr_ty) && deref.any(|l| { @@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { span_lint_and_then(cx, INDEXING_SLICING, expr.span, "slicing may panic", |diag| { diag.help(help_msg); - if cx.tcx.hir().is_inside_const_context(expr.hir_id) { + if cx.tcx.hir_is_inside_const_context(expr.hir_id) { diag.note(note); } }); @@ -223,7 +223,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing { span_lint_and_then(cx, INDEXING_SLICING, expr.span, "indexing may panic", |diag| { diag.help("consider using `.get(n)` or `.get_mut(n)` instead"); - if cx.tcx.hir().is_inside_const_context(expr.hir_id) { + if cx.tcx.hir_is_inside_const_context(expr.hir_id) { diag.note(note); } }); diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index 3cb47d8ef9191..960b9aa032bea 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -94,7 +94,6 @@ impl Finiteness { } impl From for Finiteness { - #[must_use] fn from(b: bool) -> Self { if b { Infinite } else { Finite } } diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index c68499ce9f781..620e27fa67c62 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let Some(element_count) = cst.try_to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) - && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { + && !cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| { matches!( node, Node::Item(Item { diff --git a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs index 4d206850c9984..797ff1f398668 100644 --- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs @@ -61,7 +61,7 @@ pub(super) fn check<'tcx>( } fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option> { - for (_, parent_node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, parent_node) in cx.tcx.hir_parent_iter(expr.hir_id) { match parent_node { // Skip `Coroutine` closures, these are the body of `async fn`, not async closures. // This is because we still need to backtrack one parent node to get the `OpaqueDef` ty. diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs index 1721f569541b4..aa8a2934f89bd 100644 --- a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs +++ b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs @@ -134,7 +134,7 @@ fn last_stmt_and_ret<'tcx>( } None } - let mut parent_iter = cx.tcx.hir().parent_iter(expr.hir_id); + let mut parent_iter = cx.tcx.hir_parent_iter(expr.hir_id); if let Some((node_hir, Node::Stmt(..))) = parent_iter.next() // This should be the loop // This should be the function body diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index e98c3c9698ba0..0f62183eb33d6 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -56,7 +56,7 @@ pub(super) fn check<'tcx>( // ensure that the indexed variable was declared before the loop, see #601 if let Some(indexed_extent) = indexed_extent { - let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = cx.tcx.hir_get_parent_item(expr.hir_id); let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id); let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap(); if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) { @@ -256,7 +256,7 @@ impl<'tcx> VarVisitor<'_, 'tcx> { let res = self.cx.qpath_res(seqpath, seqexpr.hir_id); match res { Res::Local(hir_id) => { - let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id); + let parent_def_id = self.cx.tcx.hir_get_parent_item(expr.hir_id); let extent = self .cx .tcx diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs index 052e6502da926..2a5aa12d126cb 100644 --- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs +++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods { && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2 && !expr.span.in_external_macro(cx.sess().source_map()) && ( - is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into()) + is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into()) || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY) ) && let [first, second, const_1, const_2] = exprs diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 393399660131f..722ea7042dd7f 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -199,7 +199,7 @@ fn find_method_sugg_for_if_let<'tcx>( // type needs to be considered, not just the inner type of the branch being matched on. // Note the last expression in a block is dropped after all local bindings. let check_ty = if has_else - || (keyword == "if" && matches!(cx.tcx.hir().parent_iter(expr.hir_id).next(), Some((_, Node::Block(..))))) + || (keyword == "if" && matches!(cx.tcx.hir_parent_iter(expr.hir_id).next(), Some((_, Node::Block(..))))) { op_ty } else { diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs index 92c81b3c49d87..1c64f78678aeb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs +++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs @@ -40,8 +40,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool { cx.tcx - .hir() - .parent_id_iter(id) + .hir_parent_id_iter(id) .any(|id| cx.tcx.hir().attrs(id).iter().any(|attr| attr.has_name(sym::cfg))) } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs b/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs index 9ff6eaa348710..4bdf589f48762 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_nth_zero.rs @@ -11,7 +11,7 @@ use rustc_span::sym; use super::ITER_NTH_ZERO; pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) { - if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) + if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id)) && let def_id = item.owner_id.to_def_id() && is_trait_method(cx, expr, sym::Iterator) && let Some(Constant::Int(0)) = ConstEvalCtxt::new(cx).eval(arg) diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs index 7d5ebdedd0c30..e1ebca0b09dfb 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs @@ -187,7 +187,7 @@ fn peel_ptr_cast<'tcx>(e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { /// ^ given this `x` expression, returns the `foo(...)` expression fn peel_ptr_cast_ancestors<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> { let mut prev = e; - for (_, node) in cx.tcx.hir().parent_iter(e.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(e.hir_id) { if let Node::Expr(e) = node && get_cast_target(e).is_some() { diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs index de37df2394d30..09ccb386a20bc 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs @@ -123,7 +123,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: }; let mut prev_expr = e; - for (_, parent) in cx.tcx.hir().parent_iter(e.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(e.hir_id) { if let Node::Expr(e) = parent { match e.kind { ExprKind::Field(_, name) diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index ccc5cd4fa417f..b58e8ba32e78b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -4671,7 +4671,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { return; } let name = impl_item.ident.name.as_str(); - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs index 4a8a221e8c360..b1107d8cc72fe 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs @@ -58,8 +58,7 @@ pub(super) fn check<'tcx>( unwrap_or_span: unwrap_arg.span, }; - let map = cx.tcx.hir(); - let body = map.body_owned_by(map.enclosing_body_owner(expr.hir_id)); + let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id)); // Visit the body, and return if we've found a reference if reference_visitor.visit_body(body).is_break() { diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs index f5f404070caba..69f933fee68f2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs @@ -92,7 +92,7 @@ pub(super) fn check<'tcx>( let in_sugg_method_implementation = { matches!( suggested_method_def_id.as_local(), - Some(local_def_id) if local_def_id == cx.tcx.hir().get_parent_item(receiver.hir_id).def_id + Some(local_def_id) if local_def_id == cx.tcx.hir_get_parent_item(receiver.hir_id).def_id ) }; if in_sugg_method_implementation { diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs index 8a99974394c32..8389c2e3f9826 100644 --- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs @@ -35,7 +35,7 @@ pub(super) fn check( }; let manual = count == 2 && msrv.meets(msrvs::STR_SPLIT_ONCE); - match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir().parent_iter(expr.hir_id)) { + match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir_parent_iter(expr.hir_id)) { Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg), Some(usage) if manual => check_manual_split_once(cx, method_name, expr, self_arg, pat_arg, &usage), None if manual => { @@ -127,7 +127,7 @@ fn check_manual_split_once_indirect( pat_arg: &Expr<'_>, ) -> Option<()> { let ctxt = expr.span.ctxt(); - let mut parents = cx.tcx.hir().parent_iter(expr.hir_id); + let mut parents = cx.tcx.hir_parent_iter(expr.hir_id); if let (_, Node::LetStmt(local)) = parents.next()? && let PatKind::Binding(BindingMode::MUT, iter_binding_id, _, None) = local.pat.kind && let (iter_stmt_id, Node::Stmt(_)) = parents.next()? @@ -220,7 +220,7 @@ fn indirect_usage<'tcx>( ControlFlow::Continue(Descend::from(path_to_binding.is_none())) }); - let mut parents = cx.tcx.hir().parent_iter(path_to_binding?.hir_id); + let mut parents = cx.tcx.hir_parent_iter(path_to_binding?.hir_id); let iter_usage = parse_iter_usage(cx, ctxt, &mut parents)?; let (parent_id, _) = parents.find(|(_, node)| { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index e80d99dca56d1..ea134c0570537 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -494,7 +494,7 @@ fn get_input_traits_and_projections<'tcx>( #[expect(clippy::too_many_lines)] fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool { - for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Stmt(_) => return true, Node::Block(..) => {}, diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs index 4119b1d1051cb..e5801124db48e 100644 --- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs +++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs @@ -121,9 +121,9 @@ impl Visitor<'_> for IdentVisitor<'_, '_> { // Check whether the node is part of a `use` statement. We don't want to emit a warning if the user // has no control over the type. let usenode = opt_as_use_node(node).or_else(|| { - cx.tcx - .hir() - .parent_iter(hir_id) + cx + .tcx + .hir_parent_iter(hir_id) .find_map(|(_, node)| opt_as_use_node(node)) }); diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs index ba4af134ccd0b..8d751c2c0acb8 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn { // Const fns are not allowed as methods in a trait. { - let parent = cx.tcx.hir().get_parent_item(hir_id).def_id; + let parent = cx.tcx.hir_get_parent_item(hir_id).def_id; if parent != CRATE_DEF_ID { if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent) { if let hir::ItemKind::Trait(..) = &item.kind { diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs index e2ca4458edaa0..d4181c677afda 100644 --- a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs +++ b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs @@ -81,7 +81,7 @@ fn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { | sym::core_panic_2015_macro | sym::std_panic_2015_macro | sym::core_panic_2021_macro - ) && !cx.tcx.hir().is_inside_const_context(expr.hir_id)) + ) && !cx.tcx.hir_is_inside_const_context(expr.hir_id)) || matches!( diag_name, sym::unimplemented_macro | sym::todo_macro | sym::unreachable_macro | sym::unreachable_2015_macro diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 06e92985e6648..47a9e17b3cfe1 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { | hir::ItemKind::Union(..) => {}, hir::ItemKind::ExternCrate(..) | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::Impl { .. } | hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span), } diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index fdc0930e957a0..3cf1a80607e8b 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { | hir::ItemKind::Static(..) | hir::ItemKind::Struct(..) | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::GlobalAsm(..) + | hir::ItemKind::GlobalAsm { .. } | hir::ItemKind::TyAlias(..) | hir::ItemKind::Union(..) | hir::ItemKind::ExternCrate(..) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs index 098098718af39..1b6896827fed8 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs @@ -41,8 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef { && !ref_pat.span.from_expansion() && cx .tcx - .hir() - .parent_iter(ref_pat.hir_id) + .hir_parent_iter(ref_pat.hir_id) .map_while(|(_, parent)| if let Node::Pat(pat) = parent { Some(pat) } else { None }) // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms .all(|pat| !matches!(pat.kind, PatKind::Or(_))) diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index 7f91e555054da..ea1d7e5d43829 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> { if self .possible_borrowers .last() - .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir().body_owner_def_id(body.id())) + .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir_body_owner_def_id(body.id())) { self.possible_borrowers.pop(); } @@ -359,7 +359,7 @@ fn referent_used_exactly_once<'tcx>( && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind && !place.is_indirect_first_projection() { - let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id); + let body_owner_local_def_id = cx.tcx.hir_enclosing_body_owner(reference.hir_id); if possible_borrowers .last() .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id) diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 4e19a2f409dd3..863a1f895c937 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -347,7 +347,7 @@ fn check<'tcx>( impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { - let mut parents = cx.tcx.hir().parent_iter(local.hir_id); + let mut parents = cx.tcx.hir_parent_iter(local.hir_id); if let LetStmt { init: None, pat: diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 6a1dc5e41a075..36a0738cbc95a 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -350,9 +350,8 @@ impl MutablyUsedVariablesCtxt<'_> { // The goal here is to find if the current scope is unsafe or not. It stops when it finds // a function or an unsafe block. fn is_in_unsafe_block(&self, item: HirId) -> bool { - let hir = self.tcx.hir(); - for (parent, node) in hir.parent_iter(item) { - if let Some(fn_sig) = hir.fn_sig_by_hir_id(parent) { + for (parent, node) in self.tcx.hir_parent_iter(item) { + if let Some(fn_sig) = self.tcx.hir_fn_sig_by_hir_id(parent) { return fn_sig.header.is_unsafe(); } else if let Node::Block(block) = node { if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) { diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index cf407e51f7afb..f0ee613791fb9 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if sig.decl.inputs.is_empty() && name == sym::new && cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id) - && let self_def_id = cx.tcx.hir().get_parent_item(id.into()) + && let self_def_id = cx.tcx.hir_get_parent_item(id.into()) && let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity() && self_ty == return_ty(cx, id) && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default) diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 4d3e6aa79d0a0..7187a8f2c11a1 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -141,7 +141,7 @@ impl NoEffect { stmt.span, "statement with no effect", |diag| { - for parent in cx.tcx.hir().parent_iter(stmt.hir_id) { + for parent in cx.tcx.hir_parent_iter(stmt.hir_id) { if let Node::Item(item) = parent.1 && let ItemKind::Fn { .. } = item.kind && let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) 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 f965ab90da239..4007ca88a00e7 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -344,7 +344,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) { if let ImplItemKind::Const(_, body_id) = &impl_item.kind { - let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let item_def_id = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(item_def_id); match &item.kind { diff --git a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs index f6ce1d1d58672..16c4391c0fbea 100644 --- a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs +++ b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for NonZeroSuggestions { check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable); } else { // Check if the parent expression is a binary operation - let parent_is_binary = cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { + let parent_is_binary = cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| { matches!(node, rustc_hir::Node::Expr(parent_expr) if matches!(parent_expr.kind, ExprKind::Binary(..))) }); diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index 9d07a14718da1..594101427f5a9 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -349,10 +349,10 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - let body_owner_kind = cx.tcx.hir().body_owner_kind(body_owner_def_id); + let body_owner_kind = cx.tcx.hir_body_owner_kind(body_owner_def_id); if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind { let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span @@ -365,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span(body_owner); if let Some(span) = self.const_span && span.contains(body_span) diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 1315c3dfc127c..5737a91031db2 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -26,7 +26,7 @@ pub(super) fn check<'tcx>( let rty = cx.typeck_results().expr_ty(rhs); if let Some((_, lang_item)) = binop_traits(op.node) && let Some(trait_id) = cx.tcx.lang_items().get(lang_item) - && let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(e.hir_id).def_id && trait_ref_of_method(cx, parent_fn).is_none_or(|t| t.path.res.def_id() != trait_id) && implements_trait(cx, ty, trait_id, &[rty.into()]) { diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs index 1c2d6e90fc95e..0358232282786 100644 --- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs +++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs @@ -120,7 +120,7 @@ fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) // the parent HIR node is an expression, or if the parent HIR node // is a Block or Stmt, and the new left hand side would need // parenthesis be treated as a statement rather than an expression. - if let Some((_, parent)) = cx.tcx.hir().parent_iter(binary.hir_id).next() { + if let Some((_, parent)) = cx.tcx.hir_parent_iter(binary.hir_id).next() { match parent { Node::Expr(_) => return Parens::Needed, Node::Block(_) | Node::Stmt(_) => { @@ -142,7 +142,7 @@ fn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) // This would mean that the rustfix suggestion will appear at the start of a line, which causes // these expressions to be interpreted as statements if they do not have parenthesis. let mut prev_id = binary.hir_id; - for (_, parent) in cx.tcx.hir().parent_iter(binary.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(binary.hir_id) { if let Node::Expr(expr) = parent && let ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) | ExprKind::Unary(_, lhs) = expr.kind && lhs.hir_id == prev_id diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs index 2083f2bf628d0..c261fd9bd9cb0 100644 --- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs @@ -68,10 +68,10 @@ impl Context { } pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); - let body_owner_def_id = cx.tcx.hir().body_owner_def_id(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); + let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id()); - match cx.tcx.hir().body_owner_kind(body_owner_def_id) { + match cx.tcx.hir_body_owner_kind(body_owner_def_id) { hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => { let body_span = cx.tcx.hir().span_with_body(body_owner); @@ -82,12 +82,12 @@ impl Context { } self.const_span = Some(body_span); }, - hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => (), + hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::GlobalAsm => (), } } pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) { - let body_owner = cx.tcx.hir().body_owner(body.id()); + let body_owner = cx.tcx.hir_body_owner(body.id()); let body_span = cx.tcx.hir().span_with_body(body_owner); if let Some(span) = self.const_span { diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs index fa5b02a5a41ba..c9bdeed660e20 100644 --- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs +++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if let Some(macro_call) = root_macro_call_first_node(cx, expr) { if is_panic(cx, macro_call.def_id) { - if cx.tcx.hir().is_inside_const_context(expr.hir_id) + if cx.tcx.hir_is_inside_const_context(expr.hir_id) || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id) { return; @@ -139,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented { && let Res::Def(DefKind::Fn, def_id) = expr_path.res && match_def_path(cx, def_id, &paths::PANIC_ANY) { - if cx.tcx.hir().is_inside_const_context(expr.hir_id) + if cx.tcx.hir_is_inside_const_context(expr.hir_id) || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id) { return; diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 9b241edf4ccf2..ef4948a05b7f4 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -186,8 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { } fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) { - let hir = cx.tcx.hir(); - let mut parents = hir.parent_iter(body.value.hir_id); + let mut parents = cx.tcx.hir_parent_iter(body.value.hir_id); let (item_id, sig, is_trait_item) = match parents.next() { Some((_, Node::Item(i))) => { if let ItemKind::Fn { sig, .. } = &i.kind { diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index fb1bc494bd948..cfa622aea582f 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { let node = mir.source_scopes[scope] .local_data .as_ref() - .assert_crate_local() + .unwrap_crate_local() .lint_root; if let Some(snip) = span.get_source_text(cx) diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs index ebe3e7c201964..f3ccc9e38f4d8 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs @@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals { /// assert_static(closure); /// ``` fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool { - let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition); + let closure_def_id = cx.tcx.hir_enclosing_body_owner(redefinition); cx.tcx.is_closure_like(closure_def_id.to_def_id()) && cx.tcx.closure_captures(closure_def_id).iter().any(|c| { @@ -122,8 +122,7 @@ fn find_binding(pat: &Pat<'_>, name: Ident) -> Option { /// Check if a rebinding of a local changes the effect of assignments to the binding. fn affects_assignments(cx: &LateContext<'_>, mutability: Mutability, bind: HirId, rebind: HirId) -> bool { - let hir = cx.tcx.hir(); - // the binding is mutable and the rebinding is in a different scope than the original binding - mutability == Mutability::Mut && hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind) + mutability == Mutability::Mut + && cx.tcx.hir_get_enclosing_scope(bind) != cx.tcx.hir_get_enclosing_scope(rebind) } diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 9f0ea84246ddd..152739c2973b6 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -177,8 +177,7 @@ declare_lint_pass!(Return => [LET_AND_RETURN, NEEDLESS_RETURN, NEEDLESS_RETURN_W /// because of the never-ness of `return` expressions fn stmt_needs_never_type(cx: &LateContext<'_>, stmt_hir_id: HirId) -> bool { cx.tcx - .hir() - .parent_iter(stmt_hir_id) + .hir_parent_iter(stmt_hir_id) .find_map(|(_, node)| if let Node::Expr(expr) = node { Some(expr) } else { None }) .is_some_and(|e| { cx.typeck_results() @@ -203,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for Return { && is_res_lang_ctor(cx, path_res(cx, maybe_constr), ResultErr) // Ensure this is not the final stmt, otherwise removing it would cause a compile error - && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id)) + && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id)) && let ItemKind::Fn { body, .. } = item.kind && let block = cx.tcx.hir_body(body).value && let ExprKind::Block(block, _) = block.kind diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index 23b47606f8aa2..fc02c3a51716e 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { _ => return, } - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 83199ba0f7076..ee282ee1dfb71 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -149,17 +149,15 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { } fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); - let owner_id = hir.body_owner_def_id(body.id()); - if !matches!(hir.body_owner_kind(owner_id), BodyOwnerKind::Closure) { + let owner_id = cx.tcx.hir_body_owner_def_id(body.id()); + if !matches!(cx.tcx.hir_body_owner_kind(owner_id), BodyOwnerKind::Closure) { self.bindings.push((FxHashMap::default(), owner_id)); } } fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) { - let hir = cx.tcx.hir(); if !matches!( - hir.body_owner_kind(hir.body_owner_def_id(body.id())), + cx.tcx.hir_body_owner_kind(cx.tcx.hir_body_owner_def_id(body.id())), BodyOwnerKind::Closure ) { self.bindings.pop(); @@ -226,9 +224,9 @@ fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) /// Returns true if the expression is a simple transformation of a local binding such as `&x` fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_id: HirId) -> bool { - let hir = cx.tcx.hir(); - let is_direct_binding = hir - .parent_iter(pat.hir_id) + let is_direct_binding = cx + .tcx + .hir_parent_iter(pat.hir_id) .map_while(|(_id, node)| match node { Node::Pat(pat) => Some(pat), _ => None, @@ -261,14 +259,14 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_ /// For closure arguments passed to a method call, returns the method call, and the `HirId` of the /// closure (which will later be skipped). This is for fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<(&'tcx Expr<'tcx>, Option)> { - for (hir_id, node) in cx.tcx.hir().parent_iter(hir_id) { + for (hir_id, node) in cx.tcx.hir_parent_iter(hir_id) { let init = match node { Node::Arm(_) | Node::Pat(_) | Node::PatField(_) | Node::Param(_) => continue, Node::Expr(expr) => match expr.kind { ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some((e, None)), // If we're a closure argument, then a parent call is also an associated item. ExprKind::Closure(_) => { - if let Some((_, node)) = cx.tcx.hir().parent_iter(hir_id).next() { + if let Some((_, node)) = cx.tcx.hir_parent_iter(hir_id).next() { match node { Node::Expr(expr) => match expr.kind { ExprKind::MethodCall(_, _, _, _) | ExprKind::Call(_, _) => Some((expr, Some(hir_id))), diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index 597bfddecbc5f..e9db7c9d031a9 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -232,8 +232,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx let block_is_ancestor = self .cx .tcx - .hir() - .parent_iter(self.ap.curr_block_hir_id) + .hir_parent_iter(self.ap.curr_block_hir_id) .any(|(id, _)| id == apa.first_block_hir_id); if last_stmt_is_not_dummy && last_stmt_is_not_curr && (block_equals_curr || block_is_ancestor) { apa.has_expensive_expr_after_last_attr = true; diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs index fdbccbaa8a594..1a2fb77acc15a 100644 --- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs +++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs @@ -90,8 +90,7 @@ impl SingleCallFn { || fn_span.in_external_macro(cx.sess().source_map()) || cx .tcx - .hir() - .maybe_body_owned_by(fn_def_id) + .hir_maybe_body_owned_by(fn_def_id) .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id)) || match cx.tcx.hir_node(fn_hir_id) { Node::Item(item) => is_from_proc_macro(cx, item), diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs index 9326b2adaffb7..fb426e91bf01d 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs @@ -63,11 +63,11 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl { // Check for more than one binary operation in the implemented function // Linting when multiple operations are involved can result in false positives - && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id).def_id && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn) && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind && let body = cx.tcx.hir_body(body_id) - && let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id).def_id + && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id).def_id && let Some(trait_ref) = trait_ref_of_method(cx, parent_fn) && let trait_id = trait_ref.path.res.def_id() && ![binop_trait_id, op_assign_trait_id].contains(&trait_id) diff --git a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs index 1209bd5b34f2c..81c0a57083e80 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::Ty; use super::EAGER_TRANSMUTE; fn peel_parent_unsafe_blocks<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { - for (_, parent) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, parent) in cx.tcx.hir_parent_iter(expr.hir_id) { match parent { Node::Block(_) => {}, Node::Expr(e) if let ExprKind::Block(..) = e.kind => {}, diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs index 4961dd6b280a1..96286fcf73d67 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::Ty; use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS; fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option> { - let mut parent_iter = cx.tcx.hir().parent_iter(expr_hir_id); + let mut parent_iter = cx.tcx.hir_parent_iter(expr_hir_id); if let Some((_, node)) = parent_iter.next() { match node { Node::LetStmt(local) => Some(*local), @@ -28,8 +28,8 @@ fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) } fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool { - let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id); - if let Some(body) = cx.tcx.hir().maybe_body_owned_by(def_id) { + let def_id = cx.tcx.hir_enclosing_body_owner(expr_hir_id); + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(def_id) { return body.value.peel_blocks().hir_id == expr_hir_id; } false diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index 579cbf447a2b0..71e6e75c1bd3a 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -375,8 +375,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ) { let is_in_trait_impl = if let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id( cx.tcx - .hir() - .get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)) + .hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)) .def_id, ) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) @@ -420,7 +419,7 @@ impl<'tcx> LateLintPass<'tcx> for Types { ImplItemKind::Const(ty, _) => { let is_in_trait_impl = if let hir::Node::Item(item) = cx .tcx - .hir_node_by_def_id(cx.tcx.hir().get_parent_item(item.hir_id()).def_id) + .hir_node_by_def_id(cx.tcx.hir_get_parent_item(item.hir_id()).def_id) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs index 529f85be37201..a443043bef902 100644 --- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs @@ -111,7 +111,7 @@ fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Opt owner_id, .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.has_attr(*owner_id, sym::automatically_derived) // It is a implementation of a trait. @@ -216,7 +216,7 @@ fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: Local owner_id, .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() // We exclude `impl` blocks generated from rustc's proc macros. && !cx.tcx.has_attr(*owner_id, sym::automatically_derived) // It is a implementation of a trait. @@ -331,8 +331,8 @@ impl UnconditionalRecursion { && let [return_expr] = get_return_calls_in_body(body).as_slice() && let ExprKind::Call(call_expr, _) = return_expr.kind // We need to use typeck here to infer the actual function being called. - && let body_def_id = cx.tcx.hir().enclosing_body_owner(call_expr.hir_id) - && let Some(body_owner) = cx.tcx.hir().maybe_body_owned_by(body_def_id) + && let body_def_id = cx.tcx.hir_enclosing_body_owner(call_expr.hir_id) + && let Some(body_owner) = cx.tcx.hir_maybe_body_owned_by(body_def_id) && let typeck = cx.tcx.typeck_body(body_owner.id()) && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id) { @@ -367,7 +367,7 @@ impl UnconditionalRecursion { kind: ItemKind::Impl(impl_), .. }), - )) = cx.tcx.hir().parent_iter(hir_id).next() + )) = cx.tcx.hir_parent_iter(hir_id).next() && let Some(implemented_ty_id) = get_hir_ty_def_id(cx.tcx, *impl_.self_ty) && { self.init_default_impl_for_type_if_needed(cx); diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index c8e3c46f2f6f1..93abf95e35773 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -291,7 +291,7 @@ fn expr_has_unnecessary_safety_comment<'tcx>( expr: &'tcx hir::Expr<'tcx>, comment_pos: BytePos, ) -> Option { - if cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, ref node)| { + if cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, ref node)| { matches!( node, Node::Block(Block { @@ -604,10 +604,9 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span fn get_body_search_span(cx: &LateContext<'_>) -> Option { let body = cx.enclosing_body?; - let map = cx.tcx.hir(); let mut span = cx.tcx.hir_body(body).value.span; let mut maybe_global_var = false; - for (_, node) in map.parent_iter(body.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(body.hir_id) { match node { Node::Expr(e) => span = e.span, Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (), diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index e65123b8a9492..0687fc319af68 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -224,7 +224,7 @@ fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { return false; }; if is_panic(cx, macro_call.def_id) { - return !cx.tcx.hir().is_inside_const_context(expr.hir_id); + return !cx.tcx.hir_is_inside_const_context(expr.hir_id); } matches!(cx.tcx.item_name(macro_call.def_id).as_str(), "unreachable") } diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs index 0f9b05c84d4b0..7487e273caa7e 100644 --- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs +++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs @@ -118,7 +118,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> ControlFlow<()> { if path_to_local_id(ex, self.expected_hir_id) { - for (_, node) in self.cx.tcx.hir().parent_iter(ex.hir_id) { + for (_, node) in self.cx.tcx.hir_parent_iter(ex.hir_id) { match node { Node::Expr(expr) => { match expr.kind { diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs index d8305a6282908..2c6c75693166f 100644 --- a/src/tools/clippy/clippy_lints/src/unused_self.rs +++ b/src/tools/clippy/clippy_lints/src/unused_self.rs @@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf { if impl_item.span.from_expansion() { return; } - let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; + let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let parent_item = cx.tcx.hir().expect_item(parent); let assoc_item = cx.tcx.associated_item(impl_item.owner_id); let contains_todo = |cx, body: &'_ Body<'_>| -> bool { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index ce489054e16e9..5fc166438e84a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -132,8 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for Author { } fn check_item(cx: &LateContext<'_>, hir_id: HirId) { - let hir = cx.tcx.hir(); - if let Some(body) = hir.maybe_body_owned_by(hir_id.expect_owner().def_id) { + if let Some(body) = cx.tcx.hir_maybe_body_owned_by(hir_id.expect_owner().def_id) { check_node(cx, hir_id, |v| { v.expr(&v.bind("expr", body.value)); }); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index e31da9e9f6119..d6f10f1e4b801 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass { output: &mut self.registered_lints, cx, }; - let body = cx.tcx.hir().body_owned_by( + let body = cx.tcx.hir_body_owned_by( impl_item_refs .iter() .find(|iiref| iiref.ident.as_str() == "lint_vec") diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 1221abec1abf0..4c9a7f0e16de6 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -73,8 +73,8 @@ impl LateLintPass<'_> for ZeroSizedMapValues { } fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool { - let parent_id = cx.tcx.hir().get_parent_item(hir_id); - let second_parent_id = cx.tcx.hir().get_parent_item(parent_id.into()).def_id; + let parent_id = cx.tcx.hir_get_parent_item(hir_id); + let second_parent_id = cx.tcx.hir_get_parent_item(parent_id.into()).def_id; if let Node::Item(item) = cx.tcx.hir_node_by_def_id(second_parent_id) { if let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind { return true; diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 4f707e34abf9a..dd149c4a29b9f 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -351,21 +351,18 @@ pub enum FullInt { } impl PartialEq for FullInt { - #[must_use] fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } } impl PartialOrd for FullInt { - #[must_use] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for FullInt { - #[must_use] fn cmp(&self, other: &Self) -> Ordering { use FullInt::{S, U}; diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 6bb876322f24f..c4d00002292c9 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -117,7 +117,7 @@ impl<'hir> IfLet<'hir> { if_else, ) = expr.kind { - let mut iter = cx.tcx.hir().parent_iter(expr.hir_id); + let mut iter = cx.tcx.hir_parent_iter(expr.hir_id); if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() { if let Some(( _, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 9ee30094d608c..0ac675345ae0c 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -968,7 +968,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(out_expr); } }, - InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => { + InlineAsmOperand::SymFn { expr } => { + self.hash_expr(expr); + } + InlineAsmOperand::Const { anon_const } => { self.hash_body(anon_const.body); }, InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path), diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index ccf32f42a47b9..40ddd75b7fad1 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -212,7 +212,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option< /// /// e.g. returns true for `x` in `fn f(x: usize) { .. }` and `let x = 1;` but false for `let x;` pub fn local_is_initialized(cx: &LateContext<'_>, local: HirId) -> bool { - for (_, node) in cx.tcx.hir().parent_iter(local) { + for (_, node) in cx.tcx.hir_parent_iter(local) { match node { Node::Pat(..) | Node::PatField(..) => {}, Node::LetStmt(let_stmt) => return let_stmt.init.is_some(), @@ -227,7 +227,7 @@ pub fn local_is_initialized(cx: &LateContext<'_>, local: HirId) -> bool { /// /// The current context is determined based on the current body which is set before calling a lint's /// entry point (any function on `LateLintPass`). If you need to check in a different context use -/// `tcx.hir().is_inside_const_context(_)`. +/// `tcx.hir_is_inside_const_context(_)`. /// /// Do not call this unless the `LateContext` has an enclosing body. For release build this case /// will safely return `false`, but debug builds will ICE. Note that `check_expr`, `check_block`, @@ -237,8 +237,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { debug_assert!(cx.enclosing_body.is_some(), "`LateContext` has no enclosing body"); cx.enclosing_body.is_some_and(|id| { cx.tcx - .hir() - .body_const_context(cx.tcx.hir().body_owner_def_id(id)) + .hir_body_const_context(cx.tcx.hir_body_owner_def_id(id)) .is_some() }) } @@ -251,8 +250,7 @@ pub fn is_in_const_context(cx: &LateContext<'_>) -> bool { /// * associated constants pub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool { use ConstContext::{Const, ConstFn, Static}; - let hir = tcx.hir(); - let Some(ctx) = hir.body_const_context(hir.enclosing_body_owner(hir_id)) else { + let Some(ctx) = tcx.hir_body_const_context(tcx.hir_enclosing_body_owner(hir_id)) else { return false; }; match ctx { @@ -808,7 +806,7 @@ pub fn get_trait_def_id(tcx: TyCtxt<'_>, path: &[&str]) -> Option { pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) -> Option<&'tcx TraitRef<'tcx>> { // Get the implemented trait for the current function let hir_id = cx.tcx.local_def_id_to_hir_id(def_id); - let parent_impl = cx.tcx.hir().get_parent_item(hir_id); + let parent_impl = cx.tcx.hir_get_parent_item(hir_id); if parent_impl != hir::CRATE_OWNER_ID && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id) && let ItemKind::Impl(impl_) = &item.kind @@ -1119,7 +1117,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind { let mut capture = CaptureKind::Value; let mut capture_expr_ty = e; - for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) { + for (parent_id, parent) in cx.tcx.hir_parent_iter(e.hir_id) { if let [ Adjustment { kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)), @@ -1338,13 +1336,13 @@ pub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool { /// Returns `true` if the expression is in the program's `#[panic_handler]`. pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - let parent = cx.tcx.hir().get_parent_item(e.hir_id); + let parent = cx.tcx.hir_get_parent_item(e.hir_id); Some(parent.to_def_id()) == cx.tcx.lang_items().panic_impl() } /// Gets the name of the item the expression is in, if available. pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option { - let parent_id = cx.tcx.hir().get_parent_item(expr.hir_id).def_id; + let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id; match cx.tcx.hir_node_by_def_id(parent_id) { Node::Item(Item { ident, .. }) | Node::TraitItem(TraitItem { ident, .. }) @@ -1409,9 +1407,9 @@ pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> O /// Gets the enclosing block, if any. pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> { - let map = &cx.tcx.hir(); - let enclosing_node = map - .get_enclosing_scope(hir_id) + let enclosing_node = cx + .tcx + .hir_get_enclosing_scope(hir_id) .map(|enclosing_id| cx.tcx.hir_node(enclosing_id)); enclosing_node.and_then(|node| match node { Node::Block(block) => Some(block), @@ -1435,7 +1433,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>( cx: &LateContext<'tcx>, expr: &Expr<'_>, ) -> Option<&'tcx Expr<'tcx>> { - for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) { + for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) { match node { Node::Expr(e) => match e.kind { ExprKind::Closure { .. } @@ -1455,7 +1453,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>( /// Gets the parent node if it's an impl block. pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> { - match tcx.hir().parent_iter(id).next() { + match tcx.hir_parent_iter(id).next() { Some(( _, Node::Item(Item { @@ -1533,7 +1531,7 @@ pub fn peel_blocks_with_stmt<'a>(mut expr: &'a Expr<'a>) -> &'a Expr<'a> { /// Checks if the given expression is the else clause of either an `if` or `if let` expression. pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { - let mut iter = tcx.hir().parent_iter(expr.hir_id); + let mut iter = tcx.hir_parent_iter(expr.hir_id); match iter.next() { Some(( _, @@ -1550,7 +1548,7 @@ pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { /// returns `true` for both the `init` and the `else` part pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { let mut child_id = expr.hir_id; - for (parent_id, node) in tcx.hir().parent_iter(child_id) { + for (parent_id, node) in tcx.hir_parent_iter(child_id) { if let Node::LetStmt(LetStmt { init: Some(init), els: Some(els), @@ -1570,7 +1568,7 @@ pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { /// Checks if the given expression is the else clause of a `let else` expression pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { let mut child_id = expr.hir_id; - for (parent_id, node) in tcx.hir().parent_iter(child_id) { + for (parent_id, node) in tcx.hir_parent_iter(child_id) { if let Node::LetStmt(LetStmt { els: Some(els), .. }) = node && els.hir_id == child_id { @@ -1648,7 +1646,7 @@ pub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool if is_integer_literal(e, value) { return true; } - let enclosing_body = cx.tcx.hir().enclosing_body_owner(e.hir_id); + let enclosing_body = cx.tcx.hir_enclosing_body_owner(e.hir_id); if let Some(Constant::Int(v)) = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e) { @@ -1963,7 +1961,7 @@ pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool return true; } prev_enclosing_node = Some(enclosing_node); - enclosing_node = map.get_parent_item(enclosing_node).into(); + enclosing_node = tcx.hir_get_parent_item(enclosing_node).into(); } false @@ -1972,8 +1970,8 @@ pub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool /// Checks if the given HIR node is inside an `impl` block with the `automatically_derived` /// attribute. pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir() - .parent_owner_iter(id) + tcx + .hir_parent_owner_iter(id) .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_)))) .any(|(id, _)| { has_attr( @@ -2204,7 +2202,7 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool /// Returns both the node and the `HirId` of the closest child node. pub fn get_expr_use_or_unification_node<'tcx>(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<(Node<'tcx>, HirId)> { let mut child_id = expr.hir_id; - let mut iter = tcx.hir().parent_iter(child_id); + let mut iter = tcx.hir_parent_iter(child_id); loop { match iter.next() { None => break None, @@ -2583,7 +2581,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool { with_test_item_names(tcx, tcx.parent_module(id), |names| { let node = tcx.hir_node(id); once((id, node)) - .chain(tcx.hir().parent_iter(id)) + .chain(tcx.hir_parent_iter(id)) // Since you can nest functions we need to collect all until we leave // function scope .any(|(_id, node)| { @@ -2619,8 +2617,8 @@ pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool { - tcx.hir() - .parent_id_iter(id) + tcx + .hir_parent_id_iter(id) .any(|parent_id| is_cfg_test(tcx, parent_id)) } @@ -2634,8 +2632,8 @@ pub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let hir = tcx.hir(); tcx.has_attr(def_id, sym::cfg) - || hir - .parent_iter(tcx.local_def_id_to_hir_id(def_id)) + || tcx + .hir_parent_iter(tcx.local_def_id_to_hir_id(def_id)) .flat_map(|(parent_id, _)| hir.attrs(parent_id)) .any(|attr| attr.has_name(sym::cfg)) } @@ -2655,8 +2653,7 @@ pub fn walk_to_expr_usage<'tcx, T>( e: &Expr<'tcx>, mut f: impl FnMut(HirId, Node<'tcx>, HirId) -> ControlFlow, ) -> Option, HirId)>> { - let map = cx.tcx.hir(); - let mut iter = map.parent_iter(e.hir_id); + let mut iter = cx.tcx.hir_parent_iter(e.hir_id); let mut child_id = e.hir_id; while let Some((parent_id, parent)) = iter.next() { @@ -2679,7 +2676,7 @@ pub fn walk_to_expr_usage<'tcx, T>( ExprKind::If(child, ..) | ExprKind::Match(child, ..) if child.hir_id != child_id => child_id = parent_id, ExprKind::Break(Destination { target_id: Ok(id), .. }, _) => { child_id = id; - iter = map.parent_iter(id); + iter = cx.tcx.hir_parent_iter(id); }, ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = parent_id, _ => return Some(ControlFlow::Continue((parent, child_id))), @@ -2762,7 +2759,7 @@ impl<'tcx> ExprUseCtxt<'tcx> { Node::Expr(use_expr) => match use_expr.kind { ExprKind::Ret(_) => ExprUseNode::Return(OwnerId { - def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), + def_id: cx.tcx.hir_body_owner_def_id(cx.enclosing_body.unwrap()), }), ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }), diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index 30fd48fc0605b..9ce0fd8318f1d 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -178,7 +178,7 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option< // get the parent node, possibly skipping over a statement // if the parent is not found, it is sensible to return `Some(root)` let hir = cx.tcx.hir(); - let mut parent_iter = hir.parent_iter(node.hir_id()); + let mut parent_iter = cx.tcx.hir_parent_iter(node.hir_id()); let (parent_id, _) = match parent_iter.next() { None => return Some(ExpnId::root()), Some((_, Node::Stmt(_))) => match parent_iter.next() { diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index 85250f81dc47b..ffcfcd240ea5a 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -30,7 +30,7 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) - locals.len() ]; - traversal::Postorder::new(&mir.basic_blocks, location.block, ()) + traversal::Postorder::new(&mir.basic_blocks, location.block, None) .collect::>() .into_iter() .rev() @@ -136,8 +136,8 @@ pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option { /// Returns the `mir::Body` containing the node associated with `hir_id`. #[allow(clippy::module_name_repetitions)] pub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> { - let body_owner_local_def_id = tcx.hir().enclosing_body_owner(hir_id); - if tcx.hir().body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { + let body_owner_local_def_id = tcx.hir_enclosing_body_owner(hir_id); + if tcx.hir_body_owner_kind(body_owner_local_def_id).is_fn_or_closure() { Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id())) } else { None diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs index a5374f6904e3a..8eef6a7f57edb 100644 --- a/src/tools/clippy/clippy_utils/src/ty/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs @@ -267,7 +267,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>( // through calling `body_owner_kind`, which would panic if the callee // does not have a body. if let Some(callee_id) = callee_id { - let _ = tcx.hir().body_owner_kind(callee_id); + let _ = tcx.hir_body_owner_kind(callee_id); } let ty = tcx.erase_regions(ty); @@ -705,7 +705,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option { let decl = id .as_local() - .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); + .and_then(|id| cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id))); Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) }, ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr index 474914299d069..8c023d0d61f4a 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.stderr +++ b/src/tools/clippy/tests/ui/async_yields_async.stderr @@ -14,9 +14,9 @@ LL | | }; = help: to override `-D warnings` add `#[allow(clippy::async_yields_async)]` help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable @@ -46,9 +46,9 @@ LL | | }; | help: consider awaiting this value | -LL ~ async { -LL + 3 -LL + }.await +LL | async { +LL | 3 +LL ~ }.await | error: an async construct yields a type which is itself awaitable diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr index 71f43af46c241..b8a0eedeb9ee8 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr +++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr @@ -13,9 +13,8 @@ LL + let x: &str = s; | help: if you would like to deref, try using `&**` | -LL - let x: &str = &*s; -LL + let x: &str = &**s; - | +LL | let x: &str = &**s; + | + error: aborting due to 1 previous error diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr index c069c9d1672de..0238e3a91369b 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr @@ -8,9 +8,8 @@ LL | let _ = foo as i8; = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]` help: did you mean to invoke the function? | -LL - let _ = foo as i8; -LL + let _ = foo() as i8; - | +LL | let _ = foo() as i8; + | ++ error: casting function pointer `foo` to `i16` --> tests/ui/fn_to_numeric_cast_any.rs:26:13 @@ -20,9 +19,8 @@ LL | let _ = foo as i16; | help: did you mean to invoke the function? | -LL - let _ = foo as i16; -LL + let _ = foo() as i16; - | +LL | let _ = foo() as i16; + | ++ error: casting function pointer `foo` to `i32` --> tests/ui/fn_to_numeric_cast_any.rs:28:13 @@ -32,9 +30,8 @@ LL | let _ = foo as i32; | help: did you mean to invoke the function? | -LL - let _ = foo as i32; -LL + let _ = foo() as i32; - | +LL | let _ = foo() as i32; + | ++ error: casting function pointer `foo` to `i64` --> tests/ui/fn_to_numeric_cast_any.rs:30:13 @@ -44,9 +41,8 @@ LL | let _ = foo as i64; | help: did you mean to invoke the function? | -LL - let _ = foo as i64; -LL + let _ = foo() as i64; - | +LL | let _ = foo() as i64; + | ++ error: casting function pointer `foo` to `i128` --> tests/ui/fn_to_numeric_cast_any.rs:32:13 @@ -56,9 +52,8 @@ LL | let _ = foo as i128; | help: did you mean to invoke the function? | -LL - let _ = foo as i128; -LL + let _ = foo() as i128; - | +LL | let _ = foo() as i128; + | ++ error: casting function pointer `foo` to `isize` --> tests/ui/fn_to_numeric_cast_any.rs:34:13 @@ -68,9 +63,8 @@ LL | let _ = foo as isize; | help: did you mean to invoke the function? | -LL - let _ = foo as isize; -LL + let _ = foo() as isize; - | +LL | let _ = foo() as isize; + | ++ error: casting function pointer `foo` to `u8` --> tests/ui/fn_to_numeric_cast_any.rs:37:13 @@ -80,9 +74,8 @@ LL | let _ = foo as u8; | help: did you mean to invoke the function? | -LL - let _ = foo as u8; -LL + let _ = foo() as u8; - | +LL | let _ = foo() as u8; + | ++ error: casting function pointer `foo` to `u16` --> tests/ui/fn_to_numeric_cast_any.rs:39:13 @@ -92,9 +85,8 @@ LL | let _ = foo as u16; | help: did you mean to invoke the function? | -LL - let _ = foo as u16; -LL + let _ = foo() as u16; - | +LL | let _ = foo() as u16; + | ++ error: casting function pointer `foo` to `u32` --> tests/ui/fn_to_numeric_cast_any.rs:41:13 @@ -104,9 +96,8 @@ LL | let _ = foo as u32; | help: did you mean to invoke the function? | -LL - let _ = foo as u32; -LL + let _ = foo() as u32; - | +LL | let _ = foo() as u32; + | ++ error: casting function pointer `foo` to `u64` --> tests/ui/fn_to_numeric_cast_any.rs:43:13 @@ -116,9 +107,8 @@ LL | let _ = foo as u64; | help: did you mean to invoke the function? | -LL - let _ = foo as u64; -LL + let _ = foo() as u64; - | +LL | let _ = foo() as u64; + | ++ error: casting function pointer `foo` to `u128` --> tests/ui/fn_to_numeric_cast_any.rs:45:13 @@ -128,9 +118,8 @@ LL | let _ = foo as u128; | help: did you mean to invoke the function? | -LL - let _ = foo as u128; -LL + let _ = foo() as u128; - | +LL | let _ = foo() as u128; + | ++ error: casting function pointer `foo` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:47:13 @@ -140,9 +129,8 @@ LL | let _ = foo as usize; | help: did you mean to invoke the function? | -LL - let _ = foo as usize; -LL + let _ = foo() as usize; - | +LL | let _ = foo() as usize; + | ++ error: casting function pointer `Struct::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:52:13 @@ -152,9 +140,8 @@ LL | let _ = Struct::static_method as usize; | help: did you mean to invoke the function? | -LL - let _ = Struct::static_method as usize; -LL + let _ = Struct::static_method() as usize; - | +LL | let _ = Struct::static_method() as usize; + | ++ error: casting function pointer `f` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:57:5 @@ -164,9 +151,8 @@ LL | f as usize | help: did you mean to invoke the function? | -LL - f as usize -LL + f() as usize - | +LL | f() as usize + | ++ error: casting function pointer `T::static_method` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:62:5 @@ -176,9 +162,8 @@ LL | T::static_method as usize | help: did you mean to invoke the function? | -LL - T::static_method as usize -LL + T::static_method() as usize - | +LL | T::static_method() as usize + | ++ error: casting function pointer `(clos as fn(u32) -> u32)` to `usize` --> tests/ui/fn_to_numeric_cast_any.rs:69:13 @@ -188,9 +173,8 @@ LL | let _ = (clos as fn(u32) -> u32) as usize; | help: did you mean to invoke the function? | -LL - let _ = (clos as fn(u32) -> u32) as usize; -LL + let _ = (clos as fn(u32) -> u32)() as usize; - | +LL | let _ = (clos as fn(u32) -> u32)() as usize; + | ++ error: casting function pointer `foo` to `*const ()` --> tests/ui/fn_to_numeric_cast_any.rs:74:13 @@ -200,9 +184,8 @@ LL | let _ = foo as *const (); | help: did you mean to invoke the function? | -LL - let _ = foo as *const (); -LL + let _ = foo() as *const (); - | +LL | let _ = foo() as *const (); + | ++ error: aborting due to 17 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr index 6e964c65a2e42..01d08a1bd9b2a 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.stderr +++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr @@ -78,9 +78,8 @@ LL | pub fn map(map: &mut HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn map(map: &mut HashMap) {} -LL + pub fn map(map: &mut HashMap) {} - | +LL | pub fn map(map: &mut HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: parameter of type `HashSet` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:70:22 @@ -90,9 +89,8 @@ LL | pub fn set(set: &mut HashSet) {} | help: add a type parameter for `BuildHasher` | -LL - pub fn set(set: &mut HashSet) {} -LL + pub fn set(set: &mut HashSet) {} - | +LL | pub fn set(set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ +++ error: impl for `HashMap` should be generalized over different hashers --> tests/ui/implicit_hasher.rs:76:43 @@ -116,9 +114,8 @@ LL | pub async fn election_vote(_data: HashMap) {} | help: add a type parameter for `BuildHasher` | -LL - pub async fn election_vote(_data: HashMap) {} -LL + pub async fn election_vote(_data: HashMap) {} - | +LL | pub async fn election_vote(_data: HashMap) {} + | +++++++++++++++++++++++++++++ +++ error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/implicit_return.stderr b/src/tools/clippy/tests/ui/implicit_return.stderr index 7ea72307450c7..936a779fa747d 100644 --- a/src/tools/clippy/tests/ui/implicit_return.stderr +++ b/src/tools/clippy/tests/ui/implicit_return.stderr @@ -9,7 +9,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:19:15 @@ -122,7 +122,7 @@ LL | format!("test {}", "test") help: add `return` as shown | LL | return format!("test {}", "test") - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:90:5 @@ -133,7 +133,7 @@ LL | m!(true, false) help: add `return` as shown | LL | return m!(true, false) - | + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:96:13 @@ -169,10 +169,8 @@ LL | | } | help: add `return` as shown | -LL ~ return loop { -LL + m!(true); -LL + } - | +LL | return loop { + | ++++++ error: missing `return` statement --> tests/ui/implicit_return.rs:130:5 @@ -183,7 +181,7 @@ LL | true help: add `return` as shown | LL | return true - | + | ++++++ error: aborting due to 16 previous errors diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr index a9192825b3543..576b38a47d2de 100644 --- a/src/tools/clippy/tests/ui/literals.stderr +++ b/src/tools/clippy/tests/ui/literals.stderr @@ -99,9 +99,8 @@ LL + let fail8 = 123; | help: if you mean to use an octal constant, use `0o` | -LL - let fail8 = 0123; -LL + let fail8 = 0o123; - | +LL | let fail8 = 0o123; + | + error: integer type suffix should not be separated by an underscore --> tests/ui/literals.rs:48:16 diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr index cf1b0a1c8bbf6..93f7f11b5e64c 100644 --- a/src/tools/clippy/tests/ui/manual_flatten.stderr +++ b/src/tools/clippy/tests/ui/manual_flatten.stderr @@ -196,11 +196,9 @@ LL | | } | |_________^ help: try | -LL ~ for n in vec![ -LL + -LL + Some(1), -LL + Some(2), -LL + Some(3) +LL | for n in vec![ +... +LL | Some(3) LL ~ ].iter().flatten() { | diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr index c8a89ac8bea42..61c781e316ef3 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.stderr +++ b/src/tools/clippy/tests/ui/octal_escapes.stderr @@ -14,9 +14,8 @@ LL + let _bad1 = "\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad1 = "\033[0m"; -LL + let _bad1 = "\x0033[0m"; - | +LL | let _bad1 = "\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:6:19 @@ -31,9 +30,8 @@ LL + let _bad2 = b"\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad2 = b"\033[0m"; -LL + let _bad2 = b"\x0033[0m"; - | +LL | let _bad2 = b"\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:7:20 @@ -48,9 +46,8 @@ LL + let _bad3 = "\\\x1b[0m"; | help: if a null escape is intended, disambiguate using | -LL - let _bad3 = "\\\033[0m"; -LL + let _bad3 = "\\\x0033[0m"; - | +LL | let _bad3 = "\\\x0033[0m"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:9:18 @@ -65,9 +62,8 @@ LL + let _bad4 = "\x0a34567"; | help: if a null escape is intended, disambiguate using | -LL - let _bad4 = "\01234567"; -LL + let _bad4 = "\x001234567"; - | +LL | let _bad4 = "\x001234567"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:10:20 @@ -77,14 +73,12 @@ LL | let _bad5 = "\0\03"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x03"; - | +LL | let _bad5 = "\0\x03"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad5 = "\0\03"; -LL + let _bad5 = "\0\x0003"; - | +LL | let _bad5 = "\0\x0003"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:23 @@ -99,9 +93,8 @@ LL + let _bad6 = "Text-\x2d\077-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\x0055\077-MoreText"; - | +LL | let _bad6 = "Text-\x0055\077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:11:27 @@ -116,9 +109,8 @@ LL + let _bad6 = "Text-\055\x3f-MoreText"; | help: if a null escape is intended, disambiguate using | -LL - let _bad6 = "Text-\055\077-MoreText"; -LL + let _bad6 = "Text-\055\x0077-MoreText"; - | +LL | let _bad6 = "Text-\055\x0077-MoreText"; + | ++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:31 @@ -128,14 +120,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x01\02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:14:34 @@ -145,14 +135,12 @@ LL | let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x02-ShortEscapes"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad7 = "EvenMoreText-\01\02-ShortEscapes"; -LL + let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; - | +LL | let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:17:19 @@ -162,14 +150,12 @@ LL | let _bad8 = "锈\01锈"; | help: if an octal escape is intended, use a hex escape instead | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x01锈"; - | +LL | let _bad8 = "锈\x01锈"; + | + help: if a null escape is intended, disambiguate using | -LL - let _bad8 = "锈\01锈"; -LL + let _bad8 = "锈\x0001锈"; - | +LL | let _bad8 = "锈\x0001锈"; + | +++ error: octal-looking escape in a literal --> tests/ui/octal_escapes.rs:18:19 @@ -184,9 +170,8 @@ LL + let _bad9 = "锈\x09锈"; | help: if a null escape is intended, disambiguate using | -LL - let _bad9 = "锈\011锈"; -LL + let _bad9 = "锈\x0011锈"; - | +LL | let _bad9 = "锈\x0011锈"; + | ++ error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr index 74bbcfcca51e1..2c26565d5ef14 100644 --- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr +++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr @@ -8,9 +8,8 @@ LL | let _ = cow.to_owned(); = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]` help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -25,9 +24,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -42,9 +40,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); @@ -59,9 +56,8 @@ LL | let _ = cow.to_owned(); | help: depending on intent, either make the Cow an Owned variant | -LL - let _ = cow.to_owned(); -LL + let _ = cow.into_owned(); - | +LL | let _ = cow.into_owned(); + | ++ help: or clone the Cow itself | LL - let _ = cow.to_owned(); diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr index 6ef333f0cfd29..84a574017a9b7 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -12,7 +12,7 @@ LL | | /// 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ /// A very short summary. +LL | /// A very short summary. LL + /// | diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr index 95f42349b9b35..8bc853132ec0b 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr @@ -12,8 +12,8 @@ LL | | //! 200 characters so I needed to write something longeeeeeeer. = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]` help: add an empty line | -LL ~ //! A very short summary. -LL + //! +LL | //! A very short summary. +LL ~ //! LL ~ //! A much longer explanation that goes into a lot more detail about | diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 1614c35cb1ce4..98ab7adf5a726 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -215,8 +215,10 @@ pub struct Config { /// `None` then these tests will be ignored. pub run_clang_based_tests_with: Option, - /// The directory containing the tests to run - pub src_base: PathBuf, + /// The directory containing the sources. + pub src_root: PathBuf, + /// The directory containing the test suite sources. Must be a subdirectory of `src_root`. + pub src_test_suite_root: PathBuf, /// The directory where programs should be built pub build_base: PathBuf, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 452a2e9a9d518..3bdf37a1f294a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1026,19 +1026,6 @@ impl Config { } } - pub fn find_rust_src_root(&self) -> Option { - let mut path = self.src_base.clone(); - let path_postfix = Path::new("src/etc/lldb_batchmode.py"); - - while path.pop() { - if path.join(&path_postfix).is_file() { - return Some(path); - } - } - - None - } - fn parse_edition(&self, line: &str) -> Option { self.parse_name_value_directive(line, "edition") } @@ -1098,7 +1085,7 @@ fn expand_variables(mut value: String, config: &Config) -> String { } if value.contains(SRC_BASE) { - value = value.replace(SRC_BASE, &config.src_base.to_string_lossy()); + value = value.replace(SRC_BASE, &config.src_test_suite_root.to_str().unwrap()); } if value.contains(BUILD_BASE) { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 55292c46bba9c..84c1cb0963e30 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -153,7 +153,8 @@ impl ConfigBuilder { "--run-lib-path=", "--python=", "--jsondocck-path=", - "--src-base=", + "--src-root=", + "--src-test-suite-root=", "--build-base=", "--sysroot-base=", "--cc=c", @@ -465,7 +466,10 @@ fn profiler_runtime() { #[test] fn asm_support() { let asms = [ + #[cfg(bootstrap)] ("avr-unknown-gnu-atmega328", false), + #[cfg(not(bootstrap))] + ("avr-none", false), ("i686-unknown-netbsd", true), ("riscv32gc-unknown-linux-gnu", true), ("riscv64imac-unknown-none-elf", true), @@ -891,8 +895,6 @@ fn test_needs_target_has_atomic() { } #[test] -// FIXME: this test will fail against stage 0 until #137037 changes reach beta. -#[cfg_attr(bootstrap, ignore)] fn test_rustc_abi() { let config = cfg().target("i686-unknown-linux-gnu").build(); assert_eq!(config.target_cfg().rustc_abi, Some("x86-sse2".to_string())); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index d0a83cab9cd99..979821701385e 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -61,7 +61,8 @@ pub fn parse_config(args: Vec) -> Config { .optopt("", "jsondoclint-path", "path to jsondoclint to use for doc tests", "PATH") .optopt("", "run-clang-based-tests-with", "path to Clang executable", "PATH") .optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR") - .reqopt("", "src-base", "directory to scan for test files", "PATH") + .reqopt("", "src-root", "directory containing sources", "PATH") + .reqopt("", "src-test-suite-root", "directory containing test suite sources", "PATH") .reqopt("", "build-base", "directory to deposit test outputs", "PATH") .reqopt("", "sysroot-base", "directory containing the compiler sysroot", "PATH") .reqopt("", "stage", "stage number under test", "N") @@ -243,7 +244,6 @@ pub fn parse_config(args: Vec) -> Config { || header::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?), ); - let src_base = opt_path(matches, "src-base"); let run_ignored = matches.opt_present("ignored"); let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); @@ -300,6 +300,15 @@ pub fn parse_config(args: Vec) -> Config { None => panic!("`--stage` is required"), }; + let src_root = opt_path(matches, "src-root"); + let src_test_suite_root = opt_path(matches, "src-test-suite-root"); + assert!( + src_test_suite_root.starts_with(&src_root), + "`src-root` must be a parent of `src-test-suite-root`: `src-root`=`{}`, `src-test-suite-root` = `{}`", + src_root.display(), + src_test_suite_root.display() + ); + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -314,7 +323,10 @@ pub fn parse_config(args: Vec) -> Config { run_clang_based_tests_with: matches.opt_str("run-clang-based-tests-with"), llvm_filecheck: matches.opt_str("llvm-filecheck").map(PathBuf::from), llvm_bin_dir: matches.opt_str("llvm-bin-dir").map(PathBuf::from), - src_base, + + src_root, + src_test_suite_root, + build_base: opt_path(matches, "build-base"), sysroot_base: opt_path(matches, "sysroot-base"), @@ -422,7 +434,10 @@ pub fn log_config(config: &Config) { logv(c, format!("rustc_path: {:?}", config.rustc_path.display())); logv(c, format!("cargo_path: {:?}", config.cargo_path)); logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path)); - logv(c, format!("src_base: {:?}", config.src_base.display())); + + logv(c, format!("src_root: {}", config.src_root.display())); + logv(c, format!("src_test_suite_root: {}", config.src_test_suite_root.display())); + logv(c, format!("build_base: {:?}", config.build_base.display())); logv(c, format!("stage: {}", config.stage)); logv(c, format!("stage_id: {}", config.stage_id)); @@ -620,20 +635,29 @@ struct TestCollector { /// regardless of whether any filters/tests were specified on the command-line, /// because filtering is handled later by libtest. pub fn collect_and_make_tests(config: Arc) -> Vec { - debug!("making tests from {:?}", config.src_base.display()); + debug!("making tests from {}", config.src_test_suite_root.display()); let common_inputs_stamp = common_inputs_stamp(&config); - let modified_tests = modified_tests(&config, &config.src_base).unwrap_or_else(|err| { - panic!("modified_tests got error from dir: {}, error: {}", config.src_base.display(), err) - }); + let modified_tests = + modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| { + panic!( + "modified_tests got error from dir: {}, error: {}", + config.src_test_suite_root.display(), + err + ) + }); let cache = HeadersCache::load(&config); let cx = TestCollectorCx { config, cache, common_inputs_stamp, modified_tests }; let mut collector = TestCollector { tests: vec![], found_path_stems: HashSet::new(), poisoned: false }; - collect_tests_from_dir(&cx, &mut collector, &cx.config.src_base, Path::new("")).unwrap_or_else( - |reason| panic!("Could not read tests from {}: {reason}", cx.config.src_base.display()), - ); + collect_tests_from_dir(&cx, &mut collector, &cx.config.src_test_suite_root, Path::new("")) + .unwrap_or_else(|reason| { + panic!( + "Could not read tests from {}: {reason}", + cx.config.src_test_suite_root.display() + ) + }); let TestCollector { tests, found_path_stems, poisoned } = collector; @@ -655,7 +679,7 @@ pub fn collect_and_make_tests(config: Arc) -> Vec { /// common to some subset of tests, and are hopefully unlikely to be modified /// while working on other tests.) fn common_inputs_stamp(config: &Config) -> Stamp { - let rust_src_dir = config.find_rust_src_root().expect("Could not find Rust source root"); + let src_root = &config.src_root; let mut stamp = Stamp::from_path(&config.rustc_path); @@ -670,17 +694,17 @@ fn common_inputs_stamp(config: &Config) -> Stamp { "src/etc/lldb_providers.py", ]; for file in &pretty_printer_files { - let path = rust_src_dir.join(file); + let path = src_root.join(file); stamp.add_path(&path); } - stamp.add_dir(&rust_src_dir.join("src/etc/natvis")); + stamp.add_dir(&src_root.join("src/etc/natvis")); stamp.add_dir(&config.run_lib_path); if let Some(ref rustdoc_path) = config.rustdoc_path { stamp.add_path(&rustdoc_path); - stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py")); + stamp.add_path(&src_root.join("src/etc/htmldocck.py")); } // Re-run coverage tests if the `coverage-dump` tool was modified, @@ -689,10 +713,10 @@ fn common_inputs_stamp(config: &Config) -> Stamp { stamp.add_path(coverage_dump_path) } - stamp.add_dir(&rust_src_dir.join("src/tools/run-make-support")); + stamp.add_dir(&src_root.join("src/tools/run-make-support")); // Compiletest itself. - stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/")); + stamp.add_dir(&src_root.join("src/tools/compiletest")); stamp } @@ -933,10 +957,7 @@ fn files_related_to_test( } // `minicore.rs` test auxiliary: we need to make sure tests get rerun if this changes. - // - // FIXME(jieyouxu): untangle these paths, we should provide both a path to root `tests/` or - // `tests/auxiliary/` and the test suite in question. `src_base` is also a terrible name. - related.push(config.src_base.parent().unwrap().join("auxiliary").join("minicore.rs")); + related.push(config.src_root.join("tests").join("auxiliary").join("minicore.rs")); related } @@ -1026,10 +1047,8 @@ fn make_test_name( testpaths: &TestPaths, revision: Option<&str>, ) -> test::TestName { - // Print the name of the file, relative to the repository root. - // `src_base` looks like `/path/to/rust/tests/ui` - let root_directory = config.src_base.parent().unwrap().parent().unwrap(); - let path = testpaths.file.strip_prefix(root_directory).unwrap(); + // Print the name of the file, relative to the sources root. + let path = testpaths.file.strip_prefix(&config.src_root).unwrap(); let debugger = match config.debugger { Some(d) => format!("-{}", d), None => String::new(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0e2da2b02ca0f..536e19bc4933e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1365,7 +1365,7 @@ impl<'test> TestCx<'test> { // // Note: avoid adding a subdirectory of an already filtered directory here, otherwise the // same slice of text will be double counted and the truncation might not happen. - add_path(&self.config.src_base); + add_path(&self.config.src_test_suite_root); add_path(&self.config.build_base); read2_abbreviated(child, &filter_paths_from_len).expect("failed to read output") @@ -1471,7 +1471,7 @@ impl<'test> TestCx<'test> { // Similarly, vendored sources shouldn't be shown when running from a dist tarball. rustc.arg("-Z").arg(format!( "ignore-directory-in-diagnostics-source-blocks={}", - self.config.find_rust_src_root().unwrap().join("vendor").display(), + self.config.src_root.join("vendor").to_str().unwrap(), )); // Optionally prevent default --sysroot if specified in test compile-flags. @@ -1632,7 +1632,7 @@ impl<'test> TestCx<'test> { if self.props.remap_src_base { rustc.arg(format!( "--remap-path-prefix={}={}", - self.config.src_base.display(), + self.config.src_test_suite_root.to_str().unwrap(), FAKE_SRC_BASE, )); } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index b236b06756903..170b8a8099687 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -257,11 +257,8 @@ impl TestCx<'_> { println!("Adb process is already finished."); } } else { - let rust_src_root = - self.config.find_rust_src_root().expect("Could not find Rust source root"); - let rust_pp_module_rel_path = Path::new("./src/etc"); - let rust_pp_module_abs_path = - rust_src_root.join(rust_pp_module_rel_path).to_str().unwrap().to_owned(); + let rust_pp_module_abs_path = self.config.src_root.join("src").join("etc"); + let rust_pp_module_abs_path = rust_pp_module_abs_path.to_str().unwrap(); // write debugger script let mut script_str = String::with_capacity(2048); script_str.push_str(&format!("set charset {}\n", Self::charset())); @@ -338,7 +335,7 @@ impl TestCx<'_> { let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") { format!("{pp}:{rust_pp_module_abs_path}") } else { - rust_pp_module_abs_path + rust_pp_module_abs_path.to_string() }; gdb.args(debugger_opts).env("PYTHONPATH", pythonpath); @@ -407,11 +404,8 @@ impl TestCx<'_> { // Make LLDB emit its version, so we have it documented in the test output script_str.push_str("version\n"); - // Switch LLDB into "Rust mode" - let rust_src_root = - self.config.find_rust_src_root().expect("Could not find Rust source root"); - let rust_pp_module_rel_path = Path::new("./src/etc"); - let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path); + // Switch LLDB into "Rust mode". + let rust_pp_module_abs_path = self.config.src_root.join("src/etc"); script_str.push_str(&format!( "command script import {}/lldb_lookup.py\n", @@ -445,7 +439,7 @@ impl TestCx<'_> { let debugger_script = self.make_out_name("debugger.script"); // Let LLDB execute the script via lldb_batchmode.py - let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root); + let debugger_run_result = self.run_lldb(&exe_file, &debugger_script); if !debugger_run_result.status.success() { self.fatal_proc_rec("Error while running LLDB", &debugger_run_result); @@ -456,18 +450,13 @@ impl TestCx<'_> { } } - fn run_lldb( - &self, - test_executable: &Path, - debugger_script: &Path, - rust_src_root: &Path, - ) -> ProcRes { + fn run_lldb(&self, test_executable: &Path, debugger_script: &Path) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script - let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); + let lldb_script_path = self.config.src_root.join("src/etc/lldb_batchmode.py"); let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") { format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap()) } else { - self.config.lldb_python_dir.as_ref().unwrap().to_string() + self.config.lldb_python_dir.clone().unwrap() }; self.run_command_to_procres( Command::new(&self.config.python) diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs index a83bcd70c8718..d630affbec104 100644 --- a/src/tools/compiletest/src/runtest/js_doc.rs +++ b/src/tools/compiletest/src/runtest/js_doc.rs @@ -9,12 +9,11 @@ impl TestCx<'_> { self.document(&out_dir, &self.testpaths); - let root = self.config.find_rust_src_root().unwrap(); let file_stem = self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem"); let res = self.run_command_to_procres( Command::new(&nodejs) - .arg(root.join("src/tools/rustdoc-js/tester.js")) + .arg(self.config.src_root.join("src/tools/rustdoc-js/tester.js")) .arg("--doc-folder") .arg(out_dir) .arg("--crate-name") diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 16c46fc13390f..74e6af36ea1dd 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -21,8 +21,6 @@ impl TestCx<'_> { fn run_rmake_legacy_test(&self) { let cwd = env::current_dir().unwrap(); - let src_root = self.config.src_base.parent().unwrap().parent().unwrap(); - let src_root = cwd.join(&src_root); // FIXME(Zalathar): This should probably be `output_base_dir` to avoid // an unnecessary extra subdirectory, but since legacy Makefile tests @@ -51,7 +49,7 @@ impl TestCx<'_> { .stderr(Stdio::piped()) .env("TARGET", &self.config.target) .env("PYTHON", &self.config.python) - .env("S", src_root) + .env("S", &self.config.src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) .env("TMPDIR", &tmpdir) @@ -181,28 +179,10 @@ impl TestCx<'_> { // library. // 2. We need to run the recipe binary. - // So we assume the rust-lang/rust project setup looks like the following (our `.` is the - // top-level directory, irrelevant entries to our purposes omitted): - // - // ``` - // . // <- `source_root` - // ├── build/ // <- `build_root` - // ├── compiler/ - // ├── library/ - // ├── src/ - // │ └── tools/ - // │ └── run_make_support/ - // └── tests - // └── run-make/ - // ``` - - // `source_root` is the top-level directory containing the rust-lang/rust checkout. - let source_root = - self.config.find_rust_src_root().expect("could not determine rust source root"); // `self.config.build_base` is actually the build base folder + "test" + test suite name, it // looks like `build//test/run-make`. But we want `build//`. Note // that the `build` directory does not need to be called `build`, nor does it need to be - // under `source_root`, so we must compute it based off of `self.config.build_base`. + // under `src_root`, so we must compute it based off of `self.config.build_base`. let build_root = self.config.build_base.parent().and_then(Path::parent).unwrap().to_path_buf(); @@ -389,10 +369,9 @@ impl TestCx<'_> { .env("TARGET", &self.config.target) // Some tests unfortunately still need Python, so provide path to a Python interpreter. .env("PYTHON", &self.config.python) - // Provide path to checkout root. This is the top-level directory containing - // rust-lang/rust checkout. - .env("SOURCE_ROOT", &source_root) - // Path to the build directory. This is usually the same as `source_root.join("build").join("host")`. + // Provide path to sources root. + .env("SOURCE_ROOT", &self.config.src_root) + // Path to the host build directory. .env("BUILD_ROOT", &build_root) // Provide path to stage-corresponding rustc. .env("RUSTC", &self.config.rustc_path) @@ -408,11 +387,11 @@ impl TestCx<'_> { .env("LLVM_COMPONENTS", &self.config.llvm_components); if let Some(ref cargo) = self.config.cargo_path { - cmd.env("CARGO", source_root.join(cargo)); + cmd.env("CARGO", cargo); } if let Some(ref rustdoc) = self.config.rustdoc_path { - cmd.env("RUSTDOC", source_root.join(rustdoc)); + cmd.env("RUSTDOC", rustdoc); } if let Some(ref node) = self.config.nodejs { diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 3f33862d2cfe2..2583ae96a6788 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -17,9 +17,10 @@ impl TestCx<'_> { if self.props.check_test_line_numbers_match { self.check_rustdoc_test_option(proc_res); } else { - let root = self.config.find_rust_src_root().unwrap(); let mut cmd = Command::new(&self.config.python); - cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file); + cmd.arg(self.config.src_root.join("src/etc/htmldocck.py")) + .arg(&out_dir) + .arg(&self.testpaths.file); if self.config.bless { cmd.arg("--bless"); } diff --git a/src/tools/enzyme b/src/tools/enzyme index 7f3b207c4413c..5004a8f6f5d84 160000 --- a/src/tools/enzyme +++ b/src/tools/enzyme @@ -1 +1 @@ -Subproject commit 7f3b207c4413c9d715fd54b36b8a8fd3179e0b67 +Subproject commit 5004a8f6f5d8468b64fae457afb7d96e1784c783 diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index f4dac6e947e32..54fe7f6eb5a9b 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -2,6 +2,7 @@ name = "error_index_generator" version = "0.0.0" edition = "2021" +workspace = "../rustbook" [dependencies] mdbook = { version = "0.4", default-features = false, features = ["search"] } diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs index 51e353e9b229f..b717bd53eb1a7 100644 --- a/src/tools/generate-copyright/src/cargo_metadata.rs +++ b/src/tools/generate-copyright/src/cargo_metadata.rs @@ -11,10 +11,6 @@ pub enum Error { Io(#[from] std::io::Error), #[error("Failed get output from cargo-metadata: {0:?}")] GettingMetadata(#[from] cargo_metadata::Error), - #[error("Failed to run cargo vendor: {0:?}")] - LaunchingVendor(std::io::Error), - #[error("Failed to complete cargo vendor")] - RunningVendor, #[error("Bad path {0:?} whilst scraping files")] Scraping(PathBuf), } @@ -43,25 +39,19 @@ pub struct PackageMetadata { pub is_in_libstd: Option, } -/// Use `cargo metadata` and `cargo vendor` to get a list of dependencies and their license data. +/// Use `cargo metadata` to get a list of dependencies and their license data. License files will +/// also be pulled from the vendor path (generated by bootstrap). /// -/// This will involve running `cargo vendor` into `vendor_path` so we can -/// grab the license files. -/// -/// Any dependency with a path beginning with `root_path` is ignored, as we -/// assume `reuse` has covered it already. +/// Any dependency with a path beginning with `root_path` is ignored, as we assume `reuse` has +/// covered it already. pub fn get_metadata_and_notices( cargo: &Path, vendor_path: &Path, root_path: &Path, - manifest_paths: &[&Path], + manifest_paths: &[PathBuf], ) -> Result, Error> { let mut output = get_metadata(cargo, root_path, manifest_paths)?; - // Now do a cargo-vendor and grab everything - println!("Vendoring deps into {}...", vendor_path.display()); - run_cargo_vendor(cargo, &vendor_path, manifest_paths)?; - // Now for each dependency we found, go and grab any important looking files for (package, metadata) in output.iter_mut() { load_important_files(package, metadata, &vendor_path)?; @@ -77,7 +67,7 @@ pub fn get_metadata_and_notices( pub fn get_metadata( cargo: &Path, root_path: &Path, - manifest_paths: &[&Path], + manifest_paths: &[PathBuf], ) -> Result, Error> { let mut output = BTreeMap::new(); // Look at the metadata for each manifest @@ -113,28 +103,6 @@ pub fn get_metadata( Ok(output) } -/// Run cargo-vendor, fetching into the given dir -fn run_cargo_vendor(cargo: &Path, dest: &Path, manifest_paths: &[&Path]) -> Result<(), Error> { - let mut vendor_command = std::process::Command::new(cargo); - vendor_command.env("RUSTC_BOOTSTRAP", "1"); - vendor_command.arg("vendor"); - vendor_command.arg("--quiet"); - vendor_command.arg("--versioned-dirs"); - for manifest_path in manifest_paths { - vendor_command.arg("-s"); - vendor_command.arg(manifest_path); - } - vendor_command.arg(dest); - - let vendor_status = vendor_command.status().map_err(Error::LaunchingVendor)?; - - if !vendor_status.success() { - return Err(Error::RunningVendor); - } - - Ok(()) -} - /// Add important files off disk into this dependency. /// /// Maybe one-day Cargo.toml will contain enough information that we don't need diff --git a/src/tools/generate-copyright/src/main.rs b/src/tools/generate-copyright/src/main.rs index 7a014989e6880..79e90d88f4446 100644 --- a/src/tools/generate-copyright/src/main.rs +++ b/src/tools/generate-copyright/src/main.rs @@ -17,29 +17,36 @@ mod cargo_metadata; fn main() -> Result<(), Error> { let dest_file = env_path("DEST")?; let libstd_dest_file = env_path("DEST_LIBSTD")?; - let out_dir = env_path("OUT_DIR")?; + let src_dir = env_path("SRC_DIR")?; + let vendor_dir = env_path("VENDOR_DIR")?; let cargo = env_path("CARGO")?; let license_metadata = env_path("LICENSE_METADATA")?; - let root_path = std::path::absolute(".")?; + let cargo_manifests = env_string("CARGO_MANIFESTS")? + .split(",") + .map(|manifest| manifest.into()) + .collect::>(); + let library_manifests = cargo_manifests + .iter() + .filter(|path| { + if let Ok(stripped) = path.strip_prefix(&src_dir) { + stripped.starts_with("library") + } else { + panic!("manifest {path:?} not relative to source dir {src_dir:?}"); + } + }) + .cloned() + .collect::>(); // Scan Cargo dependencies - let mut collected_cargo_metadata = cargo_metadata::get_metadata_and_notices( - &cargo, - &out_dir.join("vendor"), - &root_path, - &[ - Path::new("./Cargo.toml"), - Path::new("./src/tools/cargo/Cargo.toml"), - Path::new("./library/Cargo.toml"), - ], - )?; + let mut collected_cargo_metadata = + cargo_metadata::get_metadata_and_notices(&cargo, &vendor_dir, &src_dir, &cargo_manifests)?; let library_collected_cargo_metadata = cargo_metadata::get_metadata_and_notices( &cargo, - &out_dir.join("library-vendor"), - &root_path, - &[Path::new("./library/Cargo.toml")], + &vendor_dir, + &src_dir, + &library_manifests, )?; for (key, value) in collected_cargo_metadata.iter_mut() { @@ -54,7 +61,7 @@ fn main() -> Result<(), Error> { let library_collected_tree_metadata = Metadata { files: collected_tree_metadata .files - .trim_clone(&Path::new("./library"), &Path::new(".")) + .trim_clone(&src_dir.join("library"), &src_dir) .unwrap(), }; @@ -193,6 +200,17 @@ struct License { copyright: Vec, } +/// Grab an environment variable as string, or fail nicely. +fn env_string(var: &str) -> Result { + match std::env::var(var) { + Ok(var) => Ok(var), + Err(std::env::VarError::NotUnicode(_)) => { + anyhow::bail!("environment variable {var} is not utf-8") + } + Err(std::env::VarError::NotPresent) => anyhow::bail!("missing environment variable {var}"), + } +} + /// Grab an environment variable as a PathBuf, or fail nicely. fn env_path(var: &str) -> Result { if let Some(var) = std::env::var_os(var) { diff --git a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs index fdbf6171c53f2..608c6605304f4 100644 --- a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs +++ b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs @@ -27,6 +27,10 @@ pub struct Args { #[arg(long)] target_cpu: Option, + /// The target features + #[arg(long)] + target_feature: Option, + /// Write output to the filename #[arg(short, long)] output: PathBuf, @@ -49,7 +53,7 @@ fn main() -> anyhow::Result<()> { let args = Args::parse(); - let mut linker = Session::new(args.target, args.target_cpu, args.output); + let mut linker = Session::new(args.target, args.target_cpu, args.target_feature, args.output); linker.add_exported_symbols(args.export_symbol); diff --git a/src/tools/llvm-bitcode-linker/src/linker.rs b/src/tools/llvm-bitcode-linker/src/linker.rs index 9f579d1009408..dafd847e76808 100644 --- a/src/tools/llvm-bitcode-linker/src/linker.rs +++ b/src/tools/llvm-bitcode-linker/src/linker.rs @@ -8,6 +8,7 @@ use crate::{Optimization, Target}; pub struct Session { target: Target, cpu: Option, + feature: Option, symbols: Vec, /// A file that `llvm-link` supports, like a bitcode file or an archive. @@ -21,7 +22,12 @@ pub struct Session { } impl Session { - pub fn new(target: crate::Target, cpu: Option, out_path: PathBuf) -> Self { + pub fn new( + target: crate::Target, + cpu: Option, + feature: Option, + out_path: PathBuf, + ) -> Self { let link_path = out_path.with_extension("o"); let opt_path = out_path.with_extension("optimized.o"); let sym_path = out_path.with_extension("symbols.txt"); @@ -29,6 +35,7 @@ impl Session { Session { target, cpu, + feature, symbols: Vec::new(), files: Vec::new(), link_path, @@ -134,6 +141,10 @@ impl Session { lcc_command.arg("--mcpu").arg(mcpu); } + if let Some(mattr) = &self.feature { + lcc_command.arg(&format!("--mattr={}", mattr)); + } + let lcc_output = lcc_command .arg(&self.opt_path) .arg("-o").arg(&self.out_path) diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index bce78adcaea45..0faad0f7621a5 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -145,7 +145,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "rintf16" => { + "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f16()?; let mode = match intrinsic_name { @@ -153,14 +153,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf16" => Round::TowardPositive, "truncf16" => Round::TowardZero, "roundf16" => Round::NearestTiesToAway, - "rintf16" => Round::NearestTiesToEven, + "round_ties_even_f16" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => { + "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; let mode = match intrinsic_name { @@ -168,14 +168,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf32" => Round::TowardPositive, "truncf32" => Round::TowardZero, "roundf32" => Round::NearestTiesToAway, - "rintf32" => Round::NearestTiesToEven, + "round_ties_even_f32" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "rintf64" => { + "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f64()?; let mode = match intrinsic_name { @@ -183,14 +183,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf64" => Round::TowardPositive, "truncf64" => Round::TowardZero, "roundf64" => Round::NearestTiesToAway, - "rintf64" => Round::NearestTiesToEven, + "round_ties_even_f64" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } - "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "rintf128" => { + "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f128()?; let mode = match intrinsic_name { @@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ceilf128" => Round::TowardPositive, "truncf128" => Round::TowardZero, "roundf128" => Round::NearestTiesToAway, - "rintf128" => Round::NearestTiesToEven, + "round_ties_even_f128" => Round::NearestTiesToEven, _ => bug!(), }; let res = f.round_to_integral(mode).value; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 44e4f1a293213..89ad803ac3be3 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -1,4 +1,3 @@ -#![cfg_attr(bootstrap, feature(trait_upcasting))] #![feature(rustc_private)] #![feature(cell_update)] #![feature(float_gamma)] @@ -16,7 +15,6 @@ #![feature(unqualified_local_imports)] #![feature(derive_coerce_pointee)] #![feature(arbitrary_self_types)] -#![feature(unsigned_is_multiple_of)] #![feature(extract_if)] // Configure clippy and other lints #![allow( diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs index 13eb5bfb3421d..562d72b0ca0f6 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs @@ -1,9 +1,7 @@ //@normalize-stderr-test: "\d+ < \d+" -> "$$ADDR < $$ADDR" -#![feature(ptr_sub_ptr)] - fn main() { let arr = [0u8; 8]; let ptr1 = arr.as_ptr(); let ptr2 = ptr1.wrapping_add(4); - let _val = unsafe { ptr1.sub_ptr(ptr2) }; //~ERROR: first pointer has smaller address than second + let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; //~ERROR: first pointer has smaller address than second } diff --git a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr index a0a8e97e7fa95..80e3f2c22a152 100644 --- a/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr +++ b/src/tools/miri/tests/fail/intrinsics/ptr_offset_from_unsigned_neg.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR --> tests/fail/intrinsics/ptr_offset_from_unsigned_neg.rs:LL:CC | -LL | let _val = unsafe { ptr1.sub_ptr(ptr2) }; - | ^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR +LL | let _val = unsafe { ptr1.offset_from_unsigned(ptr2) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller address than second: $ADDR < $ADDR | = 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 diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr index 782303d5f3f96..80dd2f39b4260 100644 --- a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr +++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr @@ -1,6 +1,8 @@ thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null and the specified memory ranges do not overlap + +This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect thread caused non-unwinding panic. aborting. diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs new file mode 100644 index 0000000000000..7de4aef422a08 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.rs @@ -0,0 +1,30 @@ +// Test that transmuting from `&dyn Trait` to `&dyn Trait fn(&'a ())>` is UB. +// +// The vtable of `() as Trait` and `() as Trait fn(&'a ())>` can have +// different entries and, because in the former the entry for `foo` is vacant, this test will +// segfault at runtime. + +trait Trait { + fn foo(&self) + where + U: HigherRanked, + { + } +} +impl Trait for T {} + +trait HigherRanked {} +impl HigherRanked for for<'a> fn(&'a ()) {} + +// 2nd candidate is required so that selecting `(): Trait` will +// evaluate the candidates and fail the leak check instead of returning the +// only applicable candidate. +trait Unsatisfied {} +impl HigherRanked for T {} + +fn main() { + let x: &dyn Trait = &(); + let y: &dyn Trait fn(&'a ())> = unsafe { std::mem::transmute(x) }; + //~^ ERROR: wrong trait in wide pointer vtable + y.foo(); +} diff --git a/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr new file mode 100644 index 0000000000000..cfdf279a60538 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/dyn-transmute-inner-binder.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait fn(&'a ())>`, but encountered `Trait` + --> tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC + | +LL | let y: &dyn Trait fn(&'a ())> = unsafe { std::mem::transmute(x) }; + | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `Trait fn(&'a ())>`, but encountered `Trait` + | + = 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 tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs index 6f8adc09640ce..875891df2331c 100644 --- a/src/tools/miri/tests/pass/dyn-upcast.rs +++ b/src/tools/miri/tests/pass/dyn-upcast.rs @@ -9,6 +9,7 @@ fn main() { drop_principal(); modulo_binder(); modulo_assoc(); + bidirectional_subtyping(); } fn vtable_nop_cast() { @@ -531,3 +532,32 @@ fn modulo_assoc() { (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0); } + +fn bidirectional_subtyping() { + // Test that transmuting between subtypes of dyn traits is fine, even in the + // "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait. + // Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the + // *outside* here! + + trait Trait {} + impl Trait for T {} + + struct Wrapper(T); + + let x: &dyn Trait = &(); + let _y: &dyn for<'a> Trait = unsafe { std::mem::transmute(x) }; + + let x: &dyn for<'a> Trait = &(); + let _y: &dyn Trait = unsafe { std::mem::transmute(x) }; + + let x: &dyn Trait> = &(); + let _y: &dyn for<'a> Trait> = unsafe { std::mem::transmute(x) }; + + let x: &dyn for<'a> Trait> = &(); + let _y: &dyn Trait> = unsafe { std::mem::transmute(x) }; + + // This lowers to a ptr-to-ptr cast (which behaves like a transmute) + // and not an unsizing coercion: + let x: *const dyn for<'a> Trait<&'a ()> = &(); + let _y: *const Wrapper> = x as _; +} diff --git a/src/tools/miri/tests/pass/ptr_offset.rs b/src/tools/miri/tests/pass/ptr_offset.rs index 92b275b00327d..89aff7bf63505 100644 --- a/src/tools/miri/tests/pass/ptr_offset.rs +++ b/src/tools/miri/tests/pass/ptr_offset.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-permissive-provenance -#![feature(ptr_sub_ptr)] use std::{mem, ptr}; fn main() { @@ -22,7 +21,7 @@ fn smoke() { let _val = ptr.wrapping_sub(0); let _val = unsafe { ptr.sub(0) }; let _val = unsafe { ptr.offset_from(ptr) }; - let _val = unsafe { ptr.sub_ptr(ptr) }; + let _val = unsafe { ptr.offset_from_unsigned(ptr) }; } fn test_offset_from() { @@ -33,14 +32,14 @@ fn test_offset_from() { let y = x.offset(12); assert_eq!(y.offset_from(x), 12); - assert_eq!(y.sub_ptr(x), 12); + assert_eq!(y.offset_from_unsigned(x), 12); assert_eq!(x.offset_from(y), -12); assert_eq!((y as *const u32).offset_from(x as *const u32), 12 / 4); assert_eq!((x as *const u32).offset_from(y as *const u32), -12 / 4); let x = (((x as usize) * 2) / 2) as *const u8; assert_eq!(y.offset_from(x), 12); - assert_eq!(y.sub_ptr(x), 12); + assert_eq!(y.offset_from_unsigned(x), 12); assert_eq!(x.offset_from(y), -12); } } diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index fd4a20278addd..710ba025830a8 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -253,6 +253,13 @@ impl Rustc { self } + /// Specify the target CPU. + pub fn target_cpu>(&mut self, target_cpu: S) -> &mut Self { + let target_cpu = target_cpu.as_ref(); + self.cmd.arg(format!("-Ctarget-cpu={target_cpu}")); + self + } + /// Specify the crate type. pub fn crate_type(&mut self, crate_type: &str) -> &mut Self { self.cmd.arg("--crate-type"); diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index fc3680ce274ec..01e6a39f7c9b3 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -561,6 +561,7 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mbe", "ra-ap-rustc_abi", + "ra-ap-rustc_hashes", "ra-ap-rustc_parse_format", "rustc-hash 2.0.0", "rustc_apfloat", @@ -628,6 +629,7 @@ dependencies = [ "oorandom", "project-model", "ra-ap-rustc_abi", + "ra-ap-rustc_hashes", "ra-ap-rustc_index", "ra-ap-rustc_pattern_analysis", "rustc-hash 2.0.0", @@ -1505,20 +1507,30 @@ dependencies = [ [[package]] name = "ra-ap-rustc_abi" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40c4e339b71a8f075a829b1acaf32f870a11b466d9b8623d50b0ce33e65af95" +checksum = "3829c3355d1681ffeaf1450ec71edcdace6820fe2e86469d8fc1ad45e2c96460" dependencies = [ "bitflags 2.7.0", + "ra-ap-rustc_hashes", "ra-ap-rustc_index", "tracing", ] +[[package]] +name = "ra-ap-rustc_hashes" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd4d6d4c434bec08e02370a4f64a4985312097215a62e82d0f757f3a98e502e" +dependencies = [ + "rustc-stable-hash", +] + [[package]] name = "ra-ap-rustc_index" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872072e2ba11d11147ebe9fde1608fe7f7d9b5c51dac524af28ee07c6dade468" +checksum = "bad6fc4bd7522e31096e2de5b0351144fe0684b608791ee26c842bf2da1b19ae" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1526,9 +1538,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffcd77debcaf2ad690a57c2d041c11eb33fe66869754b2c5f35c52954b46af0c" +checksum = "cfb234e1f84b92be45276c3025bee18789e9bc95bec8789bec961e78edb01c52" dependencies = [ "proc-macro2", "quote", @@ -1537,9 +1549,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49265cdf8823f8d246e476c79c60bd6e5b551c81ae76e1c8d6a5e0dc73df0bca" +checksum = "7a3a40bd11dc43d1cb110e730b80620cf8102f4cca8920a02b65954da0ed931f" dependencies = [ "memchr", "unicode-properties", @@ -1548,9 +1560,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3da239fdc971176de0db45cb631d71475b52033a3d0027d91964da7be89eee6" +checksum = "5feb877478994cb4c0c0c7a5116a352eefc0634aefc8636feb00a893fa5b7135" dependencies = [ "ra-ap-rustc_index", "ra-ap-rustc_lexer", @@ -1558,9 +1570,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.95.0" +version = "0.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56057d08fdfa0d95494e461bbdd5d4b3fdb349cca6be05ad7759bc964be1b8d4" +checksum = "a76774d35934d464c4115908cde16f76a4f7e540fe1eea6b79336c556e37bdd3" dependencies = [ "ra-ap-rustc_index", "rustc-hash 2.0.0", @@ -1735,6 +1747,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +[[package]] +name = "rustc-stable-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1" + [[package]] name = "rustc_apfloat" version = "0.2.1+llvm-462a31f5a5ab" diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 5060013b13983..1ff36a68e8f7b 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -86,11 +86,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_lexer = { version = "0.95", default-features = false } -ra-ap-rustc_parse_format = { version = "0.95", default-features = false } -ra-ap-rustc_index = { version = "0.95", default-features = false } -ra-ap-rustc_abi = { version = "0.95", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.95", default-features = false } +ra-ap-rustc_hashes = { version = "0.97", default-features = false } +ra-ap-rustc_lexer = { version = "0.97", default-features = false } +ra-ap-rustc_parse_format = { version = "0.97", default-features = false } +ra-ap-rustc_index = { version = "0.97", default-features = false } +ra-ap-rustc_abi = { version = "0.97", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.97", default-features = false } # local crates that aren't published to crates.io. These should not have versions. diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index 74fe49b767648..9a448ec14ea1f 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -31,6 +31,7 @@ triomphe.workspace = true rustc_apfloat = "0.2.0" text-size.workspace = true +ra-ap-rustc_hashes.workspace = true ra-ap-rustc_parse_format.workspace = true ra-ap-rustc_abi.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 8fc19854033cb..c94622016d355 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -9,6 +9,7 @@ use hir_expand::name::Name; use intern::sym; use la_arena::Arena; use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; +use rustc_hashes::Hash64; use triomphe::Arc; use tt::iter::TtElement; @@ -172,7 +173,13 @@ fn parse_repr_tt(tt: &TopSubtree) -> Option { } } - Some(ReprOptions { int, align: max_align, pack: min_pack, flags, field_shuffle_seed: 0 }) + Some(ReprOptions { + int, + align: max_align, + pack: min_pack, + flags, + field_shuffle_seed: Hash64::ZERO, + }) } impl StructData { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index c8efd9043203b..9c947df35e990 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -18,9 +18,15 @@ extern crate ra_ap_rustc_parse_format as rustc_parse_format; #[cfg(feature = "in-rust-tree")] extern crate rustc_abi; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_hashes; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_hashes as rustc_hashes; + pub mod db; pub mod attr; diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml index eaa258a6b5d28..4d36de0b383cc 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml @@ -36,6 +36,7 @@ indexmap.workspace = true rustc_apfloat = "0.2.0" ra-ap-rustc_abi.workspace = true +ra-ap-rustc_hashes.workspace = true ra-ap-rustc_index.workspace = true ra-ap-rustc_pattern_analysis.workspace = true diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index 3312da470c039..91eb59fb3140f 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -361,11 +361,11 @@ impl PatCx for MatchCheckCtx<'_> { } } - fn ctor_sub_tys<'a>( - &'a self, - ctor: &'a rustc_pattern_analysis::constructor::Constructor, - ty: &'a Self::Ty, - ) -> impl ExactSizeIterator + Captures<'a> { + fn ctor_sub_tys( + &self, + ctor: &rustc_pattern_analysis::constructor::Constructor, + ty: &Self::Ty, + ) -> impl ExactSizeIterator { let single = |ty| smallvec![(ty, PrivateUninhabitedField(false))]; let tys: SmallVec<[_; 2]> = match ctor { Struct | Variant(_) | UnionField => match ty.kind(Interner) { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index 108171586ea89..e2ab336d2e466 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -14,6 +14,7 @@ use hir_def::{ }; use la_arena::{Idx, RawIdx}; use rustc_abi::AddressSpace; +use rustc_hashes::Hash64; use rustc_index::{IndexSlice, IndexVec}; use triomphe::Arc; @@ -178,7 +179,7 @@ fn layout_of_simd_ty( .size .checked_mul(e_len, dl) .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - let align = dl.vector_align(size); + let align = dl.llvmlike_vector_align(size); let size = size.align_to(align.abi); // Compute the placement of the vector fields: @@ -193,11 +194,12 @@ fn layout_of_simd_ty( fields, backend_repr: BackendRepr::Vector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, + uninhabited: false, size, align, max_repr_align: None, unadjusted_abi_align: align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, })) } @@ -296,25 +298,22 @@ pub fn layout_of_ty_query( .checked_mul(count, dl) .ok_or(LayoutError::BadCalc(LayoutCalculatorError::SizeOverflow))?; - let backend_repr = - if count != 0 && matches!(element.backend_repr, BackendRepr::Uninhabited) { - BackendRepr::Uninhabited - } else { - BackendRepr::Memory { sized: true } - }; + let backend_repr = BackendRepr::Memory { sized: true }; let largest_niche = if count != 0 { element.largest_niche } else { None }; + let uninhabited = if count != 0 { element.uninhabited } else { false }; Layout { variants: Variants::Single { index: struct_variant_idx() }, fields: FieldsShape::Array { stride: element.size, count }, backend_repr, largest_niche, + uninhabited, align: element.align, size, max_repr_align: None, unadjusted_abi_align: element.align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, } } TyKind::Slice(element) => { @@ -324,11 +323,12 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: element.size, count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: element.align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: element.align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, } } TyKind::Str => Layout { @@ -336,11 +336,12 @@ pub fn layout_of_ty_query( fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, backend_repr: BackendRepr::Memory { sized: false }, largest_niche: None, + uninhabited: false, align: dl.i8_align, size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align.abi, - randomization_seed: 0, + randomization_seed: Hash64::ZERO, }, // Potentially-wide pointers. TyKind::Ref(_, _, pointee) | TyKind::Raw(_, pointee) => { diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs index 55d81875a2be4..daddcf0b24248 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs @@ -12,6 +12,9 @@ extern crate ra_ap_rustc_index as rustc_index; #[cfg(feature = "in-rust-tree")] extern crate rustc_abi; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_hashes; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_abi as rustc_abi; @@ -21,6 +24,9 @@ extern crate rustc_pattern_analysis; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_pattern_analysis as rustc_pattern_analysis; +#[cfg(not(feature = "in-rust-tree"))] +extern crate ra_ap_rustc_hashes as rustc_hashes; + mod builder; mod chalk_db; mod chalk_ext; diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md index 761a7f859bef4..9d68a873ffefa 100644 --- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md @@ -1,7 +1,7 @@ //! Generated by `cargo xtask codegen assists-doc-tests`, do not edit by hand. ### `add_braces` -**Source:** [add_braces.rs](/crates/ide-assists/src/handlers/add_braces.rs#8) +**Source:** [add_braces.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_braces.rs#L8) Adds braces to lambda and match arm expressions. @@ -29,7 +29,7 @@ fn foo(n: i32) -> i32 { ### `add_explicit_type` -**Source:** [add_explicit_type.rs](/crates/ide-assists/src/handlers/add_explicit_type.rs#7) +**Source:** [add_explicit_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_explicit_type.rs#L7) Specify type for a let binding. @@ -49,7 +49,7 @@ fn main() { ### `add_hash` -**Source:** [raw_string.rs](/crates/ide-assists/src/handlers/raw_string.rs#89) +**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L89) Adds a hash to a raw string literal. @@ -69,7 +69,7 @@ fn main() { ### `add_impl_default_members` -**Source:** [add_missing_impl_members.rs](/crates/ide-assists/src/handlers/add_missing_impl_members.rs#58) +**Source:** [add_missing_impl_members.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_impl_members.rs#L58) Adds scaffold for overriding default impl members. @@ -105,7 +105,7 @@ impl Trait for () { ### `add_impl_missing_members` -**Source:** [add_missing_impl_members.rs](/crates/ide-assists/src/handlers/add_missing_impl_members.rs#16) +**Source:** [add_missing_impl_members.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_impl_members.rs#L16) Adds scaffold for required impl members. @@ -141,7 +141,7 @@ impl Trait for () { ### `add_label_to_loop` -**Source:** [add_label_to_loop.rs](/crates/ide-assists/src/handlers/add_label_to_loop.rs#9) +**Source:** [add_label_to_loop.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_label_to_loop.rs#L9) Adds a label to a loop. @@ -167,7 +167,7 @@ fn main() { ### `add_lifetime_to_type` -**Source:** [add_lifetime_to_type.rs](/crates/ide-assists/src/handlers/add_lifetime_to_type.rs#5) +**Source:** [add_lifetime_to_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_lifetime_to_type.rs#L5) Adds a new lifetime to a struct, enum or union. @@ -189,7 +189,7 @@ struct Point<'a> { ### `add_missing_match_arms` -**Source:** [add_missing_match_arms.rs](/crates/ide-assists/src/handlers/add_missing_match_arms.rs#14) +**Source:** [add_missing_match_arms.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_missing_match_arms.rs#L16) Adds missing clauses to a `match` expression. @@ -218,7 +218,7 @@ fn handle(action: Action) { ### `add_return_type` -**Source:** [add_return_type.rs](/crates/ide-assists/src/handlers/add_return_type.rs#6) +**Source:** [add_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_return_type.rs#L6) Adds the return type to a function or closure inferred from its tail expression if it doesn't have a return type specified. This assists is useable in a functions or closures tail expression or return type position. @@ -235,7 +235,7 @@ fn foo() -> i32 { 42i32 } ### `add_turbo_fish` -**Source:** [add_turbo_fish.rs](/crates/ide-assists/src/handlers/add_turbo_fish.rs#14) +**Source:** [add_turbo_fish.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/add_turbo_fish.rs#L14) Adds `::<_>` to a call of a generic method or function. @@ -257,7 +257,7 @@ fn main() { ### `apply_demorgan` -**Source:** [apply_demorgan.rs](/crates/ide-assists/src/handlers/apply_demorgan.rs#16) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L16) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws). This transforms expressions of the form `!l || !r` into `!(l && r)`. @@ -280,7 +280,7 @@ fn main() { ### `apply_demorgan_iterator` -**Source:** [apply_demorgan.rs](/crates/ide-assists/src/handlers/apply_demorgan.rs#132) +**Source:** [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L132) Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to `Iterator::all` and `Iterator::any`. @@ -311,7 +311,7 @@ fn main() { ### `auto_import` -**Source:** [auto_import.rs](/crates/ide-assists/src/handlers/auto_import.rs#73) +**Source:** [auto_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/auto_import.rs#L73) If the name is unresolved, provides all possible imports for it. @@ -333,7 +333,7 @@ fn main() { ### `bind_unused_param` -**Source:** [bind_unused_param.rs](/crates/ide-assists/src/handlers/bind_unused_param.rs#12) +**Source:** [bind_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/bind_unused_param.rs#L12) Binds unused function parameter to an underscore. @@ -351,7 +351,7 @@ fn some_function(x: i32) { ### `bool_to_enum` -**Source:** [bool_to_enum.rs](/crates/ide-assists/src/handlers/bool_to_enum.rs#29) +**Source:** [bool_to_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/bool_to_enum.rs#L29) This converts boolean local variables, fields, constants, and statics into a new enum with two variants `Bool::True` and `Bool::False`, as well as replacing @@ -385,7 +385,7 @@ fn main() { ### `change_visibility` -**Source:** [change_visibility.rs](/crates/ide-assists/src/handlers/change_visibility.rs#13) +**Source:** [change_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/change_visibility.rs#L13) Adds or changes existing visibility specifier. @@ -401,7 +401,7 @@ pub(crate) fn frobnicate() {} ### `comment_to_doc` -**Source:** [convert_comment_from_or_to_doc.rs](/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs#9) +**Source:** [convert_comment_from_or_to_doc.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs#L9) Converts comments to documentation. @@ -419,7 +419,7 @@ Converts comments to documentation. ### `convert_bool_then_to_if` -**Source:** [convert_bool_then.rs](/crates/ide-assists/src/handlers/convert_bool_then.rs#131) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L131) Converts a `bool::then` method call to an equivalent if expression. @@ -443,7 +443,7 @@ fn main() { ### `convert_closure_to_fn` -**Source:** [convert_closure_to_fn.rs](/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#25) +**Source:** [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) This converts a closure to a freestanding function, changing all captures to parameters. @@ -469,7 +469,7 @@ fn main() { ### `convert_for_loop_with_for_each` -**Source:** [convert_iter_for_each_to_for.rs](/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#76) +**Source:** [convert_iter_for_each_to_for.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#L76) Converts a for loop into a for_each loop on the Iterator. @@ -495,7 +495,7 @@ fn main() { ### `convert_from_to_tryfrom` -**Source:** [convert_from_to_tryfrom.rs](/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs#10) +**Source:** [convert_from_to_tryfrom.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_from_to_tryfrom.rs#L10) Converts a From impl to a TryFrom impl, wrapping returns in `Ok`. @@ -527,7 +527,7 @@ impl TryFrom for Thing { ### `convert_if_to_bool_then` -**Source:** [convert_bool_then.rs](/crates/ide-assists/src/handlers/convert_bool_then.rs#20) +**Source:** [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L20) Converts an if expression into a corresponding `bool::then` call. @@ -551,7 +551,7 @@ fn main() { ### `convert_integer_literal` -**Source:** [convert_integer_literal.rs](/crates/ide-assists/src/handlers/convert_integer_literal.rs#5) +**Source:** [convert_integer_literal.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_integer_literal.rs#L5) Converts the base of integer literals to other bases. @@ -567,7 +567,7 @@ const _: i32 = 0b1010; ### `convert_into_to_from` -**Source:** [convert_into_to_from.rs](/crates/ide-assists/src/handlers/convert_into_to_from.rs#8) +**Source:** [convert_into_to_from.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_into_to_from.rs#L8) Converts an Into impl to an equivalent From impl. @@ -597,7 +597,7 @@ impl From for Thing { ### `convert_iter_for_each_to_for` -**Source:** [convert_iter_for_each_to_for.rs](/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#11) +**Source:** [convert_iter_for_each_to_for.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs#L11) Converts an Iterator::for_each function into a for loop. @@ -623,7 +623,7 @@ fn main() { ### `convert_let_else_to_match` -**Source:** [convert_let_else_to_match.rs](/crates/ide-assists/src/handlers/convert_let_else_to_match.rs#9) +**Source:** [convert_let_else_to_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_let_else_to_match.rs#L9) Converts let-else statement to let statement and match expression. @@ -646,7 +646,7 @@ fn main() { ### `convert_match_to_let_else` -**Source:** [convert_match_to_let_else.rs](/crates/ide-assists/src/handlers/convert_match_to_let_else.rs#12) +**Source:** [convert_match_to_let_else.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_match_to_let_else.rs#L12) Converts let statement with match initializer to let-else statement. @@ -669,7 +669,7 @@ fn foo(opt: Option<()>) { ### `convert_named_struct_to_tuple_struct` -**Source:** [convert_named_struct_to_tuple_struct.rs](/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs#11) +**Source:** [convert_named_struct_to_tuple_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs#L11) Converts struct with named fields to tuple struct, and analogously for enum variants with named fields. @@ -714,7 +714,7 @@ impl Point { ### `convert_nested_function_to_closure` -**Source:** [convert_nested_function_to_closure.rs](/crates/ide-assists/src/handlers/convert_nested_function_to_closure.rs#7) +**Source:** [convert_nested_function_to_closure.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_nested_function_to_closure.rs#L7) Converts a function that is defined within the body of another function into a closure. @@ -742,7 +742,7 @@ fn main() { ### `convert_to_guarded_return` -**Source:** [convert_to_guarded_return.rs](/crates/ide-assists/src/handlers/convert_to_guarded_return.rs#24) +**Source:** [convert_to_guarded_return.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_to_guarded_return.rs#L24) Replace a large conditional with a guarded return. @@ -769,7 +769,7 @@ fn main() { ### `convert_tuple_return_type_to_struct` -**Source:** [convert_tuple_return_type_to_struct.rs](/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs#20) +**Source:** [convert_tuple_return_type_to_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs#L20) This converts the return type of a function from a tuple type into a tuple struct and updates the body accordingly. @@ -800,7 +800,7 @@ fn foo() -> FooResult { ### `convert_tuple_struct_to_named_struct` -**Source:** [convert_tuple_struct_to_named_struct.rs](/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs#10) +**Source:** [convert_tuple_struct_to_named_struct.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs#L10) Converts tuple struct to struct with named fields, and analogously for tuple enum variants. @@ -844,7 +844,7 @@ impl Point { ### `convert_two_arm_bool_match_to_matches_macro` -**Source:** [convert_two_arm_bool_match_to_matches_macro.rs](/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs#8) +**Source:** [convert_two_arm_bool_match_to_matches_macro.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_two_arm_bool_match_to_matches_macro.rs#L8) Convert 2-arm match that evaluates to a boolean into the equivalent matches! invocation. @@ -867,7 +867,7 @@ fn main() { ### `convert_while_to_loop` -**Source:** [convert_while_to_loop.rs](/crates/ide-assists/src/handlers/convert_while_to_loop.rs#20) +**Source:** [convert_while_to_loop.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_while_to_loop.rs#L20) Replace a while with a loop. @@ -894,7 +894,7 @@ fn main() { ### `destructure_struct_binding` -**Source:** [destructure_struct_binding.rs](/crates/ide-assists/src/handlers/destructure_struct_binding.rs#18) +**Source:** [destructure_struct_binding.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/destructure_struct_binding.rs#L18) Destructures a struct binding in place. @@ -926,7 +926,7 @@ fn main() { ### `destructure_tuple_binding` -**Source:** [destructure_tuple_binding.rs](/crates/ide-assists/src/handlers/destructure_tuple_binding.rs#19) +**Source:** [destructure_tuple_binding.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/destructure_tuple_binding.rs#L19) Destructures a tuple binding in place. @@ -948,7 +948,7 @@ fn main() { ### `desugar_async_into_impl_future` -**Source:** [toggle_async_sugar.rs](/crates/ide-assists/src/handlers/toggle_async_sugar.rs#103) +**Source:** [toggle_async_sugar.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_async_sugar.rs#L103) Rewrites asynchronous function from `async fn` into `-> impl Future`. This action does not touch the function body and therefore `0` @@ -970,7 +970,7 @@ pub fn foo() -> impl core::future::Future { ### `desugar_doc_comment` -**Source:** [desugar_doc_comment.rs](/crates/ide-assists/src/handlers/desugar_doc_comment.rs#14) +**Source:** [desugar_doc_comment.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/desugar_doc_comment.rs#L14) Desugars doc-comments to the attribute form. @@ -988,7 +988,7 @@ comment"] ### `expand_glob_import` -**Source:** [expand_glob_import.rs](/crates/ide-assists/src/handlers/expand_glob_import.rs#18) +**Source:** [expand_glob_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_glob_import.rs#L19) Expands glob imports. @@ -1017,8 +1017,34 @@ fn qux(bar: Bar, baz: Baz) {} ``` +### `expand_glob_reexport` +**Source:** [expand_glob_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/expand_glob_import.rs#L81) + +Expands non-private glob imports. + +#### Before +```rust +mod foo { + pub struct Bar; + pub struct Baz; +} + +pub use foo::*┃; +``` + +#### After +```rust +mod foo { + pub struct Bar; + pub struct Baz; +} + +pub use foo::{Bar, Baz}; +``` + + ### `explicit_enum_discriminant` -**Source:** [explicit_enum_discriminant.rs](/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs#11) +**Source:** [explicit_enum_discriminant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs#L11) Adds explicit discriminant to all enum variants. @@ -1044,7 +1070,7 @@ enum TheEnum { ### `extract_constant` -**Source:** [extract_variable.rs](/crates/ide-assists/src/handlers/extract_variable.rs#35) +**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L35) Extracts subexpression into a constant. @@ -1065,7 +1091,7 @@ fn main() { ### `extract_expressions_from_format_string` -**Source:** [extract_expressions_from_format_string.rs](/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs#14) +**Source:** [extract_expressions_from_format_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_expressions_from_format_string.rs#L14) Move an expression out of a format string. @@ -1085,7 +1111,7 @@ fn main() { ### `extract_function` -**Source:** [extract_function.rs](/crates/ide-assists/src/handlers/extract_function.rs#39) +**Source:** [extract_function.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_function.rs#L39) Extracts selected statements and comments into new function. @@ -1117,7 +1143,7 @@ fn ┃fun_name(n: i32) { ### `extract_module` -**Source:** [extract_module.rs](/crates/ide-assists/src/handlers/extract_module.rs#29) +**Source:** [extract_module.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_module.rs#L29) Extracts a selected region as separate module. All the references, visibility and imports are resolved. @@ -1148,7 +1174,7 @@ fn bar(name: i32) -> i32 { ### `extract_static` -**Source:** [extract_variable.rs](/crates/ide-assists/src/handlers/extract_variable.rs#52) +**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L52) Extracts subexpression into a static. @@ -1169,7 +1195,7 @@ fn main() { ### `extract_struct_from_enum_variant` -**Source:** [extract_struct_from_enum_variant.rs](/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs#26) +**Source:** [extract_struct_from_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs#L26) Extracts a struct from enum variant. @@ -1187,7 +1213,7 @@ enum A { One(One) } ### `extract_type_alias` -**Source:** [extract_type_alias.rs](/crates/ide-assists/src/handlers/extract_type_alias.rs#10) +**Source:** [extract_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_type_alias.rs#L10) Extracts the selected type as a type alias. @@ -1209,7 +1235,7 @@ struct S { ### `extract_variable` -**Source:** [extract_variable.rs](/crates/ide-assists/src/handlers/extract_variable.rs#18) +**Source:** [extract_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/extract_variable.rs#L18) Extracts subexpression into a variable. @@ -1230,7 +1256,7 @@ fn main() { ### `fill_record_pattern_fields` -**Source:** [fill_record_pattern_fields.rs](/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs#8) +**Source:** [fill_record_pattern_fields.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/fill_record_pattern_fields.rs#L8) Fills fields by replacing rest pattern in record patterns. @@ -1254,7 +1280,7 @@ fn foo(bar: Bar) { ### `fix_visibility` -**Source:** [fix_visibility.rs](/crates/ide-assists/src/handlers/fix_visibility.rs#14) +**Source:** [fix_visibility.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/fix_visibility.rs#L14) Makes inaccessible item public. @@ -1280,7 +1306,7 @@ fn main() { ### `flip_binexpr` -**Source:** [flip_binexpr.rs](/crates/ide-assists/src/handlers/flip_binexpr.rs#8) +**Source:** [flip_binexpr.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_binexpr.rs#L8) Flips operands of a binary expression. @@ -1300,7 +1326,7 @@ fn main() { ### `flip_comma` -**Source:** [flip_comma.rs](/crates/ide-assists/src/handlers/flip_comma.rs#10) +**Source:** [flip_comma.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_comma.rs#L10) Flips two comma-separated items. @@ -1320,7 +1346,7 @@ fn main() { ### `flip_trait_bound` -**Source:** [flip_trait_bound.rs](/crates/ide-assists/src/handlers/flip_trait_bound.rs#9) +**Source:** [flip_trait_bound.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_trait_bound.rs#L9) Flips two trait bounds. @@ -1336,7 +1362,7 @@ fn foo() { } ### `generate_constant` -**Source:** [generate_constant.rs](/crates/ide-assists/src/handlers/generate_constant.rs#14) +**Source:** [generate_constant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_constant.rs#L14) Generate a named constant. @@ -1361,7 +1387,7 @@ fn main() { ### `generate_default_from_enum_variant` -**Source:** [generate_default_from_enum_variant.rs](/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs#6) +**Source:** [generate_default_from_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_default_from_enum_variant.rs#L6) Adds a Default impl for an enum using a variant. @@ -1391,7 +1417,7 @@ impl Default for Version { ### `generate_default_from_new` -**Source:** [generate_default_from_new.rs](/crates/ide-assists/src/handlers/generate_default_from_new.rs#13) +**Source:** [generate_default_from_new.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_default_from_new.rs#L13) Generates default implementation from new method. @@ -1425,7 +1451,7 @@ impl Default for Example { ### `generate_delegate_methods` -**Source:** [generate_delegate_methods.rs](/crates/ide-assists/src/handlers/generate_delegate_methods.rs#15) +**Source:** [generate_delegate_methods.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_delegate_methods.rs#L15) Generate delegate methods. @@ -1465,7 +1491,7 @@ impl Person { ### `generate_delegate_trait` -**Source:** [generate_delegate_trait.rs](/crates/ide-assists/src/handlers/generate_delegate_trait.rs#29) +**Source:** [generate_delegate_trait.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_delegate_trait.rs#L29) Generate delegate trait implementation for `StructField`s. @@ -1531,7 +1557,7 @@ impl SomeTrait for B { ### `generate_deref` -**Source:** [generate_deref.rs](/crates/ide-assists/src/handlers/generate_deref.rs#16) +**Source:** [generate_deref.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_deref.rs#L16) Generate `Deref` impl using the given struct field. @@ -1561,7 +1587,7 @@ impl core::ops::Deref for B { ### `generate_derive` -**Source:** [generate_derive.rs](/crates/ide-assists/src/handlers/generate_derive.rs#8) +**Source:** [generate_derive.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_derive.rs#L8) Adds a new `#[derive()]` clause to a struct or enum. @@ -1584,7 +1610,7 @@ struct Point { ### `generate_doc_example` -**Source:** [generate_documentation_template.rs](/crates/ide-assists/src/handlers/generate_documentation_template.rs#76) +**Source:** [generate_documentation_template.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_documentation_template.rs#L76) Generates a rustdoc example when editing an item's documentation. @@ -1610,7 +1636,7 @@ pub fn add(a: i32, b: i32) -> i32 { a + b } ### `generate_documentation_template` -**Source:** [generate_documentation_template.rs](/crates/ide-assists/src/handlers/generate_documentation_template.rs#13) +**Source:** [generate_documentation_template.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_documentation_template.rs#L13) Adds a documentation template above a function definition / declaration. @@ -1645,7 +1671,7 @@ impl S { ### `generate_enum_as_method` -**Source:** [generate_enum_projection_method.rs](/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#59) +**Source:** [generate_enum_projection_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#L59) Generate an `as_` method for this enum variant. @@ -1677,7 +1703,7 @@ impl Value { ### `generate_enum_is_method` -**Source:** [generate_enum_is_method.rs](/crates/ide-assists/src/handlers/generate_enum_is_method.rs#11) +**Source:** [generate_enum_is_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_is_method.rs#L11) Generate an `is_` method for this enum variant. @@ -1711,7 +1737,7 @@ impl Version { ### `generate_enum_try_into_method` -**Source:** [generate_enum_projection_method.rs](/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#12) +**Source:** [generate_enum_projection_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_projection_method.rs#L12) Generate a `try_into_` method for this enum variant. @@ -1743,7 +1769,7 @@ impl Value { ### `generate_enum_variant` -**Source:** [generate_enum_variant.rs](/crates/ide-assists/src/handlers/generate_enum_variant.rs#10) +**Source:** [generate_enum_variant.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_enum_variant.rs#L10) Adds a variant to an enum. @@ -1772,7 +1798,7 @@ fn main() { ### `generate_fn_type_alias_named` -**Source:** [generate_fn_type_alias.rs](/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#10) +**Source:** [generate_fn_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#L10) Generate a type alias for the function with named parameters. @@ -1790,7 +1816,7 @@ unsafe fn foo(n: i32) -> i32 { 42i32 } ### `generate_fn_type_alias_unnamed` -**Source:** [generate_fn_type_alias.rs](/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#24) +**Source:** [generate_fn_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_fn_type_alias.rs#L24) Generate a type alias for the function with unnamed parameters. @@ -1808,7 +1834,7 @@ unsafe fn foo(n: i32) -> i32 { 42i32 } ### `generate_from_impl_for_enum` -**Source:** [generate_from_impl_for_enum.rs](/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs#8) +**Source:** [generate_from_impl_for_enum.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs#L8) Adds a From impl for this enum variant with one tuple field. @@ -1830,7 +1856,7 @@ impl From for A { ### `generate_function` -**Source:** [generate_function.rs](/crates/ide-assists/src/handlers/generate_function.rs#28) +**Source:** [generate_function.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_function.rs#L28) Adds a stub function with a signature matching the function under the cursor. @@ -1860,7 +1886,7 @@ fn bar(arg: &str, baz: Baz) ${0:-> _} { ### `generate_getter` -**Source:** [generate_getter_or_setter.rs](/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#73) +**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L73) Generate a getter method. @@ -1886,7 +1912,7 @@ impl Person { ### `generate_getter_mut` -**Source:** [generate_getter_or_setter.rs](/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#127) +**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L127) Generate a mut getter method. @@ -1912,7 +1938,7 @@ impl Person { ### `generate_impl` -**Source:** [generate_impl.rs](/crates/ide-assists/src/handlers/generate_impl.rs#20) +**Source:** [generate_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_impl.rs#L20) Adds a new inherent impl for a type. @@ -1934,7 +1960,7 @@ impl Ctx {┃} ### `generate_is_empty_from_len` -**Source:** [generate_is_empty_from_len.rs](/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs#12) +**Source:** [generate_is_empty_from_len.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_is_empty_from_len.rs#L12) Generates is_empty implementation from the len method. @@ -1969,7 +1995,7 @@ impl MyStruct { ### `generate_mut_trait_impl` -**Source:** [generate_mut_trait_impl.rs](/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs#12) +**Source:** [generate_mut_trait_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_mut_trait_impl.rs#L12) Adds a IndexMut impl from the `Index` trait. @@ -2007,7 +2033,7 @@ impl core::ops::Index for [T; 3] { ### `generate_new` -**Source:** [generate_new.rs](/crates/ide-assists/src/handlers/generate_new.rs#14) +**Source:** [generate_new.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_new.rs#L14) Adds a `fn new` for a type. @@ -2033,7 +2059,7 @@ impl Ctx { ### `generate_setter` -**Source:** [generate_getter_or_setter.rs](/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#13) +**Source:** [generate_getter_or_setter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_getter_or_setter.rs#L13) Generate a setter method. @@ -2059,7 +2085,7 @@ impl Person { ### `generate_trait_from_impl` -**Source:** [generate_trait_from_impl.rs](/crates/ide-assists/src/handlers/generate_trait_from_impl.rs#18) +**Source:** [generate_trait_from_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_trait_from_impl.rs#L18) Generate trait for an already defined inherent impl and convert impl to a trait impl. @@ -2118,7 +2144,7 @@ impl ${0:NewTrait} for Foo { ### `generate_trait_impl` -**Source:** [generate_impl.rs](/crates/ide-assists/src/handlers/generate_impl.rs#66) +**Source:** [generate_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/generate_impl.rs#L66) Adds a new trait impl for a type. @@ -2140,7 +2166,7 @@ impl ${0:_} for Ctx {} ### `inline_call` -**Source:** [inline_call.rs](/crates/ide-assists/src/handlers/inline_call.rs#170) +**Source:** [inline_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_call.rs#L170) Inlines a function or method body creating a `let` statement per parameter unless the parameter can be inlined. The parameter will be inlined either if it the supplied argument is a simple local @@ -2165,7 +2191,7 @@ fn foo(name: Option<&str>) { ### `inline_const_as_literal` -**Source:** [inline_const_as_literal.rs](/crates/ide-assists/src/handlers/inline_const_as_literal.rs#6) +**Source:** [inline_const_as_literal.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_const_as_literal.rs#L6) Evaluate and inline const variable as literal. @@ -2189,7 +2215,7 @@ fn something() -> &'static str { ### `inline_into_callers` -**Source:** [inline_call.rs](/crates/ide-assists/src/handlers/inline_call.rs#32) +**Source:** [inline_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_call.rs#L32) Inline a function or method body into all of its callers where possible, creating a `let` statement per parameter unless the parameter can be inlined. The parameter will be inlined either if it the supplied argument is a simple local @@ -2232,7 +2258,7 @@ fn bar() { ### `inline_local_variable` -**Source:** [inline_local_variable.rs](/crates/ide-assists/src/handlers/inline_local_variable.rs#17) +**Source:** [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) Inlines a local variable. @@ -2253,7 +2279,7 @@ fn main() { ### `inline_macro` -**Source:** [inline_macro.rs](/crates/ide-assists/src/handlers/inline_macro.rs#7) +**Source:** [inline_macro.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_macro.rs#L7) Takes a macro and inlines it one step. @@ -2289,7 +2315,7 @@ fn main() { ### `inline_type_alias` -**Source:** [inline_type_alias.rs](/crates/ide-assists/src/handlers/inline_type_alias.rs#106) +**Source:** [inline_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_type_alias.rs#L106) Replace a type alias with its concrete type. @@ -2313,7 +2339,7 @@ fn main() { ### `inline_type_alias_uses` -**Source:** [inline_type_alias.rs](/crates/ide-assists/src/handlers/inline_type_alias.rs#24) +**Source:** [inline_type_alias.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_type_alias.rs#L24) Inline a type alias into all of its uses where possible. @@ -2341,7 +2367,7 @@ fn foo() { ### `into_to_qualified_from` -**Source:** [into_to_qualified_from.rs](/crates/ide-assists/src/handlers/into_to_qualified_from.rs#10) +**Source:** [into_to_qualified_from.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/into_to_qualified_from.rs#L10) Convert an `into` method call to a fully qualified `from` call. @@ -2378,7 +2404,7 @@ fn main() -> () { ### `introduce_named_generic` -**Source:** [introduce_named_generic.rs](/crates/ide-assists/src/handlers/introduce_named_generic.rs#7) +**Source:** [introduce_named_generic.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_generic.rs#L7) Replaces `impl Trait` function argument with the named generic. @@ -2394,7 +2420,7 @@ fn foo<┃B: Bar>(bar: B) {} ### `introduce_named_lifetime` -**Source:** [introduce_named_lifetime.rs](/crates/ide-assists/src/handlers/introduce_named_lifetime.rs#13) +**Source:** [introduce_named_lifetime.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/introduce_named_lifetime.rs#L13) Change an anonymous lifetime to a named lifetime. @@ -2422,7 +2448,7 @@ impl<'a> Cursor<'a> { ### `invert_if` -**Source:** [invert_if.rs](/crates/ide-assists/src/handlers/invert_if.rs#13) +**Source:** [invert_if.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/invert_if.rs#L13) This transforms if expressions of the form `if !x {A} else {B}` into `if x {B} else {A}` This also works with `!=`. This assist can only be applied with the cursor on `if`. @@ -2443,7 +2469,7 @@ fn main() { ### `line_to_block` -**Source:** [convert_comment_block.rs](/crates/ide-assists/src/handlers/convert_comment_block.rs#9) +**Source:** [convert_comment_block.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_comment_block.rs#L9) Converts comments between block and single-line form. @@ -2463,7 +2489,7 @@ Converts comments between block and single-line form. ### `make_raw_string` -**Source:** [raw_string.rs](/crates/ide-assists/src/handlers/raw_string.rs#7) +**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L7) Adds `r#` to a plain string literal. @@ -2483,7 +2509,7 @@ fn main() { ### `make_usual_string` -**Source:** [raw_string.rs](/crates/ide-assists/src/handlers/raw_string.rs#47) +**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L47) Turns a raw string into a plain string. @@ -2503,7 +2529,7 @@ fn main() { ### `merge_imports` -**Source:** [merge_imports.rs](/crates/ide-assists/src/handlers/merge_imports.rs#21) +**Source:** [merge_imports.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_imports.rs#L21) Merges neighbor imports with a common prefix. @@ -2520,7 +2546,7 @@ use std::{fmt::Formatter, io}; ### `merge_match_arms` -**Source:** [merge_match_arms.rs](/crates/ide-assists/src/handlers/merge_match_arms.rs#12) +**Source:** [merge_match_arms.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_match_arms.rs#L12) Merges the current match arm with the following if their bodies are identical. @@ -2549,7 +2575,7 @@ fn handle(action: Action) { ### `merge_nested_if` -**Source:** [merge_nested_if.rs](/crates/ide-assists/src/handlers/merge_nested_if.rs#11) +**Source:** [merge_nested_if.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/merge_nested_if.rs#L11) This transforms if expressions of the form `if x { if y {A} }` into `if x && y {A}` This assist can only be applied with the cursor on `if`. @@ -2570,7 +2596,7 @@ fn main() { ### `move_arm_cond_to_match_guard` -**Source:** [move_guard.rs](/crates/ide-assists/src/handlers/move_guard.rs#69) +**Source:** [move_guard.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_guard.rs#L69) Moves if expression from match arm body into a guard. @@ -2600,7 +2626,7 @@ fn handle(action: Action) { ### `move_bounds_to_where_clause` -**Source:** [move_bounds.rs](/crates/ide-assists/src/handlers/move_bounds.rs#12) +**Source:** [move_bounds.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_bounds.rs#L12) Moves inline type bounds to a where clause. @@ -2620,7 +2646,7 @@ fn apply(f: F, x: T) -> U where F: FnOnce(T) -> U { ### `move_const_to_impl` -**Source:** [move_const_to_impl.rs](/crates/ide-assists/src/handlers/move_const_to_impl.rs#14) +**Source:** [move_const_to_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_const_to_impl.rs#L14) Move a local constant item in a method to impl's associated constant. All the references will be qualified with `Self::`. @@ -2653,7 +2679,7 @@ impl S { ### `move_from_mod_rs` -**Source:** [move_from_mod_rs.rs](/crates/ide-assists/src/handlers/move_from_mod_rs.rs#12) +**Source:** [move_from_mod_rs.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_from_mod_rs.rs#L12) Moves xxx/mod.rs to xxx.rs. @@ -2672,7 +2698,7 @@ fn t() {} ### `move_guard_to_arm_body` -**Source:** [move_guard.rs](/crates/ide-assists/src/handlers/move_guard.rs#8) +**Source:** [move_guard.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_guard.rs#L8) Moves match guard into match arm body. @@ -2704,7 +2730,7 @@ fn handle(action: Action) { ### `move_module_to_file` -**Source:** [move_module_to_file.rs](/crates/ide-assists/src/handlers/move_module_to_file.rs#15) +**Source:** [move_module_to_file.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_module_to_file.rs#L15) Moves inline module's contents to a separate file. @@ -2722,7 +2748,7 @@ mod foo; ### `move_to_mod_rs` -**Source:** [move_to_mod_rs.rs](/crates/ide-assists/src/handlers/move_to_mod_rs.rs#12) +**Source:** [move_to_mod_rs.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/move_to_mod_rs.rs#L12) Moves xxx.rs to xxx/mod.rs. @@ -2741,7 +2767,7 @@ fn t() {} ### `normalize_import` -**Source:** [normalize_import.rs](/crates/ide-assists/src/handlers/normalize_import.rs#9) +**Source:** [normalize_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/normalize_import.rs#L9) Normalizes an import. @@ -2757,7 +2783,7 @@ use std::{fmt::Formatter, io}; ### `promote_local_to_const` -**Source:** [promote_local_to_const.rs](/crates/ide-assists/src/handlers/promote_local_to_const.rs#17) +**Source:** [promote_local_to_const.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/promote_local_to_const.rs#L17) Promotes a local variable to a const item changing its name to a `SCREAMING_SNAKE_CASE` variant if the local uses no non-const expressions. @@ -2790,7 +2816,7 @@ fn main() { ### `pull_assignment_up` -**Source:** [pull_assignment_up.rs](/crates/ide-assists/src/handlers/pull_assignment_up.rs#11) +**Source:** [pull_assignment_up.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/pull_assignment_up.rs#L11) Extracts variable assignment to outside an if or match statement. @@ -2822,7 +2848,7 @@ fn main() { ### `qualify_method_call` -**Source:** [qualify_method_call.rs](/crates/ide-assists/src/handlers/qualify_method_call.rs#10) +**Source:** [qualify_method_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/qualify_method_call.rs#L10) Replaces the method call with a qualified function call. @@ -2852,7 +2878,7 @@ fn main() { ### `qualify_path` -**Source:** [qualify_path.rs](/crates/ide-assists/src/handlers/qualify_path.rs#24) +**Source:** [qualify_path.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/qualify_path.rs#L24) If the name is unresolved, provides all possible qualified paths for it. @@ -2872,7 +2898,7 @@ fn main() { ### `reformat_number_literal` -**Source:** [number_representation.rs](/crates/ide-assists/src/handlers/number_representation.rs#7) +**Source:** [number_representation.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/number_representation.rs#L7) Adds or removes separators from integer literal. @@ -2888,7 +2914,7 @@ const _: i32 = 1_012_345; ### `remove_dbg` -**Source:** [remove_dbg.rs](/crates/ide-assists/src/handlers/remove_dbg.rs#9) +**Source:** [remove_dbg.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_dbg.rs#L9) Removes `dbg!()` macro call. @@ -2908,7 +2934,7 @@ fn main() { ### `remove_hash` -**Source:** [raw_string.rs](/crates/ide-assists/src/handlers/raw_string.rs#117) +**Source:** [raw_string.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/raw_string.rs#L117) Removes a hash from a raw string literal. @@ -2928,7 +2954,7 @@ fn main() { ### `remove_mut` -**Source:** [remove_mut.rs](/crates/ide-assists/src/handlers/remove_mut.rs#5) +**Source:** [remove_mut.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_mut.rs#L5) Removes the `mut` keyword. @@ -2948,7 +2974,7 @@ impl Walrus { ### `remove_parentheses` -**Source:** [remove_parentheses.rs](/crates/ide-assists/src/handlers/remove_parentheses.rs#5) +**Source:** [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L5) Removes redundant parentheses. @@ -2968,7 +2994,7 @@ fn main() { ### `remove_unused_imports` -**Source:** [remove_unused_imports.rs](/crates/ide-assists/src/handlers/remove_unused_imports.rs#17) +**Source:** [remove_unused_imports.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_imports.rs#L17) Removes any use statements in the current selection that are unused. @@ -2989,7 +3015,7 @@ mod foo { ### `remove_unused_param` -**Source:** [remove_unused_param.rs](/crates/ide-assists/src/handlers/remove_unused_param.rs#15) +**Source:** [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L15) Removes unused function parameter. @@ -3013,7 +3039,7 @@ fn main() { ### `reorder_fields` -**Source:** [reorder_fields.rs](/crates/ide-assists/src/handlers/reorder_fields.rs#8) +**Source:** [reorder_fields.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/reorder_fields.rs#L8) Reorder the fields of record literals and record patterns in the same order as in the definition. @@ -3032,7 +3058,7 @@ const test: Foo = Foo {foo: 1, bar: 0} ### `reorder_impl_items` -**Source:** [reorder_impl_items.rs](/crates/ide-assists/src/handlers/reorder_impl_items.rs#11) +**Source:** [reorder_impl_items.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/reorder_impl_items.rs#L11) Reorder the items of an `impl Trait`. The items will be ordered in the same order as in the trait definition. @@ -3071,7 +3097,7 @@ impl Foo for Bar { ### `replace_arith_with_checked` -**Source:** [replace_arith_op.rs](/crates/ide-assists/src/handlers/replace_arith_op.rs#9) +**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L9) Replaces arithmetic on integers with the `checked_*` equivalent. @@ -3091,7 +3117,7 @@ fn main() { ### `replace_arith_with_saturating` -**Source:** [replace_arith_op.rs](/crates/ide-assists/src/handlers/replace_arith_op.rs#28) +**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L28) Replaces arithmetic on integers with the `saturating_*` equivalent. @@ -3111,7 +3137,7 @@ fn main() { ### `replace_arith_with_wrapping` -**Source:** [replace_arith_op.rs](/crates/ide-assists/src/handlers/replace_arith_op.rs#50) +**Source:** [replace_arith_op.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_arith_op.rs#L50) Replaces arithmetic on integers with the `wrapping_*` equivalent. @@ -3131,7 +3157,7 @@ fn main() { ### `replace_char_with_string` -**Source:** [replace_string_with_char.rs](/crates/ide-assists/src/handlers/replace_string_with_char.rs#51) +**Source:** [replace_string_with_char.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_string_with_char.rs#L51) Replace a char literal with a string literal. @@ -3151,7 +3177,7 @@ fn main() { ### `replace_derive_with_manual_impl` -**Source:** [replace_derive_with_manual_impl.rs](/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs#20) +**Source:** [replace_derive_with_manual_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs#L20) Converts a `derive` impl into a manual one. @@ -3175,7 +3201,7 @@ impl Debug for S { ### `replace_if_let_with_match` -**Source:** [replace_if_let_with_match.rs](/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#20) +**Source:** [replace_if_let_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#L20) Replaces a `if let` expression with a `match` expression. @@ -3206,7 +3232,7 @@ fn handle(action: Action) { ### `replace_is_some_with_if_let_some` -**Source:** [replace_is_method_with_if_let_method.rs](/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs#9) +**Source:** [replace_is_method_with_if_let_method.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs#L9) Replace `if x.is_some()` with `if let Some(_tmp) = x` or `if x.is_ok()` with `if let Ok(_tmp) = x`. @@ -3228,7 +3254,7 @@ fn main() { ### `replace_let_with_if_let` -**Source:** [replace_let_with_if_let.rs](/crates/ide-assists/src/handlers/replace_let_with_if_let.rs#9) +**Source:** [replace_let_with_if_let.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_let_with_if_let.rs#L9) Replaces `let` with an `if let`. @@ -3255,7 +3281,7 @@ fn compute() -> Option { None } ### `replace_match_with_if_let` -**Source:** [replace_if_let_with_match.rs](/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#188) +**Source:** [replace_if_let_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_if_let_with_match.rs#L188) Replaces a binary `match` with a wildcard pattern and no guards with an `if let` expression. @@ -3286,7 +3312,7 @@ fn handle(action: Action) { ### `replace_named_generic_with_impl` -**Source:** [replace_named_generic_with_impl.rs](/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs#18) +**Source:** [replace_named_generic_with_impl.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_named_generic_with_impl.rs#L18) Replaces named generic with an `impl Trait` in function argument. @@ -3302,7 +3328,7 @@ fn new(location: impl AsRef) -> Self {} ### `replace_qualified_name_with_use` -**Source:** [replace_qualified_name_with_use.rs](/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs#13) +**Source:** [replace_qualified_name_with_use.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs#L13) Adds a use statement for a given fully-qualified name. @@ -3320,7 +3346,7 @@ fn process(map: HashMap) {} ### `replace_string_with_char` -**Source:** [replace_string_with_char.rs](/crates/ide-assists/src/handlers/replace_string_with_char.rs#11) +**Source:** [replace_string_with_char.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_string_with_char.rs#L11) Replace string literal with char literal. @@ -3340,7 +3366,7 @@ fn main() { ### `replace_try_expr_with_match` -**Source:** [replace_try_expr_with_match.rs](/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs#18) +**Source:** [replace_try_expr_with_match.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_try_expr_with_match.rs#L18) Replaces a `try` expression with a `match` expression. @@ -3363,7 +3389,7 @@ fn handle() { ### `replace_turbofish_with_explicit_type` -**Source:** [replace_turbofish_with_explicit_type.rs](/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs#12) +**Source:** [replace_turbofish_with_explicit_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_turbofish_with_explicit_type.rs#L12) Converts `::<_>` to an explicit type assignment. @@ -3385,7 +3411,7 @@ fn main() { ### `replace_with_eager_method` -**Source:** [replace_method_eager_lazy.rs](/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#89) +**Source:** [replace_method_eager_lazy.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#L89) Replace `unwrap_or_else` with `unwrap_or` and `ok_or_else` with `ok_or`. @@ -3407,7 +3433,7 @@ fn foo() { ### `replace_with_lazy_method` -**Source:** [replace_method_eager_lazy.rs](/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#9) +**Source:** [replace_method_eager_lazy.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs#L9) Replace `unwrap_or` with `unwrap_or_else` and `ok_or` with `ok_or_else`. @@ -3429,7 +3455,7 @@ fn foo() { ### `sort_items` -**Source:** [sort_items.rs](/crates/ide-assists/src/handlers/sort_items.rs#12) +**Source:** [sort_items.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/sort_items.rs#L12) Sorts item members alphabetically: fields, enum variants and methods. @@ -3520,7 +3546,7 @@ enum Animal { ### `split_import` -**Source:** [split_import.rs](/crates/ide-assists/src/handlers/split_import.rs#5) +**Source:** [split_import.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/split_import.rs#L5) Wraps the tail of import into braces. @@ -3536,7 +3562,7 @@ use std::{collections::HashMap}; ### `sugar_impl_future_into_async` -**Source:** [toggle_async_sugar.rs](/crates/ide-assists/src/handlers/toggle_async_sugar.rs#13) +**Source:** [toggle_async_sugar.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_async_sugar.rs#L13) Rewrites asynchronous function from `-> impl Future` into `async fn`. This action does not touch the function body and therefore `async { 0 }` @@ -3558,7 +3584,7 @@ pub async fn foo() -> usize { ### `toggle_ignore` -**Source:** [toggle_ignore.rs](/crates/ide-assists/src/handlers/toggle_ignore.rs#8) +**Source:** [toggle_ignore.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_ignore.rs#L8) Adds `#[ignore]` attribute to the test. @@ -3581,7 +3607,7 @@ fn arithmetics { ### `toggle_macro_delimiter` -**Source:** [toggle_macro_delimiter.rs](/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs#9) +**Source:** [toggle_macro_delimiter.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs#L9) Change macro delimiters in the order of `( -> { -> [ -> (`. @@ -3605,7 +3631,7 @@ sth!{ } ### `unmerge_match_arm` -**Source:** [unmerge_match_arm.rs](/crates/ide-assists/src/handlers/unmerge_match_arm.rs#10) +**Source:** [unmerge_match_arm.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unmerge_match_arm.rs#L10) Splits the current match with a `|` pattern into two arms with identical bodies. @@ -3634,7 +3660,7 @@ fn handle(action: Action) { ### `unmerge_use` -**Source:** [unmerge_use.rs](/crates/ide-assists/src/handlers/unmerge_use.rs#12) +**Source:** [unmerge_use.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unmerge_use.rs#L12) Extracts single use item from use list. @@ -3651,7 +3677,7 @@ use std::fmt::Display; ### `unnecessary_async` -**Source:** [unnecessary_async.rs](/crates/ide-assists/src/handlers/unnecessary_async.rs#17) +**Source:** [unnecessary_async.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unnecessary_async.rs#L17) Removes the `async` mark from functions which have no `.await` in their body. Looks for calls to the functions and removes the `.await` on the call site. @@ -3670,7 +3696,7 @@ pub async fn bar() { foo() } ### `unqualify_method_call` -**Source:** [unqualify_method_call.rs](/crates/ide-assists/src/handlers/unqualify_method_call.rs#9) +**Source:** [unqualify_method_call.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unqualify_method_call.rs#L9) Transforms universal function call syntax into a method call. @@ -3692,7 +3718,7 @@ fn main() { ### `unwrap_block` -**Source:** [unwrap_block.rs](/crates/ide-assists/src/handlers/unwrap_block.rs#12) +**Source:** [unwrap_block.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_block.rs#L12) This assist removes if...else, for, while and loop control statements to just keep the body. @@ -3714,7 +3740,7 @@ fn foo() { ### `unwrap_option_return_type` -**Source:** [unwrap_return_type.rs](/crates/ide-assists/src/handlers/unwrap_return_type.rs#13) +**Source:** [unwrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_return_type.rs#L13) Unwrap the function's return type. @@ -3730,7 +3756,7 @@ fn foo() -> i32 { 42i32 } ### `unwrap_result_return_type` -**Source:** [unwrap_return_type.rs](/crates/ide-assists/src/handlers/unwrap_return_type.rs#26) +**Source:** [unwrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_return_type.rs#L26) Unwrap the function's return type. @@ -3746,7 +3772,7 @@ fn foo() -> i32 { 42i32 } ### `unwrap_tuple` -**Source:** [unwrap_tuple.rs](/crates/ide-assists/src/handlers/unwrap_tuple.rs#8) +**Source:** [unwrap_tuple.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/unwrap_tuple.rs#L8) Unwrap the tuple to different variables. @@ -3767,7 +3793,7 @@ fn main() { ### `wrap_return_type_in_option` -**Source:** [wrap_return_type.rs](/crates/ide-assists/src/handlers/wrap_return_type.rs#16) +**Source:** [wrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_return_type.rs#L16) Wrap the function's return type into Option. @@ -3783,7 +3809,7 @@ fn foo() -> Option { Some(42i32) } ### `wrap_return_type_in_result` -**Source:** [wrap_return_type.rs](/crates/ide-assists/src/handlers/wrap_return_type.rs#29) +**Source:** [wrap_return_type.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_return_type.rs#L29) Wrap the function's return type into Result. @@ -3799,7 +3825,7 @@ fn foo() -> Result { Ok(42i32) } ### `wrap_unwrap_cfg_attr` -**Source:** [wrap_unwrap_cfg_attr.rs](/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs#12) +**Source:** [wrap_unwrap_cfg_attr.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs#L12) Wraps an attribute to a cfg_attr attribute or unwraps a cfg_attr attribute to the inner attributes. diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 4006d06e4fe3e..6cd39fabeeeef 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -273465e1f2932a30a5b56ac95859cdc86f3f33fa +e0be1a02626abef2878cb7f4aaef7ae409477112 diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index b31bf61a6fbad..ddcf315a2672d 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -446,6 +446,13 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "error_index_generator" +version = "0.0.0" +dependencies = [ + "mdbook", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -867,9 +874,9 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9da1e54401fe5d45a664c57e112e70f18e8c5a73e268c179305b932ee864574" +checksum = "b07d36d96ffe1b5b16ddf2bc80b3b26bb7a498b2a6591061250bf0af8e8095ad" dependencies = [ "ammonia", "anyhow", diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index 9f9846cdee07d..6aec0bec0fa09 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +members = ["../error_index_generator"] [package] name = "rustbook" @@ -14,6 +15,6 @@ mdbook-i18n-helpers = "0.3.3" mdbook-spec = { path = "../../doc/reference/mdbook-spec" } [dependencies.mdbook] -version = "0.4.44" +version = "0.4.45" default-features = false features = ["search"] diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index e8e7dfe0d84c1..51e58b4e4fcfd 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -99,7 +99,6 @@ const EXCEPTIONS: ExceptionList = &[ ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) ("foldhash", "Zlib"), // rustc - ("mdbook", "MPL-2.0"), // mdbook ("option-ext", "MPL-2.0"), // cargo-miri (via `directories`) ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), // rustc (license is the same as LLVM uses) ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 // cargo/... (because of serde) @@ -667,7 +666,7 @@ pub static CRATES: &[&str] = &[ for extra in expected.difference(&proc_macro_deps) { tidy_error!( bad, - "`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", + "`{extra}` is registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", ); } if *bad != old_bad { diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 39c9a148e9e56..1cb47353469fa 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -3619,7 +3619,6 @@ ui/resolve/issue-21221-1.rs ui/resolve/issue-21221-2.rs ui/resolve/issue-21221-3.rs ui/resolve/issue-21221-4.rs -ui/resolve/issue-22692.rs ui/resolve/issue-2330.rs ui/resolve/issue-23305.rs ui/resolve/issue-2356.rs diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs index 439385b14b05b..8e4e085032534 100644 --- a/tests/assembly/asm/aarch64-types.rs +++ b/tests/assembly/asm/aarch64-types.rs @@ -11,8 +11,6 @@ #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] -// FIXME(f16_f128): Only needed for FIXME in check! and check_reg! -#![feature(auto_traits, lang_items)] extern crate minicore; use minicore::*; @@ -63,12 +61,6 @@ impl Copy for f16x8 {} impl Copy for f32x4 {} impl Copy for f64x2 {} -// FIXME(f16_f128): Only needed for FIXME in check! and check_reg! -#[lang = "freeze"] -unsafe auto trait Freeze {} -#[lang = "unpin"] -auto trait Unpin {} - extern "C" { fn extern_func(); static extern_static: u8; diff --git a/tests/assembly/asm/avr-modifiers.rs b/tests/assembly/asm/avr-modifiers.rs index 585fdd7b72534..124cad9bef6a8 100644 --- a/tests/assembly/asm/avr-modifiers.rs +++ b/tests/assembly/asm/avr-modifiers.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![feature(no_core, asm_experimental_arch)] diff --git a/tests/assembly/asm/avr-types.rs b/tests/assembly/asm/avr-types.rs index 25cf3ec3b4bde..309405f4d51e7 100644 --- a/tests/assembly/asm/avr-types.rs +++ b/tests/assembly/asm/avr-types.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![feature(no_core, asm_experimental_arch)] diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs index b629d8769edf2..069204bbd345f 100644 --- a/tests/assembly/closure-inherit-target-feature.rs +++ b/tests/assembly/closure-inherit-target-feature.rs @@ -8,8 +8,9 @@ use std::arch::x86_64::{__m128, _mm_blend_ps}; +// Use an explicit return pointer to prevent tail call optimization. #[no_mangle] -pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 { +pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128, ret: *mut __m128) { let f = { // check that _mm_blend_ps is not being inlined into the closure // CHECK-LABEL: {{sse41_blend_nofeature.*closure.*:}} @@ -18,9 +19,9 @@ pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 { // CHECK-NOT: blendps // CHECK: ret #[inline(never)] - |x, y| _mm_blend_ps(x, y, 0b0101) + |x, y, ret: *mut __m128| unsafe { *ret = _mm_blend_ps(x, y, 0b0101) } }; - f(x, y) + f(x, y, ret); } #[no_mangle] diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index b5c0ee5a10741..3e73d2c6eb72d 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -216,9 +216,9 @@ //@ revisions: hexagon_unknown_none_elf //@ [hexagon_unknown_none_elf] compile-flags: --target hexagon-unknown-none-elf //@ [hexagon_unknown_none_elf] needs-llvm-components: hexagon -//@ revisions: i586_pc_nto_qnx700 -//@ [i586_pc_nto_qnx700] compile-flags: --target i586-pc-nto-qnx700 -//@ [i586_pc_nto_qnx700] needs-llvm-components: x86 +//@ revisions: i686_pc_nto_qnx700 +//@ [i686_pc_nto_qnx700] compile-flags: --target i686-pc-nto-qnx700 +//@ [i686_pc_nto_qnx700] needs-llvm-components: x86 //@ revisions: i586_unknown_linux_gnu //@ [i586_unknown_linux_gnu] compile-flags: --target i586-unknown-linux-gnu //@ [i586_unknown_linux_gnu] needs-llvm-components: x86 diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs index 1fa4dc821dd37..b74d0181c4d67 100644 --- a/tests/assembly/targets/targets-pe.rs +++ b/tests/assembly/targets/targets-pe.rs @@ -15,9 +15,9 @@ //@ revisions: arm64ec_pc_windows_msvc //@ [arm64ec_pc_windows_msvc] compile-flags: --target arm64ec-pc-windows-msvc //@ [arm64ec_pc_windows_msvc] needs-llvm-components: aarch64 -//@ revisions: avr_unknown_gnu_atmega328 -//@ [avr_unknown_gnu_atmega328] compile-flags: --target avr-unknown-gnu-atmega328 -//@ [avr_unknown_gnu_atmega328] needs-llvm-components: avr +//@ revisions: avr_none +//@ [avr_none] compile-flags: --target avr-none -C target-cpu=atmega328p +//@ [avr_none] needs-llvm-components: avr //@ revisions: bpfeb_unknown_none //@ [bpfeb_unknown_none] compile-flags: --target bpfeb-unknown-none //@ [bpfeb_unknown_none] needs-llvm-components: bpf diff --git a/tests/assembly/x86-return-float.rs b/tests/assembly/x86-return-float.rs index ad760627b3a36..2c39c830684ec 100644 --- a/tests/assembly/x86-return-float.rs +++ b/tests/assembly/x86-return-float.rs @@ -33,19 +33,18 @@ use minicore::*; // CHECK-LABEL: return_f32: #[no_mangle] pub fn return_f32(x: f32) -> f32 { - // CHECK: movl {{.*}}(%ebp), %eax - // CHECK-NOT: ax - // CHECK: retl + // CHECK: movss {{.*}}(%ebp), %xmm0 + // CHECK-NEXT: popl %ebp + // CHECK-NEXT: retl x } // CHECK-LABEL: return_f64: #[no_mangle] pub fn return_f64(x: f64) -> f64 { - // CHECK: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]] - // CHECK-NEXT: movsd [[#%d,OFFSET+4]](%ebp), %[[VAL:.*]] - // CHECK-NEXT: movsd %[[VAL]], (%[[PTR]]) - // CHECK: retl + // CHECK: movsd {{.*}}(%ebp), %xmm0 + // CHECK-NEXT: popl %ebp + // CHECK-NEXT: retl x } @@ -157,7 +156,7 @@ pub unsafe fn call_f32(x: &mut f32) { } // CHECK: movl {{.*}}(%ebp), %[[PTR:.*]] // CHECK: calll {{()|_}}get_f32 - // CHECK-NEXT: movl %eax, (%[[PTR]]) + // CHECK-NEXT: movss %xmm0, (%[[PTR]]) *x = get_f32(); } @@ -169,8 +168,7 @@ pub unsafe fn call_f64(x: &mut f64) { } // CHECK: movl {{.*}}(%ebp), %[[PTR:.*]] // CHECK: calll {{()|_}}get_f64 - // CHECK: movsd {{.*}}(%{{ebp|esp}}), %[[VAL:.*]] - // CHECK-NEXT: movsd %[[VAL:.*]], (%[[PTR]]) + // CHECK-NEXT: movlps %xmm0, (%[[PTR]]) *x = get_f64(); } @@ -315,25 +313,21 @@ pub unsafe fn call_other_f64(x: &mut (usize, f64)) { #[no_mangle] pub fn return_f16(x: f16) -> f16 { // CHECK: pushl %ebp - // CHECK: movl %esp, %ebp - // CHECK: movzwl 8(%ebp), %eax - // CHECK: popl %ebp - // CHECK: retl + // CHECK-NEXT: movl %esp, %ebp + // CHECK-NEXT: pinsrw $0, 8(%ebp), %xmm0 + // CHECK-NEXT: popl %ebp + // CHECK-NEXT: retl x } // CHECK-LABEL: return_f128: #[no_mangle] pub fn return_f128(x: f128) -> f128 { - // CHECK: movl [[#%d,OFFSET:]](%ebp), %[[PTR:.*]] - // CHECK-NEXT: movl [[#%d,OFFSET+4]](%ebp), %[[VAL1:.*]] - // CHECK-NEXT: movl [[#%d,OFFSET+8]](%ebp), %[[VAL2:.*]] - // CHECK-NEXT: movl [[#%d,OFFSET+12]](%ebp), %[[VAL3:.*]] - // CHECK-NEXT: movl [[#%d,OFFSET+16]](%ebp), %[[VAL4:.*]] - // CHECK-NEXT: movl %[[VAL4:.*]] 12(%[[PTR]]) - // CHECK-NEXT: movl %[[VAL3:.*]] 8(%[[PTR]]) - // CHECK-NEXT: movl %[[VAL2:.*]] 4(%[[PTR]]) - // CHECK-NEXT: movl %[[VAL1:.*]] (%[[PTR]]) - // CHECK: retl + // CHECK: pushl %ebp + // CHECK-NEXT: movl %esp, %ebp + // linux-NEXT: movaps 8(%ebp), %xmm0 + // win-NEXT: movups 8(%ebp), %xmm0 + // CHECK-NEXT: popl %ebp + // CHECK-NEXT: retl x } diff --git a/tests/assembly/x86_64-windows-i128-abi.rs b/tests/assembly/x86_64-windows-i128-abi.rs new file mode 100644 index 0000000000000..d2aefb7daa640 --- /dev/null +++ b/tests/assembly/x86_64-windows-i128-abi.rs @@ -0,0 +1,26 @@ +//@ assembly-output: emit-asm +//@ add-core-stubs +//@ revisions: msvc softfloat +//@ compile-flags: -Copt-level=3 +//@[msvc] compile-flags: --target x86_64-pc-windows-msvc +//@[msvc] needs-llvm-components: x86 +//@[softfloat] compile-flags: --target x86_64-unknown-uefi +//@[softfloat] needs-llvm-components: x86 + +#![feature(no_core)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// CHECK-LABEL: ret_i128 +// Hardfloat targets return via xmm0, softfloat targets via rax and rdx. +// msvc: movaps {{.*}}, %xmm0 +// softfloat: movq (%[[INPUT:.*]]), %rax +// softfloat-NEXT: movq 8(%[[INPUT]]), %rdx +// CHECK-NEXT: retq +#[no_mangle] +pub extern "C" fn ret_i128(x: &i128) -> i128 { + *x +} diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index 1c5f9eeba3c49..0aa8b6b8f8919 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -14,9 +14,20 @@ //! . // ignore-tidy-linelength -#![feature(no_core, lang_items, rustc_attrs, decl_macro, naked_functions, f16, f128)] +#![feature( + no_core, + lang_items, + auto_traits, + freeze_impls, + negative_impls, + rustc_attrs, + decl_macro, + naked_functions, + f16, + f128, + asm_experimental_arch +)] #![allow(unused, improper_ctypes_definitions, internal_features)] -#![feature(asm_experimental_arch)] #![no_std] #![no_core] @@ -42,6 +53,12 @@ pub trait Copy: Sized {} #[lang = "bikeshed_guaranteed_no_drop"] pub trait BikeshedGuaranteedNoDrop {} +#[lang = "freeze"] +pub unsafe auto trait Freeze {} + +#[lang = "unpin"] +pub auto trait Unpin {} + impl_marker_trait!( Copy => [ bool, char, @@ -83,6 +100,7 @@ impl Copy for ManuallyDrop {} pub struct UnsafeCell { value: T, } +impl !Freeze for UnsafeCell {} #[rustc_builtin_macro] pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { diff --git a/tests/codegen/abi-win64-zst.rs b/tests/codegen/abi-win64-zst.rs index dd36189814427..825a5c1b09c1f 100644 --- a/tests/codegen/abi-win64-zst.rs +++ b/tests/codegen/abi-win64-zst.rs @@ -1,4 +1,5 @@ //@ compile-flags: -Z merge-functions=disabled +//@ add-core-stubs //@ revisions: windows-gnu //@[windows-gnu] compile-flags: --target x86_64-pc-windows-gnu @@ -13,12 +14,12 @@ //@[linux] compile-flags: --target x86_64-unknown-linux-gnu //@[linux] needs-llvm-components: x86 -#![feature(no_core, lang_items, rustc_attrs, abi_vectorcall)] +#![feature(no_core, rustc_attrs, abi_vectorcall)] #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; // Make sure the argument is always passed when explicitly requesting a Windows ABI. // Our goal here is to match clang: . diff --git a/tests/codegen/abi-x86-sse.rs b/tests/codegen/abi-x86-sse.rs new file mode 100644 index 0000000000000..837bf6134b01c --- /dev/null +++ b/tests/codegen/abi-x86-sse.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -Z merge-functions=disabled + +//@ revisions: x86-64 +//@[x86-64] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86-64] needs-llvm-components: x86 + +//@ revisions: x86-32 +//@[x86-32] compile-flags: --target i686-unknown-linux-gnu +//@[x86-32] needs-llvm-components: x86 + +//@ revisions: x86-32-nosse +//@[x86-32-nosse] compile-flags: --target i586-unknown-linux-gnu +//@[x86-32-nosse] needs-llvm-components: x86 + +#![feature(no_core, lang_items, rustc_attrs, repr_simd)] +#![no_core] +#![crate_type = "lib"] + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +// Ensure this type is passed without ptr indirection on targets that +// require SSE2. +#[repr(simd)] +pub struct Sse([f32; 4]); + +// x86-64: <4 x float> @sse_id(<4 x float> {{[^,]*}}) +// x86-32: <4 x float> @sse_id(<4 x float> {{[^,]*}}) +// x86-32-nosse: void @sse_id(ptr{{( [^,]*)?}} sret([16 x i8]){{( .*)?}}, ptr{{( [^,]*)?}}) +#[no_mangle] +pub fn sse_id(x: Sse) -> Sse { + x +} diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs index 835cc7393e51e..46cfb2972df3a 100644 --- a/tests/codegen/align-byval-alignment-mismatch.rs +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +//@ add-core-stubs //@ revisions:i686-linux x86_64-linux //@[i686-linux] compile-flags: --target i686-unknown-linux-gnu -C panic=abort @@ -16,18 +17,14 @@ // on i686-unknown-linux-gnu, since the alignment needs to be increased, and should codegen // to a direct call on x86_64-unknown-linux-gnu, where byval alignment matches Rust alignment. -#![feature(no_core, lang_items)] +#![feature(no_core)] #![crate_type = "lib"] #![no_std] #![no_core] #![allow(non_camel_case_types)] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; // This type has align 1 in Rust, but as a byval argument on i686-linux, it will have align 4. #[repr(C)] diff --git a/tests/codegen/align-byval-vector.rs b/tests/codegen/align-byval-vector.rs index 60d49f9308197..c33b41a7bbee1 100644 --- a/tests/codegen/align-byval-vector.rs +++ b/tests/codegen/align-byval-vector.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions:x86-linux x86-darwin //@[x86-linux] compile-flags: --target i686-unknown-linux-gnu @@ -7,18 +8,14 @@ // Tests that aggregates containing vector types get their alignment increased to 16 on Darwin. -#![feature(no_core, lang_items, repr_simd, simd_ffi)] +#![feature(no_core, repr_simd, simd_ffi)] #![crate_type = "lib"] #![no_std] #![no_core] #![allow(non_camel_case_types)] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct i32x4([i32; 4]); diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs index b057147ab13e1..75dabd74a79c0 100644 --- a/tests/codegen/align-byval.rs +++ b/tests/codegen/align-byval.rs @@ -1,4 +1,5 @@ // ignore-tidy-linelength +//@ add-core-stubs //@ revisions:m68k x86_64-linux x86_64-windows i686-linux i686-windows //@[m68k] compile-flags: --target m68k-unknown-linux-gnu @@ -16,20 +17,13 @@ // The only targets that use `byval` are m68k, x86-64, and x86. // Note also that Windows mandates a by-ref ABI here, so it does not use byval. -#![feature(no_core, lang_items)] +#![feature(no_core)] #![crate_type = "lib"] #![no_std] #![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "freeze"] -trait Freeze {} -#[lang = "copy"] -trait Copy {} - -impl Copy for i32 {} -impl Copy for i64 {} +extern crate minicore; +use minicore::*; // This struct can be represented as a pair, so it exercises the OperandValue::Pair // codepath in `codegen_argument`. diff --git a/tests/codegen/asm/avr-clobbers.rs b/tests/codegen/asm/avr-clobbers.rs index 56218cd7bcffb..9451127bf04ab 100644 --- a/tests/codegen/asm/avr-clobbers.rs +++ b/tests/codegen/asm/avr-clobbers.rs @@ -1,6 +1,6 @@ //@ add-core-stubs //@ assembly-output: emit-asm -//@ compile-flags: --target avr-unknown-gnu-atmega328 +//@ compile-flags: --target avr-none -C target-cpu=atmega328p //@ needs-llvm-components: avr #![crate_type = "rlib"] diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff.rs index abf7fcf3e4bcd..cace0edb2b544 100644 --- a/tests/codegen/autodiff.rs +++ b/tests/codegen/autodiff.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -C opt-level=3 -Clto=fat +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme #![feature(autodiff)] diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index ed8acccb1ad85..2ec7c86b5f43c 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Copt-level=3 --target=avr-unknown-gnu-atmega328 --crate-type=rlib -C panic=abort +//@ compile-flags: -Copt-level=3 --target=avr-none -C target-cpu=atmega328p --crate-type=rlib -C panic=abort //@ needs-llvm-components: avr // This test validates that function pointers can be stored in global variables diff --git a/tests/codegen/box-default-debug-copies.rs b/tests/codegen/box-default-debug-copies.rs new file mode 100644 index 0000000000000..06cc41b21c06f --- /dev/null +++ b/tests/codegen/box-default-debug-copies.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=0 + +// Test to make sure that `>::default` does not create too many copies of `T` on the stack. +// in debug mode. This regressed in dd0620b86721ae8cae86736443acd3f72ba6fc32 to +// four `T` allocas. +// +// See https://github.com/rust-lang/rust/issues/136043 for more context. +// +// FIXME: This test only wants to ensure that there are at most two allocas of `T` created, instead +// of checking for exactly two. + +#![crate_type = "lib"] + +#[allow(dead_code)] +pub struct Thing([u8; 1000000]); + +impl Default for Thing { + fn default() -> Self { + Thing([0; 1000000]) + } +} + +// CHECK-COUNT-2: %{{.*}} = alloca {{.*}}1000000 +// CHECK-NOT: %{{.*}} = alloca {{.*}}1000000 +#[no_mangle] +pub fn box_default_single_copy() -> Box { + Box::default() +} diff --git a/tests/codegen/float/f128.rs b/tests/codegen/float/f128.rs index 562a8e6c9e9ba..d87bab1172a24 100644 --- a/tests/codegen/float/f128.rs +++ b/tests/codegen/float/f128.rs @@ -1,8 +1,11 @@ // 32-bit x86 returns float types differently to avoid the x87 stack. // 32-bit systems will return 128bit values using a return area pointer. // Emscripten aligns f128 to 8 bytes, not 16. -//@ revisions: x86 bit32 bit64 emscripten -//@[x86] only-x86 +//@ revisions: x86-sse x86-nosse bit32 bit64 emscripten +//@[x86-sse] only-x86 +//@[x86-sse] only-rustc_abi-x86-sse2 +//@[x86-nosse] only-x86 +//@[x86-nosse] ignore-rustc_abi-x86-sse2 //@[bit32] ignore-x86 //@[bit32] ignore-emscripten //@[bit32] only-32bit @@ -60,7 +63,8 @@ pub fn f128_le(a: f128, b: f128) -> bool { a <= b } -// x86-LABEL: void @f128_neg({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_neg({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_neg(fp128 // bit32-LABEL: void @f128_neg({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_neg( // emscripten-LABEL: void @f128_neg({{.*}}sret([16 x i8]) @@ -70,7 +74,8 @@ pub fn f128_neg(a: f128) -> f128 { -a } -// x86-LABEL: void @f128_add({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_add({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_add(fp128 // bit32-LABEL: void @f128_add({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_add( // emscripten-LABEL: void @f128_add({{.*}}sret([16 x i8]) @@ -80,7 +85,8 @@ pub fn f128_add(a: f128, b: f128) -> f128 { a + b } -// x86-LABEL: void @f128_sub({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_sub({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_sub(fp128 // bit32-LABEL: void @f128_sub({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_sub( // emscripten-LABEL: void @f128_sub({{.*}}sret([16 x i8]) @@ -90,7 +96,8 @@ pub fn f128_sub(a: f128, b: f128) -> f128 { a - b } -// x86-LABEL: void @f128_mul({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_mul({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_mul(fp128 // bit32-LABEL: void @f128_mul({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_mul( // emscripten-LABEL: void @f128_mul({{.*}}sret([16 x i8]) @@ -100,7 +107,8 @@ pub fn f128_mul(a: f128, b: f128) -> f128 { a * b } -// x86-LABEL: void @f128_div({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_div({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_div(fp128 // bit32-LABEL: void @f128_div({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_div( // emscripten-LABEL: void @f128_div({{.*}}sret([16 x i8]) @@ -110,7 +118,8 @@ pub fn f128_div(a: f128, b: f128) -> f128 { a / b } -// x86-LABEL: void @f128_rem({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_rem({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_rem(fp128 // bit32-LABEL: void @f128_rem({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_rem( // emscripten-LABEL: void @f128_rem({{.*}}sret([16 x i8]) @@ -162,7 +171,8 @@ pub fn f128_rem_assign(a: &mut f128, b: f128) { /* float to float conversions */ -// x86-LABEL: i16 @f128_as_f16( +// x86-sse-LABEL: <2 x i8> @f128_as_f16( +// x86-nosse-LABEL: i16 @f128_as_f16( // bits32-LABEL: half @f128_as_f16( // bits64-LABEL: half @f128_as_f16( #[no_mangle] @@ -171,7 +181,8 @@ pub fn f128_as_f16(a: f128) -> f16 { a as f16 } -// x86-LABEL: i32 @f128_as_f32( +// x86-sse-LABEL: <4 x i8> @f128_as_f32( +// x86-nosse-LABEL: i32 @f128_as_f32( // bit32-LABEL: float @f128_as_f32( // bit64-LABEL: float @f128_as_f32( // emscripten-LABEL: float @f128_as_f32( @@ -181,7 +192,8 @@ pub fn f128_as_f32(a: f128) -> f32 { a as f32 } -// x86-LABEL: void @f128_as_f64( +// x86-sse-LABEL: <8 x i8> @f128_as_f64( +// x86-nosse-LABEL: void @f128_as_f64({{.*}}sret([8 x i8]) // bit32-LABEL: double @f128_as_f64( // bit64-LABEL: double @f128_as_f64( // emscripten-LABEL: double @f128_as_f64( @@ -191,7 +203,8 @@ pub fn f128_as_f64(a: f128) -> f64 { a as f64 } -// x86-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f128_as_self( +// x86-nosse-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f128_as_self( // emscripten-LABEL: void @f128_as_self({{.*}}sret([16 x i8]) @@ -204,7 +217,8 @@ pub fn f128_as_self(a: f128) -> f128 { a as f128 } -// x86-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f16_as_f128( +// x86-nosse-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f16_as_f128( // emscripten-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) @@ -214,7 +228,8 @@ pub fn f16_as_f128(a: f16) -> f128 { a as f128 } -// x86-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f32_as_f128( +// x86-nosse-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f32_as_f128( // emscripten-LABEL: void @f32_as_f128({{.*}}sret([16 x i8]) @@ -224,7 +239,8 @@ pub fn f32_as_f128(a: f32) -> f128 { a as f128 } -// x86-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f64_as_f128( +// x86-nosse-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f64_as_f128( // emscripten-LABEL: void @f64_as_f128({{.*}}sret([16 x i8]) @@ -263,7 +279,8 @@ pub fn f128_as_u64(a: f128) -> u64 { a as u64 } -// x86-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f128_as_u128( // emscripten-LABEL: void @f128_as_u128({{.*}}sret([16 x i8]) @@ -300,7 +317,8 @@ pub fn f128_as_i64(a: f128) -> i64 { a as i64 } -// x86-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f128_as_i128( // emscripten-LABEL: void @f128_as_i128({{.*}}sret([16 x i8]) @@ -312,7 +330,8 @@ pub fn f128_as_i128(a: f128) -> i128 { /* int to float conversions */ -// x86-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @u8_as_f128( +// x86-nosse-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u8_as_f128( // emscripten-LABEL: void @u8_as_f128({{.*}}sret([16 x i8]) @@ -322,7 +341,8 @@ pub fn u8_as_f128(a: u8) -> f128 { a as f128 } -// x86-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @u16_as_f128( +// x86-nosse-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u16_as_f128( // emscripten-LABEL: void @u16_as_f128({{.*}}sret([16 x i8]) @@ -332,7 +352,8 @@ pub fn u16_as_f128(a: u16) -> f128 { a as f128 } -// x86-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @u32_as_f128( +// x86-nosse-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u32_as_f128( // emscripten-LABEL: void @u32_as_f128({{.*}}sret([16 x i8]) @@ -342,7 +363,8 @@ pub fn u32_as_f128(a: u32) -> f128 { a as f128 } -// x86-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @u64_as_f128( +// x86-nosse-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u64_as_f128( // emscripten-LABEL: void @u64_as_f128({{.*}}sret([16 x i8]) @@ -352,7 +374,8 @@ pub fn u64_as_f128(a: u64) -> f128 { a as f128 } -// x86-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @u128_as_f128( +// x86-nosse-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @u128_as_f128( // emscripten-LABEL: void @u128_as_f128({{.*}}sret([16 x i8]) @@ -362,7 +385,8 @@ pub fn u128_as_f128(a: u128) -> f128 { a as f128 } -// x86-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @i8_as_f128( +// x86-nosse-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i8_as_f128( // emscripten-LABEL: void @i8_as_f128({{.*}}sret([16 x i8]) @@ -372,7 +396,8 @@ pub fn i8_as_f128(a: i8) -> f128 { a as f128 } -// x86-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @i16_as_f128( +// x86-nosse-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i16_as_f128( // emscripten-LABEL: void @i16_as_f128({{.*}}sret([16 x i8]) @@ -382,7 +407,8 @@ pub fn i16_as_f128(a: i16) -> f128 { a as f128 } -// x86-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @i32_as_f128( +// x86-nosse-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i32_as_f128( // emscripten-LABEL: void @i32_as_f128({{.*}}sret([16 x i8]) @@ -392,7 +418,8 @@ pub fn i32_as_f128(a: i32) -> f128 { a as f128 } -// x86-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @i64_as_f128( +// x86-nosse-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i64_as_f128( // emscripten-LABEL: void @i64_as_f128({{.*}}sret([16 x i8]) @@ -402,7 +429,8 @@ pub fn i64_as_f128(a: i64) -> f128 { a as f128 } -// x86-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @i128_as_f128( +// x86-nosse-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @i128_as_f128( // emscripten-LABEL: void @i128_as_f128({{.*}}sret([16 x i8]) diff --git a/tests/codegen/float/f16.rs b/tests/codegen/float/f16.rs index 5c3a5893b9d23..0c40606ad8a42 100644 --- a/tests/codegen/float/f16.rs +++ b/tests/codegen/float/f16.rs @@ -1,7 +1,10 @@ // 32-bit x86 returns float types differently to avoid the x87 stack. // 32-bit systems will return 128bit values using a return area pointer. -//@ revisions: x86 bit32 bit64 -//@[x86] only-x86 +//@ revisions: x86-sse x86-nosse bit32 bit64 +//@[x86-sse] only-x86 +//@[x86-sse] only-rustc_abi-x86-sse2 +//@[x86-nosse] only-x86 +//@[x86-nosse] ignore-rustc_abi-x86-sse2 //@[bit32] ignore-x86 //@[bit32] only-32bit //@[bit64] ignore-x86 @@ -59,8 +62,10 @@ pub fn f16_le(a: f16, b: f16) -> bool { } // This is where we check the argument and return ABI for f16. -// other-LABEL: half @f16_neg(half -// x86-LABEL: i16 @f16_neg(half +// bit32-LABEL: half @f16_neg(half +// bit64-LABEL: half @f16_neg(half +// x86-sse-LABEL: <2 x i8> @f16_neg(half +// x86-nosse-LABEL: i16 @f16_neg(half #[no_mangle] pub fn f16_neg(a: f16) -> f16 { // CHECK: fneg half %{{.+}} @@ -144,17 +149,23 @@ pub fn f16_rem_assign(a: &mut f16, b: f16) { /* float to float conversions */ -// other-LABEL: half @f16_as_self( -// x86-LABEL: i16 @f16_as_self( +// bit32-LABEL: half @f16_as_self( +// bit64-LABEL: half @f16_as_self( +// x86-sse-LABEL: <2 x i8> @f16_as_self( +// x86-nosse-LABEL: i16 @f16_as_self( #[no_mangle] pub fn f16_as_self(a: f16) -> f16 { - // other-CHECK: ret half %{{.+}} - // x86-CHECK: bitcast half - // x86-CHECK: ret i16 + // bit32-CHECK: ret half %{{.+}} + // bit64-CHECK: ret half %{{.+}} + // x86-sse-CHECK: bitcast half + // x86-nosse-CHECK: bitcast half + // x86-sse-CHECK: ret i16 + // x86-nosse-CHECK: ret i16 a as f16 } -// x86-LABEL: i32 @f16_as_f32( +// x86-sse-LABEL: <4 x i8> @f16_as_f32( +// x86-nosse-LABEL: i32 @f16_as_f32( // bit32-LABEL: float @f16_as_f32( // bit64-LABEL: float @f16_as_f32( #[no_mangle] @@ -163,7 +174,8 @@ pub fn f16_as_f32(a: f16) -> f32 { a as f32 } -// x86-LABEL: void @f16_as_f64( +// x86-sse-LABEL: <8 x i8> @f16_as_f64( +// x86-nosse-LABEL: void @f16_as_f64({{.*}}sret([8 x i8]) // bit32-LABEL: double @f16_as_f64( // bit64-LABEL: double @f16_as_f64( #[no_mangle] @@ -172,7 +184,8 @@ pub fn f16_as_f64(a: f16) -> f64 { a as f64 } -// x86-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: <16 x i8> @f16_as_f128( +// x86-nosse-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f16_as_f128({{.*}}sret([16 x i8]) // bit64-LABEL: fp128 @f16_as_f128( #[no_mangle] @@ -231,7 +244,8 @@ pub fn f16_as_u64(a: f16) -> u64 { a as u64 } -// x86-LABEL: void @f16_as_u128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: void @f16_as_u128({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f16_as_u128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f16_as_u128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f16_as_u128( #[no_mangle] @@ -267,7 +281,8 @@ pub fn f16_as_i64(a: f16) -> i64 { a as i64 } -// x86-LABEL: void @f16_as_i128({{.*}}sret([16 x i8]) +// x86-sse-LABEL: void @f16_as_i128({{.*}}sret([16 x i8]) +// x86-nosse-LABEL: void @f16_as_i128({{.*}}sret([16 x i8]) // bit32-LABEL: void @f16_as_i128({{.*}}sret([16 x i8]) // bit64-LABEL: i128 @f16_as_i128( #[no_mangle] diff --git a/tests/codegen/gep-index.rs b/tests/codegen/gep-index.rs index 1f5e8855910e9..bfb2511af87a5 100644 --- a/tests/codegen/gep-index.rs +++ b/tests/codegen/gep-index.rs @@ -11,27 +11,27 @@ struct Foo(i32, i32); // CHECK-LABEL: @index_on_struct( #[no_mangle] fn index_on_struct(a: &[Foo], index: usize) -> &Foo { - // CHECK: getelementptr inbounds %Foo, ptr %a.0, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} %Foo, ptr %a.0, {{i64|i32}} %index &a[index] } // CHECK-LABEL: @offset_on_struct( #[no_mangle] fn offset_on_struct(a: *const Foo, index: usize) -> *const Foo { - // CHECK: getelementptr inbounds %Foo, ptr %a, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} %Foo, ptr %a, {{i64|i32}} %index unsafe { a.add(index) } } // CHECK-LABEL: @index_on_i32( #[no_mangle] fn index_on_i32(a: &[i32], index: usize) -> &i32 { - // CHECK: getelementptr inbounds i32, ptr %a.0, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} i32, ptr %a.0, {{i64|i32}} %index &a[index] } // CHECK-LABEL: @offset_on_i32( #[no_mangle] fn offset_on_i32(a: *const i32, index: usize) -> *const i32 { - // CHECK: getelementptr inbounds i32, ptr %a, {{i64|i32}} %index + // CHECK: getelementptr inbounds{{( nuw)?}} i32, ptr %a, {{i64|i32}} %index unsafe { a.add(index) } } diff --git a/tests/codegen/i128-x86-callconv.rs b/tests/codegen/i128-x86-callconv.rs index 9a9c9002fc026..41c30c09c1ac4 100644 --- a/tests/codegen/i128-x86-callconv.rs +++ b/tests/codegen/i128-x86-callconv.rs @@ -4,13 +4,18 @@ //@ compile-flags: -Copt-level=1 //@ add-core-stubs -//@ revisions: MSVC MINGW +//@ revisions: MSVC MINGW softfloat //@ [MSVC] needs-llvm-components: x86 -//@ [MINGW] needs-llvm-components: x86 //@ [MSVC] compile-flags: --target x86_64-pc-windows-msvc -//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu +// Use `WIN` as a common prefix for MSVC and MINGW but *not* the softfloat test. //@ [MSVC] filecheck-flags: --check-prefix=WIN +//@ [MINGW] needs-llvm-components: x86 +//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu //@ [MINGW] filecheck-flags: --check-prefix=WIN +// The `x86_64-unknown-uefi` target also uses the Windows calling convention, +// but does not have SSE registers available. +//@ [softfloat] needs-llvm-components: x86 +//@ [softfloat] compile-flags: --target x86_64-unknown-uefi #![crate_type = "lib"] #![no_std] @@ -28,24 +33,26 @@ extern "C" { pub extern "C" fn pass(_arg0: u32, arg1: i128) { // CHECK-LABEL: @pass( // i128 is passed indirectly on Windows. It should load the pointer to the stack and pass - // a pointer to that allocation. - // WIN-SAME: %_arg0, ptr{{.*}} %arg1) - // WIN: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16 - // WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1 - // WIN: store i128 [[LOADED]], ptr [[PASS]] - // WIN: call void @extern_call + // a pointer to that allocation. The softfloat ABI works the same. + // CHECK-SAME: %_arg0, ptr{{.*}} %arg1) + // CHECK: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16 + // CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1 + // CHECK: store i128 [[LOADED]], ptr [[PASS]] + // CHECK: call void @extern_call unsafe { extern_call(arg1) }; } // Check that we produce the correct return ABI #[no_mangle] pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 { - // CHECK-LABEL: @ret( + // WIN-LABEL: @ret( // i128 is returned in xmm0 on Windows // FIXME(#134288): This may change for the `-msvc` targets in the future. // WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1) // WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1 // WIN-NEXT: ret <16 x i8> [[LOADED]] + // The softfloat ABI returns this indirectly. + // softfloat-LABEL: i128 @ret(i32{{.*}} %_arg0, ptr{{.*}} %arg1) arg1 } @@ -57,6 +64,7 @@ pub extern "C" fn forward(dst: *mut i128) { // WIN: [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret() // WIN: store <16 x i8> [[RETURNED]], ptr %dst // WIN: ret void + // softfloat: [[RETURNED:%[_0-9]+]] = tail call {{.*}}i128 @extern_ret() unsafe { *dst = extern_ret() }; } @@ -70,10 +78,10 @@ struct RetAggregate { pub extern "C" fn ret_aggregate(_arg0: u32, arg1: i128) -> RetAggregate { // CHECK-LABEL: @ret_aggregate( // Aggregates should also be returned indirectly - // WIN-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1) - // WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1 - // WIN: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]] - // WIN: store i128 [[LOADED]], ptr [[GEP]] - // WIN: ret void + // CHECK-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1) + // CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1 + // CHECK: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]] + // CHECK: store i128 [[LOADED]], ptr [[GEP]] + // CHECK: ret void RetAggregate { a: 1, b: arg1 } } diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs new file mode 100644 index 0000000000000..1e7e0478f4fd9 --- /dev/null +++ b/tests/codegen/intrinsics/cold_path2.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -O +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::cold_path; + +#[inline(never)] +#[no_mangle] +pub fn path_a() { + println!("path a"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_b() { + println!("path b"); +} + +#[no_mangle] +pub fn test(x: Option) { + if let Some(_) = x { + path_a(); + } else { + cold_path(); + path_b(); + } + + // CHECK-LABEL: @test( + // CHECK: br i1 %1, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] + // CHECK: bb1: + // CHECK: path_a + // CHECK: bb2: + // CHECK: path_b +} + +// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000} diff --git a/tests/codegen/intrinsics/cold_path3.rs b/tests/codegen/intrinsics/cold_path3.rs new file mode 100644 index 0000000000000..bf3347de665db --- /dev/null +++ b/tests/codegen/intrinsics/cold_path3.rs @@ -0,0 +1,87 @@ +//@ compile-flags: -O +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::cold_path; + +#[inline(never)] +#[no_mangle] +pub fn path_a() { + println!("path a"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_b() { + println!("path b"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_c() { + println!("path c"); +} + +#[inline(never)] +#[no_mangle] +pub fn path_d() { + println!("path d"); +} + +#[no_mangle] +pub fn test(x: Option) { + match x { + Some(0) => path_a(), + Some(1) => { + cold_path(); + path_b() + } + Some(2) => path_c(), + Some(3) => { + cold_path(); + path_d() + } + _ => path_a(), + } + + // CHECK-LABEL: @test( + // CHECK: switch i32 %1, label %bb1 [ + // CHECK: i32 0, label %bb6 + // CHECK: i32 1, label %bb5 + // CHECK: i32 2, label %bb4 + // CHECK: i32 3, label %bb3 + // CHECK: ], !prof ![[NUM1:[0-9]+]] +} + +#[no_mangle] +pub fn test2(x: Option) { + match x { + Some(10) => path_a(), + Some(11) => { + cold_path(); + path_b() + } + Some(12) => { + unsafe { core::intrinsics::unreachable() }; + path_c() + } + Some(13) => { + cold_path(); + path_d() + } + _ => { + cold_path(); + path_a() + } + } + + // CHECK-LABEL: @test2( + // CHECK: switch i32 %1, label %bb1 [ + // CHECK: i32 10, label %bb5 + // CHECK: i32 11, label %bb4 + // CHECK: i32 13, label %bb3 + // CHECK: ], !prof ![[NUM2:[0-9]+]] +} + +// CHECK: ![[NUM1]] = !{!"branch_weights", i32 2000, i32 2000, i32 1, i32 2000, i32 1} +// CHECK: ![[NUM2]] = !{!"branch_weights", i32 1, i32 2000, i32 1, i32 1} diff --git a/tests/codegen/intrinsics/nearby.rs b/tests/codegen/intrinsics/nearby.rs deleted file mode 100644 index 520fe2f1886eb..0000000000000 --- a/tests/codegen/intrinsics/nearby.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -use std::intrinsics; - -// CHECK-LABEL: @nearbyintf32 -#[no_mangle] -pub unsafe fn nearbyintf32(a: f32) -> f32 { - // CHECK: llvm.nearbyint.f32 - intrinsics::nearbyintf32(a) -} - -// CHECK-LABEL: @nearbyintf64 -#[no_mangle] -pub unsafe fn nearbyintf64(a: f64) -> f64 { - // CHECK: llvm.nearbyint.f64 - intrinsics::nearbyintf64(a) -} diff --git a/tests/codegen/intrinsics/offset.rs b/tests/codegen/intrinsics/offset.rs index d76d3e705abad..cf0c7c7ac7d74 100644 --- a/tests/codegen/intrinsics/offset.rs +++ b/tests/codegen/intrinsics/offset.rs @@ -27,7 +27,7 @@ pub unsafe fn offset_isize(p: *const u32, d: isize) -> *const u32 { // CHECK-SAME: (ptr noundef %p, [[SIZE]] noundef %d) #[no_mangle] pub unsafe fn offset_usize(p: *const u64, d: usize) -> *const u64 { - // CHECK: %[[R:.*]] = getelementptr inbounds i64, ptr %p, [[SIZE]] %d + // CHECK: %[[R:.*]] = getelementptr inbounds{{( nuw)?}} i64, ptr %p, [[SIZE]] %d // CHECK-NEXT: ret ptr %[[R]] offset(p, d) } diff --git a/tests/codegen/intrinsics/ptr_metadata.rs b/tests/codegen/intrinsics/ptr_metadata.rs index 87a32fa3d2468..044dbc2048695 100644 --- a/tests/codegen/intrinsics/ptr_metadata.rs +++ b/tests/codegen/intrinsics/ptr_metadata.rs @@ -28,7 +28,7 @@ pub unsafe fn dyn_byte_offset( p: *const dyn std::fmt::Debug, n: usize, ) -> *const dyn std::fmt::Debug { - // CHECK: %[[Q:.+]] = getelementptr inbounds i8, ptr %p.0, i64 %n + // CHECK: %[[Q:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %p.0, i64 %n // CHECK: %[[TEMP1:.+]] = insertvalue { ptr, ptr } poison, ptr %[[Q]], 0 // CHECK: %[[TEMP2:.+]] = insertvalue { ptr, ptr } %[[TEMP1]], ptr %p.1, 1 // CHECK: ret { ptr, ptr } %[[TEMP2]] diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs index 5ded0e192fa24..8ff5cc8ee4f4c 100644 --- a/tests/codegen/intrinsics/transmute-niched.rs +++ b/tests/codegen/intrinsics/transmute-niched.rs @@ -170,7 +170,7 @@ pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool { // OPT: call void @llvm.assume(i1 %2) // CHECK-NOT: icmp // CHECK-NOT: assume - // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1 // CHECK: ret i1 %[[R]] transmute(x) diff --git a/tests/codegen/intrinsics/transmute-x64.rs b/tests/codegen/intrinsics/transmute-x64.rs index fe68f18366701..be45e4db90fd9 100644 --- a/tests/codegen/intrinsics/transmute-x64.rs +++ b/tests/codegen/intrinsics/transmute-x64.rs @@ -6,15 +6,6 @@ use std::arch::x86_64::{__m128, __m128i, __m256i}; use std::mem::transmute; -// CHECK-LABEL: @check_sse_float_to_int( -#[no_mangle] -pub unsafe fn check_sse_float_to_int(x: __m128) -> __m128i { - // CHECK-NOT: alloca - // CHECK: %0 = load <4 x float>, ptr %x, align 16 - // CHECK: store <4 x float> %0, ptr %_0, align 16 - transmute(x) -} - // CHECK-LABEL: @check_sse_pair_to_avx( #[no_mangle] pub unsafe fn check_sse_pair_to_avx(x: (__m128i, __m128i)) -> __m256i { diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 5b40a6a12c0fa..ff297b2706578 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -11,6 +11,9 @@ use std::intrinsics::mir::*; use std::intrinsics::{transmute, transmute_unchecked}; use std::mem::MaybeUninit; +// FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no +// longer support it the optional flag checks can be changed to required. + pub enum ZstNever {} #[repr(align(2))] @@ -153,7 +156,7 @@ pub unsafe fn check_from_newtype(x: Scalar64) -> u64 { pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool { // CHECK: %x = alloca [1 x i8], align 1 // CHECK: %[[BYTE:.+]] = load i8, ptr %x, align 1 - // CHECK: %[[BOOL:.+]] = trunc i8 %[[BYTE]] to i1 + // CHECK: %[[BOOL:.+]] = trunc{{( nuw)?}} i8 %[[BYTE]] to i1 // CHECK: ret i1 %[[BOOL]] transmute(x) } @@ -171,7 +174,7 @@ 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: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1 // CHECK: ret i1 %[[R]] transmute(x) } @@ -284,7 +287,7 @@ pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] { #[no_mangle] pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { // CHECK-NOT: alloca - // CHECK: trunc i8 %x.0 to i1 + // CHECK: trunc{{( nuw)?}} i8 %x.0 to i1 // CHECK: zext i1 %x.1 to i8 transmute(x) } @@ -338,7 +341,7 @@ pub unsafe fn check_heterogeneous_integer_pair(x: (i32, bool)) -> (bool, u32) { // CHECK: store i8 %[[WIDER]] // CHECK: %[[BYTE:.+]] = load i8 - // CHECK: trunc i8 %[[BYTE:.+]] to i1 + // CHECK: trunc{{( nuw)?}} i8 %[[BYTE:.+]] to i1 // CHECK: load i32 transmute(x) } diff --git a/tests/codegen/issues/issue-32031.rs b/tests/codegen/issues/issue-32031.rs index 4d6895166f1cb..559e8d947fba5 100644 --- a/tests/codegen/issues/issue-32031.rs +++ b/tests/codegen/issues/issue-32031.rs @@ -1,7 +1,7 @@ //@ compile-flags: -C no-prepopulate-passes -Copt-level=0 // 32-bit x86 returns `f32` and `f64` differently to avoid the x87 stack. //@ revisions: x86 other -//@[x86] only-x86 +//@[x86] only-rustc_abi-x86-sse2 //@[other] ignore-x86 #![crate_type = "lib"] @@ -10,7 +10,7 @@ pub struct F32(f32); // other: define{{.*}}float @add_newtype_f32(float %a, float %b) -// x86: define{{.*}}i32 @add_newtype_f32(float %a, float %b) +// x86: define{{.*}}<4 x i8> @add_newtype_f32(float %a, float %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f32(a: F32, b: F32) -> F32 { @@ -21,7 +21,7 @@ pub fn add_newtype_f32(a: F32, b: F32) -> F32 { pub struct F64(f64); // other: define{{.*}}double @add_newtype_f64(double %a, double %b) -// x86: define{{.*}}void @add_newtype_f64(ptr{{.*}}sret([8 x i8]){{.*}}%_0, double %a, double %b) +// x86: define{{.*}}<8 x i8> @add_newtype_f64(double %a, double %b) #[inline(never)] #[no_mangle] pub fn add_newtype_f64(a: F64, b: F64) -> F64 { diff --git a/tests/codegen/ptr-arithmetic.rs b/tests/codegen/ptr-arithmetic.rs index ecb44b30f5cad..fc4441ef44863 100644 --- a/tests/codegen/ptr-arithmetic.rs +++ b/tests/codegen/ptr-arithmetic.rs @@ -6,7 +6,7 @@ // CHECK-SAME: [[WORD:i[0-9]+]] noundef %n) #[no_mangle] pub unsafe fn i32_add(p: *const i32, n: usize) -> *const i32 { - // CHECK: %[[TEMP:.+]] = getelementptr inbounds i32, ptr %p, [[WORD]] %n + // CHECK: %[[TEMP:.+]] = getelementptr inbounds{{( nuw)?}} i32, ptr %p, [[WORD]] %n // CHECK: ret ptr %[[TEMP]] p.add(n) } diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index 75f989d6e12c4..0d21d51055761 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -1,5 +1,14 @@ // //@ compile-flags: -C no-prepopulate-passes +// LLVM IR isn't very portable and the one tested here depends on the ABI +// which is different between x86 (where we use SSE registers) and others. +// `x86-64` and `x86-32-sse2` are identical, but compiletest does not support +// taking the union of multiple `only` annotations. +//@ revisions: x86-64 x86-32-sse2 other +//@[x86-64] only-x86_64 +//@[x86-32-sse2] only-rustc_abi-x86-sse2 +//@[other] ignore-rustc_abi-x86-sse2 +//@[other] ignore-x86_64 #![crate_type = "lib"] #![allow(non_camel_case_types)] @@ -38,7 +47,9 @@ pub fn build_array_s(x: [f32; 4]) -> S<4> { #[no_mangle] pub fn build_array_transmute_s(x: [f32; 4]) -> S<4> { // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] - // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] + // x86-32: ret <4 x float> %[[VAL:.+]] + // x86-64: ret <4 x float> %[[VAL:.+]] + // other: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } @@ -53,6 +64,8 @@ pub fn build_array_t(x: [f32; 4]) -> T { #[no_mangle] pub fn build_array_transmute_t(x: [f32; 4]) -> T { // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]] - // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] + // x86-32: ret <4 x float> %[[VAL:.+]] + // x86-64: ret <4 x float> %[[VAL:.+]] + // other: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]] unsafe { std::mem::transmute(x) } } diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs index 1df09c96e6cc0..a27d5e3af452a 100644 --- a/tests/codegen/simd/packed-simd.rs +++ b/tests/codegen/simd/packed-simd.rs @@ -1,4 +1,5 @@ //@ revisions:opt3 noopt +//@ only-x86_64 //@[opt3] compile-flags: -Copt-level=3 //@[noopt] compile-flags: -Cno-prepopulate-passes @@ -14,14 +15,14 @@ use core::{mem, ptr}; #[repr(simd, packed)] #[derive(Copy, Clone)] -pub struct Simd([T; N]); +pub struct PackedSimd([T; N]); #[repr(simd)] #[derive(Copy, Clone)] pub struct FullSimd([T; N]); // non-powers-of-two have padding and need to be expanded to full vectors -fn load(v: Simd) -> FullSimd { +fn load(v: PackedSimd) -> FullSimd { unsafe { let mut tmp = mem::MaybeUninit::>::uninit(); ptr::copy_nonoverlapping(&v as *const _, tmp.as_mut_ptr().cast(), 1); @@ -29,18 +30,16 @@ fn load(v: Simd) -> FullSimd { } } -// CHECK-LABEL: square_packed_full -// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] -// CHECK-SAME: ptr{{[a-z_ ]*}} align 4 +// CHECK-LABEL: define <3 x float> @square_packed_full(ptr{{[a-z_ ]*}} align 4 {{[^,]*}}) #[no_mangle] -pub fn square_packed_full(x: Simd) -> FullSimd { - // CHECK-NEXT: start - // noopt: alloca [[RET_TYPE]], [[RET_ALIGN]] - // CHECK: load <3 x float> +pub fn square_packed_full(x: PackedSimd) -> FullSimd { + // The unoptimized version of this is not very interesting to check + // since `load` does not get inlined. + // opt3-NEXT: start: + // opt3-NEXT: load <3 x float> let x = load(x); - // CHECK: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> - // CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]] - // CHECK-NEXT: ret void + // opt3-NEXT: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> + // opt3-NEXT: ret <3 x float> [[VREG:%[a-z0-9_]+]] unsafe { intrinsics::simd_mul(x, x) } } @@ -48,7 +47,7 @@ pub fn square_packed_full(x: Simd) -> FullSimd { // CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align 4]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] // CHECK-SAME: ptr{{[a-z_ ]*}} align 4 #[no_mangle] -pub fn square_packed(x: Simd) -> Simd { +pub fn square_packed(x: PackedSimd) -> PackedSimd { // CHECK-NEXT: start // CHECK-NEXT: load <3 x float> // noopt-NEXT: load <3 x float> diff --git a/tests/codegen/simd/project-to-simd-array-field.rs b/tests/codegen/simd/project-to-simd-array-field.rs new file mode 100644 index 0000000000000..29fab64063363 --- /dev/null +++ b/tests/codegen/simd/project-to-simd-array-field.rs @@ -0,0 +1,31 @@ +//@compile-flags: -Copt-level=3 + +#![crate_type = "lib"] +#![feature(repr_simd, core_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +struct i32x4([i32; 4]); + +#[inline(always)] +fn to_array4(a: i32x4) -> [i32; 4] { + a.0 +} + +// CHECK-LABEL: simd_add_self_then_return_array( +// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], +// CHECK-SAME: ptr{{.+}}%a) +#[no_mangle] +pub fn simd_add_self_then_return_array(a: &i32x4) -> [i32; 4] { + // It would be nice to just ban `.0` into simd types, + // but until we do this has to keep working. + // See also + + // CHECK: %[[T1:.+]] = load <4 x i32>, ptr %a + // CHECK: %[[T2:.+]] = shl <4 x i32> %[[T1]], {{splat \(i32 1\)|}} + // CHECK: store <4 x i32> %[[T2]], ptr %[[RET]] + let a = *a; + let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; + to_array4(b) +} diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index 98a1b961a6443..87907e7ad0a30 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -14,11 +14,11 @@ // CHECK-LABEL: @slice_iter_next( #[no_mangle] pub fn slice_iter_next<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&'a u32> { - // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} - // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] + // CHECK: %[[START:.+]] = load ptr, ptr %it, // CHECK-SAME: !nonnull // CHECK-SAME: !noundef - // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK: %[[ENDP:.+]] = getelementptr inbounds{{( nuw)?}} i8, ptr %it, {{i32 4|i64 8}} + // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef // CHECK: icmp eq ptr %[[START]], %[[END]] diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index 43da7c1781ef3..c080259a9172e 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -26,7 +26,7 @@ pub fn bool_to_byte(b: bool) -> u8 { } // CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8{{.*}} %byte) -// CHECK: %_0 = trunc i8 %byte to i1 +// CHECK: %_0 = trunc{{( nuw)?}} i8 %byte to i1 // CHECK-NEXT: ret i1 %_0 #[no_mangle] pub unsafe fn byte_to_bool(byte: u8) -> bool { diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs index b27eb73c0cc94..9fccaf2252e01 100644 --- a/tests/codegen/unchecked_shifts.rs +++ b/tests/codegen/unchecked_shifts.rs @@ -1,4 +1,10 @@ -//@ compile-flags: -Copt-level=3 +//@ revisions: LLVM18 LLVM19PLUS +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@[LLVM18] exact-llvm-major-version: 18 +//@[LLVM19PLUS] min-llvm-version: 19 + +// This runs mir-opts to inline the standard library call, but doesn't run LLVM +// optimizations so it doesn't need to worry about them adding more flags. #![crate_type = "lib"] #![feature(unchecked_shifts)] @@ -17,13 +23,10 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 { // CHECK-LABEL: @unchecked_shl_unsigned_smaller #[no_mangle] pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16 - // CHECK-DAG: shl i16 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 + // CHECK: shl i16 %a, %[[TRUNC]] a.unchecked_shl(b) } @@ -31,7 +34,7 @@ pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { #[no_mangle] pub unsafe fn unchecked_shl_unsigned_bigger(a: u64, b: u32) -> u64 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64 + // CHECK: %[[EXT:.+]] = zext i32 %b to i64 // CHECK: shl i64 %a, %[[EXT]] a.unchecked_shl(b) } @@ -49,13 +52,10 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 { // CHECK-LABEL: @unchecked_shr_signed_smaller #[no_mangle] pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i32 %b, 16 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i32 %b to i16 - // CHECK-DAG: ashr i16 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16 + // CHECK: ashr i16 %a, %[[TRUNC]] a.unchecked_shr(b) } @@ -63,7 +63,7 @@ pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { #[no_mangle] pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i32 %b to i64 + // CHECK: %[[EXT:.+]] = zext i32 %b to i64 // CHECK: ashr i64 %a, %[[EXT]] a.unchecked_shr(b) } @@ -72,7 +72,7 @@ pub unsafe fn unchecked_shr_signed_bigger(a: i64, b: u32) -> i64 { #[no_mangle] pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128 + // CHECK: %[[EXT:.+]] = zext i8 %b to i128 // CHECK: lshr i128 %a, %[[EXT]] std::intrinsics::unchecked_shr(a, b) } @@ -81,7 +81,7 @@ pub unsafe fn unchecked_shr_u128_i8(a: u128, b: i8) -> u128 { #[no_mangle] pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 { // CHECK-NOT: assume - // CHECK: %[[EXT:.+]] = zext{{( nneg)?}} i8 %b to i128 + // CHECK: %[[EXT:.+]] = zext i8 %b to i128 // CHECK: shl i128 %a, %[[EXT]] std::intrinsics::unchecked_shl(a, b) } @@ -89,25 +89,19 @@ pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 { // CHECK-LABEL: @unchecked_shl_u8_i128 #[no_mangle] pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8 - // CHECK-DAG: shl i8 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8 + // CHECK: shl i8 %a, %[[TRUNC]] std::intrinsics::unchecked_shl(a, b) } // CHECK-LABEL: @unchecked_shr_i8_u128 #[no_mangle] pub unsafe fn unchecked_shr_i8_u128(a: i8, b: u128) -> i8 { - // This uses -DAG to avoid failing on irrelevant reorderings, - // like emitting the truncation earlier. - - // CHECK-DAG: %[[INRANGE:.+]] = icmp ult i128 %b, 8 - // CHECK-DAG: tail call void @llvm.assume(i1 %[[INRANGE]]) - // CHECK-DAG: %[[TRUNC:.+]] = trunc{{( nuw)?( nsw)?}} i128 %b to i8 - // CHECK-DAG: ashr i8 %a, %[[TRUNC]] + // CHECK-NOT: assume + // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8 + // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8 + // CHECK: ashr i8 %a, %[[TRUNC]] std::intrinsics::unchecked_shr(a, b) } diff --git a/tests/codegen/uninhabited-transparent-return-abi.rs b/tests/codegen/uninhabited-transparent-return-abi.rs new file mode 100644 index 0000000000000..6e8b1683163ef --- /dev/null +++ b/tests/codegen/uninhabited-transparent-return-abi.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -Copt-level=3 + +// See https://github.com/rust-lang/rust/issues/135802 + +#![crate_type = "lib"] + +enum Void {} + +// Should be ABI-compatible with T, but wasn't prior to the PR adding this test. +#[repr(transparent)] +struct NoReturn(T, Void); + +// Returned by invisible reference (in most ABIs) +#[allow(dead_code)] +struct Large(u64, u64, u64); + +extern "Rust" { + fn opaque() -> NoReturn; + fn opaque_with_arg(rsi: u32) -> NoReturn; +} + +// CHECK-LABEL: @test_uninhabited_ret_by_ref +#[no_mangle] +pub fn test_uninhabited_ret_by_ref() { + // CHECK: %_1 = alloca [24 x i8], align {{8|4}} + // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_1) + // CHECK-NEXT: call void @opaque(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_1) #2 + // CHECK-NEXT: unreachable + unsafe { + opaque(); + } +} + +// CHECK-LABEL: @test_uninhabited_ret_by_ref_with_arg +#[no_mangle] +pub fn test_uninhabited_ret_by_ref_with_arg(rsi: u32) { + // CHECK: %_2 = alloca [24 x i8], align {{8|4}} + // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %_2) + // CHECK-NEXT: call void @opaque_with_arg(ptr noalias nocapture noundef nonnull sret([24 x i8]) align {{8|4}} dereferenceable(24) %_2, i32 noundef %rsi) #2 + // CHECK-NEXT: unreachable + unsafe { + opaque_with_arg(rsi); + } +} diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs index 92d40d8ac14cb..28acc4de2f327 100644 --- a/tests/codegen/union-abi.rs +++ b/tests/codegen/union-abi.rs @@ -2,8 +2,11 @@ //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes // 32-bit x86 returns `f32` differently to avoid the x87 stack. // 32-bit systems will return 128bit values using a return area pointer. -//@ revisions: x86 bit32 bit64 -//@[x86] only-x86 +//@ revisions: x86-sse x86-nosse bit32 bit64 +//@[x86-sse] only-x86 +//@[x86-sse] only-rustc_abi-x86-sse2 +//@[x86-nosse] only-x86 +//@[x86-nosse] ignore-rustc_abi-x86-sse2 //@[bit32] ignore-x86 //@[bit32] only-32bit //@[bit64] ignore-x86 @@ -75,7 +78,8 @@ pub union UnionF32 { a: f32, } -// x86: define {{(dso_local )?}}i32 @test_UnionF32(float %_1) +// x86-sse: define {{(dso_local )?}}<4 x i8> @test_UnionF32(float %_1) +// x86-nosse: define {{(dso_local )?}}i32 @test_UnionF32(float %_1) // bit32: define {{(dso_local )?}}float @test_UnionF32(float %_1) // bit64: define {{(dso_local )?}}float @test_UnionF32(float %_1) #[no_mangle] @@ -88,7 +92,8 @@ pub union UnionF32F32 { b: f32, } -// x86: define {{(dso_local )?}}i32 @test_UnionF32F32(float %_1) +// x86-sse: define {{(dso_local )?}}<4 x i8> @test_UnionF32F32(float %_1) +// x86-nosse: define {{(dso_local )?}}i32 @test_UnionF32F32(float %_1) // bit32: define {{(dso_local )?}}float @test_UnionF32F32(float %_1) // bit64: define {{(dso_local )?}}float @test_UnionF32F32(float %_1) #[no_mangle] @@ -110,7 +115,8 @@ pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { pub union UnionU128 { a: u128, } -// x86: define {{(dso_local )?}}void @test_UnionU128({{.*}}sret([16 x i8]){{.*}}, i128 %_1) +// x86-sse: define {{(dso_local )?}}void @test_UnionU128({{.*}}sret([16 x i8]){{.*}}, i128 %_1) +// x86-nosse: define {{(dso_local )?}}void @test_UnionU128({{.*}}sret([16 x i8]){{.*}}, i128 %_1) // bit32: define {{(dso_local )?}}void @test_UnionU128({{.*}}sret([16 x i8]){{.*}}, i128 %_1) // bit64: define {{(dso_local )?}}i128 @test_UnionU128(i128 %_1) #[no_mangle] @@ -136,4 +142,4 @@ pub union UnionBool { pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } } -// CHECK: %_0 = trunc i8 %b to i1 +// CHECK: %_0 = trunc{{( nuw)?}} i8 %b to i1 diff --git a/tests/coverage/holes.cov-map b/tests/coverage/holes.cov-map index 3c740d80ea05a..3deacbc8e1287 100644 --- a/tests/coverage/holes.cov-map +++ b/tests/coverage/holes.cov-map @@ -1,52 +1,57 @@ Function name: ::_method (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 25, 09, 00, 1d] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 37, 9) to (start + 0, 29) +- Code(Zero) at (prev + 43, 9) to (start + 0, 29) Highest counter ID seen: (none) Function name: holes::main -Raw bytes (44): 0x[01, 01, 00, 08, 01, 08, 01, 06, 11, 01, 0f, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 01, 02] +Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 12, 01, 05, 05, 00, 12, 01, 07, 09, 00, 11, 01, 09, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 04, 05, 00, 12, 01, 04, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 0c, 0d, 01, 0f, 0e, 05, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 -Number of file 0 mappings: 8 -- Code(Counter(0)) at (prev + 8, 1) to (start + 6, 17) -- Code(Counter(0)) at (prev + 15, 5) to (start + 0, 18) +Number of file 0 mappings: 13 +- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 18) +- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 18) - Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18) - Code(Counter(0)) at (prev + 7, 5) to (start + 0, 18) - Code(Counter(0)) at (prev + 6, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18) - Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15) - Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15) -- Code(Counter(0)) at (prev + 10, 5) to (start + 1, 2) +- Code(Counter(0)) at (prev + 10, 5) to (start + 12, 13) +- Code(Counter(0)) at (prev + 15, 14) to (start + 5, 2) Highest counter ID seen: c0 Function name: holes::main::_unused_fn (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 17] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 25, 5) to (start + 0, 23) +- Code(Zero) at (prev + 31, 5) to (start + 0, 23) Highest counter ID seen: (none) Function name: holes::main::{closure#0} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 18, 9) to (start + 2, 10) +- Code(Zero) at (prev + 24, 9) to (start + 2, 10) Highest counter ID seen: (none) Function name: holes::main::{closure#1} (unused) -Raw bytes (9): 0x[01, 01, 00, 01, 00, 3d, 09, 02, 0a] +Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 -- Code(Zero) at (prev + 61, 9) to (start + 2, 10) +- Code(Zero) at (prev + 75, 9) to (start + 2, 10) Highest counter ID seen: (none) diff --git a/tests/coverage/holes.coverage b/tests/coverage/holes.coverage index 6e65435f7e3fd..1b45c12156ae7 100644 --- a/tests/coverage/holes.coverage +++ b/tests/coverage/holes.coverage @@ -7,10 +7,16 @@ LL| | LL| 1|fn main() { LL| 1| black_box(()); - LL| 1| - LL| 1| // Splitting this across multiple lines makes it easier to see where the - LL| 1| // coverage mapping regions begin and end. - LL| 1| #[rustfmt::skip] + LL| | + LL| | static MY_STATIC: () = (); + LL| | + LL| 1| black_box(()); + LL| | + LL| | const MY_CONST: () = (); + LL| | + LL| | // Splitting this across multiple lines makes it easier to see where the + LL| | // coverage mapping regions begin and end. + LL| | #[rustfmt::skip] LL| 1| let _closure = LL| | | LL| | _arg: (), @@ -39,6 +45,14 @@ LL| | LL| 1| black_box(()); LL| | + LL| | trait MyTrait {} + LL| | + LL| 1| black_box(()); + LL| | + LL| | impl MyTrait for MyStruct {} + LL| | + LL| 1| black_box(()); + LL| | LL| | macro_rules! _my_macro { LL| | () => {}; LL| | } @@ -64,5 +78,24 @@ LL| | ; LL| | LL| 1| black_box(()); + LL| 1| + LL| 1| // This tests the edge case of a const block nested inside an "anon const", + LL| 1| // such as the length of an array literal. Handling this case requires + LL| 1| // `nested_filter::OnlyBodies` or equivalent. + LL| 1| #[rustfmt::skip] + LL| 1| let _const_block_inside_anon_const = + LL| 1| [ + LL| 1| 0 + LL| 1| ; + LL| 1| 7 + LL| 1| + + LL| 1| const + LL| | { + LL| | 3 + LL| 1| } + LL| 1| ] + LL| 1| ; + LL| 1| + LL| 1| black_box(()); LL| 1|} diff --git a/tests/coverage/holes.rs b/tests/coverage/holes.rs index b3a71e759c830..7f6671772c323 100644 --- a/tests/coverage/holes.rs +++ b/tests/coverage/holes.rs @@ -8,6 +8,12 @@ use core::hint::black_box; fn main() { black_box(()); + static MY_STATIC: () = (); + + black_box(()); + + const MY_CONST: () = (); + // Splitting this across multiple lines makes it easier to see where the // coverage mapping regions begin and end. #[rustfmt::skip] @@ -39,6 +45,14 @@ fn main() { black_box(()); + trait MyTrait {} + + black_box(()); + + impl MyTrait for MyStruct {} + + black_box(()); + macro_rules! _my_macro { () => {}; } @@ -64,4 +78,23 @@ fn main() { ; black_box(()); + + // This tests the edge case of a const block nested inside an "anon const", + // such as the length of an array literal. Handling this case requires + // `nested_filter::OnlyBodies` or equivalent. + #[rustfmt::skip] + let _const_block_inside_anon_const = + [ + 0 + ; + 7 + + + const + { + 3 + } + ] + ; + + black_box(()); } diff --git a/tests/crashes/103899.rs b/tests/crashes/103899.rs deleted file mode 100644 index 39c2d72bd357c..0000000000000 --- a/tests/crashes/103899.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #103899 - -trait BaseWithAssoc { - type Assoc; -} - -trait WrapperWithAssoc { - type BaseAssoc: BaseWithAssoc; -} - -struct Wrapper { - inner: B, -} - -struct ProjectToBase { - data_type_h: T::Assoc, -} - -struct DoubleProject { - buffer: Wrapper>, -} - -fn trigger>() -> DoubleProject { - loop {} -} - -fn main() {} diff --git a/tests/crashes/105299.rs b/tests/crashes/105299.rs deleted file mode 100644 index 8e3aafa47bc9f..0000000000000 --- a/tests/crashes/105299.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ known-bug: #105299 - -pub trait Foo: Clone {} - -pub struct Bar<'a, T: Clone> { - pub cow: std::borrow::Cow<'a, [T]>, - - pub THIS_CAUSES_ICE: (), // #1 -} - -impl Bar<'_, T> -where - T: Clone, - [T]: Foo, -{ - pub fn MOVES_SELF(self) {} // #2 -} - -pub fn main() {} diff --git a/tests/crashes/111709-2.rs b/tests/crashes/111709-2.rs deleted file mode 100644 index 6c4fb9f28c7de..0000000000000 --- a/tests/crashes/111709-2.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #111709 -//@ edition: 2021 - -use core::arch::asm; - -extern "C" fn test() {} - -fn uwu() { - unsafe { - asm!( - "/* {0} */", - sym test::<&mut ()> - ); - } -} diff --git a/tests/crashes/111709.rs b/tests/crashes/111709.rs deleted file mode 100644 index eef375b8924b7..0000000000000 --- a/tests/crashes/111709.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ known-bug: #111709 -//@ edition:2021 - -use core::arch::asm; - -struct TrapFrame; - -unsafe extern "C" fn _rust_abi_shim1(arg: A, f: fn(A) -> R) -> R { - f(arg) -} - -unsafe extern "C" fn _start_trap() { - extern "Rust" { - fn interrupt(tf: &mut TrapFrame); - } - asm!( - " - la a1, {irq} - call {shim} - ", - shim = sym crate::_rust_abi_shim1::<&mut TrapFrame, ()>, - irq = sym interrupt, - options(noreturn) - ) -} diff --git a/tests/crashes/125957.rs b/tests/crashes/125957.rs deleted file mode 100644 index e3abe5262eb90..0000000000000 --- a/tests/crashes/125957.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: rust-lang/rust#125957 -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] -#![feature(associated_const_equality)] - -pub struct Equal(); - -pub enum ParseMode { - Raw, -} -pub trait Parse { - const PARSE_MODE: ParseMode; -} -pub trait RenderRaw: Parse {} - -trait GenericVec { - fn unwrap() -> dyn RenderRaw; -} - -fn main() {} diff --git a/tests/crashes/132330.rs b/tests/crashes/132330.rs deleted file mode 100644 index 3432685749d9d..0000000000000 --- a/tests/crashes/132330.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ known-bug: #132330 -//@compile-flags: -Znext-solver=globally - -trait Service { - type S; -} - -trait Framing { - type F; -} - -impl Framing for () { - type F = (); -} - -trait HttpService: Service {} - -type BoxService = Box>; - -fn build_server BoxService>(_: F) {} - -fn make_server() -> Box> { - unimplemented!() -} - -fn main() { - build_server(|| make_server()) -} diff --git a/tests/crashes/133597.rs b/tests/crashes/133597.rs deleted file mode 100644 index f716d5e7bc74f..0000000000000 --- a/tests/crashes/133597.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #133597 - -pub trait Foo2 { - fn boxed<'a: 'a>() -> impl Sized + FnOnce<()>; -} - -impl Foo2 for () {} - - -fn f() -> impl FnOnce<()> { || () } -fn main() { () = f(); } diff --git a/tests/crashes/96304.rs b/tests/crashes/96304.rs deleted file mode 100644 index 637012f45858f..0000000000000 --- a/tests/crashes/96304.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #96304 - -#![feature(asm_sym)] -core::arch::global_asm!("/* {} */", sym<&'static ()>::clone); - -pub fn main() {} diff --git a/tests/crashes/project-to-simd-array-field.rs b/tests/crashes/project-to-simd-array-field.rs new file mode 100644 index 0000000000000..6dc916c41dbd5 --- /dev/null +++ b/tests/crashes/project-to-simd-array-field.rs @@ -0,0 +1,33 @@ +//@ known-bug: #137108 +//@compile-flags: -Copt-level=3 + +// If you fix this, put it in the corresponding codegen test, +// not in a UI test like the readme says. + +#![crate_type = "lib"] + +#![feature(repr_simd, core_intrinsics)] + +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(simd)] +struct i32x3([i32; 3]); + +const _: () = { assert!(size_of::() == 16) }; + +#[inline(always)] +fn to_array3(a: i32x3) -> [i32; 3] { + a.0 +} + +// CHECK-LABEL: simd_add_self_then_return_array_packed( +// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], +// CHECK-SAME: ptr{{.+}}%a) +#[no_mangle] +pub fn simd_add_self_then_return_array_packed(a: i32x3) -> [i32; 3] { + // CHECK: %[[T1:.+]] = load <3 x i32>, ptr %a + // CHECK: %[[T2:.+]] = shl <3 x i32> %[[T1]], + // CHECK: store <3 x i32> %[[T2]], ptr %[[RET]] + let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; + to_array3(b) +} diff --git a/tests/debuginfo/empty-string.rs b/tests/debuginfo/empty-string.rs index 014465c27cabd..6cf61e177714d 100644 --- a/tests/debuginfo/empty-string.rs +++ b/tests/debuginfo/empty-string.rs @@ -17,7 +17,7 @@ // lldb-command:run // lldb-command:fr v empty_string -// lldb-check:[...] empty_string = "" { vec = size=0 } +// lldb-check:[...] empty_string = "" // lldb-command:fr v empty_str // lldb-check:[...] empty_str = "" diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs index d60a7b81944e7..06bc25dc5d59c 100644 --- a/tests/debuginfo/msvc-pretty-enums.rs +++ b/tests/debuginfo/msvc-pretty-enums.rs @@ -30,7 +30,7 @@ // lldb-check:(msvc_pretty_enums::CStyleEnum) j = High // lldb-command:v k -// lldb-check:(core::option::Option) k = { value = { 0 = "IAMA optional string!" { vec = size=21 { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 'o' [6] = 'p' [7] = 't' [8] = 'i' [9] = 'o' [10] = 'n' [11] = 'a' [12] = 'l' [13] = ' ' [14] = 's' [15] = 't' [16] = 'r' [17] = 'i' [18] = 'n' [19] = 'g' [20] = '!' } } } } +// lldb-check:(core::option::Option) k = { value = { 0 = "IAMA optional string!" { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 'o' [6] = 'p' [7] = 't' [8] = 'i' [9] = 'o' [10] = 'n' [11] = 'a' [12] = 'l' [13] = ' ' [14] = 's' [15] = 't' [16] = 'r' [17] = 'i' [18] = 'n' [19] = 'g' [20] = '!' } } } // lldb-command:v l // lldb-check:(core::result::Result) l = { value = { 0 = {} } } diff --git a/tests/debuginfo/pretty-std.rs b/tests/debuginfo/pretty-std.rs index d7c640a5bea3e..53835d41be24e 100644 --- a/tests/debuginfo/pretty-std.rs +++ b/tests/debuginfo/pretty-std.rs @@ -51,7 +51,8 @@ // lldb-check:[...] str_slice = "IAMA string slice!" { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 's' [6] = 't' [7] = 'r' [8] = 'i' [9] = 'n' [10] = 'g' [11] = ' ' [12] = 's' [13] = 'l' [14] = 'i' [15] = 'c' [16] = 'e' [17] = '!' } // lldb-command:v string -// lldb-check:[...] string = "IAMA string!" { vec = size=12 { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 's' [6] = 't' [7] = 'r' [8] = 'i' [9] = 'n' [10] = 'g' [11] = '!' } } +// lldb-check:[...] string = "IAMA string!" { [0] = 'I' [1] = 'A' [2] = 'M' [3] = 'A' [4] = ' ' [5] = 's' [6] = 't' [7] = 'r' [8] = 'i' [9] = 'n' [10] = 'g' [11] = '!' } + // lldb-command:v some // lldb-check:[...] some = Some(8) diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs index 543e74e174417..7d550408bec37 100644 --- a/tests/debuginfo/strings-and-strs.rs +++ b/tests/debuginfo/strings-and-strs.rs @@ -24,7 +24,7 @@ // === LLDB TESTS ================================================================================== // lldb-command:run // lldb-command:v plain_string -// lldb-check:(alloc::string::String) plain_string = "Hello" { vec = size=5 { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } } +// lldb-check:(alloc::string::String) plain_string = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } // lldb-command:v plain_str // lldb-check:(&str) plain_str = "Hello" { [0] = 'H' [1] = 'e' [2] = 'l' [3] = 'l' [4] = 'o' } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index 727efe4b0d95d..267a4c1cf6beb 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -47,6 +47,7 @@ + Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); ++ nop; StorageDead(_2); - _0 = move _1; + StorageLive(_12); @@ -61,6 +62,7 @@ + Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 8d0cd97f78661..8e5c403cd7e6b 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -47,6 +47,7 @@ + Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); ++ nop; StorageDead(_2); - _0 = move _1; + StorageLive(_12); @@ -61,6 +62,7 @@ + Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 6d1e2a72fdb73..96c5aadd85fd4 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -47,6 +47,7 @@ + Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); ++ nop; StorageDead(_2); - _0 = move _1; + StorageLive(_12); @@ -61,6 +62,7 @@ + Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index 4b1406d0d623b..d20e2e08eaafd 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -47,6 +47,7 @@ + Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); ++ nop; StorageDead(_2); - _0 = move _1; + StorageLive(_12); @@ -61,6 +62,7 @@ + Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); ++ nop; StorageDead(_1); return; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index b7a9b4a1fe01c..7ef532d222dc3 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,28 +4,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::iter::Enumerate>; - let mut _13: std::iter::Enumerate>; - let mut _21: std::option::Option<(usize, &T)>; - let mut _24: &impl Fn(usize, &T); - let mut _25: (usize, &T); - let _26: (); + let mut _11: std::ptr::NonNull; + let mut _12: *const T; + let mut _13: usize; + let mut _32: std::option::Option<(usize, &T)>; + let mut _35: &impl Fn(usize, &T); + let mut _36: (usize, &T); + let _37: (); scope 1 { - debug iter => _13; - let _22: usize; - let _23: &T; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _12; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; + debug ((iter: Enumerate>).1: usize) => _13; + let _33: usize; + let _34: &T; scope 2 { - debug i => _22; - debug x => _23; + debug i => _33; + debug x => _34; } scope 19 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _19: (usize, bool); - let mut _20: (usize, &T); + let mut _27: std::option::Option<&T>; + let mut _30: (usize, bool); + let mut _31: (usize, &T); scope 20 { - let _18: usize; + let _29: usize; scope 25 { } } @@ -40,11 +42,59 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 26 (inlined as Try>::branch) { - let mut _16: isize; - let _17: &T; + let _28: &T; scope 27 { } } + scope 29 (inlined as Iterator>::next) { + let _14: std::ptr::NonNull; + let _16: std::ptr::NonNull; + let mut _19: bool; + let mut _22: std::ptr::NonNull; + let mut _24: usize; + let _26: &T; + scope 30 { + let _15: *const T; + scope 31 { + let _23: usize; + scope 32 { + scope 35 (inlined core::num::::unchecked_sub) { + scope 36 (inlined core::ub_checks::check_language_ub) { + scope 37 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 38 (inlined without_provenance_mut::) { + } + } + scope 33 (inlined std::ptr::const_ptr::::addr) { + scope 34 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 39 (inlined as PartialEq>::eq) { + let mut _17: *mut T; + let mut _18: *mut T; + scope 40 (inlined NonNull::::as_ptr) { + } + scope 41 (inlined NonNull::::as_ptr) { + } + } + scope 42 (inlined NonNull::::add) { + let mut _20: *const T; + let mut _21: *const T; + scope 43 (inlined NonNull::::as_ptr) { + } + } + scope 44 (inlined NonNull::::as_ref::<'_>) { + let _25: *const T; + scope 45 (inlined NonNull::::as_ptr) { + } + scope 46 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -89,9 +139,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); StorageLive(_3); - StorageLive(_6); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -120,86 +168,150 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb3: { - StorageLive(_10); _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); StorageDead(_9); StorageDead(_4); - StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; - StorageDead(_11); + StorageLive(_11); + StorageLive(_12); StorageLive(_13); - _13 = copy _12; + _11 = copy _6; + _12 = copy _10; + _13 = const 0_usize; goto -> bb4; } bb4: { - StorageLive(_21); - StorageLive(_18); - StorageLive(_19); - StorageLive(_15); + StorageLive(_32); + StorageLive(_29); + StorageLive(_30); + StorageLive(_27); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_15); + StorageLive(_23); + StorageLive(_24); + StorageLive(_16); + StorageLive(_26); + _14 = copy _11; + _15 = copy _12; + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageDead(_14); - StorageLive(_16); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11]; + StorageLive(_19); + _16 = copy _15 as std::ptr::NonNull (Transmute); + StorageLive(_17); + _17 = copy _14 as *mut T (Transmute); + StorageLive(_18); + _18 = copy _16 as *mut T (Transmute); + _19 = Eq(move _17, move _18); + StorageDead(_18); + StorageDead(_17); + switchInt(move _19) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_16); - StorageDead(_15); StorageDead(_19); - StorageDead(_18); + StorageLive(_22); + StorageLive(_21); + StorageLive(_20); + _20 = copy _14 as *const T (Transmute); + _21 = Offset(move _20, const 1_usize); + StorageDead(_20); + _22 = NonNull:: { pointer: move _21 }; StorageDead(_21); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind unreachable]; + _11 = move _22; + StorageDead(_22); + goto -> bb13; } bb7: { - return; + StorageDead(_19); + StorageDead(_26); + StorageDead(_16); + StorageDead(_24); + StorageDead(_23); + StorageDead(_15); + StorageDead(_14); + goto -> bb10; } bb8: { - _17 = move ((_15 as Some).0: &T); - StorageDead(_16); - StorageDead(_15); - _18 = copy (_13.1: usize); - _19 = AddWithOverflow(copy (_13.1: usize), const 1_usize); - assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable]; + _23 = copy _15 as usize (Transmute); + switchInt(copy _23) -> [0: bb9, otherwise: bb12]; } bb9: { - (_13.1: usize) = move (_19.0: usize); - StorageLive(_20); - _20 = (copy _18, copy _17); - _21 = Option::<(usize, &T)>::Some(move _20); - StorageDead(_20); - StorageDead(_19); - StorageDead(_18); - _22 = copy (((_21 as Some).0: (usize, &T)).0: usize); - _23 = copy (((_21 as Some).0: (usize, &T)).1: &T); - StorageLive(_24); - _24 = &_2; - StorageLive(_25); - _25 = (copy _22, copy _23); - _26 = >::call(move _24, move _25) -> [return: bb10, unwind unreachable]; + StorageDead(_26); + StorageDead(_16); + StorageDead(_24); + StorageDead(_23); + StorageDead(_15); + StorageDead(_14); + goto -> bb10; } bb10: { + StorageDead(_27); + StorageDead(_30); + StorageDead(_29); + StorageDead(_32); + StorageDead(_11); + StorageDead(_12); + StorageDead(_13); + drop(_2) -> [return: bb11, unwind unreachable]; + } + + bb11: { + return; + } + + bb12: { + _24 = SubUnchecked(copy _23, const 1_usize); + _12 = copy _24 as *const T (Transmute); + goto -> bb13; + } + + bb13: { + StorageLive(_25); + _25 = copy _14 as *const T (Transmute); + _26 = &(*_25); StorageDead(_25); + _27 = Option::<&T>::Some(copy _26); + StorageDead(_26); + StorageDead(_16); StorageDead(_24); - StorageDead(_21); - goto -> bb4; + StorageDead(_23); + StorageDead(_15); + StorageDead(_14); + _28 = move ((_27 as Some).0: &T); + StorageDead(_27); + _29 = copy _13; + _30 = AddWithOverflow(copy _13, const 1_usize); + assert(!move (_30.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _13, const 1_usize) -> [success: bb14, unwind unreachable]; } - bb11: { - unreachable; + bb14: { + _13 = move (_30.0: usize); + StorageLive(_31); + _31 = (copy _29, copy _28); + _32 = Option::<(usize, &T)>::Some(move _31); + StorageDead(_31); + StorageDead(_30); + StorageDead(_29); + _33 = copy (((_32 as Some).0: (usize, &T)).0: usize); + _34 = copy (((_32 as Some).0: (usize, &T)).1: &T); + StorageLive(_35); + _35 = &_2; + StorageLive(_36); + _36 = (copy _33, copy _34); + _37 = >::call(move _35, move _36) -> [return: bb15, unwind unreachable]; + } + + bb15: { + StorageDead(_36); + StorageDead(_35); + StorageDead(_32); + goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index dc13bb23c310a..62787f3447cee 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,19 +4,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _11: std::ptr::NonNull; + let mut _12: *const T; + let mut _26: std::option::Option<&T>; + let mut _28: &impl Fn(&T); + let mut _29: (&T,); + let _30: (); scope 1 { - debug iter => _12; - let _16: &T; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; + let _27: &T; scope 2 { - debug x => _16; + debug x => _27; + } + scope 17 (inlined as Iterator>::next) { + let _13: std::ptr::NonNull; + let _15: std::ptr::NonNull; + let mut _18: bool; + let mut _21: std::ptr::NonNull; + let mut _23: usize; + let _25: &T; + scope 18 { + let _14: *const T; + scope 19 { + let _22: usize; + scope 20 { + scope 23 (inlined core::num::::unchecked_sub) { + scope 24 (inlined core::ub_checks::check_language_ub) { + scope 25 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 26 (inlined without_provenance_mut::) { + } + } + scope 21 (inlined std::ptr::const_ptr::::addr) { + scope 22 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 27 (inlined as PartialEq>::eq) { + let mut _16: *mut T; + let mut _17: *mut T; + scope 28 (inlined NonNull::::as_ptr) { + } + scope 29 (inlined NonNull::::as_ptr) { + } + } + scope 30 (inlined NonNull::::add) { + let mut _19: *const T; + let mut _20: *const T; + scope 31 (inlined NonNull::::as_ptr) { + } + } + scope 32 (inlined NonNull::::as_ref::<'_>) { + let _24: *const T; + scope 33 (inlined NonNull::::as_ptr) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -58,7 +107,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_6); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -87,57 +135,125 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); StorageDead(_9); StorageDead(_4); - StorageDead(_6); StorageDead(_3); + StorageLive(_11); StorageLive(_12); - _12 = copy _11; + _11 = copy _6; + _12 = copy _10; goto -> bb4; } bb4: { + StorageLive(_26); + StorageLive(_13); StorageLive(_14); - _13 = &mut _12; - _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; + StorageLive(_22); + StorageLive(_23); + StorageLive(_15); + StorageLive(_25); + _13 = copy _11; + _14 = copy _12; + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_18); + _15 = copy _14 as std::ptr::NonNull (Transmute); + StorageLive(_16); + _16 = copy _13 as *mut T (Transmute); + StorageLive(_17); + _17 = copy _15 as *mut T (Transmute); + _18 = Eq(move _16, move _17); + StorageDead(_17); + StorageDead(_16); + switchInt(move _18) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_14); - StorageDead(_12); - drop(_2) -> [return: bb7, unwind unreachable]; + StorageDead(_18); + StorageLive(_21); + StorageLive(_20); + StorageLive(_19); + _19 = copy _13 as *const T (Transmute); + _20 = Offset(move _19, const 1_usize); + StorageDead(_19); + _21 = NonNull:: { pointer: move _20 }; + StorageDead(_20); + _11 = move _21; + StorageDead(_21); + goto -> bb13; } bb7: { - return; + StorageDead(_18); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); + StorageDead(_14); + StorageDead(_13); + goto -> bb10; } bb8: { - _16 = copy ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; + _22 = copy _14 as usize (Transmute); + switchInt(copy _22) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_18); - StorageDead(_17); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); StorageDead(_14); - goto -> bb4; + StorageDead(_13); + goto -> bb10; } bb10: { - unreachable; + StorageDead(_26); + StorageDead(_11); + StorageDead(_12); + drop(_2) -> [return: bb11, unwind unreachable]; + } + + bb11: { + return; + } + + bb12: { + _23 = SubUnchecked(copy _22, const 1_usize); + _12 = copy _23 as *const T (Transmute); + goto -> bb13; + } + + bb13: { + StorageLive(_24); + _24 = copy _13 as *const T (Transmute); + _25 = &(*_24); + StorageDead(_24); + _26 = Option::<&T>::Some(copy _25); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); + StorageDead(_14); + StorageDead(_13); + _27 = copy ((_26 as Some).0: &T); + StorageLive(_28); + _28 = &_2; + StorageLive(_29); + _29 = (copy _27,); + _30 = >::call(move _28, move _29) -> [return: bb14, unwind unreachable]; + } + + bb14: { + StorageDead(_29); + StorageDead(_28); + StorageDead(_26); + goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 3f1e0e0f746b4..e5478e2791888 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,19 +4,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; - let mut _12: std::slice::Iter<'_, T>; - let mut _13: &mut std::slice::Iter<'_, T>; - let mut _14: std::option::Option<&T>; - let mut _15: isize; - let mut _17: &impl Fn(&T); - let mut _18: (&T,); - let _19: (); + let mut _11: std::ptr::NonNull; + let mut _12: *const T; + let mut _26: std::option::Option<&T>; + let mut _28: &impl Fn(&T); + let mut _29: (&T,); + let _30: (); scope 1 { - debug iter => _12; - let _16: &T; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; + let _27: &T; scope 2 { - debug x => _16; + debug x => _27; + } + scope 17 (inlined as Iterator>::next) { + let _13: std::ptr::NonNull; + let _15: std::ptr::NonNull; + let mut _18: bool; + let mut _21: std::ptr::NonNull; + let mut _23: usize; + let _25: &T; + scope 18 { + let _14: *const T; + scope 19 { + let _22: usize; + scope 20 { + scope 23 (inlined core::num::::unchecked_sub) { + scope 24 (inlined core::ub_checks::check_language_ub) { + scope 25 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 26 (inlined without_provenance_mut::) { + } + } + scope 21 (inlined std::ptr::const_ptr::::addr) { + scope 22 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 27 (inlined as PartialEq>::eq) { + let mut _16: *mut T; + let mut _17: *mut T; + scope 28 (inlined NonNull::::as_ptr) { + } + scope 29 (inlined NonNull::::as_ptr) { + } + } + scope 30 (inlined NonNull::::add) { + let mut _19: *const T; + let mut _20: *const T; + scope 31 (inlined NonNull::::as_ptr) { + } + } + scope 32 (inlined NonNull::::as_ref::<'_>) { + let _24: *const T; + scope 33 (inlined NonNull::::as_ptr) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -58,7 +107,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { bb0: { StorageLive(_3); - StorageLive(_6); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -87,65 +135,133 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); StorageDead(_9); StorageDead(_4); - StorageDead(_6); StorageDead(_3); + StorageLive(_11); StorageLive(_12); - _12 = copy _11; + _11 = copy _6; + _12 = copy _10; goto -> bb4; } bb4: { + StorageLive(_26); + StorageLive(_13); StorageLive(_14); - _13 = &mut _12; - _14 = as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; + StorageLive(_22); + StorageLive(_23); + StorageLive(_15); + StorageLive(_25); + _13 = copy _11; + _14 = copy _12; + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - _15 = discriminant(_14); - switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_18); + _15 = copy _14 as std::ptr::NonNull (Transmute); + StorageLive(_16); + _16 = copy _13 as *mut T (Transmute); + StorageLive(_17); + _17 = copy _15 as *mut T (Transmute); + _18 = Eq(move _16, move _17); + StorageDead(_17); + StorageDead(_16); + switchInt(move _18) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_14); - StorageDead(_12); - drop(_2) -> [return: bb7, unwind continue]; + StorageDead(_18); + StorageLive(_21); + StorageLive(_20); + StorageLive(_19); + _19 = copy _13 as *const T (Transmute); + _20 = Offset(move _19, const 1_usize); + StorageDead(_19); + _21 = NonNull:: { pointer: move _20 }; + StorageDead(_20); + _11 = move _21; + StorageDead(_21); + goto -> bb13; } bb7: { - return; + StorageDead(_18); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); + StorageDead(_14); + StorageDead(_13); + goto -> bb10; } bb8: { - _16 = copy ((_14 as Some).0: &T); - StorageLive(_17); - _17 = &_2; - StorageLive(_18); - _18 = (copy _16,); - _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; + _22 = copy _14 as usize (Transmute); + switchInt(copy _22) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_18); - StorageDead(_17); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); StorageDead(_14); - goto -> bb4; + StorageDead(_13); + goto -> bb10; } bb10: { - unreachable; + StorageDead(_26); + StorageDead(_11); + StorageDead(_12); + drop(_2) -> [return: bb11, unwind continue]; + } + + bb11: { + return; + } + + bb12: { + _23 = SubUnchecked(copy _22, const 1_usize); + _12 = copy _23 as *const T (Transmute); + goto -> bb13; + } + + bb13: { + StorageLive(_24); + _24 = copy _13 as *const T (Transmute); + _25 = &(*_24); + StorageDead(_24); + _26 = Option::<&T>::Some(copy _25); + StorageDead(_25); + StorageDead(_15); + StorageDead(_23); + StorageDead(_22); + StorageDead(_14); + StorageDead(_13); + _27 = copy ((_26 as Some).0: &T); + StorageLive(_28); + _28 = &_2; + StorageLive(_29); + _29 = (copy _27,); + _30 = >::call(move _28, move _29) -> [return: bb14, unwind: bb15]; + } + + bb14: { + StorageDead(_29); + StorageDead(_28); + StorageDead(_26); + goto -> bb4; } - bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + bb15 (cleanup): { + drop(_2) -> [return: bb16, unwind terminate(cleanup)]; } - bb12 (cleanup): { + bb16 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir index 8edac638ccdd6..b6df2300efb1f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir @@ -3,12 +3,134 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { debug it => _1; let mut _0: std::option::Option<&T>; + scope 1 (inlined as Iterator>::next) { + let _2: std::ptr::NonNull; + let _4: std::ptr::NonNull; + let mut _7: bool; + let mut _10: std::ptr::NonNull; + let mut _12: usize; + let _14: &T; + scope 2 { + let _3: *const T; + scope 3 { + let _11: usize; + scope 4 { + scope 7 (inlined core::num::::unchecked_sub) { + scope 8 (inlined core::ub_checks::check_language_ub) { + scope 9 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 10 (inlined without_provenance_mut::) { + } + } + scope 5 (inlined std::ptr::const_ptr::::addr) { + scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 11 (inlined as PartialEq>::eq) { + let mut _5: *mut T; + let mut _6: *mut T; + scope 12 (inlined NonNull::::as_ptr) { + } + scope 13 (inlined NonNull::::as_ptr) { + } + } + scope 14 (inlined NonNull::::add) { + let mut _8: *const T; + let mut _9: *const T; + scope 15 (inlined NonNull::::as_ptr) { + } + } + scope 16 (inlined NonNull::::as_ref::<'_>) { + let _13: *const T; + scope 17 (inlined NonNull::::as_ptr) { + } + scope 18 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } + } bb0: { - _0 = as Iterator>::next(move _1) -> [return: bb1, unwind unreachable]; + StorageLive(_2); + StorageLive(_3); + StorageLive(_11); + StorageLive(_12); + StorageLive(_4); + StorageLive(_14); + _2 = copy ((*_1).0: std::ptr::NonNull); + _3 = copy ((*_1).1: *const T); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; } bb1: { + StorageLive(_7); + _4 = copy _3 as std::ptr::NonNull (Transmute); + StorageLive(_5); + _5 = copy _2 as *mut T (Transmute); + StorageLive(_6); + _6 = copy _4 as *mut T (Transmute); + _7 = Eq(move _5, move _6); + StorageDead(_6); + StorageDead(_5); + switchInt(move _7) -> [0: bb2, otherwise: bb3]; + } + + bb2: { + StorageDead(_7); + StorageLive(_10); + StorageLive(_9); + StorageLive(_8); + _8 = copy _2 as *const T (Transmute); + _9 = Offset(move _8, const 1_usize); + StorageDead(_8); + _10 = NonNull:: { pointer: move _9 }; + StorageDead(_9); + ((*_1).0: std::ptr::NonNull) = move _10; + StorageDead(_10); + goto -> bb7; + } + + bb3: { + _0 = const {transmute(0x0000000000000000): Option<&T>}; + StorageDead(_7); + goto -> bb8; + } + + bb4: { + _11 = copy _3 as usize (Transmute); + switchInt(copy _11) -> [0: bb5, otherwise: bb6]; + } + + bb5: { + _0 = const {transmute(0x0000000000000000): Option<&T>}; + goto -> bb8; + } + + bb6: { + _12 = SubUnchecked(copy _11, const 1_usize); + ((*_1).1: *const T) = copy _12 as *const T (Transmute); + goto -> bb7; + } + + bb7: { + StorageLive(_13); + _13 = copy _2 as *const T (Transmute); + _14 = &(*_13); + StorageDead(_13); + _0 = Option::<&T>::Some(copy _14); + goto -> bb8; + } + + bb8: { + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir index fdde07173437b..b6df2300efb1f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir @@ -3,12 +3,134 @@ fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { debug it => _1; let mut _0: std::option::Option<&T>; + scope 1 (inlined as Iterator>::next) { + let _2: std::ptr::NonNull; + let _4: std::ptr::NonNull; + let mut _7: bool; + let mut _10: std::ptr::NonNull; + let mut _12: usize; + let _14: &T; + scope 2 { + let _3: *const T; + scope 3 { + let _11: usize; + scope 4 { + scope 7 (inlined core::num::::unchecked_sub) { + scope 8 (inlined core::ub_checks::check_language_ub) { + scope 9 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 10 (inlined without_provenance_mut::) { + } + } + scope 5 (inlined std::ptr::const_ptr::::addr) { + scope 6 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + scope 11 (inlined as PartialEq>::eq) { + let mut _5: *mut T; + let mut _6: *mut T; + scope 12 (inlined NonNull::::as_ptr) { + } + scope 13 (inlined NonNull::::as_ptr) { + } + } + scope 14 (inlined NonNull::::add) { + let mut _8: *const T; + let mut _9: *const T; + scope 15 (inlined NonNull::::as_ptr) { + } + } + scope 16 (inlined NonNull::::as_ref::<'_>) { + let _13: *const T; + scope 17 (inlined NonNull::::as_ptr) { + } + scope 18 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } + } bb0: { - _0 = as Iterator>::next(move _1) -> [return: bb1, unwind continue]; + StorageLive(_2); + StorageLive(_3); + StorageLive(_11); + StorageLive(_12); + StorageLive(_4); + StorageLive(_14); + _2 = copy ((*_1).0: std::ptr::NonNull); + _3 = copy ((*_1).1: *const T); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb4]; } bb1: { + StorageLive(_7); + _4 = copy _3 as std::ptr::NonNull (Transmute); + StorageLive(_5); + _5 = copy _2 as *mut T (Transmute); + StorageLive(_6); + _6 = copy _4 as *mut T (Transmute); + _7 = Eq(move _5, move _6); + StorageDead(_6); + StorageDead(_5); + switchInt(move _7) -> [0: bb2, otherwise: bb3]; + } + + bb2: { + StorageDead(_7); + StorageLive(_10); + StorageLive(_9); + StorageLive(_8); + _8 = copy _2 as *const T (Transmute); + _9 = Offset(move _8, const 1_usize); + StorageDead(_8); + _10 = NonNull:: { pointer: move _9 }; + StorageDead(_9); + ((*_1).0: std::ptr::NonNull) = move _10; + StorageDead(_10); + goto -> bb7; + } + + bb3: { + _0 = const {transmute(0x0000000000000000): Option<&T>}; + StorageDead(_7); + goto -> bb8; + } + + bb4: { + _11 = copy _3 as usize (Transmute); + switchInt(copy _11) -> [0: bb5, otherwise: bb6]; + } + + bb5: { + _0 = const {transmute(0x0000000000000000): Option<&T>}; + goto -> bb8; + } + + bb6: { + _12 = SubUnchecked(copy _11, const 1_usize); + ((*_1).1: *const T) = copy _12 as *const T (Transmute); + goto -> bb7; + } + + bb7: { + StorageLive(_13); + _13 = copy _2 as *const T (Transmute); + _14 = &(*_13); + StorageDead(_13); + _0 = Option::<&T>::Some(copy _14); + goto -> bb8; + } + + bb8: { + StorageDead(_14); + StorageDead(_4); + StorageDead(_12); + StorageDead(_11); + StorageDead(_3); + StorageDead(_2); return; } } diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index de64b724eed2d..da314f26ca782 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -22,7 +22,12 @@ fn main() { .input("avr-rjmp-offsets.rs") .opt_level("s") .panic("abort") - .target("avr-unknown-gnu-atmega328") + .target("avr-none") + // rust-lld has some troubles understanding the -mmcu flag, so for the + // time being let's tell rustc to emit binary that's compatible with the + // target CPU that lld defaults to, i.e. just `avr` (that's simply the + // minimal common instruction set across all AVRs) + .target_cpu("avr") // normally one links with `avr-gcc`, but this is not available in CI, // hence this test diverges from the default behavior to enable linking // at all, which is necessary for the test (to resolve the labels). To @@ -49,6 +54,7 @@ fn main() { // of the Rust compiler did produce a label `rjmp .-4` (misses the first // instruction in the loop). assert!(disassembly.contains("
"), "no main function in output"); + disassembly .trim() .lines() diff --git a/tests/run-make/rustc-crates-on-stable/rmake.rs b/tests/run-make/rustc-crates-on-stable/rmake.rs index 9fbc675cc9a3e..cbc1f24b8c16e 100644 --- a/tests/run-make/rustc-crates-on-stable/rmake.rs +++ b/tests/run-make/rustc-crates-on-stable/rmake.rs @@ -35,6 +35,8 @@ fn main() { "rustc_abi", "-p", "rustc_parse_format", + "-p", + "rustc_hashes", ]) .run(); } diff --git a/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml b/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml new file mode 100644 index 0000000000000..f09f09713514d --- /dev/null +++ b/tests/rustdoc-gui/sidebar-foreign-impl-sort.goml @@ -0,0 +1,15 @@ +// Checks sidebar resizing close the Settings popover +go-to: "file://" + |DOC_PATH| + "/test_docs/SidebarSort/trait.Sort.html#foreign-impls" + +// Check that the sidebar contains the expected foreign implementations +assert-text: (".sidebar-elems section ul > li:nth-child(1)", "&'a str") +assert-text: (".sidebar-elems section ul > li:nth-child(2)", "AtomicBool") +assert-text: (".sidebar-elems section ul > li:nth-child(3)", "AtomicU8") +assert-text: (".sidebar-elems section ul > li:nth-child(4)", "AtomicU16") +assert-text: (".sidebar-elems section ul > li:nth-child(5)", "AtomicU32") +assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Cell") +assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Cell") +assert-text: (".sidebar-elems section ul > li:nth-child(8)", "u8") +assert-text: (".sidebar-elems section ul > li:nth-child(9)", "u16") +assert-text: (".sidebar-elems section ul > li:nth-child(10)", "u32") +assert-text: (".sidebar-elems section ul > li:nth-child(11)", "usize") diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index 1a9ffbe889851..f9c20ab22b89d 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -713,3 +713,21 @@ pub trait ItemsTrait { /// blablala fn bar(); } + +pub mod SidebarSort { + use std::cell::Cell; + use std::sync::atomic::*; + pub trait Sort {} + + impl Sort for u32 {} + impl Sort for u8 {} + impl Sort for u16 {} + impl Sort for usize {} + impl Sort for AtomicU32 {} + impl Sort for AtomicU16 {} + impl Sort for AtomicU8 {} + impl Sort for AtomicBool {} + impl Sort for Cell {} + impl Sort for Cell {} + impl<'a> Sort for &'a str {} +} diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout index ca6e77502640e..13e142df8370d 100644 --- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.edition2015.stdout @@ -5,7 +5,7 @@ test $DIR/relative-path-include-bytes-132203.rs - (line 18) ... FAILED failures: ---- $DIR/relative-path-include-bytes-132203.rs - (line 18) stdout ---- -error: couldn't read `$DIR/relative-dir-empty-file`: No such file or directory (os error 2) +error: couldn't read `$DIR/relative-dir-empty-file`: $FILE_NOT_FOUND_MSG (os error 2) --> $DIR/relative-path-include-bytes-132203.rs:19:9 | LL | let x = include_bytes!("relative-dir-empty-file"); diff --git a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs index 6fddaa49faced..ceacd69a5fd52 100644 --- a/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs +++ b/tests/rustdoc-ui/doctest/relative-path-include-bytes-132203.rs @@ -1,4 +1,3 @@ -//@ ignore-windows different error message //@ revisions: edition2015 edition2024 //@[edition2015]edition:2015 //@[edition2015]check-fail @@ -7,8 +6,9 @@ //@[edition2024]edition:2024 //@[edition2024]check-pass //@[edition2024]compile-flags:--test --test-args=--test-threads=1 -//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "tests.rustdoc-ui.doctest." -> "$$DIR/" //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "`: .* \(os error 2\)" -> "`: $$FILE_NOT_FOUND_MSG (os error 2)" // https://github.com/rust-lang/rust/issues/132203 // This version, because it's edition2024, passes thanks to the new diff --git a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs index e1f19e7e01736..d7f4e587d5efd 100644 --- a/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs +++ b/tests/rustdoc/anchor-id-duplicate-method-name-25001.rs @@ -24,14 +24,14 @@ impl Foo { } impl Bar for Foo { - // @has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T' + //@ has - '//*[@id="associatedtype.Item"]//h4[@class="code-header"]' 'type Item = T' type Item=T; //@ has - '//*[@id="method.quux"]//h4[@class="code-header"]' 'fn quux(self)' fn quux(self) {} } impl<'a, T> Bar for &'a Foo { - // @has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T" + //@ has - '//*[@id="associatedtype.Item-1"]//h4[@class="code-header"]' "type Item = &'a T" type Item=&'a T; //@ has - '//*[@id="method.quux-1"]//h4[@class="code-header"]' 'fn quux(self)' diff --git a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html index b20e59866dac6..64c4d5fb3e3b9 100644 --- a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html +++ b/tests/rustdoc/extremely_long_typename.extremely_long_typename.html @@ -1 +1 @@ -
  • \ No newline at end of file +
    CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer
    \ No newline at end of file diff --git a/tests/rustdoc/extremely_long_typename.rs b/tests/rustdoc/extremely_long_typename.rs index 212afe2d11033..a87c61e38bd86 100644 --- a/tests/rustdoc/extremely_long_typename.rs +++ b/tests/rustdoc/extremely_long_typename.rs @@ -3,5 +3,5 @@ // the item table has it line wrapped. // There should be some reasonably-placed `` tags in the snapshot file. -// @snapshot extremely_long_typename "extremely_long_typename/index.html" '//ul[@class="item-table"]/li' +//@ snapshot extremely_long_typename "extremely_long_typename/index.html" '//dl[@class="item-table"]/dt' pub struct CreateSubscriptionPaymentSettingsPaymentMethodOptionsCustomerBalanceBankTransferEuBankTransfer; diff --git a/tests/rustdoc/unsafe-extern-blocks.rs b/tests/rustdoc/unsafe-extern-blocks.rs index 829095f300f20..9a4e292dc834b 100644 --- a/tests/rustdoc/unsafe-extern-blocks.rs +++ b/tests/rustdoc/unsafe-extern-blocks.rs @@ -2,28 +2,28 @@ #![crate_name = "foo"] -// @has 'foo/index.html' +//@ has 'foo/index.html' // First we check that both the static and the function have a "sup" element // to tell they're unsafe. -// @count - '//ul[@class="item-table"]//sup[@title="unsafe static"]' 1 -// @has - '//ul[@class="item-table"]//sup[@title="unsafe static"]' '⚠' -// @count - '//ul[@class="item-table"]//sup[@title="unsafe function"]' 1 -// @has - '//ul[@class="item-table"]//sup[@title="unsafe function"]' '⚠' +//@ count - '//dl[@class="item-table"]//sup[@title="unsafe static"]' 1 +//@ has - '//dl[@class="item-table"]//sup[@title="unsafe static"]' '⚠' +//@ count - '//dl[@class="item-table"]//sup[@title="unsafe function"]' 1 +//@ has - '//dl[@class="item-table"]//sup[@title="unsafe function"]' '⚠' unsafe extern "C" { - // @has 'foo/static.FOO.html' - // @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32' + //@ has 'foo/static.FOO.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32' pub safe static FOO: i32; - // @has 'foo/static.BAR.html' - // @has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32' + //@ has 'foo/static.BAR.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32' pub static BAR: i32; - // @has 'foo/fn.foo.html' - // @has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()' + //@ has 'foo/fn.foo.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()' pub safe fn foo(); - // @has 'foo/fn.bar.html' - // @has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()' + //@ has 'foo/fn.bar.html' + //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()' pub fn bar(); } diff --git a/tests/ui-fulldeps/missing-rustc-driver-error.stderr b/tests/ui-fulldeps/missing-rustc-driver-error.stderr index d7bf27d634913..faad62645222d 100644 --- a/tests/ui-fulldeps/missing-rustc-driver-error.stderr +++ b/tests/ui-fulldeps/missing-rustc-driver-error.stderr @@ -2,5 +2,13 @@ error: crate `rustc_serialize` required to be available in rlib format, but was | = help: try adding `extern crate rustc_driver;` at the top level of this crate +error: crate `rustc_hashes` required to be available in rlib format, but was not found in this form + | + = help: try adding `extern crate rustc_driver;` at the top level of this crate + +error: crate `rustc_stable_hash` required to be available in rlib format, but was not found in this form + | + = help: try adding `extern crate rustc_driver;` at the top level of this crate + error: aborting due to NUMBER previous errors diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index d9742612bcfd2..57cc48aa9cf47 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -60,7 +62,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 0e98b5f806bc2..6738017673003 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -71,7 +73,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.rs b/tests/ui/abi/c-zst.rs index 6b299ffadb7b7..c1dac41f876a2 100644 --- a/tests/ui/abi/c-zst.rs +++ b/tests/ui/abi/c-zst.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ normalize-stderr: "(abi|pref|unadjusted_abi_align): Align\([1-8] bytes\)" -> "$1: $$SOME_ALIGN" /*! C doesn't have zero-sized types... except it does. @@ -52,12 +53,12 @@ extern "C" fn(i32, (), i32); //@[x86_64-pc-windows-gnu] needs-llvm-components: x86 -#![feature(lang_items, no_core, rustc_attrs)] +#![feature(no_core, rustc_attrs)] #![no_core] #![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} +extern crate minicore; +use minicore::*; #[rustc_abi(debug)] extern "C" fn pass_zst(_: ()) {} //~ ERROR: fn_abi diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 0e98b5f806bc2..6738017673003 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -71,7 +73,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 0e98b5f806bc2..6738017673003 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -71,7 +73,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index d9742612bcfd2..57cc48aa9cf47 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -60,7 +62,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 0e98b5f806bc2..6738017673003 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -56,6 +57,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -71,7 +73,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:63:1 + --> $DIR/c-zst.rs:64:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index e550e5bfcf3c3..5f73ff7d6bd58 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -20,6 +20,7 @@ error: fn_abi_of(test) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -67,6 +68,7 @@ error: fn_abi_of(test) = FnAbi { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -125,6 +127,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -163,6 +166,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -213,6 +217,7 @@ error: fn_abi_of(test_generic) = FnAbi { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -248,6 +253,7 @@ error: fn_abi_of(test_generic) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -297,6 +303,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -332,6 +339,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -369,6 +377,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -404,6 +413,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -444,6 +454,7 @@ error: ABIs are not compatible count: 32, }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -483,6 +494,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -517,6 +529,7 @@ error: ABIs are not compatible count: 32, }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -556,6 +569,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -598,6 +612,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -633,6 +648,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -670,6 +686,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -705,6 +722,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -748,6 +766,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -783,6 +802,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -820,6 +840,7 @@ error: ABIs are not compatible ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -855,6 +876,7 @@ error: ABIs are not compatible memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -923,6 +945,7 @@ error: fn_abi_of(assoc_test) = FnAbi { valid_range: $NON_NULL, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -960,6 +983,7 @@ error: fn_abi_of(assoc_test) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/simd-abi-checks.rs b/tests/ui/abi/simd-abi-checks-avx.rs similarity index 100% rename from tests/ui/simd-abi-checks.rs rename to tests/ui/abi/simd-abi-checks-avx.rs diff --git a/tests/ui/simd-abi-checks.stderr b/tests/ui/abi/simd-abi-checks-avx.stderr similarity index 94% rename from tests/ui/simd-abi-checks.stderr rename to tests/ui/abi/simd-abi-checks-avx.stderr index a849993a1663b..0dddc7dfa1c1b 100644 --- a/tests/ui/simd-abi-checks.stderr +++ b/tests/ui/abi/simd-abi-checks-avx.stderr @@ -1,5 +1,5 @@ warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:64:11 + --> $DIR/simd-abi-checks-avx.rs:64:11 | LL | f(g()); | ^^^ function called here @@ -10,7 +10,7 @@ LL | f(g()); = note: `#[warn(abi_unsupported_vector_types)]` on by default warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:64:9 + --> $DIR/simd-abi-checks-avx.rs:64:9 | LL | f(g()); | ^^^^^^ function called here @@ -20,7 +20,7 @@ LL | f(g()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:72:14 + --> $DIR/simd-abi-checks-avx.rs:72:14 | LL | gavx(favx()); | ^^^^^^ function called here @@ -30,7 +30,7 @@ LL | gavx(favx()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:72:9 + --> $DIR/simd-abi-checks-avx.rs:72:9 | LL | gavx(favx()); | ^^^^^^^^^^^^ function called here @@ -40,7 +40,7 @@ LL | gavx(favx()); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:84:19 + --> $DIR/simd-abi-checks-avx.rs:84:19 | LL | w(Wrapper(g())); | ^^^ function called here @@ -50,7 +50,7 @@ LL | w(Wrapper(g())); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:84:9 + --> $DIR/simd-abi-checks-avx.rs:84:9 | LL | w(Wrapper(g())); | ^^^^^^^^^^^^^^^ function called here @@ -60,7 +60,7 @@ LL | w(Wrapper(g())); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:100:9 + --> $DIR/simd-abi-checks-avx.rs:100:9 | LL | some_extern(); | ^^^^^^^^^^^^^ function called here @@ -70,7 +70,7 @@ LL | some_extern(); = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function definition uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:27:1 + --> $DIR/simd-abi-checks-avx.rs:27:1 | LL | unsafe extern "C" fn g() -> __m256 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -80,7 +80,7 @@ LL | unsafe extern "C" fn g() -> __m256 { = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function definition uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:21:1 + --> $DIR/simd-abi-checks-avx.rs:21:1 | LL | unsafe extern "C" fn f(_: __m256) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -90,7 +90,7 @@ LL | unsafe extern "C" fn f(_: __m256) { = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:15:1 + --> $DIR/simd-abi-checks-avx.rs:15:1 | LL | unsafe extern "C" fn w(_: Wrapper) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -100,7 +100,7 @@ LL | unsafe extern "C" fn w(_: Wrapper) { = help: consider enabling it globally (`-C target-feature=+avx`) or locally (`#[target_feature(enable="avx")]`) warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:57:8 + --> $DIR/simd-abi-checks-avx.rs:57:8 | LL | || g() | ^^^ function called here @@ -113,7 +113,7 @@ warning: 11 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:64:11 + --> $DIR/simd-abi-checks-avx.rs:64:11 | LL | f(g()); | ^^^ function called here @@ -125,7 +125,7 @@ LL | f(g()); Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:64:9 + --> $DIR/simd-abi-checks-avx.rs:64:9 | LL | f(g()); | ^^^^^^ function called here @@ -137,7 +137,7 @@ LL | f(g()); Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:72:14 + --> $DIR/simd-abi-checks-avx.rs:72:14 | LL | gavx(favx()); | ^^^^^^ function called here @@ -149,7 +149,7 @@ LL | gavx(favx()); Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:72:9 + --> $DIR/simd-abi-checks-avx.rs:72:9 | LL | gavx(favx()); | ^^^^^^^^^^^^ function called here @@ -161,7 +161,7 @@ LL | gavx(favx()); Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:84:19 + --> $DIR/simd-abi-checks-avx.rs:84:19 | LL | w(Wrapper(g())); | ^^^ function called here @@ -173,7 +173,7 @@ LL | w(Wrapper(g())); Future breakage diagnostic: warning: this function call uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:84:9 + --> $DIR/simd-abi-checks-avx.rs:84:9 | LL | w(Wrapper(g())); | ^^^^^^^^^^^^^^^ function called here @@ -185,7 +185,7 @@ LL | w(Wrapper(g())); Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:100:9 + --> $DIR/simd-abi-checks-avx.rs:100:9 | LL | some_extern(); | ^^^^^^^^^^^^^ function called here @@ -197,7 +197,7 @@ LL | some_extern(); Future breakage diagnostic: warning: this function definition uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:27:1 + --> $DIR/simd-abi-checks-avx.rs:27:1 | LL | unsafe extern "C" fn g() -> __m256 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -209,7 +209,7 @@ LL | unsafe extern "C" fn g() -> __m256 { Future breakage diagnostic: warning: this function definition uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:21:1 + --> $DIR/simd-abi-checks-avx.rs:21:1 | LL | unsafe extern "C" fn f(_: __m256) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -221,7 +221,7 @@ LL | unsafe extern "C" fn f(_: __m256) { Future breakage diagnostic: warning: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `avx` target feature, which is not enabled - --> $DIR/simd-abi-checks.rs:15:1 + --> $DIR/simd-abi-checks-avx.rs:15:1 | LL | unsafe extern "C" fn w(_: Wrapper) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -233,7 +233,7 @@ LL | unsafe extern "C" fn w(_: Wrapper) { Future breakage diagnostic: warning: this function call uses SIMD vector type `std::arch::x86_64::__m256` which (with the chosen ABI) requires the `avx` target feature, which is not enabled in the caller - --> $DIR/simd-abi-checks.rs:57:8 + --> $DIR/simd-abi-checks-avx.rs:57:8 | LL | || g() | ^^^ function called here diff --git a/tests/ui/simd-abi-checks-empty-list.rs b/tests/ui/abi/simd-abi-checks-empty-list.rs similarity index 81% rename from tests/ui/simd-abi-checks-empty-list.rs rename to tests/ui/abi/simd-abi-checks-empty-list.rs index fd4957b5b9398..ca0889364fc32 100644 --- a/tests/ui/simd-abi-checks-empty-list.rs +++ b/tests/ui/abi/simd-abi-checks-empty-list.rs @@ -1,15 +1,14 @@ +//@ add-core-stubs //@ needs-llvm-components: sparc //@ compile-flags: --target=sparc-unknown-none-elf --crate-type=rlib //@ build-pass //@ ignore-pass (test emits codegen-time warnings) #![no_core] -#![feature(no_core, lang_items, repr_simd)] +#![feature(no_core, repr_simd)] #![allow(improper_ctypes_definitions)] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct SimdVec([i32; 4]); diff --git a/tests/ui/simd-abi-checks-empty-list.stderr b/tests/ui/abi/simd-abi-checks-empty-list.stderr similarity index 92% rename from tests/ui/simd-abi-checks-empty-list.stderr rename to tests/ui/abi/simd-abi-checks-empty-list.stderr index 91c61884fd025..111dda42f33f2 100644 --- a/tests/ui/simd-abi-checks-empty-list.stderr +++ b/tests/ui/abi/simd-abi-checks-empty-list.stderr @@ -1,5 +1,5 @@ warning: this function definition uses SIMD vector type `SimdVec` which is not currently supported with the chosen ABI - --> $DIR/simd-abi-checks-empty-list.rs:17:1 + --> $DIR/simd-abi-checks-empty-list.rs:16:1 | LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -12,7 +12,7 @@ warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: warning: this function definition uses SIMD vector type `SimdVec` which is not currently supported with the chosen ABI - --> $DIR/simd-abi-checks-empty-list.rs:17:1 + --> $DIR/simd-abi-checks-empty-list.rs:16:1 | LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs similarity index 94% rename from tests/ui/simd-abi-checks-s390x.rs rename to tests/ui/abi/simd-abi-checks-s390x.rs index 7e408f665614a..424ac00edcfc5 100644 --- a/tests/ui/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: z10 z13_no_vector z13_soft_float //@ build-fail //@[z10] compile-flags: --target s390x-unknown-linux-gnu @@ -8,20 +9,14 @@ //@[z13_soft_float] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float //@[z13_soft_float] needs-llvm-components: systemz -#![feature(no_core, lang_items, repr_simd, s390x_target_feature)] +#![feature(no_core, repr_simd, s390x_target_feature)] #![no_core] #![crate_type = "lib"] #![allow(non_camel_case_types, improper_ctypes_definitions)] #![deny(abi_unsupported_vector_types)] -#[lang = "sized"] -pub trait Sized {} -#[lang = "copy"] -pub trait Copy {} -#[lang = "freeze"] -pub trait Freeze {} - -impl Copy for [T; N] {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct i8x8([i8; 8]); @@ -34,8 +29,6 @@ pub struct Wrapper(T); #[repr(transparent)] pub struct TransparentWrapper(T); -impl Copy for i8 {} -impl Copy for i64 {} impl Copy for i8x8 {} impl Copy for i8x16 {} impl Copy for i8x32 {} diff --git a/tests/ui/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr similarity index 92% rename from tests/ui/simd-abi-checks-s390x.z10.stderr rename to tests/ui/abi/simd-abi-checks-s390x.z10.stderr index ab97299e84a72..d2f7abb7c3221 100644 --- a/tests/ui/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -8,13 +8,13 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -24,7 +24,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -36,7 +36,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -48,7 +48,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -58,7 +58,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -68,7 +68,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -78,7 +78,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -88,7 +88,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -98,7 +98,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -111,7 +111,7 @@ error: aborting due to 10 previous errors Future incompatibility report: Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -120,14 +120,14 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -136,14 +136,14 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -154,14 +154,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -172,14 +172,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -188,14 +188,14 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -204,14 +204,14 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -220,14 +220,14 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -236,14 +236,14 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -252,14 +252,14 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -268,7 +268,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr similarity index 92% rename from tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr rename to tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr index ab97299e84a72..d2f7abb7c3221 100644 --- a/tests/ui/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -8,13 +8,13 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -24,7 +24,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -36,7 +36,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -48,7 +48,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -58,7 +58,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -68,7 +68,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -78,7 +78,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -88,7 +88,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -98,7 +98,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -111,7 +111,7 @@ error: aborting due to 10 previous errors Future incompatibility report: Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -120,14 +120,14 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -136,14 +136,14 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -154,14 +154,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -172,14 +172,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -188,14 +188,14 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -204,14 +204,14 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -220,14 +220,14 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -236,14 +236,14 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -252,14 +252,14 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -268,7 +268,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr similarity index 92% rename from tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr rename to tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index ab97299e84a72..d2f7abb7c3221 100644 --- a/tests/ui/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -8,13 +8,13 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -24,7 +24,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -36,7 +36,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -48,7 +48,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -58,7 +58,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -68,7 +68,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -78,7 +78,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -88,7 +88,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -98,7 +98,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -111,7 +111,7 @@ error: aborting due to 10 previous errors Future incompatibility report: Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:46:1 + --> $DIR/simd-abi-checks-s390x.rs:39:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -120,14 +120,14 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:52:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -136,14 +136,14 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:99:1 + --> $DIR/simd-abi-checks-s390x.rs:92:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -154,14 +154,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:107:1 + --> $DIR/simd-abi-checks-s390x.rs:100:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -172,14 +172,14 @@ LL | | ) -> TransparentWrapper { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:123:1 + --> $DIR/simd-abi-checks-s390x.rs:116:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -188,14 +188,14 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:129:1 + --> $DIR/simd-abi-checks-s390x.rs:122:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -204,14 +204,14 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:141:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -220,14 +220,14 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:147:1 + --> $DIR/simd-abi-checks-s390x.rs:140:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -236,14 +236,14 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:159:1 + --> $DIR/simd-abi-checks-s390x.rs:152:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -252,14 +252,14 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Future breakage diagnostic: error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:165:1 + --> $DIR/simd-abi-checks-s390x.rs:158:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -268,7 +268,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) = note: for more information, see issue #116558 = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) note: the lint level is defined here - --> $DIR/simd-abi-checks-s390x.rs:15:9 + --> $DIR/simd-abi-checks-s390x.rs:16:9 | LL | #![deny(abi_unsupported_vector_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/sse-abi-checks.rs b/tests/ui/abi/simd-abi-checks-sse.rs similarity index 72% rename from tests/ui/sse-abi-checks.rs rename to tests/ui/abi/simd-abi-checks-sse.rs index 3c9fe1f0ddbd8..cb708bea3cae9 100644 --- a/tests/ui/sse-abi-checks.rs +++ b/tests/ui/abi/simd-abi-checks-sse.rs @@ -1,18 +1,17 @@ //! Ensure we trigger abi_unsupported_vector_types for target features that are usually enabled -//! on a target, but disabled in this file via a `-C` flag. -//@ compile-flags: --crate-type=rlib --target=i586-unknown-linux-gnu -C target-feature=-sse,-sse2 +//! on a target via the base CPU, but disabled in this file via a `-C` flag. +//@ compile-flags: --crate-type=rlib --target=i586-unknown-linux-gnu +//@ compile-flags: -Ctarget-cpu=pentium4 -C target-feature=-sse,-sse2 +//@ add-core-stubs //@ build-pass //@ ignore-pass (test emits codegen-time warnings) //@ needs-llvm-components: x86 -#![feature(no_core, lang_items, repr_simd)] +#![feature(no_core, repr_simd)] #![no_core] #![allow(improper_ctypes_definitions)] -#[lang = "sized"] -trait Sized {} - -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; #[repr(simd)] pub struct SseVector([i64; 2]); diff --git a/tests/ui/sse-abi-checks.stderr b/tests/ui/abi/simd-abi-checks-sse.stderr similarity index 94% rename from tests/ui/sse-abi-checks.stderr rename to tests/ui/abi/simd-abi-checks-sse.stderr index 712322a5848b5..c0f2e6e1e1b14 100644 --- a/tests/ui/sse-abi-checks.stderr +++ b/tests/ui/abi/simd-abi-checks-sse.stderr @@ -1,5 +1,5 @@ warning: this function definition uses SIMD vector type `SseVector` which (with the chosen ABI) requires the `sse` target feature, which is not enabled - --> $DIR/sse-abi-checks.rs:21:1 + --> $DIR/simd-abi-checks-sse.rs:20:1 | LL | pub unsafe extern "C" fn f(_: SseVector) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -13,7 +13,7 @@ warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: warning: this function definition uses SIMD vector type `SseVector` which (with the chosen ABI) requires the `sse` target feature, which is not enabled - --> $DIR/sse-abi-checks.rs:21:1 + --> $DIR/simd-abi-checks-sse.rs:20:1 | LL | pub unsafe extern "C" fn f(_: SseVector) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 781e9b2f4c9d5..ec85030c10686 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -17,6 +17,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -45,6 +46,7 @@ error: fn_abi_of(pass_zst) = FnAbi { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/abi/vectorcall-abi-checks.rs b/tests/ui/abi/vectorcall-abi-checks.rs new file mode 100644 index 0000000000000..d83bbffa745f8 --- /dev/null +++ b/tests/ui/abi/vectorcall-abi-checks.rs @@ -0,0 +1,21 @@ +//@ add-core-stubs +//@ compile-flags: --crate-type=rlib --target=i586-unknown-linux-gnu -C target-feature=-sse,-sse2 +//@ build-fail +//@ ignore-pass (test emits codegen-time errors) +//@ needs-llvm-components: x86 +#![feature(no_core, abi_vectorcall)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub extern "vectorcall" fn f() { + //~^ ABI "vectorcall" which requires the `sse2` target feature +} + +#[no_mangle] +pub fn call_site() { + f(); + //~^ ABI "vectorcall" which requires the `sse2` target feature +} diff --git a/tests/ui/abi/vectorcall-abi-checks.stderr b/tests/ui/abi/vectorcall-abi-checks.stderr new file mode 100644 index 0000000000000..671ebc25b42a0 --- /dev/null +++ b/tests/ui/abi/vectorcall-abi-checks.stderr @@ -0,0 +1,18 @@ +error: this function definition uses ABI "vectorcall" which requires the `sse2` target feature, which is not enabled + --> $DIR/vectorcall-abi-checks.rs:13:1 + | +LL | pub extern "vectorcall" fn f() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: consider enabling it globally (`-C target-feature=+sse2`) or locally (`#[target_feature(enable="sse2")]`) + +error: this function call uses ABI "vectorcall" which requires the `sse2` target feature, which is not enabled in the caller + --> $DIR/vectorcall-abi-checks.rs:19:5 + | +LL | f(); + | ^^^ function called here + | + = help: consider enabling it globally (`-C target-feature=+sse2`) or locally (`#[target_feature(enable="sse2")]`) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/argument-suggestions/basic.stderr b/tests/ui/argument-suggestions/basic.stderr index 9a639d4b5e4ef..a71b6ab0e9949 100644 --- a/tests/ui/argument-suggestions/basic.stderr +++ b/tests/ui/argument-suggestions/basic.stderr @@ -42,9 +42,8 @@ LL | fn missing(_i: u32) {} | ^^^^^^^ ------- help: provide the argument | -LL - missing(); -LL + missing(/* u32 */); - | +LL | missing(/* u32 */); + | +++++++++ error[E0308]: arguments to this function are incorrect --> $DIR/basic.rs:23:5 @@ -98,9 +97,8 @@ LL | let closure = |x| x; | ^^^ help: provide the argument | -LL - closure(); -LL + closure(/* x */); - | +LL | closure(/* x */); + | +++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/argument-suggestions/display-is-suggestable.stderr b/tests/ui/argument-suggestions/display-is-suggestable.stderr index bb5df1ec234cd..921cc12333870 100644 --- a/tests/ui/argument-suggestions/display-is-suggestable.stderr +++ b/tests/ui/argument-suggestions/display-is-suggestable.stderr @@ -11,9 +11,8 @@ LL | fn foo(x: &(dyn Display + Send)) {} | ^^^ ------------------------ help: provide the argument | -LL - foo(); -LL + foo(/* &dyn std::fmt::Display + Send */); - | +LL | foo(/* &dyn std::fmt::Display + Send */); + | +++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr index 62670316cd163..28500908e7ea3 100644 --- a/tests/ui/argument-suggestions/extern-fn-arg-names.stderr +++ b/tests/ui/argument-suggestions/extern-fn-arg-names.stderr @@ -17,9 +17,8 @@ LL | fn dstfn(src: i32, dst: err); | ^^^^^ --- help: provide the argument | -LL - dstfn(1); -LL + dstfn(1, /* dst */); - | +LL | dstfn(1, /* dst */); + | +++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/argument-suggestions/issue-97197.stderr b/tests/ui/argument-suggestions/issue-97197.stderr index acaf4f1510735..ae56e12c975f8 100644 --- a/tests/ui/argument-suggestions/issue-97197.stderr +++ b/tests/ui/argument-suggestions/issue-97197.stderr @@ -11,9 +11,8 @@ LL | pub fn g(a1: (), a2: bool, a3: bool, a4: bool, a5: bool, a6: ()) -> () {} | ^ -------- -------- -------- -------- help: provide the arguments | -LL - g((), ()); -LL + g((), /* bool */, /* bool */, /* bool */, /* bool */, ()); - | +LL | g((), /* bool */, /* bool */, /* bool */, /* bool */, ()); + | +++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-98894.stderr b/tests/ui/argument-suggestions/issue-98894.stderr index 44353cb33388a..141355ff153bd 100644 --- a/tests/ui/argument-suggestions/issue-98894.stderr +++ b/tests/ui/argument-suggestions/issue-98894.stderr @@ -11,9 +11,8 @@ LL | (|_, ()| ())(if true {} else {return;}); | ^^^^^^^ help: provide the argument | -LL - (|_, ()| ())(if true {} else {return;}); -LL + (|_, ()| ())(if true {} else {return;}, ()); - | +LL | (|_, ()| ())(if true {} else {return;}, ()); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-98897.stderr b/tests/ui/argument-suggestions/issue-98897.stderr index fd3ef467b1c39..a85e723368902 100644 --- a/tests/ui/argument-suggestions/issue-98897.stderr +++ b/tests/ui/argument-suggestions/issue-98897.stderr @@ -11,9 +11,8 @@ LL | (|_, ()| ())([return, ()]); | ^^^^^^^ help: provide the argument | -LL - (|_, ()| ())([return, ()]); -LL + (|_, ()| ())([return, ()], ()); - | +LL | (|_, ()| ())([return, ()], ()); + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/issue-99482.stderr b/tests/ui/argument-suggestions/issue-99482.stderr index b3c39604a99b0..972ab401958b0 100644 --- a/tests/ui/argument-suggestions/issue-99482.stderr +++ b/tests/ui/argument-suggestions/issue-99482.stderr @@ -11,9 +11,8 @@ LL | let f = |_: (), f: fn()| f; | ^^^^^^^^^^^^^^^^ help: provide the argument | -LL - let _f = f(main); -LL + let _f = f((), main); - | +LL | let _f = f((), main); + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/argument-suggestions/missing_arguments.stderr b/tests/ui/argument-suggestions/missing_arguments.stderr index 264c485cbe1c3..9dc13c41113b6 100644 --- a/tests/ui/argument-suggestions/missing_arguments.stderr +++ b/tests/ui/argument-suggestions/missing_arguments.stderr @@ -11,9 +11,8 @@ LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- help: provide the argument | -LL - one_arg(); -LL + one_arg(/* i32 */); - | +LL | one_arg(/* i32 */); + | +++++++++ error[E0061]: this function takes 2 arguments but 0 arguments were supplied --> $DIR/missing_arguments.rs:14:3 diff --git a/tests/ui/asm/asm-with-nested-closure.rs b/tests/ui/asm/asm-with-nested-closure.rs new file mode 100644 index 0000000000000..3a5cd48d5d4df --- /dev/null +++ b/tests/ui/asm/asm-with-nested-closure.rs @@ -0,0 +1,11 @@ +//@ build-pass +//@ needs-asm-support + +fn foo() {} + +core::arch::global_asm!("/* {} */", sym foo::<{ + || {}; + 0 +}>); + +fn main() {} diff --git a/tests/ui/asm/global-asm-with-lifetimes.rs b/tests/ui/asm/global-asm-with-lifetimes.rs new file mode 100644 index 0000000000000..2709ff90fe333 --- /dev/null +++ b/tests/ui/asm/global-asm-with-lifetimes.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ needs-asm-support + +fn foo() {} + +core::arch::global_asm!("/* {} */", sym foo::<&'static ()>); + +fn main() {} diff --git a/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr b/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr new file mode 100644 index 0000000000000..f04482f9c5916 --- /dev/null +++ b/tests/ui/asm/inline-asm-with-lifetimes.bad.stderr @@ -0,0 +1,17 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/inline-asm-with-lifetimes.rs:17:26 + | +LL | fn test<'a: 'a, T>() { + | -- the parameter type `T` must be valid for the lifetime `'a` as defined here... +LL | unsafe { +LL | asm!("/* {} */", sym dep::<'a, T> ); + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn test<'a: 'a, T: 'a>() { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/asm/inline-asm-with-lifetimes.rs b/tests/ui/asm/inline-asm-with-lifetimes.rs new file mode 100644 index 0000000000000..79def03eeb232 --- /dev/null +++ b/tests/ui/asm/inline-asm-with-lifetimes.rs @@ -0,0 +1,22 @@ +//@ revisions: good bad +//@[good] build-pass +//@ needs-asm-support + +use std::arch::asm; + +// lifetime requirement, we should check it!! +#[cfg(bad)] +fn dep<'a, T: 'a>() {} + +// no lifetime requirement +#[cfg(good)] +fn dep<'a: 'a, T>() {} + +fn test<'a: 'a, T>() { + unsafe { + asm!("/* {} */", sym dep::<'a, T> ); + //[bad]~^ ERROR the parameter type `T` may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr index e68ba503c5059..041c9b485f0a3 100644 --- a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr +++ b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr @@ -16,12 +16,10 @@ LL | const ID: i32 = 1; | ^^^^^^^^^^^^^ help: use fully-qualified syntax to disambiguate | -LL - const X: i32 = ::ID; -LL + const X: i32 = ::ID; - | -LL - const X: i32 = ::ID; -LL + const X: i32 = ::ID; - | +LL | const X: i32 = ::ID; + | ++++++ +LL | const X: i32 = ::ID; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/issue-93775.rs b/tests/ui/associated-consts/issue-93775.rs index 88e88b559870f..a9b8d10a83fbf 100644 --- a/tests/ui/associated-consts/issue-93775.rs +++ b/tests/ui/associated-consts/issue-93775.rs @@ -2,11 +2,13 @@ // Similar to stress testing, the test case requires a larger call stack, // so we ignore rustc's debug assertions. -//@ build-pass -// ignore-tidy-linelength - // Regression for #93775, needs build-pass to test it. +//@ build-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![recursion_limit = "1001"] use std::marker::PhantomData; @@ -14,7 +16,64 @@ use std::marker::PhantomData; struct Z; struct S(PhantomData); -type Nested = S>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; +type Nested = S>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; trait AsNum { const NUM: u32; diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs index 9cc33d53f9cd5..048681f047789 100644 --- a/tests/ui/associated-consts/issue-93835.rs +++ b/tests/ui/associated-consts/issue-93835.rs @@ -3,9 +3,11 @@ fn e() { type_ascribe!(p, a>); //~^ ERROR cannot find type `a` in this scope + //~| ERROR path separator must be a double colon //~| ERROR cannot find value //~| ERROR associated const equality - //~| ERROR cannot find trait `p` in this scope + //~| ERROR associated const equality + //~| ERROR failed to resolve: use of unresolved module or unlinked crate `p` } fn main() {} diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/associated-consts/issue-93835.stderr index dfe78b3d1f380..e154ae25de26c 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/associated-consts/issue-93835.stderr @@ -1,3 +1,15 @@ +error: path separator must be a double colon + --> $DIR/issue-93835.rs:4:25 + | +LL | type_ascribe!(p, a>); + | ^ + | + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 +help: use a double colon instead + | +LL | type_ascribe!(p, a>); + | + + error[E0425]: cannot find value `p` in this scope --> $DIR/issue-93835.rs:4:19 | @@ -10,11 +22,15 @@ error[E0412]: cannot find type `a` in this scope LL | type_ascribe!(p, a>); | ^ not found in this scope -error[E0405]: cannot find trait `p` in this scope - --> $DIR/issue-93835.rs:4:26 +error[E0658]: associated const equality is incomplete + --> $DIR/issue-93835.rs:4:28 | LL | type_ascribe!(p, a>); - | ^ not found in this scope + | ^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete --> $DIR/issue-93835.rs:4:28 @@ -25,8 +41,17 @@ LL | type_ascribe!(p, a>); = note: see issue #92827 for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0433]: failed to resolve: use of unresolved module or unlinked crate `p` + --> $DIR/issue-93835.rs:4:24 + | +LL | type_ascribe!(p, a>); + | ^ use of unresolved module or unlinked crate `p` + | + = help: you might be missing a crate named `p` -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0405, E0412, E0425, E0658. -For more information about an error, try `rustc --explain E0405`. +Some errors have detailed explanations: E0412, E0425, E0433, E0658. +For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr index 18455f4669e91..59f8526a73e59 100644 --- a/tests/ui/associated-inherent-types/issue-109768.stderr +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -43,9 +43,8 @@ LL | struct Wrapper(T); | ^^^^^^^ help: provide the argument | -LL - const WRAPPED_ASSOC_3: Wrapper = Wrapper(); -LL + const WRAPPED_ASSOC_3: Wrapper = Wrapper(/* value */); - | +LL | const WRAPPED_ASSOC_3: Wrapper = Wrapper(/* value */); + | +++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/associated-item/associated-item-enum.stderr b/tests/ui/associated-item/associated-item-enum.stderr index 49f168b854407..c3ce7c34d0569 100644 --- a/tests/ui/associated-item/associated-item-enum.stderr +++ b/tests/ui/associated-item/associated-item-enum.stderr @@ -9,9 +9,8 @@ LL | Enum::mispellable(); | help: there is an associated function `misspellable` with a similar name | -LL - Enum::mispellable(); -LL + Enum::misspellable(); - | +LL | Enum::misspellable(); + | + error[E0599]: no variant or associated item named `mispellable_trait` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:18:11 @@ -24,9 +23,8 @@ LL | Enum::mispellable_trait(); | help: there is an associated function `misspellable_trait` with a similar name | -LL - Enum::mispellable_trait(); -LL + Enum::misspellable_trait(); - | +LL | Enum::misspellable_trait(); + | + error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `Enum` in the current scope --> $DIR/associated-item-enum.rs:19:11 @@ -39,9 +37,8 @@ LL | Enum::MISPELLABLE; | help: there is an associated constant `MISSPELLABLE` with a similar name | -LL - Enum::MISPELLABLE; -LL + Enum::MISSPELLABLE; - | +LL | Enum::MISSPELLABLE; + | + error: aborting due to 3 previous errors diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.rs b/tests/ui/associated-types/associated-types-overridden-binding-2.rs index fed60ccf089d0..247724eaaf112 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.rs @@ -4,5 +4,5 @@ trait I32Iterator = Iterator; fn main() { let _: &dyn I32Iterator = &vec![42].into_iter(); - //~^ ERROR expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` + //~^ ERROR conflicting associated type bounds } diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index 4dfd275a19058..71a4a2610aac4 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -1,11 +1,13 @@ -error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/associated-types-overridden-binding-2.rs:6:43 +error: conflicting associated type bounds for `Item` when expanding trait alias + --> $DIR/associated-types-overridden-binding-2.rs:6:13 | +LL | trait I32Iterator = Iterator; + | ---------- `Item` is specified to be `i32` here +... LL | let _: &dyn I32Iterator = &vec![42].into_iter(); - | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` - | - = note: required for the cast from `&std::vec::IntoIter` to `&dyn Iterator` + | ^^^^^^^^^^^^^^^^----------^ + | | + | `Item` is specified to be `u32` here error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/associated-types-overridden-binding.rs b/tests/ui/associated-types/associated-types-overridden-binding.rs index 9a64a06c31bad..333a3e30c7dcf 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding.rs @@ -8,4 +8,5 @@ trait U32Iterator = I32Iterator; //~ ERROR type annotations needed fn main() { let _: &dyn I32Iterator; + //~^ ERROR conflicting associated type bounds } diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr index dc087e4185fb6..3b20015dfcab3 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr @@ -22,6 +22,17 @@ note: required by a bound in `I32Iterator` LL | trait I32Iterator = Iterator; | ^^^^^^^^^^ required by this bound in `I32Iterator` -error: aborting due to 2 previous errors +error: conflicting associated type bounds for `Item` when expanding trait alias + --> $DIR/associated-types-overridden-binding.rs:10:13 + | +LL | trait I32Iterator = Iterator; + | ---------- `Item` is specified to be `i32` here +... +LL | let _: &dyn I32Iterator; + | ^^^^^^^^^^^^^^^^----------^ + | | + | `Item` is specified to be `u32` here + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/async-await/issue-84841.stderr b/tests/ui/async-await/issue-84841.stderr index 69c1c882d60ac..0d008477310a7 100644 --- a/tests/ui/async-await/issue-84841.stderr +++ b/tests/ui/async-await/issue-84841.stderr @@ -17,8 +17,6 @@ LL | | test()?; ... | LL | | } | |_- this function should return `Result` or `Option` to accept `?` - | - = help: the trait `FromResidual<_>` is not implemented for `()` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/try-on-option-in-async.stderr b/tests/ui/async-await/try-on-option-in-async.stderr index 9e0bb42a697cc..332f4d4ec0c27 100644 --- a/tests/ui/async-await/try-on-option-in-async.stderr +++ b/tests/ui/async-await/try-on-option-in-async.stderr @@ -6,8 +6,6 @@ LL | async { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in an async block that returns `{integer}` - | - = help: the trait `FromResidual>` is not implemented for `{integer}` error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option-in-async.rs:16:10 @@ -20,8 +18,6 @@ LL | | x?; LL | | 22_u32 LL | | }; | |_____- this function should return `Result` or `Option` to accept `?` - | - = help: the trait `FromResidual>` is not implemented for `u32` error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option-in-async.rs:25:6 @@ -34,8 +30,6 @@ LL | | x?; LL | | 22 LL | | } | |_- this function should return `Result` or `Option` to accept `?` - | - = help: the trait `FromResidual>` is not implemented for `u32` error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/key-value-expansion-scope.rs b/tests/ui/attributes/key-value-expansion-scope.rs index b6eab1571d490..49a59502377f5 100644 --- a/tests/ui/attributes/key-value-expansion-scope.rs +++ b/tests/ui/attributes/key-value-expansion-scope.rs @@ -1,7 +1,7 @@ -#![doc = in_root!()] //~ WARN cannot find macro `in_root` in this scope +#![doc = in_root!()] //~ WARN cannot find macro `in_root` //~| WARN this was previously accepted by the compiler #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope -#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope +#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope @@ -18,10 +18,10 @@ fn before() { macro_rules! in_root { () => { "" } } -#[doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope +#[doc = in_mod!()] //~ WARN cannot find macro `in_mod` //~| WARN this was previously accepted by the compiler mod macros_stay { - #![doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope + #![doc = in_mod!()] //~ WARN cannot find macro `in_mod` //~| WARN this was previously accepted by the compiler macro_rules! in_mod { () => { "" } } @@ -33,10 +33,10 @@ mod macros_stay { } #[macro_use] -#[doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope +#[doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler mod macros_escape { - #![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope + #![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler macro_rules! in_mod_escape { () => { "" } } diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index d22fef7dd251e..91a602e57d9e4 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -126,62 +126,62 @@ LL | #![doc = in_block!()] | = help: have you added the `#[macro_use]` on the module/import? -warning: cannot find macro `in_root` in this scope +warning: cannot find macro `in_root` in the current scope when looking from the crate root --> $DIR/key-value-expansion-scope.rs:1:10 | LL | #![doc = in_root!()] - | ^^^^^^^ + | ^^^^^^^ not found from the crate root | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition = note: `#[warn(out_of_scope_macro_calls)]` on by default -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in the current scope when looking from the crate root --> $DIR/key-value-expansion-scope.rs:4:10 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found from the crate root | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` --> $DIR/key-value-expansion-scope.rs:21:9 | LL | #[doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found from module `macros_stay` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod` in this scope +warning: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` --> $DIR/key-value-expansion-scope.rs:24:14 | LL | #![doc = in_mod!()] - | ^^^^^^ + | ^^^^^^ not found from module `macros_stay` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` --> $DIR/key-value-expansion-scope.rs:36:9 | LL | #[doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found from module `macros_escape` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -warning: cannot find macro `in_mod_escape` in this scope +warning: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` --> $DIR/key-value-expansion-scope.rs:39:14 | LL | #![doc = in_mod_escape!()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not found from module `macros_escape` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #124535 diff --git a/tests/ui/binop/placement-syntax.stderr b/tests/ui/binop/placement-syntax.stderr index e398c0b0702ab..c07ee7184c775 100644 --- a/tests/ui/binop/placement-syntax.stderr +++ b/tests/ui/binop/placement-syntax.stderr @@ -6,9 +6,8 @@ LL | if x<-1 { | help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` | -LL - if x<-1 { -LL + if x< -1 { - | +LL | if x< -1 { + | + error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/bad-drop-side-effects.rs b/tests/ui/borrowck/bad-drop-side-effects.rs new file mode 100644 index 0000000000000..a09b7087608f6 --- /dev/null +++ b/tests/ui/borrowck/bad-drop-side-effects.rs @@ -0,0 +1,18 @@ +// Regression test for . + +trait B { + type C; +} + +impl B for &Missing { +//~^ ERROR cannot find type `Missing` in this scope + type C = (); +} + +struct E { + g: ::C, +} + +fn h(i: Box>) {} + +fn main() {} diff --git a/tests/ui/borrowck/bad-drop-side-effects.stderr b/tests/ui/borrowck/bad-drop-side-effects.stderr new file mode 100644 index 0000000000000..0a5998c7e4830 --- /dev/null +++ b/tests/ui/borrowck/bad-drop-side-effects.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/bad-drop-side-effects.rs:7:16 + | +LL | impl B for &Missing { + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr b/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr index d953ed2ad3ef0..5cc5b87cd44b7 100644 --- a/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr +++ b/tests/ui/borrowck/borrowck-struct-update-with-dtor.stderr @@ -116,9 +116,8 @@ LL | let _s2 = T { ..s0 }; | help: clone the value from the field instead of using the functional record update syntax | -LL - let _s2 = T { ..s0 }; -LL + let _s2 = T { b: s0.b.clone(), ..s0 }; - | +LL | let _s2 = T { b: s0.b.clone(), ..s0 }; + | ++++++++++++++++ error[E0509]: cannot move out of type `T`, which implements the `Drop` trait --> $DIR/borrowck-struct-update-with-dtor.rs:47:32 diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr index 1e3570fc85570..a392177ffe2f3 100644 --- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr +++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr @@ -9,9 +9,8 @@ LL | let sfoo: *mut Foo = &mut SFOO; = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - let sfoo: *mut Foo = &mut SFOO; -LL + let sfoo: *mut Foo = &raw mut SFOO; - | +LL | let sfoo: *mut Foo = &raw mut SFOO; + | +++ warning: 1 warning emitted diff --git a/tests/ui/borrowck/issue-85765-closure.stderr b/tests/ui/borrowck/issue-85765-closure.stderr index fa4e544150877..cd2544ec5c952 100644 --- a/tests/ui/borrowck/issue-85765-closure.stderr +++ b/tests/ui/borrowck/issue-85765-closure.stderr @@ -6,9 +6,8 @@ LL | rofl.push(Vec::new()); | help: consider changing this binding's type | -LL - let rofl: &Vec> = &mut test; -LL + let rofl: &mut Vec> = &mut test; - | +LL | let rofl: &mut Vec> = &mut test; + | +++ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:13:9 @@ -29,9 +28,8 @@ LL | *x = 1; | help: consider changing this binding's type | -LL - let x: &usize = &mut{0}; -LL + let x: &mut usize = &mut{0}; - | +LL | let x: &mut usize = &mut{0}; + | +++ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765-closure.rs:27:9 @@ -41,9 +39,8 @@ LL | *y = 1; | help: consider changing this binding's type | -LL - let y: &usize = &mut(0); -LL + let y: &mut usize = &mut(0); - | +LL | let y: &mut usize = &mut(0); + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/issue-85765.stderr b/tests/ui/borrowck/issue-85765.stderr index 9354294f52b21..e252f3d44d976 100644 --- a/tests/ui/borrowck/issue-85765.stderr +++ b/tests/ui/borrowck/issue-85765.stderr @@ -6,9 +6,8 @@ LL | rofl.push(Vec::new()); | help: consider changing this binding's type | -LL - let rofl: &Vec> = &mut test; -LL + let rofl: &mut Vec> = &mut test; - | +LL | let rofl: &mut Vec> = &mut test; + | +++ error[E0594]: cannot assign to `*r`, which is behind a `&` reference --> $DIR/issue-85765.rs:12:5 @@ -29,9 +28,8 @@ LL | *x = 1; | help: consider changing this binding's type | -LL - let x: &usize = &mut{0}; -LL + let x: &mut usize = &mut{0}; - | +LL | let x: &mut usize = &mut{0}; + | +++ error[E0594]: cannot assign to `*y`, which is behind a `&` reference --> $DIR/issue-85765.rs:26:5 @@ -41,9 +39,8 @@ LL | *y = 1; | help: consider changing this binding's type | -LL - let y: &usize = &mut(0); -LL + let y: &mut usize = &mut(0); - | +LL | let y: &mut usize = &mut(0); + | +++ error: aborting due to 4 previous errors diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 061eae9729e2e..39dfb2548a3bb 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -17,9 +17,8 @@ LL | fn foo(f: isize, x: u8, ...); | ^^^ - - help: provide the arguments | -LL - foo(); -LL + foo(/* isize */, /* u8 */); - | +LL | foo(/* isize */, /* u8 */); + | +++++++++++++++++++++ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied --> $DIR/variadic-ffi-1.rs:23:9 @@ -34,9 +33,8 @@ LL | fn foo(f: isize, x: u8, ...); | ^^^ - help: provide the argument | -LL - foo(1); -LL + foo(1, /* u8 */); - | +LL | foo(1, /* u8 */); + | ++++++++++ error[E0308]: mismatched types --> $DIR/variadic-ffi-1.rs:25:56 diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index 402ee27386ddd..0b2ab1dfc4c17 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -48,9 +48,8 @@ LL | struct MyType<'a>(Cell>>, Pin); | ^^^^^^ help: provide the argument | -LL - let mut unpinned = MyType(Cell::new(None)); -LL + let mut unpinned = MyType(Cell::new(None), /* value */); - | +LL | let mut unpinned = MyType(Cell::new(None), /* value */); + | +++++++++++++ error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid --> $DIR/ice-cast-type-with-error-124848.rs:14:20 diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index 70852423bdbef..51808c5c7bcdb 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -58,6 +58,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `cssc` `d` `d32` +`deflate-conversion` `dit` `doloop` `dotprod` @@ -72,6 +73,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `ecv` `edsp` `elrw` +`enhanced-sort` `ermsb` `exception-handling` `extended-const` @@ -109,11 +111,13 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `frintts` `fxsr` `gfni` +`guarded-storage` `hard-float` `hard-float-abi` `hard-tp` `hbc` `high-registers` +`high-word` `hvx` `hvx-length128b` `hwdiv` @@ -151,6 +155,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `multivalue` `mutable-globals` `neon` +`nnp-assist` `nontrapping-fptoint` `nvic` `paca` @@ -229,6 +234,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `thumb-mode` `thumb2` `tme` +`transactional-execution` `trust` `trustzone` `ual` @@ -262,6 +268,11 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `vdspv1` `vdspv2` `vector` +`vector-enhancements-1` +`vector-enhancements-2` +`vector-packed-decimal` +`vector-packed-decimal-enhancement` +`vector-packed-decimal-enhancement-2` `vfp2` `vfp3` `vfp4` diff --git a/tests/ui/closures/deduce-from-object-supertrait.rs b/tests/ui/closures/deduce-from-object-supertrait.rs new file mode 100644 index 0000000000000..aff750dc62ea3 --- /dev/null +++ b/tests/ui/closures/deduce-from-object-supertrait.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// This test checks that we look at consider the super traits of trait objects +// when deducing closure signatures. + +trait Foo: Fn(Bar) {} +impl Foo for T where T: Fn(Bar) {} + +struct Bar; +impl Bar { + fn bar(&self) {} +} + +fn main() { + let x: &dyn Foo = &|x| { + x.bar(); + }; +} diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.stderr b/tests/ui/conditional-compilation/cfg-attr-parse.stderr index 1605761e59195..76f199caace37 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-parse.stderr @@ -7,9 +7,8 @@ LL | #[cfg_attr()] = note: for more information, visit help: missing condition and attribute | -LL - #[cfg_attr()] -LL + #[cfg_attr(condition, attribute, other_attribute, ...)] - | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++ error: expected `,`, found end of `cfg_attr` input --> $DIR/cfg-attr-parse.rs:8:17 diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr index 2e0c04dcf1ea9..df588fcc5e10f 100644 --- a/tests/ui/const-ptr/forbidden_slices.stderr +++ b/tests/ui/const-ptr/forbidden_slices.stderr @@ -104,7 +104,7 @@ error[E0080]: could not evaluate static initializer | = note: the evaluated program panicked at 'assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize', $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, ()>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -192,7 +192,7 @@ error[E0080]: could not evaluate static initializer | = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -207,7 +207,7 @@ error[E0080]: could not evaluate static initializer | = note: `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation | -note: inside `std::ptr::const_ptr::::sub_ptr` +note: inside `std::ptr::const_ptr::::offset_from_unsigned` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `from_ptr_range::<'_, u32>` --> $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr index be0ffefc80dee..0d76f142d174d 100644 --- a/tests/ui/consts/const_let_assign2.stderr +++ b/tests/ui/consts/const_let_assign2.stderr @@ -9,9 +9,8 @@ LL | let ptr = unsafe { &mut BB }; = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - let ptr = unsafe { &mut BB }; -LL + let ptr = unsafe { &raw mut BB }; - | +LL | let ptr = unsafe { &raw mut BB }; + | +++ warning: 1 warning emitted diff --git a/tests/ui/consts/offset_from.rs b/tests/ui/consts/offset_from.rs index 7737b5ab0b8a6..02e8d145f65a9 100644 --- a/tests/ui/consts/offset_from.rs +++ b/tests/ui/consts/offset_from.rs @@ -1,8 +1,5 @@ //@ run-pass -#![feature(const_ptr_sub_ptr)] -#![feature(ptr_sub_ptr)] - struct Struct { field: (), } @@ -47,7 +44,7 @@ pub const OFFSET_EQUAL_INTS: isize = { pub const OFFSET_UNSIGNED: usize = { let a = ['a', 'b', 'c']; let ptr = a.as_ptr(); - unsafe { ptr.add(2).sub_ptr(ptr) } + unsafe { ptr.add(2).offset_from_unsigned(ptr) } }; fn main() { diff --git a/tests/ui/consts/offset_from_ub.rs b/tests/ui/consts/offset_from_ub.rs index 8835690060505..39384bf0c8b93 100644 --- a/tests/ui/consts/offset_from_ub.rs +++ b/tests/ui/consts/offset_from_ub.rs @@ -1,5 +1,4 @@ //@ normalize-stderr: "\d+ bytes" -> "$$BYTES bytes" -#![feature(const_ptr_sub_ptr)] #![feature(core_intrinsics)] use std::intrinsics::{ptr_offset_from, ptr_offset_from_unsigned}; diff --git a/tests/ui/consts/offset_from_ub.stderr b/tests/ui/consts/offset_from_ub.stderr index 1379365cc25cc..8cfbdd131909a 100644 --- a/tests/ui/consts/offset_from_ub.stderr +++ b/tests/ui/consts/offset_from_ub.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:19:27 + --> $DIR/offset_from_ub.rs:18:27 | LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation @@ -12,67 +12,67 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `NOT_PTR` - --> $DIR/offset_from_ub.rs:25:14 + --> $DIR/offset_from_ub.rs:24:14 | LL | unsafe { (42 as *const u8).offset_from(&5u8) as usize } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:32:14 + --> $DIR/offset_from_ub.rs:31:14 | LL | unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:39:14 + --> $DIR/offset_from_ub.rs:38:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:48:14 + --> $DIR/offset_from_ub.rs:47:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:57:14 + --> $DIR/offset_from_ub.rs:56:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on two different pointers where the memory range between them is not in-bounds of an allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:66:14 + --> $DIR/offset_from_ub.rs:65:14 | LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on two different pointers that are not both derived from the same allocation error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:73:14 + --> $DIR/offset_from_ub.rs:72:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far ahead of second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:79:14 + --> $DIR/offset_from_ub.rs:78:14 | LL | unsafe { ptr_offset_from(ptr1, ptr2) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:87:14 + --> $DIR/offset_from_ub.rs:86:14 | LL | unsafe { ptr_offset_from(ptr1, ptr2) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:94:14 + --> $DIR/offset_from_ub.rs:93:14 | LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8 error[E0080]: evaluation of constant value failed - --> $DIR/offset_from_ub.rs:101:14 + --> $DIR/offset_from_ub.rs:100:14 | LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second @@ -85,7 +85,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `OFFSET_VERY_FAR1` - --> $DIR/offset_from_ub.rs:110:14 + --> $DIR/offset_from_ub.rs:109:14 | LL | unsafe { ptr2.offset_from(ptr1) } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -98,7 +98,7 @@ error[E0080]: evaluation of constant value failed note: inside `std::ptr::const_ptr::::offset_from` --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL note: inside `OFFSET_VERY_FAR2` - --> $DIR/offset_from_ub.rs:116:14 + --> $DIR/offset_from_ub.rs:115:14 | LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/coroutine/issue-102645.stderr b/tests/ui/coroutine/issue-102645.stderr index bec0518d8c602..be16674668ead 100644 --- a/tests/ui/coroutine/issue-102645.stderr +++ b/tests/ui/coroutine/issue-102645.stderr @@ -8,9 +8,8 @@ note: method defined here --> $SRC_DIR/core/src/ops/coroutine.rs:LL:COL help: provide the argument | -LL - Pin::new(&mut b).resume(); -LL + Pin::new(&mut b).resume(()); - | +LL | Pin::new(&mut b).resume(()); + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/resume-arg-outlives.stderr b/tests/ui/coroutine/resume-arg-outlives.stderr index 0150009c8fa23..045c77e8d054c 100644 --- a/tests/ui/coroutine/resume-arg-outlives.stderr +++ b/tests/ui/coroutine/resume-arg-outlives.stderr @@ -9,9 +9,8 @@ LL | generator | help: consider changing `impl Coroutine<&'not_static str> + 'static`'s explicit `'static` bound to the lifetime of argument `s` | -LL - fn demo<'not_static>(s: &'not_static str) -> Pin + 'static>> { -LL + fn demo<'not_static>(s: &'not_static str) -> Pin + 'not_static>> { - | +LL | fn demo<'not_static>(s: &'not_static str) -> Pin + 'not_static>> { + | ++++ help: alternatively, add an explicit `'static` bound to this reference | LL - fn demo<'not_static>(s: &'not_static str) -> Pin + 'static>> { diff --git a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr index a8a70e363b7e6..dc84394fe3c0c 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.feat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.feat.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr index 6443fafef3e41..49b8974bfdfb8 100644 --- a/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr +++ b/tests/ui/coverage-attr/bad-attr-ice.nofeat.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error[E0658]: the `#[coverage]` attribute is an experimental feature --> $DIR/bad-attr-ice.rs:11:1 diff --git a/tests/ui/coverage-attr/bad-syntax.stderr b/tests/ui/coverage-attr/bad-syntax.stderr index 3123066e7bf97..fa500b542097d 100644 --- a/tests/ui/coverage-attr/bad-syntax.stderr +++ b/tests/ui/coverage-attr/bad-syntax.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:20:1 @@ -36,12 +34,10 @@ LL | #[coverage()] | help: the following are the possible correct uses | -LL - #[coverage()] -LL + #[coverage(off)] - | -LL - #[coverage()] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++ +LL | #[coverage(on)] + | ++ error: malformed `coverage` attribute input --> $DIR/bad-syntax.rs:26:1 diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index c034149d8ec92..612301885dcc8 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -6,12 +6,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:17:5 @@ -21,12 +19,10 @@ LL | #![coverage] | help: the following are the possible correct uses | -LL - #![coverage] -LL + #![coverage(off)] - | -LL - #![coverage] -LL + #![coverage(on)] - | +LL | #![coverage(off)] + | +++++ +LL | #![coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:21:1 @@ -36,12 +32,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:29:5 @@ -51,12 +45,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:26:1 @@ -66,12 +58,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:39:5 @@ -81,12 +71,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:44:5 @@ -96,12 +84,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:35:1 @@ -111,12 +97,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:53:5 @@ -126,12 +110,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:58:5 @@ -141,12 +123,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:50:1 @@ -156,12 +136,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error: malformed `coverage` attribute input --> $DIR/word-only.rs:64:1 @@ -171,12 +149,10 @@ LL | #[coverage] | help: the following are the possible correct uses | -LL - #[coverage] -LL + #[coverage(off)] - | -LL - #[coverage] -LL + #[coverage(on)] - | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ error[E0788]: coverage attribute not allowed here --> $DIR/word-only.rs:21:1 diff --git a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr index 7efc0b20e54be..2d02e33b2586b 100644 --- a/tests/ui/destructuring-assignment/struct_destructure_fail.stderr +++ b/tests/ui/destructuring-assignment/struct_destructure_fail.stderr @@ -31,9 +31,8 @@ LL + Struct { a, b } = Struct { a: 1, b: 2 }; | help: if you don't care about this missing field, you can explicitly ignore it | -LL - Struct { a, _ } = Struct { a: 1, b: 2 }; -LL + Struct { a, b: _ } = Struct { a: 1, b: 2 }; - | +LL | Struct { a, b: _ } = Struct { a: 1, b: 2 }; + | ++ help: or always ignore missing fields here | LL - Struct { a, _ } = Struct { a: 1, b: 2 }; diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr index 28e7975c7a234..305fbbd275f1f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&str: AsExpression` is not satisfied - --> $DIR/as_expression.rs:55:15 + --> $DIR/as_expression.rs:56:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index 4f685c508c721..90bb715a0522f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&str: AsExpression<::SqlType>` is not satisfied - --> $DIR/as_expression.rs:55:21 + --> $DIR/as_expression.rs:56:21 | LL | SelectInt.check("bar"); | ----- ^^^^^ the trait `AsExpression<::SqlType>` is not implemented for `&str` @@ -8,7 +8,7 @@ LL | SelectInt.check("bar"); | = help: the trait `AsExpression` is implemented for `&str` note: required by a bound in `Foo::check` - --> $DIR/as_expression.rs:46:12 + --> $DIR/as_expression.rs:47:12 | LL | fn check(&self, _: T) -> ::SqlType>>::Expression | ----- required by a bound in this associated function @@ -17,7 +17,7 @@ LL | T: AsExpression, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check` error[E0271]: type mismatch resolving `::SqlType == Text` - --> $DIR/as_expression.rs:55:5 + --> $DIR/as_expression.rs:56:5 | LL | SelectInt.check("bar"); | ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs index 48c1ed2b02d71..73a238ddf50d5 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro pub trait Expression { type SqlType; diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr index 47597a5d405e4..8a478a5c7336f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:10:1 + --> $DIR/does_not_acccept_args.rs:11:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:14:1 + --> $DIR/does_not_acccept_args.rs:15:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:18:1 + --> $DIR/does_not_acccept_args.rs:19:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr index 47597a5d405e4..8a478a5c7336f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:10:1 + --> $DIR/does_not_acccept_args.rs:11:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:14:1 + --> $DIR/does_not_acccept_args.rs:15:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:18:1 + --> $DIR/does_not_acccept_args.rs:19:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs index eeff5e2e6e8fc..5c21c045e10aa 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs @@ -2,6 +2,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.syntax trait Foo {} trait Bar {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index ee6ebabadd97a..e348f0c890287 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:6:1 + --> $DIR/incorrect-locations.rs:7:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,49 +7,49 @@ LL | #[diagnostic::do_not_recommend] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:10:1 + --> $DIR/incorrect-locations.rs:11:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:14:1 + --> $DIR/incorrect-locations.rs:15:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:18:1 + --> $DIR/incorrect-locations.rs:19:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:22:1 + --> $DIR/incorrect-locations.rs:23:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:26:1 + --> $DIR/incorrect-locations.rs:27:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:30:1 + --> $DIR/incorrect-locations.rs:31:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:34:1 + --> $DIR/incorrect-locations.rs:35:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:38:1 + --> $DIR/incorrect-locations.rs:39:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr index ee6ebabadd97a..e348f0c890287 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:6:1 + --> $DIR/incorrect-locations.rs:7:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,49 +7,49 @@ LL | #[diagnostic::do_not_recommend] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:10:1 + --> $DIR/incorrect-locations.rs:11:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:14:1 + --> $DIR/incorrect-locations.rs:15:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:18:1 + --> $DIR/incorrect-locations.rs:19:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:22:1 + --> $DIR/incorrect-locations.rs:23:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:26:1 + --> $DIR/incorrect-locations.rs:27:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:30:1 + --> $DIR/incorrect-locations.rs:31:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:34:1 + --> $DIR/incorrect-locations.rs:35:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:38:1 + --> $DIR/incorrect-locations.rs:39:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs index 1cf436aa2af3f..e716457eaedf4 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs @@ -2,6 +2,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.allowed-positions #[diagnostic::do_not_recommend] //~^WARN `#[diagnostic::do_not_recommend]` can only be placed diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr index b14c68d689766..cb1da8ff8be38 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/nested.rs:21:18 + --> $DIR/nested.rs:22:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/nested.rs:18:18 + --> $DIR/nested.rs:19:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr index b14c68d689766..cb1da8ff8be38 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/nested.rs:21:18 + --> $DIR/nested.rs:22:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/nested.rs:18:18 + --> $DIR/nested.rs:19:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs index 6534157d1fb2e..3c96c760dfb21 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro trait Root {} trait DontRecommend {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr index 884b13c17b802..dd425f1e6ee6b 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:15:17 + --> $DIR/simple.rs:16:17 | LL | needs_foo::<*mut ()>(); | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | note: required by a bound in `needs_foo` - --> $DIR/simple.rs:10:17 + --> $DIR/simple.rs:11:17 | LL | fn needs_foo() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr index 884b13c17b802..dd425f1e6ee6b 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:15:17 + --> $DIR/simple.rs:16:17 | LL | needs_foo::<*mut ()>(); | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | note: required by a bound in `needs_foo` - --> $DIR/simple.rs:10:17 + --> $DIR/simple.rs:11:17 | LL | fn needs_foo() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs index 6bca2b724d240..a6fa7ac7949e0 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro trait Foo {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr index d86058063955e..d940c3fd47793 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/stacked.rs:17:18 + --> $DIR/stacked.rs:18:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/stacked.rs:14:18 + --> $DIR/stacked.rs:15:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr index d86058063955e..d940c3fd47793 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/stacked.rs:17:18 + --> $DIR/stacked.rs:18:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/stacked.rs:14:18 + --> $DIR/stacked.rs:15:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs index 842e04b9d9017..fd7be35ff841a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro trait Root {} trait DontRecommend {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr index 95ccbb92a89b0..0b07b0731725b 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/supress_suggestions_in_help.rs:21:11 + --> $DIR/supress_suggestions_in_help.rs:22:11 | LL | check(()); | ----- ^^ the trait `Foo` is not implemented for `()` @@ -8,7 +8,7 @@ LL | check(()); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `check` - --> $DIR/supress_suggestions_in_help.rs:18:18 + --> $DIR/supress_suggestions_in_help.rs:19:18 | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr index 95ccbb92a89b0..0b07b0731725b 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/supress_suggestions_in_help.rs:21:11 + --> $DIR/supress_suggestions_in_help.rs:22:11 | LL | check(()); | ----- ^^ the trait `Foo` is not implemented for `()` @@ -8,7 +8,7 @@ LL | check(()); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `check` - --> $DIR/supress_suggestions_in_help.rs:18:18 + --> $DIR/supress_suggestions_in_help.rs:19:18 | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs index 2c7c151612303..04cf8243a6733 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro trait Foo {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr index b53febbb71ab8..31a1ae991ec43 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr @@ -1,11 +1,11 @@ error[E0277]: Very important message! - --> $DIR/type_mismatch.rs:23:14 + --> $DIR/type_mismatch.rs:24:14 | LL | verify::(); | ^^ the trait `TheImportantOne` is not implemented for `u8` | note: required by a bound in `verify` - --> $DIR/type_mismatch.rs:20:14 + --> $DIR/type_mismatch.rs:21:14 | LL | fn verify() {} | ^^^^^^^^^^^^^^^ required by this bound in `verify` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr index b53febbb71ab8..31a1ae991ec43 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr @@ -1,11 +1,11 @@ error[E0277]: Very important message! - --> $DIR/type_mismatch.rs:23:14 + --> $DIR/type_mismatch.rs:24:14 | LL | verify::(); | ^^ the trait `TheImportantOne` is not implemented for `u8` | note: required by a bound in `verify` - --> $DIR/type_mismatch.rs:20:14 + --> $DIR/type_mismatch.rs:21:14 | LL | fn verify() {} | ^^^^^^^^^^^^^^^ required by this bound in `verify` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs index 7f30fdb06c75a..b5bd14745cda3 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro #[diagnostic::on_unimplemented(message = "Very important message!")] trait TheImportantOne {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr index a8429ff60f83a..7e348842e19da 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/with_lifetime.rs:17:5 + --> $DIR/with_lifetime.rs:18:5 | LL | fn foo<'a>(a: &'a ()) { | -- lifetime `'a` defined here diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr index a8429ff60f83a..7e348842e19da 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/with_lifetime.rs:17:5 + --> $DIR/with_lifetime.rs:18:5 | LL | fn foo<'a>(a: &'a ()) { | -- lifetime `'a` defined here diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs index 6a67d83d5fe4d..98916ed061f1a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver +//@ reference: attributes.diagnostic.do_not_recommend.intro trait Root {} trait DontRecommend {} diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr index f41e2f6555675..86d778c6ec05b 100644 --- a/tests/ui/diagnostic_namespace/suggest_typos.stderr +++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr @@ -11,9 +11,8 @@ LL | #![deny(unknown_or_malformed_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: an attribute with a similar name exists | -LL - #[diagnostic::onunimplemented] -LL + #[diagnostic::on_unimplemented] - | +LL | #[diagnostic::on_unimplemented] + | + error: unknown diagnostic attribute --> $DIR/suggest_typos.rs:9:15 @@ -35,9 +34,8 @@ LL | #[diagnostic::on_implemented] | help: an attribute with a similar name exists | -LL - #[diagnostic::on_implemented] -LL + #[diagnostic::on_unimplemented] - | +LL | #[diagnostic::on_unimplemented] + | ++ error: aborting due to 3 previous errors diff --git a/tests/ui/dropck/dropck-only-error-ambiguity.rs b/tests/ui/dropck/dropck-only-error-ambiguity.rs new file mode 100644 index 0000000000000..ddba2af707032 --- /dev/null +++ b/tests/ui/dropck/dropck-only-error-ambiguity.rs @@ -0,0 +1,23 @@ +// Test that we don't ICE for a typeck error that only shows up in dropck +// Version where the normalization error is an ambiguous trait implementation. +// <[T] as ToOwned>::Owned is ambiguous on whether to use T: Clone or [T]::Clone. +// Regression test for #105299 + +pub trait Foo: Clone {} + +pub struct Bar<'a, T: Clone> { + pub cow: std::borrow::Cow<'a, [T]>, + + pub THIS_CAUSES_ICE: (), +} + +impl Bar<'_, T> +where + T: Clone, + [T]: Foo, +{ + pub fn MOVES_SELF(self) {} + //~^ ERROR type annotations needed +} + +pub fn main() {} diff --git a/tests/ui/dropck/dropck-only-error-ambiguity.stderr b/tests/ui/dropck/dropck-only-error-ambiguity.stderr new file mode 100644 index 0000000000000..de19bd49f4e9a --- /dev/null +++ b/tests/ui/dropck/dropck-only-error-ambiguity.stderr @@ -0,0 +1,11 @@ +error[E0284]: type annotations needed + --> $DIR/dropck-only-error-ambiguity.rs:19:23 + | +LL | pub fn MOVES_SELF(self) {} + | ^^^^ cannot infer type + | + = note: cannot satisfy `<[T] as ToOwned>::Owned == _` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/crashes/135039.rs b/tests/ui/dropck/dropck-only-error-async.rs similarity index 62% rename from tests/crashes/135039.rs rename to tests/ui/dropck/dropck-only-error-async.rs index c4c5336fd4fdd..71158e3c6ef7a 100644 --- a/tests/crashes/135039.rs +++ b/tests/ui/dropck/dropck-only-error-async.rs @@ -1,7 +1,6 @@ -//@ known-bug: #135039 -//@ edition:2021 - -pub type UserId = <::User as AuthUser>::Id; +// Test that we don't ICE for a typeck error that only shows up in dropck +// issue #135039 +//@ edition:2018 pub trait AuthUser { type Id; @@ -13,7 +12,7 @@ pub trait AuthnBackend { pub struct AuthSession { user: Option, - data: Option>, + data: Option<<::User as AuthUser>::Id>, } pub trait Authz: Sized { @@ -27,8 +26,12 @@ pub trait Query { pub async fn run_query + 'static>( auth: AuthSession, + //~^ ERROR the trait bound `User: AuthUser` is not satisfied [E0277] + //~| ERROR the trait bound `User: AuthUser` is not satisfied [E0277] query: Q, ) -> Result { let user = auth.user; query.run().await } + +fn main() {} diff --git a/tests/ui/dropck/dropck-only-error-async.stderr b/tests/ui/dropck/dropck-only-error-async.stderr new file mode 100644 index 0000000000000..4a069c8ac33a6 --- /dev/null +++ b/tests/ui/dropck/dropck-only-error-async.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `User: AuthUser` is not satisfied + --> $DIR/dropck-only-error-async.rs:28:5 + | +LL | auth: AuthSession, + | ^^^^ the trait `AuthUser` is not implemented for `User` + +error[E0277]: the trait bound `User: AuthUser` is not satisfied + --> $DIR/dropck-only-error-async.rs:28:5 + | +LL | auth: AuthSession, + | ^^^^ the trait `AuthUser` is not implemented for `User` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/crashes/91985.rs b/tests/ui/dropck/dropck-only-error-gat.rs similarity index 70% rename from tests/crashes/91985.rs rename to tests/ui/dropck/dropck-only-error-gat.rs index 338550430e1f8..dadcf76a43f35 100644 --- a/tests/crashes/91985.rs +++ b/tests/ui/dropck/dropck-only-error-gat.rs @@ -1,6 +1,6 @@ -//@ known-bug: #91985 - -#![feature(generic_associated_types)] +// Test that we don't ICE for a typeck error that only shows up in dropck +// Version that uses a generic associated type +// Regression test for #91985 pub trait Trait1 { type Associated: Ord; @@ -22,7 +22,7 @@ impl GatTrait for GatStruct { pub struct OuterStruct { inner: InnerStruct, - t1: T1, + t1: T1, } pub struct InnerStruct { @@ -35,6 +35,7 @@ where T2: Trait2, { pub fn new() -> Self { + //~^ ERROR the trait bound `::Associated: Clone` is not satisfied todo!() } } diff --git a/tests/ui/dropck/dropck-only-error-gat.stderr b/tests/ui/dropck/dropck-only-error-gat.stderr new file mode 100644 index 0000000000000..53982c0826a74 --- /dev/null +++ b/tests/ui/dropck/dropck-only-error-gat.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `::Associated: Clone` is not satisfied + --> $DIR/dropck-only-error-gat.rs:37:21 + | +LL | pub fn new() -> Self { + | ^^^^ the trait `Clone` is not implemented for `::Associated` + | +note: required by a bound in `GatTrait::Gat` + --> $DIR/dropck-only-error-gat.rs:14:17 + | +LL | type Gat; + | ^^^^^ required by this bound in `GatTrait::Gat` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dropck/dropck-only-error.rs b/tests/ui/dropck/dropck-only-error.rs new file mode 100644 index 0000000000000..e85eeb82e00b9 --- /dev/null +++ b/tests/ui/dropck/dropck-only-error.rs @@ -0,0 +1,23 @@ +// Test that we don't ICE for a typeck error that only shows up in dropck +// issue #135039 + +pub trait AuthUser { + type Id; +} + +pub trait AuthnBackend { + type User: AuthUser; +} + +pub struct AuthSession { + data: Option<<::User as AuthUser>::Id>, +} + +pub trait Authz: Sized { + type AuthnBackend: AuthnBackend; +} + +pub fn run_query(auth: AuthSession) {} +//~^ ERROR the trait bound `User: AuthUser` is not satisfied [E0277] + +fn main() {} diff --git a/tests/ui/dropck/dropck-only-error.stderr b/tests/ui/dropck/dropck-only-error.stderr new file mode 100644 index 0000000000000..6c7cd5d296c40 --- /dev/null +++ b/tests/ui/dropck/dropck-only-error.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `User: AuthUser` is not satisfied + --> $DIR/dropck-only-error.rs:20:31 + | +LL | pub fn run_query(auth: AuthSession) {} + | ^^^^ the trait `AuthUser` is not implemented for `User` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-compatibility/multiple-supers-should-work.rs b/tests/ui/dyn-compatibility/multiple-supers-should-work.rs new file mode 100644 index 0000000000000..6f381da9a2200 --- /dev/null +++ b/tests/ui/dyn-compatibility/multiple-supers-should-work.rs @@ -0,0 +1,21 @@ +//@ check-pass + +// We previously incorrectly deduplicated the list of projection bounds +// of trait objects, causing us to incorrectly reject this code, cc #136458. + +trait Sup { + type Assoc; +} + +impl Sup for () { + type Assoc = T; +} + +trait Trait: Sup + Sup {} + +impl Trait for () {} + +fn main() { + let x: &dyn Trait<(), _> = &(); + let y: &dyn Trait<_, ()> = x; +} diff --git a/tests/ui/error-codes/E0027.stderr b/tests/ui/error-codes/E0027.stderr index 3a1ebf2971946..72f20a845567b 100644 --- a/tests/ui/error-codes/E0027.stderr +++ b/tests/ui/error-codes/E0027.stderr @@ -25,19 +25,16 @@ LL | Dog { name: x, } => {} | help: include the missing field in the pattern | -LL - Dog { name: x, } => {} -LL + Dog { name: x, age } => {} - | +LL | Dog { name: x, age } => {} + | +++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - Dog { name: x, } => {} -LL + Dog { name: x, age: _ } => {} - | +LL | Dog { name: x, age: _ } => {} + | ++++++ help: or always ignore missing fields here | -LL - Dog { name: x, } => {} -LL + Dog { name: x, .. } => {} - | +LL | Dog { name: x, .. } => {} + | ++ error[E0027]: pattern does not mention field `age` --> $DIR/E0027.rs:19:9 @@ -47,19 +44,16 @@ LL | Dog { name: x , } => {} | help: include the missing field in the pattern | -LL - Dog { name: x , } => {} -LL + Dog { name: x, age } => {} - | +LL | Dog { name: x, age } => {} + | ~~~~~~~ help: if you don't care about this missing field, you can explicitly ignore it | -LL - Dog { name: x , } => {} -LL + Dog { name: x, age: _ } => {} - | +LL | Dog { name: x, age: _ } => {} + | ~~~~~~~~~~ help: or always ignore missing fields here | -LL - Dog { name: x , } => {} -LL + Dog { name: x, .. } => {} - | +LL | Dog { name: x, .. } => {} + | ~~~~~~ error[E0027]: pattern does not mention fields `name`, `age` --> $DIR/E0027.rs:22:9 @@ -69,19 +63,16 @@ LL | Dog {} => {} | help: include the missing fields in the pattern | -LL - Dog {} => {} -LL + Dog { name, age } => {} - | +LL | Dog { name, age } => {} + | +++++++++ help: if you don't care about these missing fields, you can explicitly ignore them | -LL - Dog {} => {} -LL + Dog { name: _, age: _ } => {} - | +LL | Dog { name: _, age: _ } => {} + | +++++++++++++++ help: or always ignore missing fields here | -LL - Dog {} => {} -LL + Dog { .. } => {} - | +LL | Dog { .. } => {} + | ++ error: aborting due to 4 previous errors diff --git a/tests/ui/error-codes/E0057.stderr b/tests/ui/error-codes/E0057.stderr index 35bd842b2cf4c..26c9689b9c58e 100644 --- a/tests/ui/error-codes/E0057.stderr +++ b/tests/ui/error-codes/E0057.stderr @@ -11,9 +11,8 @@ LL | let f = |x| x * 3; | ^^^ help: provide the argument | -LL - let a = f(); -LL + let a = f(/* x */); - | +LL | let a = f(/* x */); + | +++++++ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/E0057.rs:5:13 diff --git a/tests/ui/error-codes/E0060.stderr b/tests/ui/error-codes/E0060.stderr index fc52c6fc5ea50..7065b623ad325 100644 --- a/tests/ui/error-codes/E0060.stderr +++ b/tests/ui/error-codes/E0060.stderr @@ -11,9 +11,8 @@ LL | fn printf(_: *const u8, ...) -> u32; | ^^^^^^ - help: provide the argument | -LL - unsafe { printf(); } -LL + unsafe { printf(/* *const u8 */); } - | +LL | unsafe { printf(/* *const u8 */); } + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0061.stderr b/tests/ui/error-codes/E0061.stderr index b70d607ebeb64..cab72a984a6b0 100644 --- a/tests/ui/error-codes/E0061.stderr +++ b/tests/ui/error-codes/E0061.stderr @@ -11,9 +11,8 @@ LL | fn f(a: u16, b: &str) {} | ^ ------- help: provide the argument | -LL - f(0); -LL + f(0, /* &str */); - | +LL | f(0, /* &str */); + | ++++++++++++ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/E0061.rs:9:5 @@ -28,9 +27,8 @@ LL | fn f2(a: u16) {} | ^^ ------ help: provide the argument | -LL - f2(); -LL + f2(/* u16 */); - | +LL | f2(/* u16 */); + | +++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0259.stderr b/tests/ui/error-codes/E0259.stderr index 08d3deb68d233..1833fe90f3d5c 100644 --- a/tests/ui/error-codes/E0259.stderr +++ b/tests/ui/error-codes/E0259.stderr @@ -10,9 +10,8 @@ LL | extern crate test as alloc; = note: `alloc` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate test as alloc; -LL + extern crate test as other_alloc; - | +LL | extern crate test as other_alloc; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0260.stderr b/tests/ui/error-codes/E0260.stderr index cb47b77904a38..10811d1f31871 100644 --- a/tests/ui/error-codes/E0260.stderr +++ b/tests/ui/error-codes/E0260.stderr @@ -10,9 +10,8 @@ LL | mod alloc { = note: `alloc` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate alloc; -LL + extern crate alloc as other_alloc; - | +LL | extern crate alloc as other_alloc; + | ++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr index 54bde98b57f9f..d9acdbea3fc02 100644 --- a/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr +++ b/tests/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -12,11 +12,8 @@ LL | | )) {} = note: `#[warn(anonymous_parameters)]` on by default help: try naming the parameter or explicitly ignoring it | -LL ~ fn test(x: u32, _: ( -LL + -LL + -LL ~ )) {} - | +LL | fn test(x: u32, _: ( + | ++ warning: 1 warning emitted diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr index b9a128e02e16b..79efcc5d8b041 100644 --- a/tests/ui/extern-flag/empty-extern-arg.stderr +++ b/tests/ui/extern-flag/empty-extern-arg.stderr @@ -7,11 +7,5 @@ error: unwinding panics are not supported without std = help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem -error: requires `sized` lang_item - --> $DIR/empty-extern-arg.rs:6:11 - | -LL | fn main() {} - | ^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/extern/extern-crate-rename.stderr b/tests/ui/extern/extern-crate-rename.stderr index 4d4a585de60c1..88b78a07485d4 100644 --- a/tests/ui/extern/extern-crate-rename.stderr +++ b/tests/ui/extern/extern-crate-rename.stderr @@ -9,9 +9,8 @@ LL | extern crate m2 as m1; = note: `m1` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate m2 as m1; -LL + extern crate m2 as other_m1; - | +LL | extern crate m2 as other_m1; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/extern/extern-vectorcall.rs b/tests/ui/extern/extern-vectorcall.rs index c0d872bc14beb..fb23c4cd5b549 100644 --- a/tests/ui/extern/extern-vectorcall.rs +++ b/tests/ui/extern/extern-vectorcall.rs @@ -2,6 +2,7 @@ //@ revisions: x64 x32 //@ [x64]only-x86_64 //@ [x32]only-x86 +//@ [x32]compile-flags: -Ctarget-feature=+sse2 #![feature(abi_vectorcall)] diff --git a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs index 5386628a8e069..ce3d3fc645d76 100644 --- a/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs +++ b/tests/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -1,5 +1,5 @@ //@ needs-llvm-components: avr -//@ compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib +//@ compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib #![no_core] #![feature(no_core, lang_items)] #[lang="sized"] diff --git a/tests/ui/feature-gates/feature-gate-never_patterns.stderr b/tests/ui/feature-gates/feature-gate-never_patterns.stderr index dcd5db56da882..473e263c79650 100644 --- a/tests/ui/feature-gates/feature-gate-never_patterns.stderr +++ b/tests/ui/feature-gates/feature-gate-never_patterns.stderr @@ -58,19 +58,34 @@ error: `match` arm with no body --> $DIR/feature-gate-never_patterns.rs:38:9 | LL | Some(_) - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) => { todo!() } + | ++++++++++++++ error: `match` arm with no body --> $DIR/feature-gate-never_patterns.rs:43:9 | LL | Some(_) if false, - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if false => { todo!() }, + | ++++++++++++++ error: `match` arm with no body --> $DIR/feature-gate-never_patterns.rs:45:9 | LL | Some(_) if false - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if false => { todo!() } + | ++++++++++++++ error[E0658]: `!` patterns are experimental --> $DIR/feature-gate-never_patterns.rs:50:13 @@ -96,13 +111,23 @@ error: `match` arm with no body --> $DIR/feature-gate-never_patterns.rs:64:9 | LL | Some(_) - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) => { todo!() } + | ++++++++++++++ error: `match` arm with no body --> $DIR/feature-gate-never_patterns.rs:70:9 | LL | Some(_) if false - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if false => { todo!() } + | ++++++++++++++ error: a guard on a never pattern will never be run --> $DIR/feature-gate-never_patterns.rs:54:19 diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index 214725b77c049..7768c25bd2c37 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -165,9 +165,8 @@ LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} found signature `extern "rust-call" fn(&Bar, ()) -> ()` help: change the self-receiver type to match the trait | -LL - extern "rust-call" fn call_mut(&self, args: ()) -> () {} -LL + extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} - | +LL | extern "rust-call" fn call_mut(&mut self, args: ()) -> () {} + | +++ error[E0046]: not all trait items implemented, missing: `Output` --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:1 diff --git a/tests/ui/fmt/no-inline-literals-out-of-range.stderr b/tests/ui/fmt/no-inline-literals-out-of-range.stderr index e17023887046f..0800fb2497619 100644 --- a/tests/ui/fmt/no-inline-literals-out-of-range.stderr +++ b/tests/ui/fmt/no-inline-literals-out-of-range.stderr @@ -13,9 +13,8 @@ LL + format_args!("{}", 0x8f_u8); // issue #115423 | help: to use as a negative number (decimal `-113`), consider using the type `u8` for the literal and cast it to `i8` | -LL - format_args!("{}", 0x8f_i8); // issue #115423 -LL + format_args!("{}", 0x8f_u8 as i8); // issue #115423 - | +LL | format_args!("{}", 0x8f_u8 as i8); // issue #115423 + | +++++ error: literal out of range for `u8` --> $DIR/no-inline-literals-out-of-range.rs:6:24 diff --git a/tests/ui/fn/issue-3044.stderr b/tests/ui/fn/issue-3044.stderr index 8351818dc897c..787eeec09cc2f 100644 --- a/tests/ui/fn/issue-3044.stderr +++ b/tests/ui/fn/issue-3044.stderr @@ -11,8 +11,8 @@ note: method defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: provide the argument | -LL ~ needlesArr.iter().fold(|x, y| { -LL + +LL | needlesArr.iter().fold(|x, y| { +LL | LL ~ }, /* f */); | diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr index 88aa3cd036833..835e0a3343e9a 100644 --- a/tests/ui/fn/param-mismatch-foreign.stderr +++ b/tests/ui/fn/param-mismatch-foreign.stderr @@ -11,9 +11,8 @@ LL | fn foo(x: i32, y: u32, z: i32); | ^^^ - help: provide the argument | -LL - foo(1i32, 2i32); -LL + foo(1i32, /* u32 */, 2i32); - | +LL | foo(1i32, /* u32 */, 2i32); + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-91883.stderr b/tests/ui/generic-associated-types/issue-91883.current.stderr similarity index 90% rename from tests/ui/generic-associated-types/issue-91883.stderr rename to tests/ui/generic-associated-types/issue-91883.current.stderr index ac636ebb648cb..0741cf9581d58 100644 --- a/tests/ui/generic-associated-types/issue-91883.stderr +++ b/tests/ui/generic-associated-types/issue-91883.current.stderr @@ -1,5 +1,5 @@ error[E0478]: lifetime bound not satisfied - --> $DIR/issue-91883.rs:30:24 + --> $DIR/issue-91883.rs:34:24 | LL | type Cursor<'tx>: Cursor<'tx> | ----------------------------- definition of `Cursor` from trait @@ -8,12 +8,12 @@ LL | type Cursor<'tx> = CursorImpl<'tx>; | ^^^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'db` as defined here - --> $DIR/issue-91883.rs:29:6 + --> $DIR/issue-91883.rs:33:6 | LL | impl<'db> Transaction<'db> for TransactionImpl<'db> { | ^^^ note: but lifetime parameter must outlive the lifetime `'tx` as defined here - --> $DIR/issue-91883.rs:30:17 + --> $DIR/issue-91883.rs:34:17 | LL | type Cursor<'tx> = CursorImpl<'tx>; | ^^^ diff --git a/tests/ui/generic-associated-types/issue-91883.next.stderr b/tests/ui/generic-associated-types/issue-91883.next.stderr new file mode 100644 index 0000000000000..b3ed2d81b63e8 --- /dev/null +++ b/tests/ui/generic-associated-types/issue-91883.next.stderr @@ -0,0 +1,20 @@ +error[E0478]: lifetime bound not satisfied + --> $DIR/issue-91883.rs:34:24 + | +LL | type Cursor<'tx> = CursorImpl<'tx>; + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'db` as defined here + --> $DIR/issue-91883.rs:33:6 + | +LL | impl<'db> Transaction<'db> for TransactionImpl<'db> { + | ^^^ +note: but lifetime parameter must outlive the lifetime `'tx` as defined here + --> $DIR/issue-91883.rs:34:17 + | +LL | type Cursor<'tx> = CursorImpl<'tx>; + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0478`. diff --git a/tests/ui/generic-associated-types/issue-91883.rs b/tests/ui/generic-associated-types/issue-91883.rs index e870e08a3a2b0..d31e1736cf28f 100644 --- a/tests/ui/generic-associated-types/issue-91883.rs +++ b/tests/ui/generic-associated-types/issue-91883.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::fmt::Debug; use std::marker::PhantomData; diff --git a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr index 4f9fc0ac6492c..9f94b3aff8821 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr @@ -11,9 +11,8 @@ LL | fn f(i: I) | ^ ---- help: provide the argument | -LL - f(&[f()]); -LL + f(&[f(/* i */)]); - | +LL | f(&[f(/* i */)]); + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/implicit-capture-late.rs b/tests/ui/impl-trait/implicit-capture-late.rs index 986620b101bdd..13cbcd66f8d87 100644 --- a/tests/ui/impl-trait/implicit-capture-late.rs +++ b/tests/ui/impl-trait/implicit-capture-late.rs @@ -1,13 +1,13 @@ -//@ known-bug: #117647 +//@ edition: 2024 -#![feature(lifetime_capture_rules_2024)] #![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] use std::ops::Deref; -fn foo(x: Vec) -> Box Deref> { +fn foo(x: Vec) -> Box Deref> { //~ ['a: o] + //~^ ERROR cannot capture higher-ranked lifetime Box::new(x) } diff --git a/tests/ui/impl-trait/implicit-capture-late.stderr b/tests/ui/impl-trait/implicit-capture-late.stderr index 3adf78322d2e5..085d3eaedd48c 100644 --- a/tests/ui/impl-trait/implicit-capture-late.stderr +++ b/tests/ui/impl-trait/implicit-capture-late.stderr @@ -1,17 +1,17 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/implicit-capture-late.rs:10:55 + --> $DIR/implicit-capture-late.rs:9:55 | LL | fn foo(x: Vec) -> Box Deref> { | ^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here - --> $DIR/implicit-capture-late.rs:10:36 + --> $DIR/implicit-capture-late.rs:9:36 | LL | fn foo(x: Vec) -> Box Deref> { | ^^ error: ['a: o] - --> $DIR/implicit-capture-late.rs:10:55 + --> $DIR/implicit-capture-late.rs:9:55 | LL | fn foo(x: Vec) -> Box Deref> { | ^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs index c1a78bc23885c..1bbff839ffa56 100644 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs +++ b/tests/ui/impl-trait/in-trait/default-body-with-rpit.rs @@ -1,5 +1,8 @@ //@ edition:2021 //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver use std::fmt::Debug; diff --git a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr index b7797317ea68f..7c064cc717699 100644 --- a/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr +++ b/tests/ui/impl-trait/in-trait/expeced-refree-to-map-to-reearlybound-ice-108580.stderr @@ -12,9 +12,8 @@ LL | fn bar(&self) -> impl Iterator + '_ { = note: `#[warn(refining_impl_trait_internal)]` on by default help: replace the return type so that it matches the trait | -LL - fn bar(&self) -> impl Iterator + '_ { -LL + fn bar(&self) -> impl Iterator + '_ { - | +LL | fn bar(&self) -> impl Iterator + '_ { + | +++++++++++++++++++ warning: 1 warning emitted diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit-bounds.rs b/tests/ui/impl-trait/in-trait/nested-rpitit-bounds.rs index 10c2a81124346..6954a7d806726 100644 --- a/tests/ui/impl-trait/in-trait/nested-rpitit-bounds.rs +++ b/tests/ui/impl-trait/in-trait/nested-rpitit-bounds.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver use std::ops::Deref; diff --git a/tests/ui/impl-trait/in-trait/refine-captures.stderr b/tests/ui/impl-trait/in-trait/refine-captures.stderr index 8a5c8d3c77b0f..166991894d166 100644 --- a/tests/ui/impl-trait/in-trait/refine-captures.stderr +++ b/tests/ui/impl-trait/in-trait/refine-captures.stderr @@ -9,9 +9,8 @@ LL | fn test() -> impl Sized + use<> {} = note: `#[warn(refining_impl_trait_internal)]` on by default help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<> {} -LL + fn test() -> impl Sized + use<'a> {} - | +LL | fn test() -> impl Sized + use<'a> {} + | ++ warning: impl trait in impl method captures fewer lifetimes than in trait --> $DIR/refine-captures.rs:22:31 @@ -23,9 +22,8 @@ LL | fn test() -> impl Sized + use<> {} = note: we are soliciting feedback, see issue #121718 for more information help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<> {} -LL + fn test() -> impl Sized + use<'a> {} - | +LL | fn test() -> impl Sized + use<'a> {} + | ++ warning: impl trait in impl method captures fewer lifetimes than in trait --> $DIR/refine-captures.rs:27:31 @@ -37,9 +35,8 @@ LL | fn test() -> impl Sized + use<'b> {} = note: we are soliciting feedback, see issue #121718 for more information help: modify the `use<..>` bound to capture the same lifetimes that the trait does | -LL - fn test() -> impl Sized + use<'b> {} -LL + fn test() -> impl Sized + use<'a, 'b> {} - | +LL | fn test() -> impl Sized + use<'a, 'b> {} + | ++++ error: `impl Trait` must mention all type parameters in scope in `use<...>` --> $DIR/refine-captures.rs:32:18 diff --git a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 46561b66c8ee1..ba7d7770e5038 100644 --- a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -41,9 +41,8 @@ LL + fn elided2(x: &i32) -> impl Copy + '_ { x } | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn elided2(x: &i32) -> impl Copy + 'static { x } -LL + fn elided2(x: &'static i32) -> impl Copy + 'static { x } - | +LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } + | +++++++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:12:55 @@ -172,9 +171,8 @@ LL + fn elided4(x: &i32) -> Box { Box::new(x) } | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn elided4(x: &i32) -> Box { Box::new(x) } -LL + fn elided4(x: &'static i32) -> Box { Box::new(x) } - | +LL | fn elided4(x: &'static i32) -> Box { Box::new(x) } + | +++++++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:27:60 diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs index 3dc8523e9635d..925f03589e894 100644 --- a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs @@ -1,9 +1,8 @@ //@ check-pass +//@ edition: 2024 // Show how precise captures allow us to skip capturing a higher-ranked lifetime -#![feature(lifetime_capture_rules_2024)] - trait Trait<'a> { type Item; } diff --git a/tests/ui/impl-trait/precise-capturing/outlives.rs b/tests/ui/impl-trait/precise-capturing/outlives.rs index f86a61be1e078..45e46848eea7c 100644 --- a/tests/ui/impl-trait/precise-capturing/outlives.rs +++ b/tests/ui/impl-trait/precise-capturing/outlives.rs @@ -1,9 +1,8 @@ //@ check-pass +//@ edition: 2024 // Show that precise captures allow us to skip a lifetime param for outlives -#![feature(lifetime_capture_rules_2024)] - fn hello<'a: 'a, 'b: 'b>() -> impl Sized + use<'a> { } fn outlives<'a, T: 'a>(_: T) {} diff --git a/tests/ui/impl-trait/variance.e2024.stderr b/tests/ui/impl-trait/variance.e2024.stderr index 361a165da66f3..adbe8b91e866f 100644 --- a/tests/ui/impl-trait/variance.e2024.stderr +++ b/tests/ui/impl-trait/variance.e2024.stderr @@ -1,23 +1,23 @@ error: ['a: *, 'a: o] - --> $DIR/variance.rs:13:36 + --> $DIR/variance.rs:11:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 + --> $DIR/variance.rs:15:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:20:40 + --> $DIR/variance.rs:17:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:25:36 + --> $DIR/variance.rs:21:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.new.stderr b/tests/ui/impl-trait/variance.new.stderr deleted file mode 100644 index 361a165da66f3..0000000000000 --- a/tests/ui/impl-trait/variance.new.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: ['a: *, 'a: o] - --> $DIR/variance.rs:13:36 - | -LL | fn not_captured_early<'a: 'a>() -> impl Sized {} - | ^^^^^^^^^^ - -error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 - | -LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: ['a: o] - --> $DIR/variance.rs:20:40 - | -LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} - | ^^^^^^^^^^ - -error: ['a: o] - --> $DIR/variance.rs:25:36 - | -LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - diff --git a/tests/ui/impl-trait/variance.old.stderr b/tests/ui/impl-trait/variance.old.stderr index 578d6fd14cd20..57ffa7cde31c4 100644 --- a/tests/ui/impl-trait/variance.old.stderr +++ b/tests/ui/impl-trait/variance.old.stderr @@ -1,23 +1,23 @@ error: ['a: *] - --> $DIR/variance.rs:13:36 + --> $DIR/variance.rs:11:36 | LL | fn not_captured_early<'a: 'a>() -> impl Sized {} | ^^^^^^^^^^ error: ['a: *, 'a: o] - --> $DIR/variance.rs:18:32 + --> $DIR/variance.rs:15:32 | LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [] - --> $DIR/variance.rs:20:40 + --> $DIR/variance.rs:17:40 | LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} | ^^^^^^^^^^ error: ['a: o] - --> $DIR/variance.rs:25:36 + --> $DIR/variance.rs:21:36 | LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/variance.rs b/tests/ui/impl-trait/variance.rs index 1e359f033ff52..bde3a886a4d38 100644 --- a/tests/ui/impl-trait/variance.rs +++ b/tests/ui/impl-trait/variance.rs @@ -1,8 +1,6 @@ -//@ revisions: old new e2024 +//@ revisions: old e2024 //@[e2024] edition: 2024 -#![cfg_attr(new, feature(lifetime_capture_rules_2024))] - #![feature(rustc_attrs)] #![allow(internal_features)] #![rustc_variance_of_opaques] @@ -12,15 +10,13 @@ impl Captures<'_> for T {} fn not_captured_early<'a: 'a>() -> impl Sized {} //[old]~^ ['a: *] -//[new]~^^ ['a: *, 'a: o] -//[e2024]~^^^ ['a: *, 'a: o] +//[e2024]~^^ ['a: *, 'a: o] fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o] fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} //[old]~^ [] -//[new]~^^ ['a: o] -//[e2024]~^^^ ['a: o] +//[e2024]~^^ ['a: o] fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o] diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs index e36be26d003f2..6548c03d1b00c 100644 --- a/tests/ui/implied-bounds/bevy_world_query.rs +++ b/tests/ui/implied-bounds/bevy_world_query.rs @@ -1,3 +1,5 @@ +#![crate_name = "bevy_ecs"] + //@ check-pass // We currently special case bevy from erroring on incorrect implied bounds diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr index f498257e12f13..f8ee6fef82423 100644 --- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr +++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5 | LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str { @@ -25,4 +25,4 @@ LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr b/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr index 9a3ebfddc49c5..ec700cf7e5900 100644 --- a/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr +++ b/tests/ui/imports/extern-crate-self/extern-crate-self-fail.stderr @@ -6,9 +6,8 @@ LL | extern crate self; | help: rename the `self` crate to be able to import it | -LL - extern crate self; -LL + extern crate self as name; - | +LL | extern crate self as name; + | +++++++ error: `#[macro_use]` is not supported on `extern crate self` --> $DIR/extern-crate-self-fail.rs:3:1 diff --git a/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr index def0676a0f82c..2621f913186ee 100644 --- a/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr +++ b/tests/ui/imports/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr @@ -7,9 +7,8 @@ LL | extern crate std; = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate std; -LL + extern crate std as other_std; - | +LL | extern crate std as other_std; + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/import-self.stderr b/tests/ui/imports/issue-45829/import-self.stderr index b392d93c15410..5094a50635d53 100644 --- a/tests/ui/imports/issue-45829/import-self.stderr +++ b/tests/ui/imports/issue-45829/import-self.stderr @@ -62,9 +62,8 @@ LL | use foo::{self as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use foo::{self as A}; -LL + use foo::{self as OtherA}; - | +LL | use foo::{self as OtherA}; + | +++++ error: aborting due to 5 previous errors diff --git a/tests/ui/imports/issue-45829/issue-45829.stderr b/tests/ui/imports/issue-45829/issue-45829.stderr index 9fd0e5a767295..618fac350f023 100644 --- a/tests/ui/imports/issue-45829/issue-45829.stderr +++ b/tests/ui/imports/issue-45829/issue-45829.stderr @@ -9,9 +9,8 @@ LL | use foo::{A, B as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use foo::{A, B as A}; -LL + use foo::{A, B as OtherA}; - | +LL | use foo::{A, B as OtherA}; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr b/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr index 98fe16824ff76..f33b093725f06 100644 --- a/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr +++ b/tests/ui/imports/issue-45829/rename-extern-vs-use.stderr @@ -9,9 +9,8 @@ LL | extern crate issue_45829_b as bar; = note: `bar` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate issue_45829_b as bar; -LL + extern crate issue_45829_b as other_bar; - | +LL | extern crate issue_45829_b as other_bar; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-extern.stderr b/tests/ui/imports/issue-45829/rename-extern.stderr index f99f433c64241..2a3a05d1e7b48 100644 --- a/tests/ui/imports/issue-45829/rename-extern.stderr +++ b/tests/ui/imports/issue-45829/rename-extern.stderr @@ -9,9 +9,8 @@ LL | extern crate issue_45829_b as issue_45829_a; = note: `issue_45829_a` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate issue_45829_b as issue_45829_a; -LL + extern crate issue_45829_b as other_issue_45829_a; - | +LL | extern crate issue_45829_b as other_issue_45829_a; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr index e0647cd3ab68b..399de74a5919c 100644 --- a/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr +++ b/tests/ui/imports/issue-45829/rename-use-vs-extern.stderr @@ -9,9 +9,8 @@ LL | use std as issue_45829_b; = note: `issue_45829_b` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std as issue_45829_b; -LL + use std as other_issue_45829_b; - | +LL | use std as other_issue_45829_b; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename-with-path.stderr b/tests/ui/imports/issue-45829/rename-with-path.stderr index 45fdd46850e04..fc30eb1cf8d7e 100644 --- a/tests/ui/imports/issue-45829/rename-with-path.stderr +++ b/tests/ui/imports/issue-45829/rename-with-path.stderr @@ -9,9 +9,8 @@ LL | use std::{collections::HashMap as A, sync::Arc as A}; = note: `A` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std::{collections::HashMap as A, sync::Arc as A}; -LL + use std::{collections::HashMap as A, sync::Arc as OtherA}; - | +LL | use std::{collections::HashMap as A, sync::Arc as OtherA}; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-45829/rename.stderr b/tests/ui/imports/issue-45829/rename.stderr index dc5775e3d56d2..a17dc6964dada 100644 --- a/tests/ui/imports/issue-45829/rename.stderr +++ b/tests/ui/imports/issue-45829/rename.stderr @@ -9,9 +9,8 @@ LL | use std as core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std as core; -LL + use std as other_core; - | +LL | use std as other_core; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr index 4a5c85479d33d..bc9755732813c 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-buitlin.stderr @@ -14,9 +14,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as core; -LL + extern crate std as other_core; - | +LL | extern crate std as other_core; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr index 8b87ae93b4d5e..f1b60bbe39d5b 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-custom.stderr @@ -14,9 +14,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as empty; -LL + extern crate std as other_empty; - | +LL | extern crate std as other_empty; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr index 9a9e538740d7b..13e1aaacd7025 100644 --- a/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr +++ b/tests/ui/imports/multiple-extern-by-macro-for-inexist.stderr @@ -20,9 +20,8 @@ LL | m!(); = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can use `as` to change the binding name of the import | -LL - extern crate std as non_existent; -LL + extern crate std as other_non_existent; - | +LL | extern crate std as other_non_existent; + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/imports/no-std-inject.stderr b/tests/ui/imports/no-std-inject.stderr index d3952a50cd311..7299c2e8a9f39 100644 --- a/tests/ui/imports/no-std-inject.stderr +++ b/tests/ui/imports/no-std-inject.stderr @@ -7,9 +7,8 @@ LL | extern crate core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate core; -LL + extern crate core as other_core; - | +LL | extern crate core as other_core; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/include-macros/parent_dir.stderr b/tests/ui/include-macros/parent_dir.stderr index 23029e911203c..d0a1f4fd3b91f 100644 --- a/tests/ui/include-macros/parent_dir.stderr +++ b/tests/ui/include-macros/parent_dir.stderr @@ -20,9 +20,8 @@ LL | let _ = include_str!("hello.rs"); = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is a file with the same name in a different directory | -LL - let _ = include_str!("hello.rs"); -LL + let _ = include_str!("../hello.rs"); - | +LL | let _ = include_str!("../hello.rs"); + | +++ error: couldn't read `$DIR/../../data.bin`: $FILE_NOT_FOUND_MSG --> $DIR/parent_dir.rs:8:13 diff --git a/tests/ui/intrinsics/intrinsic-nearby.rs b/tests/ui/intrinsics/intrinsic-nearby.rs deleted file mode 100644 index 990ecfc2b70d0..0000000000000 --- a/tests/ui/intrinsics/intrinsic-nearby.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![feature(core_intrinsics)] - -use std::intrinsics::*; - -fn main() { - unsafe { - assert_eq!(nearbyintf32(5.234f32), 5f32); - assert_eq!(nearbyintf64(6.777f64), 7f64); - } -} diff --git a/tests/ui/issues/issue-20225.stderr b/tests/ui/issues/issue-20225.stderr index 6a3c4e2a836e0..775f23dd7e623 100644 --- a/tests/ui/issues/issue-20225.stderr +++ b/tests/ui/issues/issue-20225.stderr @@ -10,9 +10,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} found signature `extern "rust-call" fn(&Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call(&self, (_,): (T,)) {} -LL + extern "rust-call" fn call(&self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} + | +++ error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:51 @@ -26,9 +25,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} found signature `extern "rust-call" fn(&mut Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} -LL + extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} + | +++ error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:47 @@ -43,9 +41,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} found signature `extern "rust-call" fn(Foo, (_,))` help: change the parameter type to match the trait | -LL - extern "rust-call" fn call_once(self, (_,): (T,)) {} -LL + extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} - | +LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-20831-debruijn.stderr b/tests/ui/issues/issue-20831-debruijn.stderr index fe310998f091d..bed75ed6ba200 100644 --- a/tests/ui/issues/issue-20831-debruijn.stderr +++ b/tests/ui/issues/issue-20831-debruijn.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/issue-20831-debruijn.rs:28:33 | LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { @@ -48,4 +48,4 @@ LL | fn subscribe(&mut self, t : Box::Foo>::T; | help: if there were a trait named `Example` with associated type `T` implemented for `::Foo`, you could use the fully-qualified path | -LL - type FooT = <::Foo>::T; -LL + type FooT = <::Foo as Example>::T; - | +LL | type FooT = <::Foo as Example>::T; + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr index eabb08421121e..f54990d5d8618 100644 --- a/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr +++ b/tests/ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.stderr @@ -6,9 +6,8 @@ LL | let foo::Foo {} = foo::Foo::default(); | help: ignore the inaccessible and unused fields | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { .. } = foo::Foo::default(); - | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ++ error: pattern requires `..` due to inaccessible fields --> $DIR/issue-76077-1.rs:16:9 diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 81dc72852543d..b87a1d2031df4 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -82,3 +82,8 @@ type Impossible = (str, str); //~ ERROR: cannot be known at compilation time #[rustc_layout(debug)] union EmptyUnion {} //~ ERROR: has an unknown layout //~^ ERROR: unions cannot have zero fields + +// Test the error message of `LayoutError::TooGeneric` +// (this error is never emitted to users). +#[rustc_layout(debug)] +type TooGeneric = T; //~ ERROR: does not have a fixed layout diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 319c0de26a90e..07cad7766920f 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -31,6 +31,7 @@ error: layout_of(E) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(E) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -69,7 +71,9 @@ error: layout_of(E) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(4 bytes), @@ -83,6 +87,7 @@ error: layout_of(E) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 1, }, @@ -136,6 +141,7 @@ error: layout_of(S) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -161,6 +167,7 @@ error: layout_of(U) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -213,6 +220,7 @@ error: layout_of(Result) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -255,6 +263,7 @@ error: layout_of(Result) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -293,6 +302,7 @@ error: layout_of(Result) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -328,6 +338,7 @@ error: layout_of(i32) = Layout { ), fields: Primitive, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -353,6 +364,7 @@ error: layout_of(V) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -378,6 +390,7 @@ error: layout_of(W) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -403,6 +416,7 @@ error: layout_of(Y) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -428,6 +442,7 @@ error: layout_of(P1) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -453,6 +468,7 @@ error: layout_of(P2) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -478,6 +494,7 @@ error: layout_of(P3) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -503,6 +520,7 @@ error: layout_of(P4) = Layout { 1, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -533,6 +551,7 @@ error: layout_of(P5) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -563,6 +582,7 @@ error: layout_of(MaybeUninit) = Layout { 2, ), largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -596,12 +616,18 @@ error: the type has an unknown layout LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^ +error: the type `T` does not have a fixed layout + --> $DIR/debug.rs:89:1 + | +LL | type TooGeneric = T; + | ^^^^^^^^^^^^^^^^^^ + error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases --> $DIR/debug.rs:75:5 | LL | const C: () = (); | ^^^^^^^^^^^ -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.rs b/tests/ui/layout/gce-rigid-const-in-array-len.rs new file mode 100644 index 0000000000000..8e57907a2c5ec --- /dev/null +++ b/tests/ui/layout/gce-rigid-const-in-array-len.rs @@ -0,0 +1,27 @@ +//! With `feature(generic_const_exprs)`, anon consts (e.g. length in array types) will +//! inherit their parent's predicates. When combined with `feature(trivial_bounds)`, it +//! is possible to have an unevaluated constant that is rigid, but not generic. +//! +//! This is what happens below: `u8: A` does not hold in the global environment, but +//! with trivial bounds + GCE it it possible that `::B` can appear in an array +//! length without causing a compile error. This constant is *rigid* (i.e. it cannot be +//! normalized further), but it is *not generic* (i.e. it does not depend on any generic +//! parameters). +//! +//! This test ensures that we do not ICE in layout computation when encountering such a +//! constant. + +#![feature(rustc_attrs)] +#![feature(generic_const_exprs)] //~ WARNING: the feature `generic_const_exprs` is incomplete +#![feature(trivial_bounds)] + +#![crate_type = "lib"] + +trait A { + const B: usize; +} + +#[rustc_layout(debug)] +struct S([u8; ::B]) //~ ERROR: the type `[u8; ::B]` has an unknown layout +where + u8: A; diff --git a/tests/ui/layout/gce-rigid-const-in-array-len.stderr b/tests/ui/layout/gce-rigid-const-in-array-len.stderr new file mode 100644 index 0000000000000..6149debdfe88d --- /dev/null +++ b/tests/ui/layout/gce-rigid-const-in-array-len.stderr @@ -0,0 +1,17 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/gce-rigid-const-in-array-len.rs:15:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: the type `[u8; ::B]` has an unknown layout + --> $DIR/gce-rigid-const-in-array-len.rs:25:1 + | +LL | struct S([u8; ::B]) + | ^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 96f0a8c874086..90c06ba1f834e 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -31,6 +31,7 @@ error: layout_of(A) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(A) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -107,6 +109,7 @@ error: layout_of(B) = Layout { valid_range: 255..=255, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -132,6 +135,7 @@ error: layout_of(B) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -183,6 +187,7 @@ error: layout_of(C) = Layout { valid_range: 256..=256, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -208,6 +213,7 @@ error: layout_of(C) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -259,6 +265,7 @@ error: layout_of(P) = Layout { valid_range: 268435456..=268435456, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -284,6 +291,7 @@ error: layout_of(P) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -335,6 +343,7 @@ error: layout_of(T) = Layout { valid_range: 2164260864..=2164260864, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -360,6 +369,7 @@ error: layout_of(T) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index cd9e4c0278150..3bdb9c5c143e4 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -37,6 +37,7 @@ error: layout_of(MissingPayloadField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -78,6 +79,7 @@ error: layout_of(MissingPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -99,6 +101,7 @@ error: layout_of(MissingPayloadField) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -157,6 +160,7 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -199,6 +203,7 @@ error: layout_of(CommonPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -237,6 +242,7 @@ error: layout_of(CommonPayloadField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -294,6 +300,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -335,6 +342,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -372,6 +380,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -429,6 +438,7 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=4, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -486,6 +496,7 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -507,6 +518,7 @@ error: layout_of(NicheFirst) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -528,6 +540,7 @@ error: layout_of(NicheFirst) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 2, }, @@ -585,6 +598,7 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=4, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -642,6 +656,7 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -663,6 +678,7 @@ error: layout_of(NicheSecond) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -684,6 +700,7 @@ error: layout_of(NicheSecond) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 2, }, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 15a3f6004f50f..1d4e443644826 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -25,6 +25,7 @@ error: layout_of(Aligned1) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -50,6 +51,7 @@ error: layout_of(Aligned1) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -73,6 +75,7 @@ error: layout_of(Aligned1) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -128,6 +131,7 @@ error: layout_of(Aligned2) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -153,6 +157,7 @@ error: layout_of(Aligned2) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -176,6 +181,7 @@ error: layout_of(Aligned2) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/layout/normalization-failure.rs b/tests/ui/layout/normalization-failure.rs new file mode 100644 index 0000000000000..c0f8710c03cb3 --- /dev/null +++ b/tests/ui/layout/normalization-failure.rs @@ -0,0 +1,57 @@ +//! This test demonstrates how `LayoutError::NormalizationFailure` can happen and why +//! it is necessary. +//! +//! This code does not cause an immediate normalization error in typeck, because we +//! don't reveal the hidden type returned by `opaque` in the analysis typing mode. +//! Instead, `<{opaque} as Project2>::Assoc2` is a *rigid projection*, because we know +//! that `{opaque}: Project2` holds, due to the opaque type's `impl Project2` bound, +//! but cannot normalize `<{opaque} as Project2>::Assoc2` any further. +//! +//! However, in the post-analysis typing mode, which is used for the layout computation, +//! the opaque's hidden type is revealed to be `PhantomData`, and now we fail to +//! normalize ` as Project2>::Assoc2` if there is a `T: Project1` bound +//! in the param env! This happens, because `PhantomData: Project2` only holds if +//! `::Assoc1 == ()` holds. This would usually be satisfied by the +//! blanket `impl Project1 for T`, but due to the `T: Project1` bound we do not +//! normalize `::Assoc1` via the impl and treat it as rigid instead. +//! Therefore, `PhantomData: Project2` does NOT hold and normalizing +//! ` as Project2>::Assoc2` fails. +//! +//! Note that this layout error can only happen when computing the layout in a generic +//! context, which is not required for codegen, but may happen for lints, MIR optimizations, +//! and the transmute check. + +use std::marker::PhantomData; + +trait Project1 { + type Assoc1; +} + +impl Project1 for T { + type Assoc1 = (); +} + +trait Project2 { + type Assoc2; + fn get(self) -> Self::Assoc2; +} + +impl> Project2 for PhantomData { + type Assoc2 = (); + fn get(self) -> Self::Assoc2 {} +} + +fn opaque() -> impl Project2 { + PhantomData:: +} + +fn check() { + unsafe { + std::mem::transmute::<_, ()>(opaque::().get()); + //~^ ERROR: cannot transmute + //~| NOTE: (unable to determine layout for `::Assoc2` because `::Assoc2` cannot be normalized) + //~| NOTE: (0 bits) + } +} + +fn main() {} diff --git a/tests/ui/layout/normalization-failure.stderr b/tests/ui/layout/normalization-failure.stderr new file mode 100644 index 0000000000000..5fe38d4403a20 --- /dev/null +++ b/tests/ui/layout/normalization-failure.stderr @@ -0,0 +1,12 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/normalization-failure.rs:50:9 + | +LL | std::mem::transmute::<_, ()>(opaque::().get()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `::Assoc2` (unable to determine layout for `::Assoc2` because `::Assoc2` cannot be normalized) + = note: target type: `()` (0 bits) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 120081d193c69..0c34331856474 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -31,6 +31,7 @@ error: layout_of(A) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -56,6 +57,7 @@ error: layout_of(A) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -107,6 +109,7 @@ error: layout_of(B) = Layout { valid_range: 255..=255, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -132,6 +135,7 @@ error: layout_of(B) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -183,6 +187,7 @@ error: layout_of(C) = Layout { valid_range: 256..=256, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -208,6 +213,7 @@ error: layout_of(C) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -259,6 +265,7 @@ error: layout_of(P) = Layout { valid_range: 268435456..=268435456, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -284,6 +291,7 @@ error: layout_of(P) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -335,6 +343,7 @@ error: layout_of(T) = Layout { valid_range: 2164260864..=2164260864, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -360,6 +369,7 @@ error: layout_of(T) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs new file mode 100644 index 0000000000000..c9b1e0a4b9ec3 --- /dev/null +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -0,0 +1,18 @@ +//! Regression test for . +//! +//! This used to ICE in layout computation, because `::B` fails to normalize +//! due to the unconstrained param on the impl. + +#![feature(rustc_attrs)] +#![crate_type = "lib"] + +trait A { + const B: usize; +} + +impl A for u8 { //~ ERROR: the type parameter `C` is not constrained + const B: usize = 42; +} + +#[rustc_layout(debug)] +struct S([u8; ::B]); //~ ERROR: the type has an unknown layout diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr new file mode 100644 index 0000000000000..615c131eb9045 --- /dev/null +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -0,0 +1,15 @@ +error[E0207]: the type parameter `C` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained-param-ice-137308.rs:13:6 + | +LL | impl A for u8 { + | ^ unconstrained type parameter + +error: the type has an unknown layout + --> $DIR/unconstrained-param-ice-137308.rs:18:1 + | +LL | struct S([u8; ::B]); + | ^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index b6fcc14c063c5..33d2eede22090 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -25,6 +25,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -54,6 +55,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -88,6 +90,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -133,6 +136,7 @@ error: layout_of(MultipleAlignments) = Layout { valid_range: 0..=2, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -162,6 +166,7 @@ error: layout_of(MultipleAlignments) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -187,6 +192,7 @@ error: layout_of(MultipleAlignments) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -221,6 +227,7 @@ error: layout_of(MultipleAlignments) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Single { index: 2, }, @@ -266,6 +273,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -295,6 +303,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -329,6 +338,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { valid_range: 1..=65535, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -374,6 +384,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -407,6 +418,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -441,6 +453,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { valid_range: 0..=0, }, ), + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr index 4703d7f10dc28..9020ee22f9bd8 100644 --- a/tests/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr @@ -13,7 +13,7 @@ LL | x.use_mut(); help: consider consuming the `Vec` when turning it into an `Iterator` | LL | let mut x = vec![1].into_iter(); - | +++++ + | +++++ help: consider using a `let` binding to create a longer lived value | LL ~ let binding = vec![1]; diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index 8aa94f66812f3..bdf911367653b 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -56,9 +56,8 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } | help: provide the argument | -LL - fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } -LL + fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } - | +LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } + | +++++++++ error[E0308]: mismatched types --> $DIR/issue-26638.rs:4:47 diff --git a/tests/ui/lint/invalid_from_utf8.rs b/tests/ui/lint/invalid_from_utf8.rs index 8f8000fe34d4d..87a906761c075 100644 --- a/tests/ui/lint/invalid_from_utf8.rs +++ b/tests/ui/lint/invalid_from_utf8.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(concat_bytes)] -#![feature(inherent_str_constructors)] #![warn(invalid_from_utf8_unchecked)] #![warn(invalid_from_utf8)] diff --git a/tests/ui/lint/invalid_from_utf8.stderr b/tests/ui/lint/invalid_from_utf8.stderr index 715ecf56f218b..3cd4d227fc276 100644 --- a/tests/ui/lint/invalid_from_utf8.stderr +++ b/tests/ui/lint/invalid_from_utf8.stderr @@ -1,5 +1,5 @@ warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:22:9 + --> $DIR/invalid_from_utf8.rs:21:9 | LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -7,13 +7,13 @@ LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112 | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:5:9 + --> $DIR/invalid_from_utf8.rs:4:9 | LL | #![warn(invalid_from_utf8_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:24:9 + --> $DIR/invalid_from_utf8.rs:23:9 | LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -21,7 +21,7 @@ LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121 | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:26:9 + --> $DIR/invalid_from_utf8.rs:25:9 | LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -29,7 +29,7 @@ LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:28:9 + --> $DIR/invalid_from_utf8.rs:27:9 | LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -37,7 +37,7 @@ LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:50:9 + --> $DIR/invalid_from_utf8.rs:49:9 | LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -45,7 +45,7 @@ LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:52:9 + --> $DIR/invalid_from_utf8.rs:51:9 | LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -53,7 +53,7 @@ LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:54:9 + --> $DIR/invalid_from_utf8.rs:53:9 | LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -61,7 +61,7 @@ LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:56:9 + --> $DIR/invalid_from_utf8.rs:55:9 | LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -69,7 +69,7 @@ LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:58:9 + --> $DIR/invalid_from_utf8.rs:57:9 | LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^ @@ -77,7 +77,7 @@ LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:60:9 + --> $DIR/invalid_from_utf8.rs:59:9 | LL | str::from_utf8_unchecked(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^^^^^^-------------^ @@ -85,7 +85,7 @@ LL | str::from_utf8_unchecked(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:62:9 + --> $DIR/invalid_from_utf8.rs:61:9 | LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -93,7 +93,7 @@ LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:64:9 + --> $DIR/invalid_from_utf8.rs:63:9 | LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -101,7 +101,7 @@ LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:84:9 + --> $DIR/invalid_from_utf8.rs:83:9 | LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -109,13 +109,13 @@ LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:6:9 + --> $DIR/invalid_from_utf8.rs:5:9 | LL | #![warn(invalid_from_utf8)] | ^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:86:9 + --> $DIR/invalid_from_utf8.rs:85:9 | LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -123,7 +123,7 @@ LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:88:9 + --> $DIR/invalid_from_utf8.rs:87:9 | LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -131,7 +131,7 @@ LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:90:9 + --> $DIR/invalid_from_utf8.rs:89:9 | LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -139,7 +139,7 @@ LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:112:9 + --> $DIR/invalid_from_utf8.rs:111:9 | LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -147,7 +147,7 @@ LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:114:9 + --> $DIR/invalid_from_utf8.rs:113:9 | LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^----------------------------------^ @@ -155,7 +155,7 @@ LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:116:9 + --> $DIR/invalid_from_utf8.rs:115:9 | LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -163,7 +163,7 @@ LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']) | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:118:9 + --> $DIR/invalid_from_utf8.rs:117:9 | LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -171,7 +171,7 @@ LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:120:9 + --> $DIR/invalid_from_utf8.rs:119:9 | LL | std::str::from_utf8(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^-------------^ @@ -179,7 +179,7 @@ LL | std::str::from_utf8(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:122:9 + --> $DIR/invalid_from_utf8.rs:121:9 | LL | str::from_utf8(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^-------------^ @@ -187,7 +187,7 @@ LL | str::from_utf8(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:124:9 + --> $DIR/invalid_from_utf8.rs:123:9 | LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -195,7 +195,7 @@ LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:126:9 + --> $DIR/invalid_from_utf8.rs:125:9 | LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^---------------------------------^ @@ -203,7 +203,7 @@ LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:133:5 + --> $DIR/invalid_from_utf8.rs:132:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -211,7 +211,7 @@ LL | std::str::from_utf8_mut(&mut a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:135:5 + --> $DIR/invalid_from_utf8.rs:134:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -220,7 +220,7 @@ LL | str::from_utf8_mut(&mut a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:139:5 + --> $DIR/invalid_from_utf8.rs:138:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -229,7 +229,7 @@ LL | std::str::from_utf8_mut(c); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8_mut` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:141:5 + --> $DIR/invalid_from_utf8.rs:140:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -238,7 +238,7 @@ LL | str::from_utf8_mut(c); | ^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:144:5 + --> $DIR/invalid_from_utf8.rs:143:5 | LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -246,7 +246,7 @@ LL | std::str::from_utf8(c); | ^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:146:5 + --> $DIR/invalid_from_utf8.rs:145:5 | LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -255,7 +255,7 @@ LL | str::from_utf8(c); | ^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:149:5 + --> $DIR/invalid_from_utf8.rs:148:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -263,7 +263,7 @@ LL | std::str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:151:5 + --> $DIR/invalid_from_utf8.rs:150:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -272,7 +272,7 @@ LL | str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:154:5 + --> $DIR/invalid_from_utf8.rs:153:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -280,7 +280,7 @@ LL | std::str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:156:5 + --> $DIR/invalid_from_utf8.rs:155:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -289,7 +289,7 @@ LL | str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:159:5 + --> $DIR/invalid_from_utf8.rs:158:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -297,7 +297,7 @@ LL | std::str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:161:5 + --> $DIR/invalid_from_utf8.rs:160:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -306,7 +306,7 @@ LL | str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:164:5 + --> $DIR/invalid_from_utf8.rs:163:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -314,7 +314,7 @@ LL | std::str::from_utf8(INVALID_4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `str::from_utf8` with an invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:166:5 + --> $DIR/invalid_from_utf8.rs:165:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr index 337d5d0b307ee..00a2ca99f241c 100644 --- a/tests/ui/lint/static-mut-refs.e2021.stderr +++ b/tests/ui/lint/static-mut-refs.e2021.stderr @@ -22,9 +22,8 @@ LL | let _y = &mut X; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _y = &mut X; -LL + let _y = &raw mut X; - | +LL | let _y = &raw mut X; + | +++ warning: creating a shared reference to mutable static is discouraged --> $DIR/static-mut-refs.rs:50:22 diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr index cf7f0a86f4fe7..ff41f316250d1 100644 --- a/tests/ui/lint/static-mut-refs.e2024.stderr +++ b/tests/ui/lint/static-mut-refs.e2024.stderr @@ -22,9 +22,8 @@ LL | let _y = &mut X; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _y = &mut X; -LL + let _y = &raw mut X; - | +LL | let _y = &raw mut X; + | +++ error: creating a shared reference to mutable static is discouraged --> $DIR/static-mut-refs.rs:50:22 diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index 6ba0c9d907c5e..4d6403b1e7db2 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -26,9 +26,8 @@ LL + let fail = 0b1000_0001u8; | help: to use as a negative number (decimal `-127`), consider using the type `u8` for the literal and cast it to `i8` | -LL - let fail = 0b1000_0001i8; -LL + let fail = 0b1000_0001u8 as i8; - | +LL | let fail = 0b1000_0001u8 as i8; + | +++++ warning: literal out of range for `i64` --> $DIR/type-overflow.rs:15:16 @@ -44,9 +43,8 @@ LL + let fail = 0x8000_0000_0000_0000u64; | help: to use as a negative number (decimal `-9223372036854775808`), consider using the type `u64` for the literal and cast it to `i64` | -LL - let fail = 0x8000_0000_0000_0000i64; -LL + let fail = 0x8000_0000_0000_0000u64 as i64; - | +LL | let fail = 0x8000_0000_0000_0000u64 as i64; + | ++++++ warning: literal out of range for `u32` --> $DIR/type-overflow.rs:19:16 diff --git a/tests/ui/lint/unaligned_references_fake_borrow.rs b/tests/ui/lint/unaligned_references_fake_borrow.rs new file mode 100644 index 0000000000000..b0ef8b471caad --- /dev/null +++ b/tests/ui/lint/unaligned_references_fake_borrow.rs @@ -0,0 +1,27 @@ +//@ check-pass + +// Regression test for . + +// Ensure that we don't emit unaligned packed field reference errors for the fake +// borrows that we generate during match lowering. These fake borrows are there to +// ensure in *borrow-checking* that we don't modify the value being matched, but +// they are removed after the MIR is processed by `CleanupPostBorrowck`. + +#[repr(packed)] +pub struct Packed(i32); + +fn f(x: Packed) { + match &x { + Packed(4) => {}, + _ if true => {}, + _ => {} + } + + match x { + Packed(4) => {}, + _ if true => {}, + _ => {} + } +} + +fn main() {} diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs index 51f868706b69b..860fc5046d103 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.rs +++ b/tests/ui/lint/unused/unused_attributes-must_use.rs @@ -79,6 +79,11 @@ trait Use { #[must_use] //~ ERROR `#[must_use]` has no effect impl Use for () { type AssocTy = (); + + #[must_use] //~ ERROR `#[must_use]` has no effect + fn get_four(&self) -> usize { + 4 + } } #[must_use] //~ ERROR `#[must_use]` has no effect diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 9633767c44287..28fd8eeb8cbdc 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -76,43 +76,43 @@ LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a trait alias - --> $DIR/unused_attributes-must_use.rs:84:1 + --> $DIR/unused_attributes-must_use.rs:89:1 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a macro def - --> $DIR/unused_attributes-must_use.rs:87:1 + --> $DIR/unused_attributes-must_use.rs:92:1 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a statement - --> $DIR/unused_attributes-must_use.rs:95:5 + --> $DIR/unused_attributes-must_use.rs:100:5 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a closure - --> $DIR/unused_attributes-must_use.rs:99:13 + --> $DIR/unused_attributes-must_use.rs:104:13 | LL | let x = #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to an match arm - --> $DIR/unused_attributes-must_use.rs:121:9 + --> $DIR/unused_attributes-must_use.rs:126:9 | LL | #[must_use] | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a struct field - --> $DIR/unused_attributes-must_use.rs:129:28 + --> $DIR/unused_attributes-must_use.rs:134:28 | LL | let s = PatternField { #[must_use] foo: 123 }; | ^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to a pattern field - --> $DIR/unused_attributes-must_use.rs:130:24 + --> $DIR/unused_attributes-must_use.rs:135:24 | LL | let PatternField { #[must_use] foo } = s; | ^^^^^^^^^^^ @@ -129,6 +129,12 @@ error: `#[must_use]` has no effect when applied to an associated type LL | #[must_use] | ^^^^^^^^^^^ +error: `#[must_use]` has no effect when applied to a provided trait method + --> $DIR/unused_attributes-must_use.rs:83:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: `#[must_use]` has no effect when applied to a foreign static item --> $DIR/unused_attributes-must_use.rs:50:5 | @@ -136,7 +142,7 @@ LL | #[must_use] | ^^^^^^^^^^^ error: unused `X` that must be used - --> $DIR/unused_attributes-must_use.rs:103:5 + --> $DIR/unused_attributes-must_use.rs:108:5 | LL | X; | ^ @@ -152,7 +158,7 @@ LL | let _ = X; | +++++++ error: unused `Y` that must be used - --> $DIR/unused_attributes-must_use.rs:104:5 + --> $DIR/unused_attributes-must_use.rs:109:5 | LL | Y::Z; | ^^^^ @@ -163,7 +169,7 @@ LL | let _ = Y::Z; | +++++++ error: unused `U` that must be used - --> $DIR/unused_attributes-must_use.rs:105:5 + --> $DIR/unused_attributes-must_use.rs:110:5 | LL | U { unit: () }; | ^^^^^^^^^^^^^^ @@ -174,7 +180,7 @@ LL | let _ = U { unit: () }; | +++++++ error: unused return value of `U::method` that must be used - --> $DIR/unused_attributes-must_use.rs:106:5 + --> $DIR/unused_attributes-must_use.rs:111:5 | LL | U::method(); | ^^^^^^^^^^^ @@ -185,7 +191,7 @@ LL | let _ = U::method(); | +++++++ error: unused return value of `foo` that must be used - --> $DIR/unused_attributes-must_use.rs:107:5 + --> $DIR/unused_attributes-must_use.rs:112:5 | LL | foo(); | ^^^^^ @@ -196,7 +202,7 @@ LL | let _ = foo(); | +++++++ error: unused return value of `foreign_foo` that must be used - --> $DIR/unused_attributes-must_use.rs:110:9 + --> $DIR/unused_attributes-must_use.rs:115:9 | LL | foreign_foo(); | ^^^^^^^^^^^^^ @@ -207,7 +213,7 @@ LL | let _ = foreign_foo(); | +++++++ error: unused return value of `Use::get_four` that must be used - --> $DIR/unused_attributes-must_use.rs:118:5 + --> $DIR/unused_attributes-must_use.rs:123:5 | LL | ().get_four(); | ^^^^^^^^^^^^^ @@ -217,5 +223,5 @@ help: use `let _ = ...` to ignore the resulting value LL | let _ = ().get_four(); | +++++++ -error: aborting due to 28 previous errors +error: aborting due to 29 previous errors diff --git a/tests/ui/macros/block-to-expr-metavar.rs b/tests/ui/macros/block-to-expr-metavar.rs new file mode 100644 index 0000000000000..04f10ad0f9886 --- /dev/null +++ b/tests/ui/macros/block-to-expr-metavar.rs @@ -0,0 +1,17 @@ +//@ check-pass +// +// A test case where a `block` fragment specifier is interpreted as an `expr` +// fragment specifier. It's an interesting case for the handling of invisible +// delimiters. + +macro_rules! m_expr { + ($e:expr) => { const _CURRENT: u32 = $e; }; +} + +macro_rules! m_block { + ($b:block) => ( m_expr!($b); ); +} + +fn main() { + m_block!({ 1 }); +} diff --git a/tests/ui/macros/macro-interpolation.rs b/tests/ui/macros/macro-interpolation.rs index 48c1f19e777f7..b5d2322c8052c 100644 --- a/tests/ui/macros/macro-interpolation.rs +++ b/tests/ui/macros/macro-interpolation.rs @@ -19,7 +19,7 @@ macro_rules! qpath { (ty, <$type:ty as $trait:ty>::$name:ident) => { <$type as $trait>::$name - //~^ ERROR expected identifier, found `!` + //~^ ERROR expected identifier, found metavariable }; } diff --git a/tests/ui/macros/macro-interpolation.stderr b/tests/ui/macros/macro-interpolation.stderr index e6b39dfef8581..bc24a15861295 100644 --- a/tests/ui/macros/macro-interpolation.stderr +++ b/tests/ui/macros/macro-interpolation.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found `!` +error: expected identifier, found metavariable --> $DIR/macro-interpolation.rs:21:19 | LL | <$type as $trait>::$name - | ^^^^^^ expected identifier + | ^^^^^^ expected identifier, found metavariable ... LL | let _: qpath!(ty, ::Owned); | ----------------------------- diff --git a/tests/ui/macros/syntax-error-recovery.rs b/tests/ui/macros/syntax-error-recovery.rs index 016e4def28497..6cf9d54e82636 100644 --- a/tests/ui/macros/syntax-error-recovery.rs +++ b/tests/ui/macros/syntax-error-recovery.rs @@ -9,8 +9,8 @@ macro_rules! values { } }; } -//~^^^^^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found type `(String)` -//~| ERROR macro expansion ignores type `(String)` and any tokens following +//~^^^^^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `ty` metavariable +//~| ERROR macro expansion ignores `ty` metavariable and any tokens following values!(STRING(1) as (String) => cfg(test),); //~^ ERROR expected one of `!` or `::`, found `` diff --git a/tests/ui/macros/syntax-error-recovery.stderr b/tests/ui/macros/syntax-error-recovery.stderr index 3cfbd8ce82b56..61758fb9d7dc6 100644 --- a/tests/ui/macros/syntax-error-recovery.stderr +++ b/tests/ui/macros/syntax-error-recovery.stderr @@ -1,4 +1,4 @@ -error: expected one of `(`, `,`, `=`, `{`, or `}`, found type `(String)` +error: expected one of `(`, `,`, `=`, `{`, or `}`, found `ty` metavariable --> $DIR/syntax-error-recovery.rs:7:26 | LL | $token $($inner)? = $value, @@ -10,7 +10,7 @@ LL | values!(STRING(1) as (String) => cfg(test),); = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` = note: this error originates in the macro `values` (in Nightly builds, run with -Z macro-backtrace for more info) -error: macro expansion ignores type `(String)` and any tokens following +error: macro expansion ignores `ty` metavariable and any tokens following --> $DIR/syntax-error-recovery.rs:7:26 | LL | $token $($inner)? = $value, diff --git a/tests/ui/malformed/malformed-special-attrs.stderr b/tests/ui/malformed/malformed-special-attrs.stderr index a6220710cf912..b6a1a6b50e468 100644 --- a/tests/ui/malformed/malformed-special-attrs.stderr +++ b/tests/ui/malformed/malformed-special-attrs.stderr @@ -7,9 +7,8 @@ LL | #[cfg_attr] = note: for more information, visit help: missing condition and attribute | -LL - #[cfg_attr] -LL + #[cfg_attr(condition, attribute, other_attribute, ...)] - | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++++ error: malformed `cfg_attr` attribute input --> $DIR/malformed-special-attrs.rs:4:1 diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 7cda928aca9d3..95de40ff891be 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -28,9 +28,8 @@ LL | fn one(self, _: isize) -> Foo { self } | ^^^ -------- help: provide the argument | -LL - .one() -LL + .one(/* isize */) - | +LL | .one(/* isize */) + | +++++++++++ error[E0061]: this method takes 2 arguments but 1 argument was supplied --> $DIR/method-call-err-msg.rs:15:7 @@ -45,9 +44,8 @@ LL | fn two(self, _: isize, _: isize) -> Foo { self } | ^^^ -------- help: provide the argument | -LL - .two(0); -LL + .two(0, /* isize */); - | +LL | .two(0, /* isize */); + | +++++++++++++ error[E0599]: `Foo` is not an iterator --> $DIR/method-call-err-msg.rs:19:7 @@ -84,9 +82,8 @@ LL | fn three(self, _: T, _: T, _: T) -> Foo { self } | ^^^^^ ---- ---- ---- help: provide the arguments | -LL - y.three::(); -LL + y.three::(/* usize */, /* usize */, /* usize */); - | +LL | y.three::(/* usize */, /* usize */, /* usize */); + | +++++++++++++++++++++++++++++++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/mismatched_types/closure-arg-count.stderr b/tests/ui/mismatched_types/closure-arg-count.stderr index 8704d0f661be2..e0fcf9beb3c4c 100644 --- a/tests/ui/mismatched_types/closure-arg-count.stderr +++ b/tests/ui/mismatched_types/closure-arg-count.stderr @@ -8,9 +8,8 @@ LL | [1, 2, 3].sort_by(|| panic!()); | help: consider changing the closure to take and ignore the expected arguments | -LL - [1, 2, 3].sort_by(|| panic!()); -LL + [1, 2, 3].sort_by(|_, _| panic!()); - | +LL | [1, 2, 3].sort_by(|_, _| panic!()); + | ++++ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument --> $DIR/closure-arg-count.rs:7:15 @@ -64,9 +63,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^ required by this bound in `f` help: consider changing the closure to take and ignore the expected argument | -LL - f(|| panic!()); -LL + f(|_| panic!()); - | +LL | f(|_| panic!()); + | + error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:15:5 @@ -84,9 +82,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^ required by this bound in `f` help: consider changing the closure to take and ignore the expected argument | -LL - f( move || panic!()); -LL + f( move |_| panic!()); - | +LL | f( move |_| panic!()); + | + error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:18:53 diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index 7756217b56000..61786ef14c252 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -13,9 +13,8 @@ LL | fn bar(&mut self, other: &mut dyn Foo); found signature `fn(&mut Baz, &dyn Foo)` help: change the parameter type to match the trait | -LL - fn bar(&mut self, other: &dyn Foo) {} -LL + fn bar(&mut self, other: &mut dyn Foo) {} - | +LL | fn bar(&mut self, other: &mut dyn Foo) {} + | +++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr b/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr index dbd313fada99c..13f51cb7b094a 100644 --- a/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr +++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-128848.stderr @@ -8,9 +8,8 @@ note: method defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: provide the argument | -LL - f.call_once() -LL + f.call_once(/* args */) - | +LL | f.call_once(/* args */) + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr index d9d99f3d1cf52..8ed4530e85e3c 100644 --- a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr +++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr @@ -11,9 +11,8 @@ LL | fn foo(&mut self) -> _ { | ^^^ --------- help: provide the argument | -LL - Self::foo() -LL + Self::foo(/* value */) - | +LL | Self::foo(/* value */) + | +++++++++++ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/mismatch-args-crash-issue-130400.rs:2:26 diff --git a/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr b/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr index 7acc361fdb8df..b949b4ea298ad 100644 --- a/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr +++ b/tests/ui/mismatched_types/mismatch-args-vargs-issue-130372.stderr @@ -11,9 +11,8 @@ LL | unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {} | ^^^^^^^^^^^^ ------ help: provide the argument | -LL - test_va_copy(); -LL + test_va_copy(/* u64 */); - | +LL | test_va_copy(/* u64 */); + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/mismatched_types/overloaded-calls-bad.stderr b/tests/ui/mismatched_types/overloaded-calls-bad.stderr index 9f5c35a30097d..0a872da601482 100644 --- a/tests/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/tests/ui/mismatched_types/overloaded-calls-bad.stderr @@ -25,9 +25,8 @@ LL | impl FnMut<(isize,)> for S { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: provide the argument | -LL - let ans = s(); -LL + let ans = s(/* isize */); - | +LL | let ans = s(/* isize */); + | +++++++++++ error[E0057]: this function takes 1 argument but 2 arguments were supplied --> $DIR/overloaded-calls-bad.rs:37:15 diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index d232cc50e5230..45a02982289de 100644 --- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -32,9 +32,8 @@ LL | fn bar(&mut self, bar: &mut Bar); found signature `fn(&mut Bar, &Bar)` help: change the parameter type to match the trait | -LL - fn bar(&mut self, bar: &Bar) { } -LL + fn bar(&mut self, bar: &mut Bar) { } - | +LL | fn bar(&mut self, bar: &mut Bar) { } + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr index 7e11b23d681b8..9dbd676969364 100644 --- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr +++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -9,9 +9,8 @@ LL | S1 { a: unsafe { &mut X1 } } = note: `#[warn(static_mut_refs)]` on by default help: use `&raw mut` instead to create a raw pointer | -LL - S1 { a: unsafe { &mut X1 } } -LL + S1 { a: unsafe { &raw mut X1 } } - | +LL | S1 { a: unsafe { &raw mut X1 } } + | +++ warning: 1 warning emitted diff --git a/tests/ui/nll/normalization-bounds-error.stderr b/tests/ui/nll/normalization-bounds-error.stderr index d4254881863ff..47d2663313db6 100644 --- a/tests/ui/nll/normalization-bounds-error.stderr +++ b/tests/ui/nll/normalization-bounds-error.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements --> $DIR/normalization-bounds-error.rs:12:31 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} @@ -36,4 +36,4 @@ LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/not-enough-arguments.stderr b/tests/ui/not-enough-arguments.stderr index 637c2774d5a31..099d82eb93552 100644 --- a/tests/ui/not-enough-arguments.stderr +++ b/tests/ui/not-enough-arguments.stderr @@ -11,9 +11,8 @@ LL | fn foo(a: isize, b: isize, c: isize, d:isize) { | ^^^ ------- help: provide the argument | -LL - foo(1, 2, 3); -LL + foo(1, 2, 3, /* isize */); - | +LL | foo(1, 2, 3, /* isize */); + | +++++++++++++ error[E0061]: this function takes 6 arguments but 3 arguments were supplied --> $DIR/not-enough-arguments.rs:29:3 @@ -35,9 +34,8 @@ LL | f: i32, | ------ help: provide the arguments | -LL - bar(1, 2, 3); -LL + bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */); - | +LL | bar(1, 2, 3, /* i32 */, /* i32 */, /* i32 */); + | +++++++++++++++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/obsolete-in-place/bad.stderr b/tests/ui/obsolete-in-place/bad.stderr index 1409a6637890f..a1321a46351a9 100644 --- a/tests/ui/obsolete-in-place/bad.stderr +++ b/tests/ui/obsolete-in-place/bad.stderr @@ -6,9 +6,8 @@ LL | x <- y; | help: if you meant to write a comparison against a negative value, add a space in between `<` and `-` | -LL - x <- y; -LL + x < - y; - | +LL | x < - y; + | + error: expected expression, found keyword `in` --> $DIR/bad.rs:10:5 diff --git a/tests/ui/on-unimplemented/bad-annotation.stderr b/tests/ui/on-unimplemented/bad-annotation.stderr index 0482a5c58559e..4ceea779b29dc 100644 --- a/tests/ui/on-unimplemented/bad-annotation.stderr +++ b/tests/ui/on-unimplemented/bad-annotation.stderr @@ -6,12 +6,10 @@ LL | #[rustc_on_unimplemented] | help: the following are the possible correct uses | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented = "message"] - | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] - | +LL | #[rustc_on_unimplemented = "message"] + | +++++++++++ +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0230]: there is no parameter `C` on trait `BadAnnotation2` --> $DIR/bad-annotation.rs:22:1 diff --git a/tests/ui/on-unimplemented/issue-104140.stderr b/tests/ui/on-unimplemented/issue-104140.stderr index 5c9d5e8d55398..3c317135dd43a 100644 --- a/tests/ui/on-unimplemented/issue-104140.stderr +++ b/tests/ui/on-unimplemented/issue-104140.stderr @@ -6,12 +6,10 @@ LL | #[rustc_on_unimplemented] | help: the following are the possible correct uses | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented = "message"] - | -LL - #[rustc_on_unimplemented] -LL + #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] - | +LL | #[rustc_on_unimplemented = "message"] + | +++++++++++ +LL | #[rustc_on_unimplemented(/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...")] + | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/weak-lang-item.stderr b/tests/ui/panic-handler/weak-lang-item.stderr index e9d444c1c4d8c..5dcb37df68921 100644 --- a/tests/ui/panic-handler/weak-lang-item.stderr +++ b/tests/ui/panic-handler/weak-lang-item.stderr @@ -7,9 +7,8 @@ LL | extern crate core; = note: `core` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate core; -LL + extern crate core as other_core; - | +LL | extern crate core as other_core; + | +++++++++++++ error: `#[panic_handler]` function required, but not found diff --git a/tests/ui/parser/doc-before-bad-variant.rs b/tests/ui/parser/doc-before-bad-variant.rs new file mode 100644 index 0000000000000..bfede28c10892 --- /dev/null +++ b/tests/ui/parser/doc-before-bad-variant.rs @@ -0,0 +1,6 @@ +enum TestEnum { + Works, + /// Some documentation + Self, //~ ERROR expected identifier, found keyword `Self` + //~^ HELP enum variants can be +} diff --git a/tests/ui/parser/doc-before-bad-variant.stderr b/tests/ui/parser/doc-before-bad-variant.stderr new file mode 100644 index 0000000000000..5e4d4116f259f --- /dev/null +++ b/tests/ui/parser/doc-before-bad-variant.stderr @@ -0,0 +1,13 @@ +error: expected identifier, found keyword `Self` + --> $DIR/doc-before-bad-variant.rs:4:5 + | +LL | enum TestEnum { + | -------- while parsing this enum +... +LL | Self, + | ^^^^ expected identifier, found keyword + | + = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/doc-before-syntax-error.rs b/tests/ui/parser/doc-before-syntax-error.rs new file mode 100644 index 0000000000000..435f497d186ed --- /dev/null +++ b/tests/ui/parser/doc-before-syntax-error.rs @@ -0,0 +1,2 @@ +/// Some documentation +<> //~ ERROR expected identifier diff --git a/tests/ui/parser/doc-before-syntax-error.stderr b/tests/ui/parser/doc-before-syntax-error.stderr new file mode 100644 index 0000000000000..93e39d6300077 --- /dev/null +++ b/tests/ui/parser/doc-before-syntax-error.stderr @@ -0,0 +1,8 @@ +error: expected identifier, found `<` + --> $DIR/doc-before-syntax-error.rs:2:1 + | +LL | <> + | ^ expected identifier + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index f0e90082bff9d..ef4e647b9f506 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -81,9 +81,8 @@ LL | fn full_of_✨() -> 👀 { | ^^^^^^^^^^^^^^^^^^^^^ help: there is an associated function `full_of_✨` with a similar name | -LL - 👀::full_of✨() -LL + 👀::full_of_✨() - | +LL | 👀::full_of_✨() + | + error[E0425]: cannot find function `i_like_to_😄_a_lot` in this scope --> $DIR/emoji-identifiers.rs:13:13 diff --git a/tests/ui/parser/extern-crate-unexpected-token.stderr b/tests/ui/parser/extern-crate-unexpected-token.stderr index 3d48f0adfa11a..033db85a6c7f1 100644 --- a/tests/ui/parser/extern-crate-unexpected-token.stderr +++ b/tests/ui/parser/extern-crate-unexpected-token.stderr @@ -6,9 +6,8 @@ LL | extern crte foo; | help: there is a keyword `crate` with a similar name | -LL - extern crte foo; -LL + extern crate foo; - | +LL | extern crate foo; + | + error: aborting due to 1 previous error diff --git a/tests/ui/parser/ferris-static-mut.rs b/tests/ui/parser/ferris-static-mut.rs new file mode 100644 index 0000000000000..67186982691e0 --- /dev/null +++ b/tests/ui/parser/ferris-static-mut.rs @@ -0,0 +1,3 @@ +static mut 🦀: &str = "ferris!";//~ ERROR Ferris cannot be used as an identifier + +fn main() {} diff --git a/tests/ui/parser/ferris-static-mut.stderr b/tests/ui/parser/ferris-static-mut.stderr new file mode 100644 index 0000000000000..6af85bbaf7dad --- /dev/null +++ b/tests/ui/parser/ferris-static-mut.stderr @@ -0,0 +1,8 @@ +error: Ferris cannot be used as an identifier + --> $DIR/ferris-static-mut.rs:1:12 + | +LL | static mut 🦀: &str = "ferris!"; + | ^^ help: try using their name instead: `FERRIS` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/ferris-struct.rs b/tests/ui/parser/ferris-struct.rs new file mode 100644 index 0000000000000..581957fa7757e --- /dev/null +++ b/tests/ui/parser/ferris-struct.rs @@ -0,0 +1,3 @@ +struct 🦀 {}//~ ERROR Ferris cannot be used as an identifier + +fn main() {} diff --git a/tests/ui/parser/ferris-struct.stderr b/tests/ui/parser/ferris-struct.stderr new file mode 100644 index 0000000000000..34fe28c62975c --- /dev/null +++ b/tests/ui/parser/ferris-struct.stderr @@ -0,0 +1,8 @@ +error: Ferris cannot be used as an identifier + --> $DIR/ferris-struct.rs:1:8 + | +LL | struct 🦀 {} + | ^^ help: try using their name instead: `Ferris` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/issue-37113.rs b/tests/ui/parser/macro/issue-37113.rs index 0044aa5610f5f..e0957542f8f19 100644 --- a/tests/ui/parser/macro/issue-37113.rs +++ b/tests/ui/parser/macro/issue-37113.rs @@ -1,7 +1,7 @@ macro_rules! test_macro { ( $( $t:ty ),* $(),*) => { enum SomeEnum { - $( $t, )* //~ ERROR expected identifier, found `String` + $( $t, )* //~ ERROR expected identifier, found metavariable }; }; } diff --git a/tests/ui/parser/macro/issue-37113.stderr b/tests/ui/parser/macro/issue-37113.stderr index 1f2fe23106ae3..560329df5ccbd 100644 --- a/tests/ui/parser/macro/issue-37113.stderr +++ b/tests/ui/parser/macro/issue-37113.stderr @@ -1,10 +1,10 @@ -error: expected identifier, found `String` +error: expected identifier, found metavariable --> $DIR/issue-37113.rs:4:16 | LL | enum SomeEnum { | -------- while parsing this enum LL | $( $t, )* - | ^^ expected identifier + | ^^ expected identifier, found metavariable ... LL | test_macro!(String,); | -------------------- in this macro invocation diff --git a/tests/ui/parser/macro/macro-expand-to-match-arm.stderr b/tests/ui/parser/macro/macro-expand-to-match-arm.stderr index 1927d80fd724c..702e76d59f984 100644 --- a/tests/ui/parser/macro/macro-expand-to-match-arm.stderr +++ b/tests/ui/parser/macro/macro-expand-to-match-arm.stderr @@ -14,7 +14,12 @@ error: `match` arm with no body --> $DIR/macro-expand-to-match-arm.rs:14:9 | LL | arm!(None => {}), - | ^^^^^^^^^^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | arm!(None => {}) => { todo!() }, + | ++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.rs b/tests/ui/parser/macro/trait-object-macro-matcher.rs index 560195977d03a..d4ec199070e7c 100644 --- a/tests/ui/parser/macro/trait-object-macro-matcher.rs +++ b/tests/ui/parser/macro/trait-object-macro-matcher.rs @@ -10,5 +10,6 @@ macro_rules! m { fn main() { m!('static); //~^ ERROR lifetime in trait object type must be followed by `+` + //~| ERROR lifetime in trait object type must be followed by `+` //~| ERROR at least one trait is required for an object type } diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.stderr b/tests/ui/parser/macro/trait-object-macro-matcher.stderr index 40082564bad4c..81dca6f71c436 100644 --- a/tests/ui/parser/macro/trait-object-macro-matcher.stderr +++ b/tests/ui/parser/macro/trait-object-macro-matcher.stderr @@ -4,12 +4,20 @@ error: lifetime in trait object type must be followed by `+` LL | m!('static); | ^^^^^^^ +error: lifetime in trait object type must be followed by `+` + --> $DIR/trait-object-macro-matcher.rs:11:8 + | +LL | m!('static); + | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0224]: at least one trait is required for an object type --> $DIR/trait-object-macro-matcher.rs:11:8 | LL | m!('static); | ^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/parser/match-arm-without-body.stderr b/tests/ui/parser/match-arm-without-body.stderr index 9df8485972f33..a65875b787a39 100644 --- a/tests/ui/parser/match-arm-without-body.stderr +++ b/tests/ui/parser/match-arm-without-body.stderr @@ -68,49 +68,89 @@ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:7:9 | LL | Some(_) - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) => { todo!() } + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:30:9 | LL | Some(_) if true - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if true => { todo!() } + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:40:9 | LL | Some(_) if true, - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if true => { todo!() }, + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:45:9 | LL | Some(_) if true, - | ^^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | Some(_) if true => { todo!() }, + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:51:9 | LL | pat!() - | ^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^ + | +help: add a body after the pattern + | +LL | pat!() => { todo!() } + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:56:9 | LL | pat!(), - | ^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^ + | +help: add a body after the pattern + | +LL | pat!() => { todo!() }, + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:61:9 | LL | pat!() if true, - | ^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^^^^^^^^^ + | +help: add a body after the pattern + | +LL | pat!() if true => { todo!() }, + | ++++++++++++++ error: `match` arm with no body --> $DIR/match-arm-without-body.rs:72:9 | LL | pat!(), - | ^^^^^^- help: add a body after the pattern: `=> todo!(),` + | ^^^^^^ + | +help: add a body after the pattern + | +LL | pat!() => { todo!() }, + | ++++++++++++++ error: aborting due to 13 previous errors diff --git a/tests/ui/parser/misspelled-keywords/const-fn.stderr b/tests/ui/parser/misspelled-keywords/const-fn.stderr index 46a6d8ca779fc..cc4c0f92917db 100644 --- a/tests/ui/parser/misspelled-keywords/const-fn.stderr +++ b/tests/ui/parser/misspelled-keywords/const-fn.stderr @@ -6,9 +6,8 @@ LL | cnst fn code() {} | help: there is a keyword `const` with a similar name | -LL - cnst fn code() {} -LL + const fn code() {} - | +LL | const fn code() {} + | + error: aborting due to 1 previous error diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs index daa9b7368fd0e..b18f87fd56995 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs @@ -9,3 +9,10 @@ macro_rules! mixed_edition_pat { Some(mut $foo) }; } + +#[macro_export] +macro_rules! bind_ref { + ($foo:ident) => { + ref $foo + }; +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs new file mode 100644 index 0000000000000..14d26be91a082 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/auxiliary/mixed-editions-macros.rs @@ -0,0 +1,48 @@ +//@[classic2021] edition: 2024 +//@[structural2021] edition: 2024 +//@[classic2024] edition: 2021 +//@[structural2024] edition: 2021 +//! This contains macros in an edition *different* to the one used in `../mixed-editions.rs`, in +//! order to test typing mixed-edition patterns. + +#[macro_export] +macro_rules! match_ctor { + ($p:pat) => { + [$p] + }; +} + +#[macro_export] +macro_rules! match_ref { + ($p:pat) => { + &$p + }; +} + +#[macro_export] +macro_rules! bind { + ($i:ident) => { + $i + } +} + +#[macro_export] +macro_rules! bind_ref { + ($i:ident) => { + ref $i + } +} + +#[macro_export] +macro_rules! bind_mut { + ($i:ident) => { + mut $i + } +} + +#[macro_export] +macro_rules! bind_ref_mut { + ($i:ident) => { + ref mut $i + } +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr new file mode 100644 index 0000000000000..355a8af6760f3 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2021.stderr @@ -0,0 +1,37 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:31:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - if let Some(&Some(x)) = Some(&Some(&mut 0)) { +LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:36:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:41:23 + | +LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:46:11 + | +LL | let &[x] = &&mut [0]; + | ^ cannot borrow as mutable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr index 1c44617830828..d40bdb9111b30 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.classic2024.stderr @@ -1,25 +1,25 @@ -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:13:16 +error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:15:16 | LL | let [&x] = &[&mut 0]; | - ^^^^^^^^^ cannot move out of here | | | data moved here - | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait | help: consider borrowing the pattern binding | LL | let [&ref x] = &[&mut 0]; | +++ -error[E0508]: cannot move out of type `[&mut u32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:19:16 +error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array + --> $DIR/borrowck-errors.rs:22:16 | LL | let [&x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here | | | data moved here - | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait | help: consider borrowing the pattern binding | @@ -27,7 +27,7 @@ LL | let [&ref x] = &mut [&mut 0]; | +++ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -42,25 +42,25 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:37:23 + --> $DIR/borrowck-errors.rs:41:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:42:11 + --> $DIR/borrowck-errors.rs:46:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable error[E0508]: cannot move out of type `[&mut i32; 1]`, a non-copy array - --> $DIR/borrowck-errors.rs:46:20 + --> $DIR/borrowck-errors.rs:50:20 | LL | let [&mut x] = &mut [&mut 0]; | - ^^^^^^^^^^^^^ cannot move out of here diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs index 59cafc50d8661..621ca7cc792eb 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.rs @@ -1,11 +1,13 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Tests for pattern errors not handled by the pattern typing rules, but by borrowck. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] /// These patterns additionally use `&` to match a `&mut` reference type, which causes compilation /// to fail in HIR typeck on stable. As such, they need to be separate from the other tests. @@ -14,13 +16,15 @@ fn errors_caught_in_hir_typeck_on_stable() { //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; let [&x] = &mut [&mut 0]; //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability //[classic2024]~^^^ ERROR: cannot move out of type - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(structural2024)] let _: &u32 = x; } pub fn main() { @@ -35,16 +39,16 @@ pub fn main() { // For 2021 edition, this is also a regression test for #136223 // since the maximum mutability is downgraded during the pattern check process. if let &Some(Some(x)) = &Some(&mut Some(0)) { - //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable - let _: &u32 = x; + //[stable2021,classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] let _: &u32 = x; } let &[x] = &&mut [0]; - //[stable2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable - let _: &u32 = x; + //[stable2021,classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] let _: &u32 = x; let [&mut x] = &mut [&mut 0]; //[classic2024]~^ ERROR: cannot move out of type - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr index deefe21ca7d45..edcf9f3035707 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:13:10 + --> $DIR/borrowck-errors.rs:15:10 | LL | let [&x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/borrowck-errors.rs:19:10 + --> $DIR/borrowck-errors.rs:22:10 | LL | let [&x] = &mut [&mut 0]; | ^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [x] = &mut [&mut 0]; | error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -46,19 +46,19 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:37:23 + --> $DIR/borrowck-errors.rs:41:23 | LL | if let &Some(Some(x)) = &Some(&mut Some(0)) { | ^ cannot borrow as mutable error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:42:11 + --> $DIR/borrowck-errors.rs:46:11 | LL | let &[x] = &&mut [0]; | ^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr new file mode 100644 index 0000000000000..208f6c8bbed03 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2021.stderr @@ -0,0 +1,25 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/borrowck-errors.rs:31:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - if let Some(&Some(x)) = Some(&Some(&mut 0)) { +LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/borrowck-errors.rs:36:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr index 30d2f9f3d702f..208f6c8bbed03 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/borrowck-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of a shared reference - --> $DIR/borrowck-errors.rs:27:29 + --> $DIR/borrowck-errors.rs:31:29 | LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | - ^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL + if let Some(Some(x)) = Some(&Some(&mut 0)) { | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/borrowck-errors.rs:32:10 + --> $DIR/borrowck-errors.rs:36:10 | LL | let &ref mut x = &0; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr new file mode 100644 index 0000000000000..7e3caaf979748 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr @@ -0,0 +1,103 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:41:10 + | +LL | let [bind_mut!(y)] = &[0]; + | ^^^^^^^^^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: this error originates in the macro `bind_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:76:21 + | +LL | let match_ref!([x]) = &mut &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:80:22 + | +LL | let &match_ctor!(y) = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:84:17 + | +LL | let &[bind!(z)] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:30:10 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/mixed-editions.rs:30:9 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[bind_ref!(y)] = &[0]; + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:61:21 + | +LL | let match_ref!([x]) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:65:22 + | +LL | let &match_ctor!(y) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:69:11 + | +LL | let &[bind!(z)] = &&mut [0]; + | ^^^^^^^^ cannot borrow as mutable + | + = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr new file mode 100644 index 0000000000000..466993a1671f4 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr @@ -0,0 +1,97 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:37:21 + | +LL | let match_ctor!(mut x) = &[0]; + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:76:21 + | +LL | let match_ref!([x]) = &mut &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:80:22 + | +LL | let &match_ctor!(y) = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:84:17 + | +LL | let &[bind!(z)] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:26:21 + | +LL | let match_ctor!(ref x) = &[0]; + | ^^^ binding modifier not allowed under `ref` default binding mode + | + = note: for more information, see +help: make the implied reference pattern explicit + --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 + | +LL | &[$p] + | + + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:61:21 + | +LL | let match_ref!([x]) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:65:22 + | +LL | let &match_ctor!(y) = &&mut [0]; + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/mixed-editions.rs:69:11 + | +LL | let &[bind!(z)] = &&mut [0]; + | ^^^^^^^^ cannot borrow as mutable + | + = note: this error originates in the macro `bind` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs new file mode 100644 index 0000000000000..0a22b55ab6374 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs @@ -0,0 +1,122 @@ +//@ revisions: classic2021 structural2021 classic2024 structural2024 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 +//@[classic2024] edition: 2024 +//@[structural2024] edition: 2024 +//@ aux-build:mixed-editions-macros.rs +//! Tests for typing mixed-edition patterns under the `ref_pat_eat_one_layer_2024` and +//! `ref_pat_eat_one_layer_2024_structural` feature gates. +//! This is meant both to check that patterns are typed with edition-appropriate typing rules and +//! that we keep our internal state consistent when mixing editions. +#![allow(incomplete_features, unused)] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] + +extern crate mixed_editions_macros; +use mixed_editions_macros::*; + +// Tests type equality in a way that avoids coercing `&&T` to `&T`. +trait Eq {} +impl Eq for T {} +fn assert_type_eq>(_: T, _: U) {} + +/// Make sure binding with `ref` in the presence of an inherited reference is forbidden when and +/// only when the binding is from edition 2024. +fn ref_binding_tests() { + let match_ctor!(ref x) = &[0]; + //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, &0u32); + + let [bind_ref!(y)] = &[0]; + //[classic2021,structural2021]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, &0u32); +} + +/// Likewise, when binding with `mut`. +fn mut_binding_tests() { + let match_ctor!(mut x) = &[0]; + //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, 0u32); + + let [bind_mut!(y)] = &[0]; + //[classic2021,structural2021]~^ ERROR: binding cannot be both mutable and by-reference + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, 0u32); +} + +/// Make sure reference patterns correspond to one deref on edition 2024 and two on edition 2021. +fn layers_eaten_tests() { + let match_ctor!(&x) = &[&0]; + #[cfg(any(classic2021, structural2021))] assert_type_eq(x, 0u32); + #[cfg(any(classic2024, structural2024))] assert_type_eq(x, &0u32); + + let [match_ref!(y)] = &[&0]; + #[cfg(any(classic2021, structural2021))] assert_type_eq(y, &0u32); + #[cfg(any(classic2024, structural2024))] assert_type_eq(y, 0u32); +} + +/// Make sure downgrading mutable binding modes inside shared refs ("Rule 3") doesn't break. +/// This only applies to `ref_pat_eat_one_layer_2024_structural`, which has Rule 3 in all editions; +/// under `ref_pat_eat_one_layer_2024`, these should be errors. +fn rule_3_tests() { + let match_ref!([x]) = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(x, &0u32); + + let &match_ctor!(y) = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(y, &0u32); + + let &[bind!(z)] = &&mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow data in a `&` reference as mutable + #[cfg(any(structural2021, structural2024))] assert_type_eq(z, &0u32); +} + +/// Test that the interaction between Rules 3 and 5 doesn't break. +fn rules_3_and_5_tests() { + let match_ref!([x]) = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(x, &0u32); + + let &match_ctor!(y) = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(y, &0u32); + + let &[bind!(z)] = &mut &mut [0]; + //[classic2021,classic2024]~^ ERROR: cannot borrow as mutable inside an `&` pattern + #[cfg(any(structural2021, structural2024))] assert_type_eq(z, &0u32); +} + +/// Make sure matching a lone shared reference with a `&` ("Rule 4") doesn't break. +fn rule_4_tests() { + let match_ref!([x]) = &[0]; + assert_type_eq(x, 0u32); + + let &match_ctor!(y) = &[0]; + assert_type_eq(y, 0u32); +} + +/// Make sure matching a `&mut` reference with a `&` pattern ("Rule 5") doesn't break. +fn rule_5_tests() { + let match_ref!(x) = &mut 0; + assert_type_eq(x, 0u32); + + // also test inherited references (assumes rule 4) + let [match_ref!(y)] = &mut [0]; + assert_type_eq(y, 0u32); +} + +/// Make sure binding with `ref mut` is an error within a `&` pattern matching a `&mut` reference. +fn rule_5_mutability_error_tests() { + let match_ref!(ref mut x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let &bind_ref_mut!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + + // also test inherited references (assumes rule 4) + let [match_ref!(ref mut x)] = &mut [0]; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let [&bind_ref_mut!(x)] = &mut [0]; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern +} + +fn main() {} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr new file mode 100644 index 0000000000000..4075dc9529da1 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr @@ -0,0 +1,61 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:41:10 + | +LL | let [bind_mut!(y)] = &[0]; + | ^^^^^^^^^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: this error originates in the macro `bind_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:30:10 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/mixed-editions.rs:30:9 + | +LL | let [bind_ref!(y)] = &[0]; + | ^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[bind_ref!(y)] = &[0]; + | + + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr new file mode 100644 index 0000000000000..819a54299ea1c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr @@ -0,0 +1,55 @@ +error[E0658]: binding cannot be both mutable and by-reference + --> $DIR/mixed-editions.rs:37:21 + | +LL | let match_ctor!(mut x) = &[0]; + | ^^^^ + | + = note: see issue #123076 for more information + = help: add `#![feature(mut_ref)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:110:28 + | +LL | let match_ref!(ref mut x) = &mut 0; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:112:24 + | +LL | let &bind_ref_mut!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:116:29 + | +LL | let [match_ref!(ref mut x)] = &mut [0]; + | ^ + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/mixed-editions.rs:118:25 + | +LL | let [&bind_ref_mut!(x)] = &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/mixed-editions.rs:26:21 + | +LL | let match_ctor!(ref x) = &[0]; + | ^^^ binding modifier not allowed under `ref` default binding mode + | + = note: for more information, see +help: make the implied reference pattern explicit + --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 + | +LL | &[$p] + | + + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0596, E0658. +For more information about an error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr index fa95b2b5a575d..6ddced3d16812 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.classic2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:14:13 + --> $DIR/mut-ref-mut.rs:18:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:19:13 + --> $DIR/mut-ref-mut.rs:23:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/mut-ref-mut.rs:24:10 + --> $DIR/mut-ref-mut.rs:28:10 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs index fbd6514df73d6..c8e988ad76d97 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.rs @@ -1,29 +1,33 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[stable2021] run-pass +//@[classic2021] run-pass +//@[structural2021] run-pass //! Test diagnostics for binding with `mut` when the default binding mode is by-ref. #![allow(incomplete_features, unused_assignments, unused_variables)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { struct Foo(u8); let Foo(mut a) = &Foo(0); //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] { a = 42 } + #[cfg(any(stable2021, classic2021, structural2021))] { a = 42 } #[cfg(any(classic2024, structural2024))] { a = &42 } let Foo(mut a) = &mut Foo(0); //[classic2024,structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] { a = 42 } + #[cfg(any(stable2021, classic2021, structural2021))] { a = 42 } #[cfg(any(classic2024, structural2024))] { a = &mut 42 } let [&mut mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ binding cannot be both mutable and by-reference - #[cfg(stable2021)] { x = 0 } + #[cfg(any(stable2021, classic2021, structural2021))] { x = 0 } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr index fd82da70a18de..c0c0f966b6804 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mut-ref-mut.structural2024.stderr @@ -1,5 +1,5 @@ error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:14:13 + --> $DIR/mut-ref-mut.rs:18:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^ @@ -9,7 +9,7 @@ LL | let Foo(mut a) = &Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:19:13 + --> $DIR/mut-ref-mut.rs:23:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^ @@ -19,7 +19,7 @@ LL | let Foo(mut a) = &mut Foo(0); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/mut-ref-mut.rs:24:15 + --> $DIR/mut-ref-mut.rs:28:15 | LL | let [&mut mut x] = &[&mut 0]; | ^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr new file mode 100644 index 0000000000000..a856a0eaf2a7c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2021.stderr @@ -0,0 +1,219 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:20:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:33:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:45:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:56:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - if let Some(&mut Some(x)) = &Some(Some(0)) { +LL + if let Some(&Some(x)) = &Some(Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:114:11 + | +LL | let [&&mut x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &[&mut 0]; +LL + let [&x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:121:11 + | +LL | let [&&mut x] = &mut [&mut 0]; + | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &mut [&mut 0]; +LL + let [&x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:128:11 + | +LL | let [&&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &[&mut 0]; +LL + let [&ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:135:11 + | +LL | let [&&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &mut [&mut 0]; +LL + let [&ref x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:142:11 + | +LL | let [&&mut mut x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:149:11 + | +LL | let [&&mut mut x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &mut [&mut 0]; +LL + let [&mut x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:164:15 + | +LL | let [&mut &x] = &[&mut 0]; + | ^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:170:15 + | +LL | let [&mut &ref x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &[&mut 0]; +LL + let [&mut ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:176:15 + | +LL | let [&mut &(mut x)] = &[&mut 0]; + | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &[&mut 0]; +LL + let [&mut mut x)] = &[&mut 0]; + | + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr index 6726a72631533..90510d23e6614 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:12:17 + --> $DIR/pattern-errors.rs:14:17 | LL | if let Some(&mut x) = &Some(&mut 0) { | ^^^^^ @@ -12,7 +12,7 @@ LL + if let Some(&x) = &Some(&mut 0) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:18:17 + --> $DIR/pattern-errors.rs:20:17 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^^^^ @@ -25,7 +25,7 @@ LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:24:22 + --> $DIR/pattern-errors.rs:26:22 | LL | if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { | ^^^^^ @@ -38,7 +38,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -51,7 +51,7 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -77,7 +77,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:147:10 + --> $DIR/pattern-errors.rs:158:10 | LL | let [&mut x] = &[&mut 0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let [&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:153:10 + --> $DIR/pattern-errors.rs:164:10 | LL | let [&mut &x] = &[&mut 0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:159:10 + --> $DIR/pattern-errors.rs:170:10 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:165:10 + --> $DIR/pattern-errors.rs:176:10 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs index c07c2972cd055..5e677445644a6 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.rs @@ -1,170 +1,181 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Test cases for poorly-typed patterns in edition 2024 which are caught by HIR typeck. These must //! be separate from cases caught by MIR borrowck or the latter errors may not be emitted. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut x) = &Some(&mut 0) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //[stable2021,classic2024]~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&_` + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; } if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; } if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| types differ in mutability + //[stable2021,classic2021,structural2021]~| types differ in mutability //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } - if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { - //[stable2021,structural2024]~^ ERROR: mismatched types + if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~| expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(classic2024)] let _: u32 = x; } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types - //[stable2021]~| expected integer, found `&mut _` + //[stable2021,classic2021,structural2021]~| expected integer, found `&mut _` //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } - if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { - //[stable2021,structural2024]~^ ERROR: mismatched types + if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; } if let Some(&mut Some(x)) = &Some(Some(0)) { //~^ ERROR: mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&mut _` - //[classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern + //[classic2021,structural2021,classic2024,structural2024]~| cannot match inherited `&` with `&mut` pattern } } fn structural_errors_0() { let &[&mut x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut ref x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut ref x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: &u32 = x; let &[&mut mut x] = &&mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&mut _` - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; let &[&mut mut x] = &mut &mut [0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability - //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + //[structural2021,structural2024]~| cannot match inherited `&` with `&mut` pattern + #[cfg(any(classic2021, classic2024))] let _: u32 = x; } fn structural_errors_1() { let [&(mut x)] = &[&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(classic2024)] let _: &u32 = x; let [&(mut x)] = &mut [&0]; //[structural2024]~^ ERROR: binding cannot be both mutable and by-reference - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(classic2024)] let _: &u32 = x; } fn structural_errors_2() { let [&&mut x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut ref x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(classic2024)] let _: &u32 = x; let [&&mut ref x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(classic2024)] let _: &u32 = x; let [&&mut mut x] = &[&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; let [&&mut mut x] = &mut [&mut 0]; - //[stable2021,structural2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,structural2024]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability + //[classic2021,structural2021] expected integer, found `&mut _` //[structural2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(classic2024)] let _: u32 = x; } fn classic_errors_0() { let [&mut x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(structural2024)] let _: &u32 = x; let [&mut &x] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; let [&mut &ref x] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: &u32 = x; + #[cfg(structural2024)] let _: &u32 = x; let [&mut &(mut x)] = &[&mut 0]; - //[stable2021,classic2024]~^ ERROR: mismatched types + //[stable2021,classic2021,structural2021,classic2024]~^ ERROR: mismatched types //[stable2021]~| expected integer, found `&_` //[classic2024]~| cannot match inherited `&` with `&mut` pattern - let _: u32 = x; + #[cfg(structural2024)] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr index ad19b122c20d7..76e6d2f562a27 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:18:27 + --> $DIR/pattern-errors.rs:20:27 | LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -15,7 +15,7 @@ LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -26,9 +26,9 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:36:17 + --> $DIR/pattern-errors.rs:38:17 | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` | | | types differ in mutability @@ -37,7 +37,7 @@ LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -48,9 +48,9 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:46:17 + --> $DIR/pattern-errors.rs:50:17 | -LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` | | | expected `Option<&mut Option<{integer}>>`, found `&_` @@ -59,7 +59,7 @@ LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` @@ -70,7 +70,7 @@ LL | if let Some(&mut Some(x)) = &Some(Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -80,7 +80,7 @@ LL | let &[&mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^^ @@ -91,7 +91,7 @@ LL + let &[x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:65:9 + --> $DIR/pattern-errors.rs:70:9 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -102,7 +102,7 @@ LL | let &[&mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -112,7 +112,7 @@ LL | let &[&mut ref x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^^^^^^ @@ -123,7 +123,7 @@ LL + let &[ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:77:9 + --> $DIR/pattern-errors.rs:82:9 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -134,7 +134,7 @@ LL | let &[&mut ref x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ --------- this expression has type `&&mut [{integer}; 1]` @@ -144,7 +144,7 @@ LL | let &[&mut mut x] = &&mut [0]; = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^^^^^^ @@ -155,7 +155,7 @@ LL + let &[mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:89:9 + --> $DIR/pattern-errors.rs:94:9 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^^^^^^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` @@ -166,7 +166,7 @@ LL | let &[&mut mut x] = &mut &mut [0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:109:10 + --> $DIR/pattern-errors.rs:114:10 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -177,7 +177,7 @@ LL | let [&&mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:115:10 + --> $DIR/pattern-errors.rs:121:10 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -188,7 +188,7 @@ LL | let [&&mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:10 + --> $DIR/pattern-errors.rs:128:10 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -199,7 +199,7 @@ LL | let [&&mut ref x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:127:10 + --> $DIR/pattern-errors.rs:135:10 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -210,7 +210,7 @@ LL | let [&&mut ref x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:10 + --> $DIR/pattern-errors.rs:142:10 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -221,7 +221,7 @@ LL | let [&&mut mut x] = &[&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:139:10 + --> $DIR/pattern-errors.rs:149:10 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -232,7 +232,7 @@ LL | let [&&mut mut x] = &mut [&mut 0]; found reference `&_` error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:153:15 + --> $DIR/pattern-errors.rs:164:15 | LL | let [&mut &x] = &[&mut 0]; | ^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -248,7 +248,7 @@ LL + let [&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:159:15 + --> $DIR/pattern-errors.rs:170:15 | LL | let [&mut &ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -264,7 +264,7 @@ LL + let [&mut ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:165:15 + --> $DIR/pattern-errors.rs:176:15 | LL | let [&mut &(mut x)] = &[&mut 0]; | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr new file mode 100644 index 0000000000000..1ca6bff3f38c3 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2021.stderr @@ -0,0 +1,310 @@ +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:20:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:33:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/pattern-errors.rs:38:23 + | +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:45:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:50:28 + | +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { +LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:56:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - if let Some(&mut Some(x)) = &Some(Some(0)) { +LL + if let Some(&Some(x)) = &Some(Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:64:11 + | +LL | let &[&mut x] = &&mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut x] = &&mut [0]; +LL + let &[&x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:70:11 + | +LL | let &[&mut x] = &mut &mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut x] = &mut &mut [0]; +LL + let &[&x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:76:11 + | +LL | let &[&mut ref x] = &&mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut ref x] = &&mut [0]; +LL + let &[&ref x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:82:11 + | +LL | let &[&mut ref x] = &mut &mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut ref x] = &mut &mut [0]; +LL + let &[&ref x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:88:11 + | +LL | let &[&mut mut x] = &&mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut mut x] = &&mut [0]; +LL + let &[&mut x] = &&mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:94:11 + | +LL | let &[&mut mut x] = &mut &mut [0]; + | ^^^^^ + | + = note: cannot match inherited `&` with `&mut` pattern +help: replace this `&mut` pattern with `&` + | +LL - let &[&mut mut x] = &mut &mut [0]; +LL + let &[&mut x] = &mut &mut [0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:114:11 + | +LL | let [&&mut x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &[&mut 0]; +LL + let [&x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:121:11 + | +LL | let [&&mut x] = &mut [&mut 0]; + | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut x] = &mut [&mut 0]; +LL + let [&x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:128:11 + | +LL | let [&&mut ref x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &[&mut 0]; +LL + let [&ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:135:11 + | +LL | let [&&mut ref x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut ref x] = &mut [&mut 0]; +LL + let [&ref x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:142:11 + | +LL | let [&&mut mut x] = &[&mut 0]; + | ^^^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:149:11 + | +LL | let [&&mut mut x] = &mut [&mut 0]; + | ^^^^^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +help: consider removing `&mut` from the pattern + | +LL - let [&&mut mut x] = &mut [&mut 0]; +LL + let [&mut x] = &mut [&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:164:15 + | +LL | let [&mut &x] = &[&mut 0]; + | ^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &[&mut 0]; +LL + let [&mut x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:170:15 + | +LL | let [&mut &ref x] = &[&mut 0]; + | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &[&mut 0]; +LL + let [&mut ref x] = &[&mut 0]; + | + +error[E0308]: mismatched types + --> $DIR/pattern-errors.rs:176:15 + | +LL | let [&mut &(mut x)] = &[&mut 0]; + | ^^^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &[&mut 0]; +LL + let [&mut mut x)] = &[&mut 0]; + | + +error: aborting due to 21 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr index fdf48a5a71b5f..3658893df9cc1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/pattern-errors.structural2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:31:17 + --> $DIR/pattern-errors.rs:33:17 | LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^ @@ -12,20 +12,20 @@ LL + if let Some(&Some(&_)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:36:23 + --> $DIR/pattern-errors.rs:38:23 | -LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { +LL | if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { | ^^^^^ | = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | -LL - if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { -LL + if let Some(&Some(&_)) = &Some(&mut Some(0)) { +LL - if let Some(&Some(&mut x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(&x)) = &Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:41:23 + --> $DIR/pattern-errors.rs:45:23 | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^ @@ -38,20 +38,20 @@ LL + if let Some(&Some(&_)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:46:28 + --> $DIR/pattern-errors.rs:50:28 | -LL | if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { +LL | if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { | ^^^^^ | = note: cannot match inherited `&` with `&mut` pattern help: replace this `&mut` pattern with `&` | -LL - if let Some(&Some(Some(&mut _))) = &Some(Some(&mut Some(0))) { -LL + if let Some(&Some(Some(&_))) = &Some(Some(&mut Some(0))) { +LL - if let Some(&Some(Some(&mut x))) = &Some(Some(&mut Some(0))) { +LL + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:51:17 + --> $DIR/pattern-errors.rs:56:17 | LL | if let Some(&mut Some(x)) = &Some(Some(0)) { | ^^^^^ @@ -64,7 +64,7 @@ LL + if let Some(&Some(x)) = &Some(Some(0)) { | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:59:11 + --> $DIR/pattern-errors.rs:64:11 | LL | let &[&mut x] = &&mut [0]; | ^^^^^ @@ -77,7 +77,7 @@ LL + let &[&x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:65:11 + --> $DIR/pattern-errors.rs:70:11 | LL | let &[&mut x] = &mut &mut [0]; | ^^^^^ @@ -90,7 +90,7 @@ LL + let &[&x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:71:11 + --> $DIR/pattern-errors.rs:76:11 | LL | let &[&mut ref x] = &&mut [0]; | ^^^^^ @@ -103,7 +103,7 @@ LL + let &[&ref x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:77:11 + --> $DIR/pattern-errors.rs:82:11 | LL | let &[&mut ref x] = &mut &mut [0]; | ^^^^^ @@ -116,7 +116,7 @@ LL + let &[&ref x] = &mut &mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:83:11 + --> $DIR/pattern-errors.rs:88:11 | LL | let &[&mut mut x] = &&mut [0]; | ^^^^^ @@ -129,7 +129,7 @@ LL + let &[&mut x] = &&mut [0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:89:11 + --> $DIR/pattern-errors.rs:94:11 | LL | let &[&mut mut x] = &mut &mut [0]; | ^^^^^ @@ -142,7 +142,7 @@ LL + let &[&mut x] = &mut &mut [0]; | error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:97:12 + --> $DIR/pattern-errors.rs:102:12 | LL | let [&(mut x)] = &[&0]; | ^^^^ @@ -152,7 +152,7 @@ LL | let [&(mut x)] = &[&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: binding cannot be both mutable and by-reference - --> $DIR/pattern-errors.rs:102:12 + --> $DIR/pattern-errors.rs:107:12 | LL | let [&(mut x)] = &mut [&0]; | ^^^^ @@ -162,7 +162,7 @@ LL | let [&(mut x)] = &mut [&0]; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:109:11 + --> $DIR/pattern-errors.rs:114:11 | LL | let [&&mut x] = &[&mut 0]; | ^^^^^ @@ -175,7 +175,7 @@ LL + let [&&x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:115:11 + --> $DIR/pattern-errors.rs:121:11 | LL | let [&&mut x] = &mut [&mut 0]; | ^^^^^ @@ -188,7 +188,7 @@ LL + let [&&x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:121:11 + --> $DIR/pattern-errors.rs:128:11 | LL | let [&&mut ref x] = &[&mut 0]; | ^^^^^ @@ -201,7 +201,7 @@ LL + let [&&ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:127:11 + --> $DIR/pattern-errors.rs:135:11 | LL | let [&&mut ref x] = &mut [&mut 0]; | ^^^^^ @@ -214,7 +214,7 @@ LL + let [&&ref x] = &mut [&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:133:11 + --> $DIR/pattern-errors.rs:142:11 | LL | let [&&mut mut x] = &[&mut 0]; | ^^^^^ @@ -227,7 +227,7 @@ LL + let [&&mut x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/pattern-errors.rs:139:11 + --> $DIR/pattern-errors.rs:149:11 | LL | let [&&mut mut x] = &mut [&mut 0]; | ^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr new file mode 100644 index 0000000000000..1dda2dca4a48a --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2021.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 56125be2d6fc8..44cb005a748da 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:10 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^ @@ -12,14 +12,14 @@ LL + let [&ref x] = &[&mut 0]; | error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -29,20 +29,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -52,14 +52,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -69,14 +69,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index 4e048570c33c2..ea6f028fe4b8b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -1,35 +1,37 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //! Tests for errors from binding with `ref x` under a by-ref default binding mode in edition 2024. //! These can't be in the same body as tests for other errors, since they're emitted during THIR //! construction. The errors on stable edition 2021 Rust are unrelated. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] /// These only fail on the eat-inner variant of the new edition 2024 pattern typing rules. /// The eat-outer variant eats the inherited reference, so binding with `ref` isn't a problem. fn errors_from_eating_the_real_reference() { let [&ref x] = &[&0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&ref x] = &mut [&0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&mut ref x] = &mut [&mut 0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref mut x] = &mut [&mut 0]; //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &mut u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; #[cfg(classic2024)] let _: &mut &mut u32 = x; } @@ -40,12 +42,14 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { //[stable2021]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&ref x] = &mut [&mut 0]; //[stable2021]~^ ERROR: mismatched types //[stable2021]~| types differ in mutability //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; } @@ -55,7 +59,7 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { //[classic2024]~^ ERROR: mismatched types //[classic2024]~| cannot match inherited `&` with `&mut` pattern //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; } /// These should be errors in all editions. In edition 2024, they should be caught by the pattern @@ -74,13 +78,13 @@ fn borrowck_errors_in_old_editions() { pub fn main() { let [ref x] = &[0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref x] = &mut [0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref mut x] = &mut [0]; //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` - #[cfg(stable2021)] let _: &mut u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr index 26095d8460572..2ec6650dd7d0b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:10 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^ --------- this expression has type `&[&mut {integer}; 1]` @@ -15,7 +15,7 @@ LL + let [ref x] = &[&mut 0]; | error[E0308]: mismatched types - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:10 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^ ------------- this expression has type `&mut [&mut {integer}; 1]` @@ -31,7 +31,7 @@ LL + let [ref x] = &mut [&mut 0]; | error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr new file mode 100644 index 0000000000000..1dda2dca4a48a --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2021.stderr @@ -0,0 +1,9 @@ +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 + | +LL | let [ref mut x] = &[0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index 31930e8c03371..6f62ad06cc493 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -1,12 +1,12 @@ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:15:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:17:11 | LL | let [&ref x] = &[&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:15:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:17:9 | LL | let [&ref x] = &[&0]; | ^^^^^^^^ this matches on type `&_` @@ -16,14 +16,14 @@ LL | let &[&ref x] = &[&0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:20:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:22:11 | LL | let [&ref x] = &mut [&0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:20:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:22:9 | LL | let [&ref x] = &mut [&0]; | ^^^^^^^^ this matches on type `&mut _` @@ -33,14 +33,14 @@ LL | let &mut [&ref x] = &mut [&0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:25:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:27:15 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:25:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:27:9 | LL | let [&mut ref x] = &mut [&mut 0]; | ^^^^^^^^^^^^ this matches on type `&mut _` @@ -50,14 +50,14 @@ LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:30:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:32:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:30:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:32:9 | LL | let [&mut ref mut x] = &mut [&mut 0]; | ^^^^^^^^^^^^^^^^ this matches on type `&mut _` @@ -67,14 +67,14 @@ LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:11 | LL | let [&ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:39:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:41:9 | LL | let [&ref x] = &[&mut 0]; | ^^^^^^^^ this matches on type `&_` @@ -84,14 +84,14 @@ LL | let &[&ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:11 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:11 | LL | let [&ref x] = &mut [&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:45:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:48:9 | LL | let [&ref x] = &mut [&mut 0]; | ^^^^^^^^ this matches on type `&mut _` @@ -101,14 +101,14 @@ LL | let &mut [&ref x] = &mut [&mut 0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:15 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:15 | LL | let [&mut ref x] = &[&mut 0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:54:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:58:9 | LL | let [&mut ref x] = &[&mut 0]; | ^^^^^^^^^^^^ this matches on type `&_` @@ -118,14 +118,14 @@ LL | let &[&mut ref x] = &[&mut 0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:9 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^^^ this matches on type `&_` @@ -135,20 +135,20 @@ LL | let &[ref mut x] = &[0]; | + error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/ref-binding-on-inh-ref-errors.rs:67:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:71:10 | LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 | LL | let [ref x] = &[0]; | ^^^ binding modifier not allowed under `ref` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:75:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 | LL | let [ref x] = &[0]; | ^^^^^^^ this matches on type `&_` @@ -158,14 +158,14 @@ LL | let &[ref x] = &[0]; | + error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 | LL | let [ref x] = &mut [0]; | ^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:79:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 | LL | let [ref x] = &mut [0]; | ^^^^^^^ this matches on type `&mut _` @@ -175,14 +175,14 @@ LL | let &mut [ref x] = &mut [0]; | ++++ error: binding modifiers may only be written when the default binding mode is `move` - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:10 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:10 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode | = note: for more information, see note: matching on a reference type with a non-reference pattern changes the default binding mode - --> $DIR/ref-binding-on-inh-ref-errors.rs:83:9 + --> $DIR/ref-binding-on-inh-ref-errors.rs:87:9 | LL | let [ref mut x] = &mut [0]; | ^^^^^^^^^^^ this matches on type `&mut _` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr new file mode 100644 index 0000000000000..8127ca92e025e --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2021.stderr @@ -0,0 +1,51 @@ +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:11 + | +LL | let &[x] = &mut &mut [0]; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed index c01784d5076b7..57de9cb4c10d0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.fixed @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &mut pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &mut (ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &mut [x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr index 5e98b77be40cd..8127ca92e025e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.classic2024.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -39,7 +39,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:41:11 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:11 | LL | let &[x] = &mut &mut [0]; | - ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs index fe40dabb55394..277ff90b673ce 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.rs @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &(ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr index 72c6c05e18443..5fbaacd7281d2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:17 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:17 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | ^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -10,7 +10,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:12 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:12 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | ^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -21,7 +21,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:9 | LL | let &pat!(x) = &mut 0; | ^^^^^^^^ ------ this expression has type `&mut {integer}` @@ -32,7 +32,7 @@ LL | let &pat!(x) = &mut 0; found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:9 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | ^^^^^^^^^^^^^^^^^^^^^^^ ------------------ this expression has type `&mut (bool, bool)` @@ -43,7 +43,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); found reference `&_` error[E0308]: mismatched types - --> $DIR/ref-mut-inside-shared-ref-pat.rs:41:9 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:43:9 | LL | let &[x] = &mut &mut [0]; | ^^^^ ------------- this expression has type `&mut &mut [{integer}; 1]` diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr new file mode 100644 index 0000000000000..e735cfed2492f --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2021.stderr @@ -0,0 +1,43 @@ +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed index 4ee849b38c53b..bcde4b90f592c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.fixed @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-rustfix @@ -7,19 +9,19 @@ //! Tests for `&` patterns matched against `&mut` reference types where the inner pattern attempts //! to bind by mutable reference. #![allow(incomplete_features)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; } @@ -28,18 +30,18 @@ pub fn main() { } let &mut pat!(x) = &mut 0; //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut u8 = x; let &mut (ref mut a, ref mut b) = &mut (true, false); //[stable2021]~^ ERROR: mismatched types - //[classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern - //[classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,structural2021,classic2024,structural2024]~| ERROR: cannot borrow as mutable inside an `&` pattern let _: &mut bool = a; let _: &mut bool = b; let &[x] = &mut &mut [0]; //[stable2021]~^ ERROR: mismatched types - //[classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern + //[classic2021,classic2024]~^^ ERROR: cannot borrow as mutable inside an `&` pattern let _: &u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr index 69cb6c438b6ed..e735cfed2492f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-mut-inside-shared-ref-pat.structural2024.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:14:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:16:31 | LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -7,7 +7,7 @@ LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:20:31 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:22:31 | LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | - ^ @@ -15,7 +15,7 @@ LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:29:15 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:31:15 | LL | let &pat!(x) = &mut 0; | - ^ @@ -23,7 +23,7 @@ LL | let &pat!(x) = &mut 0; | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:19 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:19 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ @@ -31,7 +31,7 @@ LL | let &(ref mut a, ref mut b) = &mut (true, false); | help: replace this `&` with `&mut`: `&mut` error[E0596]: cannot borrow as mutable inside an `&` pattern - --> $DIR/ref-mut-inside-shared-ref-pat.rs:34:30 + --> $DIR/ref-mut-inside-shared-ref-pat.rs:36:30 | LL | let &(ref mut a, ref mut b) = &mut (true, false); | - ^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs deleted file mode 100644 index ab3264704acc0..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ edition: 2021 -//@ revisions: classic structural -#![allow(incomplete_features)] -#![cfg_attr(classic, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural, feature(ref_pat_eat_one_layer_2024_structural))] - -pub fn main() { - #[cfg(structural)] - if let &Some(Some(x)) = &Some(&mut Some(0)) { - let _: &u32 = x; - } - - if let Some(&x) = Some(&mut 0) { - let _: u32 = x; - } -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs deleted file mode 100644 index d28567f2859a3..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ edition: 2021 -#![allow(incomplete_features)] -#![feature(ref_pat_eat_one_layer_2024)] -pub fn main() { - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(Some(&0)) { - let _: &u32 = x; - //~^ ERROR: mismatched types - } - if let Some(Some(&&x)) = &Some(Some(&0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&Some(x)) = &Some(Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(Some(&x)) = &Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } - if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - //~^ ERROR: mismatched types - let _: u32 = x; - } -} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr deleted file mode 100644 index 0158ed0f42357..0000000000000 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref_pat_eat_one_layer_2021_fail.stderr +++ /dev/null @@ -1,133 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:5:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:10:23 - | -LL | let _: &u32 = x; - | ---- ^ expected `&u32`, found integer - | | - | expected due to this - | -help: consider borrowing here - | -LL | let _: &u32 = &x; - | + - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:13:23 - | -LL | if let Some(Some(&&x)) = &Some(Some(&0)) { - | ^^ --------------- this expression has type `&Option>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&&x)) = &Some(Some(&0)) { -LL + if let Some(Some(&x)) = &Some(Some(&0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:17:17 - | -LL | if let Some(&Some(x)) = &Some(Some(0)) { - | ^^^^^^^^ -------------- this expression has type `&Option>` - | | - | expected `Option<{integer}>`, found `&_` - | - = note: expected enum `Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:21:22 - | -LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { -LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:25:22 - | -LL | if let Some(Some(&x)) = &Some(&Some(0)) { - | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(Some(&x)) = &Some(&Some(0)) { -LL + if let Some(Some(x)) = &Some(&Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:29:27 - | -LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { - | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL - if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { -LL + if let Some(&mut Some(x)) = &Some(&mut Some(0)) { - | - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 - | -LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` - | | - | expected integer, found `&mut _` - | - = note: expected type `{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/ref_pat_eat_one_layer_2021_fail.rs:33:23 - | -LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { - | ^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { -LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { - | - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr new file mode 100644 index 0000000000000..f8c2bd9a92128 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.classic2021.stderr @@ -0,0 +1,122 @@ +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:32:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:63:23 + | +LL | if let Some(&Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&Some(0)) { +LL + if let Some(&Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:82:23 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:88:23 + | +LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { + | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &mut Some(&Some(0)) { +LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:123:15 + | +LL | let [&mut &x] = &mut [&0]; + | ^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &mut [&0]; +LL + let [&mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:129:15 + | +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &mut [&0]; +LL + let [&mut ref x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:135:15 + | +LL | let [&mut &(mut x)] = &mut [&0]; + | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &mut [&0]; +LL + let [&mut mut x)] = &mut [&0]; + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/well-typed-edition-2024.rs:109:19 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs index 3114b9d3bf8cb..62c1c28022b7d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs @@ -1,5 +1,7 @@ -//@ revisions: stable2021 classic2024 structural2024 +//@ revisions: stable2021 classic2021 structural2021 classic2024 structural2024 //@[stable2021] edition: 2021 +//@[classic2021] edition: 2021 +//@[structural2021] edition: 2021 //@[classic2024] edition: 2024 //@[structural2024] edition: 2024 //@[classic2024] run-pass @@ -7,8 +9,8 @@ //! Test cases for well-typed patterns in edition 2024. These are in their own file to ensure we //! pass both HIR typeck and MIR borrowck, as we may skip the latter if grouped with failing tests. #![allow(incomplete_features, unused_mut)] -#![cfg_attr(classic2024, feature(ref_pat_eat_one_layer_2024))] -#![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))] +#![cfg_attr(any(classic2021, classic2024), feature(ref_pat_eat_one_layer_2024))] +#![cfg_attr(any(structural2021, structural2024), feature(ref_pat_eat_one_layer_2024_structural))] pub fn main() { // Tests not using match ergonomics. These should always succeed with the same bindings. @@ -18,110 +20,121 @@ pub fn main() { // Tests for differences in how many layers of reference are eaten by reference patterns if let Some(Some(&x)) = &Some(Some(&0)) { - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; } if let Some(&Some(x)) = &mut Some(&Some(0)) { // This additionally tests that `&` patterns can eat inherited `&mut` refs. // This is possible on stable when the real reference being eaten is of a `&` type. - #[cfg(stable2021)] let _: u32 = x; + #[cfg(any(stable2021, classic2021, structural2021))] let _: u32 = x; #[cfg(any(classic2024, structural2024))] let _: &u32 = x; } if let Some(Some(&&x)) = &Some(Some(&0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for eating a lone inherited reference if let Some(Some(&x)) = &Some(&Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &Some(Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected integer, found `&mut _` - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for `&` patterns matching real `&mut` reference types if let Some(&Some(&x)) = Some(&Some(&mut 0)) { //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests for eating only one layer and also eating a lone inherited reference if let Some(&Some(&x)) = &Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } // Tests for `&` matching a lone inherited possibly-`&mut` reference if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_` - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(x)) = &mut Some(Some(0)) { //[stable2021]~^ mismatched types //[stable2021]~| expected `Option<{integer}>`, found `&_` - let _: u32 = x; + #[cfg(any(classic2021, structural2021, classic2024, structural2024))] let _: u32 = x; } // Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies) if let Some(&Some(&x)) = &Some(&mut Some(0)) { - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + //[classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } if let Some(&Some(&x)) = &mut Some(&Some(0)) { - //[stable2021]~^ mismatched types - //[stable2021]~| expected integer, found `&_` - let _: u32 = x; + //[stable2021,classic2021,structural2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } - // Tests for eat-inner rulesets matching on the outer reference if matching on the inner - // reference causes a mutability mismatch, i.e. `Deref(EatInner, FallbackToOuter)`: + // Tests for eat-inner and eat-both rulesets matching on the outer reference if matching on the + // inner reference causes a mutability mismatch. i.e. tests for "fallback-to-outer" deref rules. let [&mut x] = &mut [&0]; //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut ref x] = &mut [&0]; //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: &&u32 = x; + #[cfg(any(classic2021, structural2021))] let _: &u32 = x; + #[cfg(any(classic2024, structural2024))] let _: &&u32 = x; - let [&mut ref mut x] = &mut [&0]; - //[stable2021]~^ mismatched types - //[stable2021]~| types differ in mutability - let _: &mut &u32 = x; + fn borrowck_error_on_structural2021() { + let [&mut ref mut x] = &mut [&0]; + //[stable2021]~^ mismatched types + //[stable2021]~| types differ in mutability + //[classic2021,structural2021]~^^^ cannot borrow data in a `&` reference as mutable + #[cfg(any(classic2024, structural2024))] let _: &mut &u32 = x; + } + borrowck_error_on_structural2021(); let [&mut mut x] = &mut [&0]; //[stable2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: &u32 = x; + #[cfg(any(classic2021, structural2021))] let _: u32 = x; + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &x] = &mut [&0]; - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + //[classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; let [&mut &ref x] = &mut [&0]; - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: &u32 = x; + //[classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: &u32 = x; let [&mut &(mut x)] = &mut [&0]; - //[stable2021]~^ mismatched types + //[stable2021,classic2021,structural2021]~^ mismatched types //[stable2021]~| types differ in mutability - let _: u32 = x; + //[classic2021,structural2021]~| expected integer, found `&_` + #[cfg(any(classic2024, structural2024))] let _: u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr index b1a8024397bdc..adb47172f34cc 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:30:23 + --> $DIR/well-typed-edition-2024.rs:32:23 | LL | if let Some(Some(&&x)) = &Some(Some(&0)) { | ^^ --------------- this expression has type `&Option>` @@ -15,7 +15,7 @@ LL + if let Some(Some(&x)) = &Some(Some(&0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:37:22 + --> $DIR/well-typed-edition-2024.rs:39:22 | LL | if let Some(Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -31,7 +31,7 @@ LL + if let Some(Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:42:17 + --> $DIR/well-typed-edition-2024.rs:44:17 | LL | if let Some(&Some(x)) = &Some(Some(0)) { | ^^^^^^^^ -------------- this expression has type `&Option>` @@ -42,7 +42,7 @@ LL | if let Some(&Some(x)) = &Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:47:22 + --> $DIR/well-typed-edition-2024.rs:49:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` @@ -52,7 +52,7 @@ LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { = note: expected type `{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:47:22 + --> $DIR/well-typed-edition-2024.rs:49:22 | LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { | ^^^^^^ @@ -63,7 +63,7 @@ LL + if let Some(Some(x)) = &mut Some(&mut Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:54:23 + --> $DIR/well-typed-edition-2024.rs:56:23 | LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` @@ -79,7 +79,7 @@ LL + if let Some(&Some(x)) = Some(&Some(&mut 0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:61:23 + --> $DIR/well-typed-edition-2024.rs:63:23 | LL | if let Some(&Some(&x)) = &Some(&Some(0)) { | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` @@ -95,7 +95,7 @@ LL + if let Some(&Some(x)) = &Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:68:17 + --> $DIR/well-typed-edition-2024.rs:70:17 | LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { | ^^^^^^^^^^^^^^^ ------------------------- this expression has type `&Option>>` @@ -106,7 +106,7 @@ LL | if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:73:17 + --> $DIR/well-typed-edition-2024.rs:75:17 | LL | if let Some(&Some(x)) = &mut Some(Some(0)) { | ^^^^^^^^ ------------------ this expression has type `&mut Option>` @@ -117,7 +117,7 @@ LL | if let Some(&Some(x)) = &mut Some(Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:80:17 + --> $DIR/well-typed-edition-2024.rs:82:17 | LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { | ^^^^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` @@ -128,7 +128,7 @@ LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { found reference `&_` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:85:23 + --> $DIR/well-typed-edition-2024.rs:88:23 | LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` @@ -144,7 +144,7 @@ LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:93:10 + --> $DIR/well-typed-edition-2024.rs:96:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -154,7 +154,7 @@ LL | let [&mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:93:10 + --> $DIR/well-typed-edition-2024.rs:96:10 | LL | let [&mut x] = &mut [&0]; | ^^^^^^ @@ -165,7 +165,7 @@ LL + let [x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:98:10 + --> $DIR/well-typed-edition-2024.rs:102:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -175,7 +175,7 @@ LL | let [&mut ref x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:98:10 + --> $DIR/well-typed-edition-2024.rs:102:10 | LL | let [&mut ref x] = &mut [&0]; | ^^^^^^^^^^ @@ -186,28 +186,7 @@ LL + let [ref x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:103:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` - | | - | types differ in mutability - | - = note: expected reference `&{integer}` - found mutable reference `&mut _` -note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:103:10 - | -LL | let [&mut ref mut x] = &mut [&0]; - | ^^^^^^^^^^^^^^ -help: consider removing `&mut` from the pattern - | -LL - let [&mut ref mut x] = &mut [&0]; -LL + let [ref mut x] = &mut [&0]; - | - -error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:108:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -217,7 +196,7 @@ LL | let [&mut mut x] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/well-typed-edition-2024.rs:108:10 + --> $DIR/well-typed-edition-2024.rs:117:10 | LL | let [&mut mut x] = &mut [&0]; | ^^^^^^^^^^ @@ -228,7 +207,7 @@ LL + let [mut x] = &mut [&0]; | error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:113:10 + --> $DIR/well-typed-edition-2024.rs:123:10 | LL | let [&mut &x] = &mut [&0]; | ^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -239,7 +218,7 @@ LL | let [&mut &x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:118:10 + --> $DIR/well-typed-edition-2024.rs:129:10 | LL | let [&mut &ref x] = &mut [&0]; | ^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -250,7 +229,7 @@ LL | let [&mut &ref x] = &mut [&0]; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/well-typed-edition-2024.rs:123:10 + --> $DIR/well-typed-edition-2024.rs:135:10 | LL | let [&mut &(mut x)] = &mut [&0]; | ^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` @@ -260,6 +239,27 @@ LL | let [&mut &(mut x)] = &mut [&0]; = note: expected reference `&{integer}` found mutable reference `&mut _` +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/well-typed-edition-2024.rs:109:14 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - let [&mut ref mut x] = &mut [&0]; +LL + let [ref mut x] = &mut [&0]; + | + error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr new file mode 100644 index 0000000000000..f8c2bd9a92128 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.structural2021.stderr @@ -0,0 +1,122 @@ +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:32:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:63:23 + | +LL | if let Some(&Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&Some(0)) { +LL + if let Some(&Some(x)) = &Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:82:23 + | +LL | if let Some(&Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &Some(&mut Some(0)) { +LL + if let Some(&Some(x)) = &Some(&mut Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:88:23 + | +LL | if let Some(&Some(&x)) = &mut Some(&Some(0)) { + | ^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(&Some(&x)) = &mut Some(&Some(0)) { +LL + if let Some(&Some(x)) = &mut Some(&Some(0)) { + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:123:15 + | +LL | let [&mut &x] = &mut [&0]; + | ^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &x] = &mut [&0]; +LL + let [&mut x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:129:15 + | +LL | let [&mut &ref x] = &mut [&0]; + | ^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &ref x] = &mut [&0]; +LL + let [&mut ref x] = &mut [&0]; + | + +error[E0308]: mismatched types + --> $DIR/well-typed-edition-2024.rs:135:15 + | +LL | let [&mut &(mut x)] = &mut [&0]; + | ^^^^^^^^ --------- this expression has type `&mut [&{integer}; 1]` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - let [&mut &(mut x)] = &mut [&0]; +LL + let [&mut mut x)] = &mut [&0]; + | + +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/well-typed-edition-2024.rs:109:19 + | +LL | let [&mut ref mut x] = &mut [&0]; + | ^^^^^^^^^ cannot borrow as mutable + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0308, E0596. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 0a22e939496e5..bb4ecc09063b7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -239,4 +239,15 @@ fn main() { assert_type_eq(b, &0u32); assert_type_eq(c, &[0u32]); assert_type_eq(d, 0u32); + + // Test that we use the correct message and suggestion style when pointing inside expansions. + let &[migration_lint_macros::bind_ref!(a)] = &[0]; + //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + assert_type_eq(a, &0u32); + + // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. + let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; + //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 7a6f2269d44a2..2837c8d81dbdd 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -239,4 +239,15 @@ fn main() { assert_type_eq(b, &0u32); assert_type_eq(c, &[0u32]); assert_type_eq(d, 0u32); + + // Test that we use the correct message and suggestion style when pointing inside expansions. + let [migration_lint_macros::bind_ref!(a)] = &[0]; + //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + assert_type_eq(a, &0u32); + + // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. + let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 191800df07a2e..6efda4f757ff6 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -562,5 +562,41 @@ help: make the implied reference patterns explicit LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | + + -error: aborting due to 29 previous errors +error: binding modifiers may only be written when the default binding mode is `move` + --> $DIR/migration_lint.rs:244:10 + | +LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion + | + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/migration_lint.rs:244:9 + | +LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` + = note: this error originates in the macro `migration_lint_macros::bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) +help: make the implied reference pattern explicit + | +LL | let &[migration_lint_macros::bind_ref!(a)] = &[0]; + | + + +error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + --> $DIR/migration_lint.rs:249:10 + | +LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + | ^ reference pattern not allowed under `ref` default binding mode + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: matching on a reference type with a non-reference pattern changes the default binding mode + --> $DIR/migration_lint.rs:249:9 + | +LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` +help: make the implied reference pattern explicit + | +LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; + | + + +error: aborting due to 31 previous errors diff --git a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr index 23821decd6e43..d241f417553fc 100644 --- a/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-types.exhaustive_patterns.stderr @@ -37,7 +37,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -100,7 +100,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -374,7 +374,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[]` not covered @@ -415,7 +415,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -462,7 +462,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr index 84aefe7d96370..ea63d7ba1afd1 100644 --- a/tests/ui/pattern/usefulness/empty-types.never_pats.stderr +++ b/tests/ui/pattern/usefulness/empty-types.never_pats.stderr @@ -46,7 +46,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -76,7 +76,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered @@ -321,7 +321,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[!, ..]` not covered @@ -376,7 +376,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty @@ -390,7 +390,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -502,7 +502,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *ref_tuple_half_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/empty-types.normal.stderr b/tests/ui/pattern/usefulness/empty-types.normal.stderr index f3af74c16c30f..a1a44e7774428 100644 --- a/tests/ui/pattern/usefulness/empty-types.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-types.normal.stderr @@ -37,7 +37,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match ref_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -67,7 +67,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match res_u32_never { LL + Ok(_) => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered @@ -312,7 +312,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered @@ -367,7 +367,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *slice_never { LL + _ => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty @@ -381,7 +381,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match array_0_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -493,7 +493,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match *ref_tuple_half_never { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr index 34f8eb1e1635d..c3e1c267b6140 100644 --- a/tests/ui/pattern/usefulness/impl-trait.stderr +++ b/tests/ui/pattern/usefulness/impl-trait.stderr @@ -36,7 +36,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match return_never_rpit(x) { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern @@ -118,7 +118,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match return_never_tait(x) { LL + _ => todo!(), -LL + } +LL ~ } | error: unreachable pattern diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr index 914c6ed60c839..7caee64a33fbc 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr @@ -154,7 +154,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match 7usize { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 12 previous errors diff --git a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr index 2acde84965066..c37a9a5157904 100644 --- a/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr +++ b/tests/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr @@ -15,7 +15,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match a { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/usefulness/unstable-gated-fields.stderr b/tests/ui/pattern/usefulness/unstable-gated-fields.stderr index 4487f2735345a..bd51aca65ee2d 100644 --- a/tests/ui/pattern/usefulness/unstable-gated-fields.stderr +++ b/tests/ui/pattern/usefulness/unstable-gated-fields.stderr @@ -6,19 +6,16 @@ LL | let UnstableStruct { stable, stable2, } = UnstableStruct::default(); | help: include the missing field in the pattern | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, unstable } = UnstableStruct::default(); + | ++++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, unstable: _ } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, unstable: _ } = UnstableStruct::default(); + | +++++++++++ help: or always ignore missing fields here | -LL - let UnstableStruct { stable, stable2, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); + | ++ error[E0027]: pattern does not mention field `stable2` --> $DIR/unstable-gated-fields.rs:13:9 @@ -28,19 +25,16 @@ LL | let UnstableStruct { stable, unstable, } = UnstableStruct::default(); | help: include the missing field in the pattern | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, stable2 } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, stable2 } = UnstableStruct::default(); + | +++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, stable2: _ } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, stable2: _ } = UnstableStruct::default(); + | ++++++++++ help: or always ignore missing fields here | -LL - let UnstableStruct { stable, unstable, } = UnstableStruct::default(); -LL + let UnstableStruct { stable, unstable, .. } = UnstableStruct::default(); - | +LL | let UnstableStruct { stable, unstable, .. } = UnstableStruct::default(); + | ++ error: aborting due to 2 previous errors diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs index 3c6e9825e7288..136e0ceeb5bec 100644 --- a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs +++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs @@ -1,6 +1,5 @@ //@ aux-crate:priv:reexport=reexport.rs //@ compile-flags: -Zunstable-options -//@ check-pass // Checks the behavior of a reexported item from a private dependency. @@ -9,7 +8,7 @@ extern crate reexport; -// FIXME: This should trigger. pub fn leaks_priv() -> reexport::Shared { + //~^ ERROR type `Shared` from private dependency 'shared' in public interface reexport::Shared } diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr new file mode 100644 index 0000000000000..f1573283ff2e3 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr @@ -0,0 +1,14 @@ +error: type `Shared` from private dependency 'shared' in public interface + --> $DIR/reexport_from_priv.rs:11:1 + | +LL | pub fn leaks_priv() -> reexport::Shared { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/reexport_from_priv.rs:7:9 + | +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.rs b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs index 34b624b4a1a40..2fe66ae80cf48 100644 --- a/tests/ui/privacy/pub-priv-dep/shared_indirect.rs +++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs @@ -1,7 +1,6 @@ //@ aux-crate:priv:shared=shared.rs //@ aux-crate:priv:indirect1=indirect1.rs //@ compile-flags: -Zunstable-options -//@ check-pass // A shared dependency, where it is only indirectly public. // @@ -23,7 +22,7 @@ extern crate shared; extern crate indirect1; -// FIXME: This should trigger. pub fn leaks_priv() -> shared::Shared { + //~^ ERROR type `Shared` from private dependency 'shared' in public interface shared::Shared } diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr new file mode 100644 index 0000000000000..dbc534713d16e --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr @@ -0,0 +1,14 @@ +error: type `Shared` from private dependency 'shared' in public interface + --> $DIR/shared_indirect.rs:25:1 + | +LL | pub fn leaks_priv() -> shared::Shared { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/shared_indirect.rs:20:9 + | +LL | #![deny(exported_private_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/proc-macro/auxiliary/quote-issue-137345.rs b/tests/ui/proc-macro/auxiliary/quote-issue-137345.rs new file mode 100644 index 0000000000000..f125a14669f79 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/quote-issue-137345.rs @@ -0,0 +1,19 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +fn items() -> impl IntoIterator { + vec![1, 2, 3] +} + +#[macro_export] +macro_rules! quote { + // Rule for any other number of tokens. + ($($tt:tt)*) => {{ + fn items() -> impl IntoIterator { + vec![1, 2, 3] + } + let _s = TokenStream::new(); + let other_items = items().map(|i| i + 1); + _s + }}; +} diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs index c1b55fd99dfad..6afafb7114a61 100644 --- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs +++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -3,7 +3,8 @@ //@ edition:2018 //@ proc-macro: issue-59191.rs -//@ error-pattern: requires `sized` lang_item +//@ needs-unwind (affects error output) +//@ error-pattern: error: `#[panic_handler]` function required #![feature(custom_inner_attributes)] #![issue_59191::no_main] diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr index 2d0c92ff2974f..3cd98d9c72b82 100644 --- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr +++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.stderr @@ -1,10 +1,9 @@ -error: requires `sized` lang_item - --> $DIR/issue-59191-replace-root-with-fn.rs:9:1 - | -LL | #![issue_59191::no_main] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +error: `#[panic_handler]` function required, but not found + +error: unwinding panics are not supported without std | - = note: this error originates in the attribute macro `issue_59191::no_main` (in Nightly builds, run with -Z macro-backtrace for more info) + = help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding + = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index fae8446515af0..1ee7179e84c04 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -20,7 +20,6 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#1 */; -extern crate compiler_builtins /* NNN */ as _ /* 0#1 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index e7dda7d3c1606..c80a33206fb4f 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -39,7 +39,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#2 */; -extern crate compiler_builtins /* NNN */ as _ /* 0#2 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; diff --git a/tests/ui/proc-macro/valid-sugg-issue-137345.rs b/tests/ui/proc-macro/valid-sugg-issue-137345.rs new file mode 100644 index 0000000000000..78674797b8da6 --- /dev/null +++ b/tests/ui/proc-macro/valid-sugg-issue-137345.rs @@ -0,0 +1,17 @@ +//@ aux-crate: quote=quote-issue-137345.rs + +extern crate proc_macro; +extern crate quote; + +use proc_macro::TokenStream; + +pub fn default_args_fn(_: TokenStream) -> TokenStream { + let decl_macro = TokenStream::new(); + + quote::quote! { + #(#decl_macro)* + } + .into() //~^^^ ERROR no method named `map` found for opaque type +} + +fn main() {} diff --git a/tests/ui/proc-macro/valid-sugg-issue-137345.stderr b/tests/ui/proc-macro/valid-sugg-issue-137345.stderr new file mode 100644 index 0000000000000..40336803f0dbc --- /dev/null +++ b/tests/ui/proc-macro/valid-sugg-issue-137345.stderr @@ -0,0 +1,13 @@ +error[E0599]: no method named `map` found for opaque type `impl IntoIterator` in the current scope + --> $DIR/valid-sugg-issue-137345.rs:11:5 + | +LL | / quote::quote! { +LL | | #(#decl_macro)* +LL | | } + | |_____^ `impl IntoIterator` is not an iterator + | + = note: this error originates in the macro `quote::quote` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 453e53379fc49..3ecf271599d23 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -9,9 +9,9 @@ // Make sure that these behaviors don't get inherited to children // spawned via std::process, since they're needed for traditional UNIX // filter behavior. -// This test checks that `while echo y ; do : ; done | head` terminates -// (instead of running forever), and that it does not print an error -// message about a broken pipe. +// This test checks that `yes` or `while echo y ; do : ; done | head` +// terminates (instead of running forever), and that it does not print an +// error message about a broken pipe. //@ ignore-vxworks no 'sh' //@ ignore-fuchsia no 'sh' @@ -22,14 +22,21 @@ use std::process; use std::thread; fn main() { - // Just in case `yes` doesn't check for EPIPE... + // Just in case `yes` or `while-echo` doesn't check for EPIPE... thread::spawn(|| { thread::sleep_ms(5000); process::exit(1); }); + // QNX Neutrino does not have `yes`. Therefore, use `while-echo` for `nto` + // and `yes` for other platforms. + let command = if cfg!(target_os = "nto") { + "while echo y ; do : ; done | head" + } else { + "yes | head" + }; let output = process::Command::new("sh") .arg("-c") - .arg("while echo y ; do : ; done | head") + .arg(command) .output() .unwrap(); assert!(output.status.success()); diff --git a/tests/ui/regions/region-object-lifetime-in-coercion.stderr b/tests/ui/regions/region-object-lifetime-in-coercion.stderr index 3880ae8228377..5f6a11786cc8e 100644 --- a/tests/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/tests/ui/regions/region-object-lifetime-in-coercion.stderr @@ -13,9 +13,8 @@ LL + fn a(v: &[u8]) -> Box { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn a(v: &[u8]) -> Box { -LL + fn a(v: &'static [u8]) -> Box { - | +LL | fn a(v: &'static [u8]) -> Box { + | +++++++ error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:14:5 @@ -32,9 +31,8 @@ LL + fn b(v: &[u8]) -> Box { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn b(v: &[u8]) -> Box { -LL + fn b(v: &'static [u8]) -> Box { - | +LL | fn b(v: &'static [u8]) -> Box { + | +++++++ error: lifetime may not live long enough --> $DIR/region-object-lifetime-in-coercion.rs:21:5 diff --git a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr index 2e76333e26f00..ca9ceeeeff35f 100644 --- a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/regions-normalize-in-where-clause-list.rs:24:4 | LL | fn bar<'a, 'b>() @@ -24,4 +24,4 @@ LL | fn bar<'a, 'b>() error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/regions/regions-proc-bound-capture.stderr b/tests/ui/regions/regions-proc-bound-capture.stderr index 3149cd8c9a1bc..75e04bcb7c2a4 100644 --- a/tests/ui/regions/regions-proc-bound-capture.stderr +++ b/tests/ui/regions/regions-proc-bound-capture.stderr @@ -14,9 +14,8 @@ LL + fn static_proc(x: &isize) -> Box (isize) + '_> { | help: alternatively, add an explicit `'static` bound to this reference | -LL - fn static_proc(x: &isize) -> Box (isize) + 'static> { -LL + fn static_proc(x: &'static isize) -> Box (isize) + 'static> { - | +LL | fn static_proc(x: &'static isize) -> Box (isize) + 'static> { + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr index 41c5f0fa92eba..f463a97c5bc1e 100644 --- a/tests/ui/regions/resolve-re-error-ice.stderr +++ b/tests/ui/regions/resolve-re-error-ice.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements --> $DIR/resolve-re-error-ice.rs:12:5 | LL | fn key_set(&self) -> Subject<'a, Keys, (), R> { @@ -34,4 +34,4 @@ LL | struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index 2b6bbf1265083..011076882d24f 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -2,7 +2,7 @@ //@ revisions: avr msp430 // //@ [avr] needs-llvm-components: avr -//@ [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib +//@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib #![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)] diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 2cd0960ce3eec..1fab00bf50c49 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(1 bytes), + size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 8e8f1d159b740..204db30786ee3 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -4,7 +4,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(Univariant) = Layout { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -50,6 +67,7 @@ error: layout_of(Univariant) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariants) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariants) = Layout { tag_field: 0, variants: [ Layout { - size: Size(4 bytes), + size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(4 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I32, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(4 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariants) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index fa08b323dec2a..f852212deb908 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -4,7 +4,15 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(0 bytes), @@ -23,6 +31,7 @@ error: layout_of(UnivariantU8) = Layout { valid_range: 0..=0, }, ), + uninhabited: true, variants: Multiple { tag: Initialized { value: Int( @@ -40,7 +49,15 @@ error: layout_of(UnivariantU8) = Layout { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Scalar( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=0, + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -50,6 +67,7 @@ error: layout_of(UnivariantU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -107,6 +125,7 @@ error: layout_of(TwoVariantsU8) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -119,12 +138,26 @@ error: layout_of(TwoVariantsU8) = Layout { tag_field: 0, variants: [ Layout { - size: Size(1 bytes), + size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), fields: Arbitrary { offsets: [ Size(1 bytes), @@ -134,6 +167,7 @@ error: layout_of(TwoVariantsU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -171,6 +205,7 @@ error: layout_of(TwoVariantsU8) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +251,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { valid_range: 0..=1, }, ), + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -233,7 +269,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { abi: Align(8 bytes), pref: $SOME_ALIGN, }, - abi: Uninhabited, + abi: Memory { + sized: true, + }, fields: Arbitrary { offsets: [ Size(8 bytes), @@ -245,6 +283,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], }, largest_niche: None, + uninhabited: true, variants: Single { index: 0, }, @@ -272,6 +311,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Single { index: 1, }, diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs new file mode 100644 index 0000000000000..432e3c0b77efc --- /dev/null +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.rs @@ -0,0 +1,123 @@ +// see also https://github.com/rust-lang/rust/issues/22692 + +type Alias = Vec; + +mod foo { + fn bar() {} +} + +fn main() { + let _ = String.new(); + //~^ ERROR expected value, found struct `String` + //~| HELP use the path separator + + let _ = String.default; + //~^ ERROR expected value, found struct `String` + //~| HELP use the path separator + + let _ = Vec::<()>.with_capacity(1); + //~^ ERROR expected value, found struct `Vec` + //~| HELP use the path separator + + let _ = Alias.new(); + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + + let _ = Alias.default; + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + + let _ = foo.bar; + //~^ ERROR expected value, found module `foo` + //~| HELP use the path separator +} + +macro_rules! Type { + () => { + ::std::cell::Cell + //~^ ERROR expected value, found struct `std::cell::Cell` + //~| ERROR expected value, found struct `std::cell::Cell` + //~| ERROR expected value, found struct `std::cell::Cell` + }; + (alias) => { + Alias + //~^ ERROR expected value, found type alias `Alias` + //~| ERROR expected value, found type alias `Alias` + //~| ERROR expected value, found type alias `Alias` + }; +} + +macro_rules! create { + (type method) => { + Vec.new() + //~^ ERROR expected value, found struct `Vec` + //~| HELP use the path separator + }; + (type field) => { + Vec.new + //~^ ERROR expected value, found struct `Vec` + //~| HELP use the path separator + }; + (macro method) => { + Type!().new(0) + //~^ HELP use the path separator + }; + (macro method alias) => { + Type!(alias).new(0) + //~^ HELP use the path separator + }; +} + +macro_rules! check_ty { + ($Ty:ident) => { + $Ty.foo + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; +} +macro_rules! check_ident { + ($Ident:ident) => { + Alias.$Ident + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; +} +macro_rules! check_ty_ident { + ($Ty:ident, $Ident:ident) => { + $Ty.$Ident + //~^ ERROR expected value, found type alias `Alias` + //~| HELP use the path separator + }; +} + +fn interaction_with_macros() { + // + // Verify that we do not only suggest to replace `.` with `::` if the receiver is a + // macro call but that we also correctly suggest to surround it with angle brackets. + // + + Type!().get(); + //~^ HELP use the path separator + + Type! {}.get; + //~^ HELP use the path separator + + Type!(alias).get(); + //~^ HELP use the path separator + + Type! {alias}.get; + //~^ HELP use the path separator + + // + // Ensure that the suggestion is shown for expressions inside of macro definitions. + // + + let _ = create!(type method); + let _ = create!(type field); + let _ = create!(macro method); + let _ = create!(macro method alias); + + let _ = check_ty!(Alias); + let _ = check_ident!(foo); + let _ = check_ty_ident!(Alias, foo); +} diff --git a/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr new file mode 100644 index 0000000000000..d74814dd876c2 --- /dev/null +++ b/tests/ui/resolve/dot-notation-type-namespace-suggest-path-sep.stderr @@ -0,0 +1,251 @@ +error[E0423]: expected value, found struct `String` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:10:13 + | +LL | let _ = String.new(); + | ^^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = String.new(); +LL + let _ = String::new(); + | + +error[E0423]: expected value, found struct `String` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:14:13 + | +LL | let _ = String.default; + | ^^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = String.default; +LL + let _ = String::default; + | + +error[E0423]: expected value, found struct `Vec` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:18:13 + | +LL | let _ = Vec::<()>.with_capacity(1); + | ^^^^^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = Vec::<()>.with_capacity(1); +LL + let _ = Vec::<()>::with_capacity(1); + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:22:13 + | +LL | let _ = Alias.new(); + | ^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = Alias.new(); +LL + let _ = Alias::new(); + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:26:13 + | +LL | let _ = Alias.default; + | ^^^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = Alias.default; +LL + let _ = Alias::default; + | + +error[E0423]: expected value, found module `foo` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:30:13 + | +LL | let _ = foo.bar; + | ^^^ + | +help: use the path separator to refer to an item + | +LL - let _ = foo.bar; +LL + let _ = foo::bar; + | + +error[E0423]: expected value, found struct `std::cell::Cell` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 + | +LL | ::std::cell::Cell + | ^^^^^^^^^^^^^^^^^ +... +LL | Type!().get(); + | ------- in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type!().get(); +LL + ::get(); + | + +error[E0423]: expected value, found struct `std::cell::Cell` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 + | +LL | ::std::cell::Cell + | ^^^^^^^^^^^^^^^^^ +... +LL | Type! {}.get; + | -------- in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type! {}.get; +LL + ::get; + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | Type!(alias).get(); + | ------------ in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type!(alias).get(); +LL + ::get(); + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | Type! {alias}.get; + | ------------- in this macro invocation + | + = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type! {alias}.get; +LL + ::get; + | + +error[E0423]: expected value, found struct `Vec` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:52:9 + | +LL | Vec.new() + | ^^^ +... +LL | let _ = create!(type method); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Vec.new() +LL + Vec::new() + | + +error[E0423]: expected value, found struct `Vec` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:57:9 + | +LL | Vec.new + | ^^^ +... +LL | let _ = create!(type field); + | ------------------- in this macro invocation + | + = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Vec.new +LL + Vec::new + | + +error[E0423]: expected value, found struct `std::cell::Cell` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:37:9 + | +LL | ::std::cell::Cell + | ^^^^^^^^^^^^^^^^^ +... +LL | let _ = create!(macro method); + | --------------------- in this macro invocation + | + = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type!().new(0) +LL + ::new(0) + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:43:9 + | +LL | Alias + | ^^^^^ +... +LL | let _ = create!(macro method alias); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Type!(alias).new(0) +LL + ::new(0) + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:73:9 + | +LL | $Ty.foo + | ^^^ +... +LL | let _ = check_ty!(Alias); + | ---------------- in this macro invocation + | + = note: this error originates in the macro `check_ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - $Ty.foo +LL + $Ty::foo + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:80:9 + | +LL | Alias.$Ident + | ^^^^^ +... +LL | let _ = check_ident!(foo); + | ----------------- in this macro invocation + | + = note: this error originates in the macro `check_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - Alias.$Ident +LL + ::$Ident + | + +error[E0423]: expected value, found type alias `Alias` + --> $DIR/dot-notation-type-namespace-suggest-path-sep.rs:87:9 + | +LL | $Ty.$Ident + | ^^^ +... +LL | let _ = check_ty_ident!(Alias, foo); + | --------------------------- in this macro invocation + | + = note: this error originates in the macro `check_ty_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use the path separator to refer to an item + | +LL - $Ty.$Ident +LL + <$Ty>::$Ident + | + +error: aborting due to 17 previous errors + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.rs b/tests/ui/resolve/enum-expected-value-suggest-variants.rs new file mode 100644 index 0000000000000..9f86a0a1ecc76 --- /dev/null +++ b/tests/ui/resolve/enum-expected-value-suggest-variants.rs @@ -0,0 +1,58 @@ +enum Foo { + //~^ HELP consider importing this tuple variant + A(u32), + B(u32), +} + +enum Bar { + C(u32), + D(u32), + E, + F, +} + +fn main() { + let _: Foo = Foo(0); + //~^ ERROR expected function + //~| HELP try to construct one of the enum's variants + + let _: Foo = Foo.A(0); + //~^ ERROR expected value, found enum `Foo` + //~| HELP use the path separator to refer to a variant + + let _: Foo = Foo.Bad(0); + //~^ ERROR expected value, found enum `Foo` + //~| HELP the following enum variants are available + + let _: Bar = Bar(0); + //~^ ERROR expected function + //~| HELP try to construct one of the enum's variants + //~| HELP you might have meant to construct one of the enum's non-tuple variants + + let _: Bar = Bar.C(0); + //~^ ERROR expected value, found enum `Bar` + //~| HELP use the path separator to refer to a variant + + let _: Bar = Bar.E; + //~^ ERROR expected value, found enum `Bar` + //~| HELP use the path separator to refer to a variant + + let _: Bar = Bar.Bad(0); + //~^ ERROR expected value, found enum `Bar` + //~| HELP you might have meant to use one of the following enum variants + //~| HELP alternatively, the following enum variants are also available + + let _: Bar = Bar.Bad; + //~^ ERROR expected value, found enum `Bar` + //~| HELP you might have meant to use one of the following enum variants + //~| HELP alternatively, the following enum variants are also available + + match Foo::A(42) { + A(..) => {} + //~^ ERROR cannot find tuple struct or tuple variant `A` in this scope + Foo(..) => {} + //~^ ERROR expected tuple struct or tuple variant + //~| HELP try to match against one of the enum's variants + _ => {} + } +} diff --git a/tests/ui/resolve/enum-expected-value-suggest-variants.stderr b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr new file mode 100644 index 0000000000000..548a4c0e59320 --- /dev/null +++ b/tests/ui/resolve/enum-expected-value-suggest-variants.stderr @@ -0,0 +1,234 @@ +error[E0423]: expected value, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:19:18 + | +LL | let _: Foo = Foo.A(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL - let _: Foo = Foo.A(0); +LL + let _: Foo = Foo::A(0); + | + +error[E0423]: expected value, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:23:18 + | +LL | let _: Foo = Foo.Bad(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: the following enum variants are available + | +LL - let _: Foo = Foo.Bad(0); +LL + let _: Foo = (Foo::A(/* fields */)).Bad(0); + | +LL - let _: Foo = Foo.Bad(0); +LL + let _: Foo = (Foo::B(/* fields */)).Bad(0); + | + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:32:18 + | +LL | let _: Bar = Bar.C(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL - let _: Bar = Bar.C(0); +LL + let _: Bar = Bar::C(0); + | + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:36:18 + | +LL | let _: Bar = Bar.E; + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: use the path separator to refer to a variant + | +LL - let _: Bar = Bar.E; +LL + let _: Bar = Bar::E; + | + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:40:18 + | +LL | let _: Bar = Bar.Bad(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: you might have meant to use one of the following enum variants + | +LL | let _: Bar = Bar::E.Bad(0); + | +++ +LL | let _: Bar = Bar::F.Bad(0); + | +++ +help: alternatively, the following enum variants are also available + | +LL - let _: Bar = Bar.Bad(0); +LL + let _: Bar = (Bar::C(/* fields */)).Bad(0); + | +LL - let _: Bar = Bar.Bad(0); +LL + let _: Bar = (Bar::D(/* fields */)).Bad(0); + | + +error[E0423]: expected value, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:45:18 + | +LL | let _: Bar = Bar.Bad; + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: you might have meant to use one of the following enum variants + | +LL | let _: Bar = Bar::E.Bad; + | +++ +LL | let _: Bar = Bar::F.Bad; + | +++ +help: alternatively, the following enum variants are also available + | +LL - let _: Bar = Bar.Bad; +LL + let _: Bar = (Bar::C(/* fields */)).Bad; + | +LL - let _: Bar = Bar.Bad; +LL + let _: Bar = (Bar::D(/* fields */)).Bad; + | + +error[E0531]: cannot find tuple struct or tuple variant `A` in this scope + --> $DIR/enum-expected-value-suggest-variants.rs:51:9 + | +LL | A(..) => {} + | ^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use Foo::A; + | + +error[E0532]: expected tuple struct or tuple variant, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:53:9 + | +LL | Foo(..) => {} + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: try to match against one of the enum's variants + | +LL | Foo::A(..) => {} + | +++ +LL | Foo::B(..) => {} + | +++ + +error[E0423]: expected function, tuple struct or tuple variant, found enum `Foo` + --> $DIR/enum-expected-value-suggest-variants.rs:15:18 + | +LL | let _: Foo = Foo(0); + | ^^^ + | +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:1:1 + | +LL | / enum Foo { +LL | | +LL | | A(u32), +LL | | B(u32), +LL | | } + | |_^ +help: try to construct one of the enum's variants + | +LL | let _: Foo = Foo::A(0); + | +++ +LL | let _: Foo = Foo::B(0); + | +++ + +error[E0423]: expected function, tuple struct or tuple variant, found enum `Bar` + --> $DIR/enum-expected-value-suggest-variants.rs:27:18 + | +LL | let _: Bar = Bar(0); + | ^^^ + | + = help: you might have meant to construct one of the enum's non-tuple variants +note: the enum is defined here + --> $DIR/enum-expected-value-suggest-variants.rs:7:1 + | +LL | / enum Bar { +LL | | C(u32), +LL | | D(u32), +LL | | E, +LL | | F, +LL | | } + | |_^ +help: try to construct one of the enum's variants + | +LL | let _: Bar = Bar::C(0); + | +++ +LL | let _: Bar = Bar::D(0); + | +++ + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0423, E0531, E0532. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/issue-22692.rs b/tests/ui/resolve/issue-22692.rs deleted file mode 100644 index 31a76261408ef..0000000000000 --- a/tests/ui/resolve/issue-22692.rs +++ /dev/null @@ -1,60 +0,0 @@ -fn main() { - let _ = String.new(); - //~^ ERROR expected value, found struct `String` - //~| HELP use the path separator - - let _ = String.default; - //~^ ERROR expected value, found struct `String` - //~| HELP use the path separator - - let _ = Vec::<()>.with_capacity(1); - //~^ ERROR expected value, found struct `Vec` - //~| HELP use the path separator -} - -macro_rules! Type { - () => { - ::std::cell::Cell - //~^ ERROR expected value, found struct `std::cell::Cell` - //~| ERROR expected value, found struct `std::cell::Cell` - //~| ERROR expected value, found struct `std::cell::Cell` - }; -} - -macro_rules! create { - (type method) => { - Vec.new() - //~^ ERROR expected value, found struct `Vec` - //~| HELP use the path separator - }; - (type field) => { - Vec.new - //~^ ERROR expected value, found struct `Vec` - //~| HELP use the path separator - }; - (macro method) => { - Type!().new(0) - //~^ HELP use the path separator - }; -} - -fn interaction_with_macros() { - // - // Verify that we do not only suggest to replace `.` with `::` if the receiver is a - // macro call but that we also correctly suggest to surround it with angle brackets. - // - - Type!().get(); - //~^ HELP use the path separator - - Type! {}.get; - //~^ HELP use the path separator - - // - // Ensure that the suggestion is shown for expressions inside of macro definitions. - // - - let _ = create!(type method); - let _ = create!(type field); - let _ = create!(macro method); -} diff --git a/tests/ui/resolve/issue-22692.stderr b/tests/ui/resolve/issue-22692.stderr deleted file mode 100644 index 546f12b35c156..0000000000000 --- a/tests/ui/resolve/issue-22692.stderr +++ /dev/null @@ -1,119 +0,0 @@ -error[E0423]: expected value, found struct `String` - --> $DIR/issue-22692.rs:2:13 - | -LL | let _ = String.new(); - | ^^^^^^ - | -help: use the path separator to refer to an item - | -LL - let _ = String.new(); -LL + let _ = String::new(); - | - -error[E0423]: expected value, found struct `String` - --> $DIR/issue-22692.rs:6:13 - | -LL | let _ = String.default; - | ^^^^^^ - | -help: use the path separator to refer to an item - | -LL - let _ = String.default; -LL + let _ = String::default; - | - -error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:10:13 - | -LL | let _ = Vec::<()>.with_capacity(1); - | ^^^^^^^^^ - | -help: use the path separator to refer to an item - | -LL - let _ = Vec::<()>.with_capacity(1); -LL + let _ = Vec::<()>::with_capacity(1); - | - -error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 - | -LL | ::std::cell::Cell - | ^^^^^^^^^^^^^^^^^ -... -LL | Type!().get(); - | ------- in this macro invocation - | - = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - Type!().get(); -LL + ::get(); - | - -error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 - | -LL | ::std::cell::Cell - | ^^^^^^^^^^^^^^^^^ -... -LL | Type! {}.get; - | -------- in this macro invocation - | - = note: this error originates in the macro `Type` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - Type! {}.get; -LL + ::get; - | - -error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:26:9 - | -LL | Vec.new() - | ^^^ -... -LL | let _ = create!(type method); - | -------------------- in this macro invocation - | - = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - Vec.new() -LL + Vec::new() - | - -error[E0423]: expected value, found struct `Vec` - --> $DIR/issue-22692.rs:31:9 - | -LL | Vec.new - | ^^^ -... -LL | let _ = create!(type field); - | ------------------- in this macro invocation - | - = note: this error originates in the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - Vec.new -LL + Vec::new - | - -error[E0423]: expected value, found struct `std::cell::Cell` - --> $DIR/issue-22692.rs:17:9 - | -LL | ::std::cell::Cell - | ^^^^^^^^^^^^^^^^^ -... -LL | let _ = create!(macro method); - | --------------------- in this macro invocation - | - = note: this error originates in the macro `Type` which comes from the expansion of the macro `create` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use the path separator to refer to an item - | -LL - Type!().new(0) -LL + ::new(0) - | - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr b/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr index f1db2d71b6a66..a9b45a18af397 100644 --- a/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr +++ b/tests/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.stderr @@ -3,9 +3,8 @@ error[E0259]: the name `std` is defined multiple times = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - extern crate std; -LL + extern crate std as other_std; - | +LL | extern crate std as other_std; + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr index 40c76821bb835..ef8723408dae8 100644 --- a/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr +++ b/tests/ui/resolve/resolve-conflict-import-vs-extern-crate.stderr @@ -7,9 +7,8 @@ LL | use std::slice as std; = note: `std` must be defined only once in the type namespace of this module help: you can use `as` to change the binding name of the import | -LL - use std::slice as std; -LL + use std::slice as other_std; - | +LL | use std::slice as other_std; + | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr index e22f33fd242a6..877995dfe1266 100644 --- a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr @@ -6,7 +6,6 @@ LL | fn test1() { LL | let mut _file = File::create("foo.txt")?; | ^ cannot use the `?` operator in a function that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn test1() -> Result<(), Box> { @@ -23,7 +22,6 @@ LL | fn test2() { LL | let mut _file = File::create("foo.txt")?; | ^ cannot use the `?` operator in a function that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn test2() -> Result<(), Box> { @@ -41,7 +39,6 @@ LL | fn test4(&self) { LL | let mut _file = File::create("foo.txt")?; | ^ cannot use the `?` operator in a method that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn test4(&self) -> Result<(), Box> { @@ -59,7 +56,6 @@ LL | fn test5(&self) { LL | let mut _file = File::create("foo.txt")?; | ^ cannot use the `?` operator in a method that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn test5(&self) -> Result<(), Box> { @@ -78,7 +74,6 @@ LL | fn main() { LL | let mut _file = File::create("foo.txt")?; | ^ cannot use the `?` operator in a function that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn main() -> Result<(), Box> { @@ -99,7 +94,6 @@ LL | let mut _file = File::create("foo.txt")?; LL | mac!(); | ------ in this macro invocation | - = help: the trait `FromResidual>` is not implemented for `()` = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding return type | diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr index 45a0ca01a5603..100e0a501e016 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr @@ -38,7 +38,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match NonExhaustiveEnum::Unit { LL + NonExhaustiveEnum::Unit | NonExhaustiveEnum::Tuple(_) | NonExhaustiveEnum::Struct { .. } => todo!(), -LL + } +LL ~ } | error[E0004]: non-exhaustive patterns: `NormalEnum::Unit`, `NormalEnum::Tuple(_)` and `NormalEnum::Struct { .. }` not covered @@ -65,7 +65,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match NormalEnum::Unit { LL + NormalEnum::Unit | NormalEnum::Tuple(_) | NormalEnum::Struct { .. } => todo!(), -LL + } +LL ~ } | error: aborting due to 3 previous errors diff --git a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr index 8843efc6ff8c9..a30cf605829f8 100644 --- a/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr +++ b/tests/ui/self/arbitrary_self_types_not_allow_call_with_no_deref.stderr @@ -13,9 +13,8 @@ LL | foo_cpp_ref.0.frobnicate_ref(); | ++ help: there is a method `frobnicate_cpp_ref` with a similar name | -LL - foo_cpp_ref.frobnicate_ref(); -LL + foo_cpp_ref.frobnicate_cpp_ref(); - | +LL | foo_cpp_ref.frobnicate_cpp_ref(); + | ++++ error[E0599]: no method named `frobnicate_self` found for struct `CppRef` in the current scope --> $DIR/arbitrary_self_types_not_allow_call_with_no_deref.rs:32:17 diff --git a/tests/ui/span/missing-unit-argument.stderr b/tests/ui/span/missing-unit-argument.stderr index e77ec3c8447a5..e83f7b6cb70f3 100644 --- a/tests/ui/span/missing-unit-argument.stderr +++ b/tests/ui/span/missing-unit-argument.stderr @@ -8,9 +8,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: provide the argument | -LL - let _: Result<(), String> = Ok(); -LL + let _: Result<(), String> = Ok(()); - | +LL | let _: Result<(), String> = Ok(()); + | ++ error[E0061]: this function takes 2 arguments but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:12:5 @@ -25,9 +24,8 @@ LL | fn foo(():(), ():()) {} | ^^^ ----- ----- help: provide the arguments | -LL - foo(); -LL + foo((), ()); - | +LL | foo((), ()); + | ++++++ error[E0061]: this function takes 2 arguments but 1 argument was supplied --> $DIR/missing-unit-argument.rs:13:5 @@ -42,9 +40,8 @@ LL | fn foo(():(), ():()) {} | ^^^ ----- help: provide the argument | -LL - foo(()); -LL + foo((), ()); - | +LL | foo((), ()); + | ++++ error[E0061]: this function takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:14:5 @@ -59,9 +56,8 @@ LL | fn bar(():()) {} | ^^^ ----- help: provide the argument | -LL - bar(); -LL + bar(()); - | +LL | bar(()); + | ++ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:15:7 @@ -76,9 +72,8 @@ LL | fn baz(self, (): ()) { } | ^^^ ------ help: provide the argument | -LL - S.baz(); -LL + S.baz(()); - | +LL | S.baz(()); + | ++ error[E0061]: this method takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:16:7 @@ -93,9 +88,8 @@ LL | fn generic(self, _: T) { } | ^^^^^^^ ---- help: provide the argument | -LL - S.generic::<()>(); -LL + S.generic::<()>(()); - | +LL | S.generic::<()>(()); + | ++ error: aborting due to 6 previous errors diff --git a/tests/ui/static/static-lifetime.stderr b/tests/ui/static/static-lifetime.stderr index 7a956dbfeef6e..9b5869fd0dc46 100644 --- a/tests/ui/static/static-lifetime.stderr +++ b/tests/ui/static/static-lifetime.stderr @@ -11,7 +11,7 @@ LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} | ^^ = note: but lifetime parameter must outlive the static lifetime -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/static-lifetime.rs:3:34 | LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} @@ -38,5 +38,5 @@ LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} error: aborting due to 2 previous errors -Some errors have detailed explanations: E0478, E0495. +Some errors have detailed explanations: E0478, E0803. For more information about an error, try `rustc --explain E0478`. diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr index 3d4b55909cdee..30a586c286ae7 100644 --- a/tests/ui/statics/static-mut-shared-parens.stderr +++ b/tests/ui/statics/static-mut-shared-parens.stderr @@ -22,9 +22,8 @@ LL | let _ = unsafe { ((&mut TEST)) as *const usize }; = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - let _ = unsafe { ((&mut TEST)) as *const usize }; -LL + let _ = unsafe { ((&raw mut TEST)) as *const usize }; - | +LL | let _ = unsafe { ((&raw mut TEST)) as *const usize }; + | +++ warning: 2 warnings emitted diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr index 48cac28a6eb51..69f334a5636af 100644 --- a/tests/ui/statics/static-mut-xc.stderr +++ b/tests/ui/statics/static-mut-xc.stderr @@ -67,9 +67,8 @@ LL | static_bound_set(&mut static_mut_xc::a); = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives help: use `&raw mut` instead to create a raw pointer | -LL - static_bound_set(&mut static_mut_xc::a); -LL + static_bound_set(&raw mut static_mut_xc::a); - | +LL | static_bound_set(&raw mut static_mut_xc::a); + | +++ warning: 7 warnings emitted diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs new file mode 100644 index 0000000000000..71d90ddd935ff --- /dev/null +++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs @@ -0,0 +1,6 @@ +#![feature(default_field_values)] +struct A<'a> { //~ ERROR lifetime parameter `'a` is never used + x: Vec = Vec::new(), //~ ERROR missing lifetime specifier +} + +fn main() {} diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr new file mode 100644 index 0000000000000..20b9afe80cdc8 --- /dev/null +++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr @@ -0,0 +1,23 @@ +error[E0106]: missing lifetime specifier + --> $DIR/do-not-ice-on-invalid-lifetime.rs:3:12 + | +LL | x: Vec = Vec::new(), + | ^ expected named lifetime parameter + | +help: consider using the `'a` lifetime + | +LL | x: Vec> = Vec::new(), + | ++++ + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/do-not-ice-on-invalid-lifetime.rs:2:10 + | +LL | struct A<'a> { + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0392. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr b/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr index c7689cfd323a0..09506703b7ec0 100644 --- a/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor.disabled.stderr @@ -66,9 +66,8 @@ LL | let _ = S { }; | help: all remaining fields have default values, if you added `#![feature(default_field_values)]` to your crate you could use those values with `..` | -LL - let _ = S { }; -LL + let _ = S { .. }; - | +LL | let _ = S { .. }; + | ++ error[E0063]: missing fields `field1` and `field2` in initializer of `S` --> $DIR/non-exhaustive-ctor.rs:26:13 diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr b/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr index d9b8e76aa0de6..229f47093adcc 100644 --- a/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor.enabled.stderr @@ -6,9 +6,8 @@ LL | let _ = S { }; | help: all remaining fields have default values, you can use those values with `..` | -LL - let _ = S { }; -LL + let _ = S { .. }; - | +LL | let _ = S { .. }; + | ++ error[E0063]: missing fields `field1` and `field2` in initializer of `S` --> $DIR/non-exhaustive-ctor.rs:26:13 diff --git a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr index 8644f4a1dd452..2ad9c807e48ac 100644 --- a/tests/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -60,9 +60,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: provide the argument | -LL - let _: Option<(i8,)> = Some(); -LL + let _: Option<(i8,)> = Some(/* (i8,) */); - | +LL | let _: Option<(i8,)> = Some(/* (i8,) */); + | +++++++++++ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple-errors.rs:14:34 diff --git a/tests/ui/suggestions/args-instead-of-tuple.stderr b/tests/ui/suggestions/args-instead-of-tuple.stderr index 4b0bab971ee71..4093d06970e1b 100644 --- a/tests/ui/suggestions/args-instead-of-tuple.stderr +++ b/tests/ui/suggestions/args-instead-of-tuple.stderr @@ -34,9 +34,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: provide the argument | -LL - let _: Option<()> = Some(); -LL + let _: Option<()> = Some(()); - | +LL | let _: Option<()> = Some(()); + | ++ error[E0308]: mismatched types --> $DIR/args-instead-of-tuple.rs:14:34 diff --git a/tests/ui/suggestions/bad-hex-float-lit.stderr b/tests/ui/suggestions/bad-hex-float-lit.stderr index 94c0715a4e683..351dc879be3c7 100644 --- a/tests/ui/suggestions/bad-hex-float-lit.stderr +++ b/tests/ui/suggestions/bad-hex-float-lit.stderr @@ -8,9 +8,8 @@ LL | let _f: f32 = 0xAAf32; | help: rewrite this as a decimal floating point literal, or use `as` to turn a hex literal into a float | -LL - let _f: f32 = 0xAAf32; -LL + let _f: f32 = 0xAA as f32; - | +LL | let _f: f32 = 0xAA as f32; + | ++ LL - let _f: f32 = 0xAAf32; LL + let _f: f32 = 170_f32; | diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg index 0f2ade633c5ad..279fd30f2165c 100644 --- a/tests/ui/suggestions/incorrect-variant-literal.svg +++ b/tests/ui/suggestions/incorrect-variant-literal.svg @@ -1,4 +1,4 @@ - + diff --git a/tests/ui/suggestions/return-bindings.stderr b/tests/ui/suggestions/return-bindings.stderr index 6f906c27ba943..8e396d17dc072 100644 --- a/tests/ui/suggestions/return-bindings.stderr +++ b/tests/ui/suggestions/return-bindings.stderr @@ -22,8 +22,8 @@ LL | | } else { | help: consider returning the local binding `s` | -LL ~ let s: String = if let Some(s) = opt_str { -LL + s +LL | let s: String = if let Some(s) = opt_str { +LL ~ s LL ~ | @@ -54,8 +54,8 @@ LL | | } else { | help: consider returning the local binding `s` | -LL ~ let s: String = if let Some(s) = opt_str { -LL + s +LL | let s: String = if let Some(s) = opt_str { +LL ~ s LL ~ | @@ -71,8 +71,8 @@ LL | String::new() | help: consider returning the local binding `s` | -LL ~ let s = if let Some(s) = opt_str { -LL + s +LL | let s = if let Some(s) = opt_str { +LL ~ s LL ~ } else { | diff --git a/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr index 2061b3f122a2f..6092272aa8c5a 100644 --- a/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr +++ b/tests/ui/suggestions/suggest-deref-in-match-issue-132784.stderr @@ -43,9 +43,8 @@ LL | Some(_) => {} found enum `Option<_>` help: consider dereferencing to access the inner value using the Deref trait | -LL - match &x { -LL + match &*x { - | +LL | match &*x { + | + error[E0308]: mismatched types --> $DIR/suggest-deref-in-match-issue-132784.rs:18:9 @@ -60,9 +59,8 @@ LL | None => {} found enum `Option<_>` help: consider dereferencing to access the inner value using the Deref trait | -LL - match &x { -LL + match &*x { - | +LL | match &*x { + | + error[E0308]: mismatched types --> $DIR/suggest-deref-in-match-issue-132784.rs:26:9 diff --git a/tests/ui/suggestions/suggest-field-through-deref.stderr b/tests/ui/suggestions/suggest-field-through-deref.stderr index e3889781884b1..a742745f6a53a 100644 --- a/tests/ui/suggestions/suggest-field-through-deref.stderr +++ b/tests/ui/suggestions/suggest-field-through-deref.stderr @@ -6,9 +6,8 @@ LL | let _ = x.longname; | help: a field with a similar name exists | -LL - let _ = x.longname; -LL + let _ = x.long_name; - | +LL | let _ = x.long_name; + | + error[E0609]: no field `longname` on type `S` --> $DIR/suggest-field-through-deref.rs:12:15 @@ -18,9 +17,8 @@ LL | let _ = y.longname; | help: a field with a similar name exists | -LL - let _ = y.longname; -LL + let _ = y.long_name; - | +LL | let _ = y.long_name; + | + error[E0609]: no field `longname` on type `Option>` --> $DIR/suggest-field-through-deref.rs:14:15 diff --git a/tests/ui/suggestions/suggest-let-for-assignment.stderr b/tests/ui/suggestions/suggest-let-for-assignment.stderr index 9dc859dbe0e0c..eb4bfc9a78354 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.stderr +++ b/tests/ui/suggestions/suggest-let-for-assignment.stderr @@ -58,9 +58,8 @@ LL | letother_variable = 6; | help: you might have meant to introduce a new binding | -LL - letother_variable = 6; -LL + let other_variable = 6; - | +LL | let other_variable = 6; + | + error[E0425]: cannot find value `other_variable` in this scope --> $DIR/suggest-let-for-assignment.rs:14:36 diff --git a/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr index fac93da98293d..aa6f8cebe2a4a 100644 --- a/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr +++ b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr @@ -6,12 +6,10 @@ LL | impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} | help: use fully-qualified syntax | -LL - impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} -LL + impl Foo for Bar where for<'a> <&'a S as IntoAsyncIterator>::Item: Foo {} - | -LL - impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} -LL + impl Foo for Bar where for<'a> <&'a S as IntoIterator>::Item: Foo {} - | +LL | impl Foo for Bar where for<'a> <&'a S as IntoAsyncIterator>::Item: Foo {} + | ++++++++++++++++++++ +LL | impl Foo for Bar where for<'a> <&'a S as IntoIterator>::Item: Foo {} + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/test-attrs/inaccessible-test-modules.stderr b/tests/ui/test-attrs/inaccessible-test-modules.stderr index dfb6985730af5..c66dc0d0fc26c 100644 --- a/tests/ui/test-attrs/inaccessible-test-modules.stderr +++ b/tests/ui/test-attrs/inaccessible-test-modules.stderr @@ -13,7 +13,7 @@ LL | use test as y; help: consider importing this module instead | LL | use test::test as y; - | ++++++ + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/predicate-entailment-passes.rs b/tests/ui/traits/const-traits/predicate-entailment-passes.rs index 9c8d5a5e3f6ad..28ae21891f386 100644 --- a/tests/ui/traits/const-traits/predicate-entailment-passes.rs +++ b/tests/ui/traits/const-traits/predicate-entailment-passes.rs @@ -6,32 +6,21 @@ #[const_trait] trait Bar {} impl const Bar for () {} - #[const_trait] trait TildeConst { - type Bar where T: ~const Bar; - fn foo() where T: ~const Bar; } impl TildeConst for () { - type Bar = () where T: Bar; - fn foo() where T: Bar {} } #[const_trait] trait AlwaysConst { - type Bar where T: const Bar; - fn foo() where T: const Bar; } impl AlwaysConst for i32 { - type Bar = () where T: Bar; - fn foo() where T: Bar {} } impl const AlwaysConst for u32 { - type Bar = () where T: ~const Bar; - fn foo() where T: ~const Bar {} } diff --git a/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr index 8bf8536c74e46..4e324209fe9e7 100644 --- a/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr +++ b/tests/ui/traits/impl-of-supertrait-has-wrong-lifetime-parameters.stderr @@ -1,4 +1,4 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements --> $DIR/impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:28 | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { @@ -24,4 +24,4 @@ LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr index 1d42dbdfe00e7..294fa0d7613c5 100644 --- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr +++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr @@ -1,18 +1,8 @@ -error[E0275]: overflow evaluating the requirement `::Assoc: Sized` +error[E0275]: overflow evaluating the requirement `::Assoc == _` --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18 | LL | type Assoc = ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `Overflow::Assoc` - --> $DIR/trait_ref_is_knowable-norm-overflow.rs:7:5 - | -LL | type Assoc; - | ^^^^^^^^^^^ required by this bound in `Overflow::Assoc` -help: consider relaxing the implicit `Sized` restriction - | -LL | type Assoc: ?Sized; - | ++++++++ error[E0119]: conflicting implementations of trait `Trait` --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1 diff --git a/tests/ui/traits/next-solver/gat-wf.rs b/tests/ui/traits/next-solver/gat-wf.rs new file mode 100644 index 0000000000000..ff6e2665ef3ee --- /dev/null +++ b/tests/ui/traits/next-solver/gat-wf.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -Znext-solver + +// Make sure that, like the old trait solver, we end up requiring that the WC of +// impl GAT matches that of the trait. This is not a restriction that we *need*, +// but is a side-effect of registering the where clauses when normalizing the GAT +// when proving it satisfies its item bounds. + +trait Foo { + type T<'a>: Sized where Self: 'a; +} + +impl Foo for &() { + type T<'a> = (); //~ the type `&()` does not fulfill the required lifetime +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/gat-wf.stderr b/tests/ui/traits/next-solver/gat-wf.stderr new file mode 100644 index 0000000000000..620bca77e4b97 --- /dev/null +++ b/tests/ui/traits/next-solver/gat-wf.stderr @@ -0,0 +1,15 @@ +error[E0477]: the type `&()` does not fulfill the required lifetime + --> $DIR/gat-wf.rs:13:18 + | +LL | type T<'a> = (); + | ^^ + | +note: type must outlive the lifetime `'a` as defined here + --> $DIR/gat-wf.rs:13:12 + | +LL | type T<'a> = (); + | ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0477`. diff --git a/tests/crashes/126944.rs b/tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs similarity index 77% rename from tests/crashes/126944.rs rename to tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs index c0c5622e26020..b1f7c4a600021 100644 --- a/tests/crashes/126944.rs +++ b/tests/ui/traits/object/crash-due-to-projections-modulo-norm.rs @@ -1,9 +1,12 @@ -//@ known-bug: rust-lang/rust#126944 +//@ check-pass + +// Regression test for #126944. + // Step 1: Create two names for a single type: `Thing` and `AlsoThing` struct Thing; struct Dummy; -pub trait DummyTrait { +trait DummyTrait { type DummyType; } impl DummyTrait for Dummy { @@ -13,7 +16,7 @@ type AlsoThing = ::DummyType; // Step 2: Create names for a single trait object type: `TraitObject` and `AlsoTraitObject` -pub trait SomeTrait { +trait SomeTrait { type Item; } type TraitObject = dyn SomeTrait; @@ -21,12 +24,12 @@ type AlsoTraitObject = dyn SomeTrait; // Step 3: Force the compiler to check whether the two names are the same type -pub trait Supertrait { +trait Supertrait { type Foo; } -pub trait Subtrait: Supertrait {} +trait Subtrait: Supertrait {} -pub trait HasOutput { +trait HasOutput { type Output; } @@ -36,3 +39,5 @@ where { todo!() } + +fn main() {} diff --git a/tests/ui/traits/object/incomplete-multiple-super-projection.rs b/tests/ui/traits/object/incomplete-multiple-super-projection.rs new file mode 100644 index 0000000000000..c7294eca4bdbe --- /dev/null +++ b/tests/ui/traits/object/incomplete-multiple-super-projection.rs @@ -0,0 +1,32 @@ +// Regression test for #133361. + +trait Sup { + type Assoc; +} + +impl Sup for () { + type Assoc = T; +} +impl Dyn for () {} + +trait Dyn: Sup + Sup {} + +trait Trait { + type Assoc; +} +impl Trait for dyn Dyn<(), ()> { + type Assoc = &'static str; +} +impl Trait for dyn Dyn { +//~^ ERROR conflicting implementations of trait `Trait` for type `(dyn Dyn<(), ()> + 'static)` + type Assoc = usize; +} + +fn call(x: usize) -> as Trait>::Assoc { + x +} + +fn main() { + let x: &'static str = call::<(), ()>(0xDEADBEEF); + println!("{x}"); +} diff --git a/tests/ui/traits/object/incomplete-multiple-super-projection.stderr b/tests/ui/traits/object/incomplete-multiple-super-projection.stderr new file mode 100644 index 0000000000000..b4271f70ed055 --- /dev/null +++ b/tests/ui/traits/object/incomplete-multiple-super-projection.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn Dyn<(), ()> + 'static)` + --> $DIR/incomplete-multiple-super-projection.rs:20:1 + | +LL | impl Trait for dyn Dyn<(), ()> { + | ------------------------------ first implementation here +... +LL | impl Trait for dyn Dyn { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Dyn<(), ()> + 'static)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/79590.rs b/tests/ui/traits/object/infer-shadows-implied-projection.rs similarity index 92% rename from tests/crashes/79590.rs rename to tests/ui/traits/object/infer-shadows-implied-projection.rs index b73864cce2349..628912c54faaa 100644 --- a/tests/crashes/79590.rs +++ b/tests/ui/traits/object/infer-shadows-implied-projection.rs @@ -1,4 +1,4 @@ -//@ known-bug: #79590 +//@ check-pass trait Database: Restriction {} diff --git a/tests/ui/traits/object/outlives-super-proj.rs b/tests/ui/traits/object/outlives-super-proj.rs new file mode 100644 index 0000000000000..15b67d9ab68e7 --- /dev/null +++ b/tests/ui/traits/object/outlives-super-proj.rs @@ -0,0 +1,24 @@ +//@ check-pass + +// Make sure that we still deduce outlives bounds from supertrait projections +// and require them for well-formedness. + +trait Trait { + type Assoc; +} + +trait Bar { + type Assoc; +} + +trait Foo<'a, T: 'a>: Bar { + +} + +fn outlives<'a, T: 'a>() {} + +fn implied_outlives<'a, T: Trait>(x: &dyn Foo<'a, T::Assoc>) { + outlives::<'a, T::Assoc>(); +} + +fn main() {} diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr index 2f9fdf151f08c..37fe142951d89 100644 --- a/tests/ui/traits/object/pretty.stderr +++ b/tests/ui/traits/object/pretty.stderr @@ -154,12 +154,12 @@ error[E0308]: mismatched types --> $DIR/pretty.rs:41:56 | LL | fn dyn_has_gat(x: &dyn HasGat = ()>) { x } - | - ^ expected `()`, found `&dyn HasGat = ()>` + | - ^ expected `()`, found `&dyn HasGat` | | - | help: try adding a return type: `-> &dyn HasGat = ()>` + | help: try adding a return type: `-> &dyn HasGat` | = note: expected unit type `()` - found reference `&dyn HasGat = ()>` + found reference `&dyn HasGat` error: aborting due to 14 previous errors; 1 warning emitted diff --git a/tests/ui/traits/object/redundant.rs b/tests/ui/traits/object/redundant.rs new file mode 100644 index 0000000000000..be07b15713898 --- /dev/null +++ b/tests/ui/traits/object/redundant.rs @@ -0,0 +1,12 @@ +//@ check-pass + +trait Foo: Bar {} +trait Bar { + type Out; +} + +fn w(x: &dyn Foo) { + let x: &dyn Foo = x; +} + +fn main() {} diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs index 0ca18b5b0ddce..df1d5105a34a1 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.rs +++ b/tests/ui/traits/question-mark-result-err-mismatch.rs @@ -1,3 +1,4 @@ +#![feature(try_trait_v2)] fn foo() -> Result { //~ NOTE expected `String` because of this let test = String::from("one,two"); let x = test diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index bad325a672042..0f83c9e73a314 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr @@ -1,5 +1,5 @@ error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:14:22 + --> $DIR/question-mark-result-err-mismatch.rs:15:22 | LL | fn foo() -> Result { | ---------------------- expected `String` because of this @@ -17,7 +17,7 @@ LL | .map(|()| "")?; = note: required for `Result` to implement `FromResidual>` error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:28:25 + --> $DIR/question-mark-result-err-mismatch.rs:29:25 | LL | fn bar() -> Result<(), String> { | ------------------ expected `String` because of this @@ -40,7 +40,7 @@ LL | .map_err(|_| ())?; = note: required for `Result<(), String>` to implement `FromResidual>` error[E0277]: `?` couldn't convert the error to `String` - --> $DIR/question-mark-result-err-mismatch.rs:48:11 + --> $DIR/question-mark-result-err-mismatch.rs:49:11 | LL | fn baz() -> Result { | ---------------------- expected `String` because of this diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index c67ad762a83b9..818ab499306f0 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -10,7 +10,6 @@ LL | Err("")?; = help: the trait `From<&str>` is not implemented for `TryFromSliceError` but trait `From` is implemented for it = help: for that trait implementation, expected `Infallible`, found `&str` - = note: required for `Result` to implement `FromResidual>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` --> $DIR/try-block-bad-type.rs:12:9 diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index bb5e5646ad294..6df05747f32c4 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -12,7 +12,6 @@ LL | Ok(Err(123_i32)?) = help: the following other types implement trait `From`: `u8` implements `From` `u8` implements `From` - = note: required for `Result` to implement `FromResidual>` error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` --> $DIR/bad-interconversion.rs:9:12 @@ -21,9 +20,6 @@ LL | fn option_to_result() -> Result { | -------------------------------------------- this function returns a `Result` LL | Some(3)?; | ^ use `.ok_or(...)?` to provide an error compatible with `Result` - | - = help: the trait `FromResidual>` is not implemented for `Result` - = help: the trait `FromResidual>` is implemented for `Result` error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/bad-interconversion.rs:15:31 @@ -32,9 +28,6 @@ LL | fn control_flow_to_result() -> Result { | -------------------------------------------------- this function returns a `Result` LL | Ok(ControlFlow::Break(123)?) | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Result` - | - = help: the trait `FromResidual>` is not implemented for `Result` - = help: the trait `FromResidual>` is implemented for `Result` error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/bad-interconversion.rs:20:22 @@ -43,9 +36,6 @@ LL | fn result_to_option() -> Option { | ------------------------------------ this function returns an `Option` LL | Some(Err("hello")?) | ^ use `.ok()?` if you want to discard the `Result` error information - | - = help: the trait `FromResidual>` is not implemented for `Option` - = help: the trait `FromResidual>` is implemented for `Option` error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option` --> $DIR/bad-interconversion.rs:25:33 @@ -54,9 +44,6 @@ LL | fn control_flow_to_option() -> Option { | ------------------------------------------ this function returns an `Option` LL | Some(ControlFlow::Break(123)?) | ^ this `?` produces `ControlFlow<{integer}, Infallible>`, which is incompatible with `Option` - | - = help: the trait `FromResidual>` is not implemented for `Option` - = help: the trait `FromResidual>` is implemented for `Option` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:30:39 diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.rs b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs new file mode 100644 index 0000000000000..2a0d14b175030 --- /dev/null +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs @@ -0,0 +1,29 @@ +struct E; +//~^ NOTE `E` needs to implement `std::error::Error` +//~| NOTE alternatively, `E` needs to implement `Into` +struct X; //~ NOTE `X` needs to implement `From` + +fn foo() -> Result<(), Box> { //~ NOTE required `E: std::error::Error` because of this + Ok(bar()?) + //~^ ERROR `?` couldn't convert the error: `E: std::error::Error` is not satisfied + //~| NOTE the trait `std::error::Error` is not implemented for `E` + //~| NOTE the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + //~| NOTE required for `Box` to implement `From` + //~| NOTE this has type `Result<_, E>` + //~| NOTE in this expansion + //~| NOTE in this expansion + //~| NOTE in this expansion +} +fn bat() -> Result<(), X> { //~ NOTE expected `X` because of this + Ok(bar()?) + //~^ ERROR `?` couldn't convert the error to `X` + //~| NOTE the trait `From` is not implemented for `X` + //~| NOTE this can't be annotated with `?` because it has type `Result<_, E>` + //~| NOTE the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + //~| NOTE in this expansion + //~| NOTE in this expansion +} +fn bar() -> Result<(), E> { + Err(E) +} +fn main() {} diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr new file mode 100644 index 0000000000000..dd380850c9ec3 --- /dev/null +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr @@ -0,0 +1,43 @@ +error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied + --> $DIR/bad-question-mark-on-trait-object.rs:7:13 + | +LL | fn foo() -> Result<(), Box> { + | -------------------------------------- required `E: std::error::Error` because of this +LL | Ok(bar()?) + | -----^ the trait `std::error::Error` is not implemented for `E` + | | + | this has type `Result<_, E>` + | +note: `E` needs to implement `std::error::Error` + --> $DIR/bad-question-mark-on-trait-object.rs:1:1 + | +LL | struct E; + | ^^^^^^^^ + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required for `Box` to implement `From` + +error[E0277]: `?` couldn't convert the error to `X` + --> $DIR/bad-question-mark-on-trait-object.rs:18:13 + | +LL | fn bat() -> Result<(), X> { + | ------------- expected `X` because of this +LL | Ok(bar()?) + | -----^ the trait `From` is not implemented for `X` + | | + | this can't be annotated with `?` because it has type `Result<_, E>` + | +note: `X` needs to implement `From` + --> $DIR/bad-question-mark-on-trait-object.rs:4:1 + | +LL | struct X; + | ^^^^^^^^ +note: alternatively, `E` needs to implement `Into` + --> $DIR/bad-question-mark-on-trait-object.rs:1:1 + | +LL | struct E; + | ^^^^^^^^ + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/try-trait/issue-32709.stderr b/tests/ui/try-trait/issue-32709.stderr index 475bd1ff3ac57..20454e12de558 100644 --- a/tests/ui/try-trait/issue-32709.stderr +++ b/tests/ui/try-trait/issue-32709.stderr @@ -19,7 +19,6 @@ LL | Err(5)?; `(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>` `(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>` and 4 others - = note: required for `Result` to implement `FromResidual>` error: aborting due to 1 previous error diff --git a/tests/ui/try-trait/option-to-result.stderr b/tests/ui/try-trait/option-to-result.stderr index 1a5a925f92fce..8a4c4707942ce 100644 --- a/tests/ui/try-trait/option-to-result.stderr +++ b/tests/ui/try-trait/option-to-result.stderr @@ -6,9 +6,6 @@ LL | fn test_result() -> Result<(),()> { LL | let a:Option<()> = Some(()); LL | a?; | ^ use `.ok_or(...)?` to provide an error compatible with `Result<(), ()>` - | - = help: the trait `FromResidual>` is not implemented for `Result<(), ()>` - = help: the trait `FromResidual>` is implemented for `Result` error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/option-to-result.rs:11:6 @@ -18,9 +15,6 @@ LL | fn test_option() -> Option{ LL | let a:Result = Ok(5); LL | a?; | ^ use `.ok()?` if you want to discard the `Result` error information - | - = help: the trait `FromResidual>` is not implemented for `Option` - = help: the trait `FromResidual>` is implemented for `Option` error: aborting due to 2 previous errors diff --git a/tests/ui/try-trait/try-on-option-diagnostics.stderr b/tests/ui/try-trait/try-on-option-diagnostics.stderr index 9ee540c79fdda..08675e242a354 100644 --- a/tests/ui/try-trait/try-on-option-diagnostics.stderr +++ b/tests/ui/try-trait/try-on-option-diagnostics.stderr @@ -6,8 +6,6 @@ LL | fn a_function() -> u32 { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in a function that returns `u32` - | - = help: the trait `FromResidual>` is not implemented for `u32` error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option-diagnostics.rs:14:10 @@ -17,8 +15,6 @@ LL | let a_closure = || { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in a closure that returns `{integer}` - | - = help: the trait `FromResidual>` is not implemented for `{integer}` error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option-diagnostics.rs:26:14 @@ -28,8 +24,6 @@ LL | fn a_method() { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in a method that returns `()` - | - = help: the trait `FromResidual>` is not implemented for `()` error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option-diagnostics.rs:39:14 @@ -39,8 +33,6 @@ LL | fn a_trait_method() { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in a trait method that returns `()` - | - = help: the trait `FromResidual>` is not implemented for `()` error: aborting due to 4 previous errors diff --git a/tests/ui/try-trait/try-on-option.stderr b/tests/ui/try-trait/try-on-option.stderr index 15d0b28ddc1d7..aeb519086d8c1 100644 --- a/tests/ui/try-trait/try-on-option.stderr +++ b/tests/ui/try-trait/try-on-option.stderr @@ -6,9 +6,6 @@ LL | fn foo() -> Result { LL | let x: Option = None; LL | x?; | ^ use `.ok_or(...)?` to provide an error compatible with `Result` - | - = help: the trait `FromResidual>` is not implemented for `Result` - = help: the trait `FromResidual>` is implemented for `Result` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option.rs:11:6 @@ -18,8 +15,6 @@ LL | fn bar() -> u32 { LL | let x: Option = None; LL | x?; | ^ cannot use the `?` operator in a function that returns `u32` - | - = help: the trait `FromResidual>` is not implemented for `u32` error: aborting due to 2 previous errors diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr index 311e8076ed48e..9c2526442ab5b 100644 --- a/tests/ui/try-trait/try-operator-on-main.stderr +++ b/tests/ui/try-trait/try-operator-on-main.stderr @@ -7,7 +7,6 @@ LL | // error for a `Try` type on a non-`Try` fn LL | std::fs::File::open("foo")?; | ^ cannot use the `?` operator in a function that returns `()` | - = help: the trait `FromResidual>` is not implemented for `()` help: consider adding return type | LL ~ fn main() -> Result<(), Box> { @@ -33,8 +32,6 @@ LL | fn main() { ... LL | ()?; | ^ cannot use the `?` operator in a function that returns `()` - | - = help: the trait `FromResidual<_>` is not implemented for `()` error[E0277]: the trait bound `(): Try` is not satisfied --> $DIR/try-operator-on-main.rs:14:25 diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr index c4deafd4f6b7a..03fd43d43a931 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr @@ -11,9 +11,8 @@ LL | V(u8) | ^ help: provide the argument | -LL - ::V(); -LL + ::V(/* u8 */); - | +LL | ::V(/* u8 */); + | ++++++++ error[E0308]: mismatched types --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17 diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr index 55df117d0664c..38fbff9d59dae 100644 --- a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -69,7 +69,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match x { LL + UninhabitedVariants::Tuple(_) => todo!(), -LL + } +LL ~ } | error: aborting due to 5 previous errors diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr index 04288112fa86d..ae00d3fc6678e 100644 --- a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr +++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr @@ -15,7 +15,7 @@ note: but lifetime parameter must outlive the lifetime `'b` as defined here LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b; | ^^ -error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements +error[E0803]: cannot infer an appropriate lifetime due to conflicting requirements --> $DIR/closure_wf_outlives.rs:34:9 | LL | || {} @@ -63,5 +63,5 @@ LL | type Opaque = impl Sized; error: aborting due to 3 previous errors -Some errors have detailed explanations: E0310, E0478, E0495. +Some errors have detailed explanations: E0310, E0478, E0803. For more information about an error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr index 6d9c8eabfad59..5c9a4688105ff 100644 --- a/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr +++ b/tests/ui/type-alias-impl-trait/unconstrained-due-to-bad-pattern.stderr @@ -9,7 +9,7 @@ help: ensure that all possible cases are being handled by adding a match arm wit | LL ~ match empty_opaque() { LL + _ => todo!(), -LL + } +LL ~ } | error: aborting due to 1 previous error diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 7da8cfd4dbc2d..690592ba0b8da 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -31,6 +31,7 @@ error: layout_of(NonZero) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -69,6 +70,7 @@ error: layout_of((u32) is 1..=) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, @@ -105,6 +107,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -134,6 +137,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -174,6 +178,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -216,6 +221,7 @@ error: layout_of(Option>) = Layout { ], }, largest_niche: None, + uninhabited: false, variants: Multiple { tag: Initialized { value: Int( @@ -245,6 +251,7 @@ error: layout_of(Option>) = Layout { memory_index: [], }, largest_niche: None, + uninhabited: false, variants: Single { index: 0, }, @@ -285,6 +292,7 @@ error: layout_of(Option>) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 1, }, @@ -336,6 +344,7 @@ error: layout_of(NonZeroU32New) = Layout { valid_range: 1..=4294967295, }, ), + uninhabited: false, variants: Single { index: 0, }, diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index 52d603c598082..adfb0cebf26ec 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -11,9 +11,8 @@ LL | fn infer(&self, a: A, b: B) {} | ^^^^^ ---- help: provide the argument | -LL - s.infer(0i32); -LL + s.infer(0i32, /* b */); - | +LL | s.infer(0i32, /* b */); + | +++++++++ error[E0308]: mismatched types --> $DIR/point-at-inference-4.rs:18:24 diff --git a/tests/ui/typeck/issue-103899.current.stderr b/tests/ui/typeck/issue-103899.current.stderr new file mode 100644 index 0000000000000..a3a164907be48 --- /dev/null +++ b/tests/ui/typeck/issue-103899.current.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): BaseWithAssoc` is not satisfied + --> $DIR/issue-103899.rs:24:54 + | +LL | fn trigger>() -> DoubleProject { + | ^^^^^^^^^^^^^^^^ the trait `BaseWithAssoc` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-103899.rs:4:1 + | +LL | trait BaseWithAssoc { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/issue-103899.next.stderr b/tests/ui/typeck/issue-103899.next.stderr new file mode 100644 index 0000000000000..a3a164907be48 --- /dev/null +++ b/tests/ui/typeck/issue-103899.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): BaseWithAssoc` is not satisfied + --> $DIR/issue-103899.rs:24:54 + | +LL | fn trigger>() -> DoubleProject { + | ^^^^^^^^^^^^^^^^ the trait `BaseWithAssoc` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-103899.rs:4:1 + | +LL | trait BaseWithAssoc { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/issue-103899.rs b/tests/ui/typeck/issue-103899.rs index 81ab92a8994c4..92356ecf288b1 100644 --- a/tests/ui/typeck/issue-103899.rs +++ b/tests/ui/typeck/issue-103899.rs @@ -1,9 +1,5 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@ check-fail -//@ failure-status: 101 -//@ dont-check-compiler-stderr -//@ known-bug: #103899 trait BaseWithAssoc { type Assoc; @@ -26,6 +22,7 @@ struct DoubleProject { } fn trigger>() -> DoubleProject { + //~^ ERROR the trait bound `(): BaseWithAssoc` is not satisfied [E0277] loop {} } diff --git a/tests/ui/typeck/issue-110052.stderr b/tests/ui/typeck/issue-110052.stderr index 649fc8429b9c2..832cdf6f710be 100644 --- a/tests/ui/typeck/issue-110052.stderr +++ b/tests/ui/typeck/issue-110052.stderr @@ -6,12 +6,10 @@ LL | for<'iter> dyn Validator<<&'iter I>::Item>:, | help: use fully-qualified syntax | -LL - for<'iter> dyn Validator<<&'iter I>::Item>:, -LL + for<'iter> dyn Validator<<&'iter I as IntoAsyncIterator>::Item>:, - | -LL - for<'iter> dyn Validator<<&'iter I>::Item>:, -LL + for<'iter> dyn Validator<<&'iter I as IntoIterator>::Item>:, - | +LL | for<'iter> dyn Validator<<&'iter I as IntoAsyncIterator>::Item>:, + | ++++++++++++++++++++ +LL | for<'iter> dyn Validator<<&'iter I as IntoIterator>::Item>:, + | +++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr index 388d5ec746ce6..4e483a0a58ef1 100644 --- a/tests/ui/typeck/issue-13853-5.stderr +++ b/tests/ui/typeck/issue-13853-5.stderr @@ -14,8 +14,8 @@ LL | fn deserialize_token>(_x: D, _y: &'a str) -> &'a st | help: consider returning the local binding `_y` | -LL ~ fn deserialize_token>(_x: D, _y: &'a str) -> &'a str { -LL + _y +LL | fn deserialize_token>(_x: D, _y: &'a str) -> &'a str { +LL ~ _y LL ~ | diff --git a/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr b/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr index ed0e4eb9ece81..da9caebb2d635 100644 --- a/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr +++ b/tests/ui/typeck/issue-87872-missing-inaccessible-field-pattern.stderr @@ -6,19 +6,16 @@ LL | let foo::Foo {} = foo::Foo::default(); | help: include the missing field in the pattern and ignore the inaccessible fields | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { visible, .. } = foo::Foo::default(); - | +LL | let foo::Foo { visible, .. } = foo::Foo::default(); + | +++++++++++ help: if you don't care about this missing field, you can explicitly ignore it | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { visible: _, .. } = foo::Foo::default(); - | +LL | let foo::Foo { visible: _, .. } = foo::Foo::default(); + | ++++++++++++++ help: or always ignore missing fields here | -LL - let foo::Foo {} = foo::Foo::default(); -LL + let foo::Foo { .. } = foo::Foo::default(); - | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ++ error: aborting due to 1 previous error diff --git a/tests/ui/typeck/struct-enum-wrong-args.stderr b/tests/ui/typeck/struct-enum-wrong-args.stderr index d1003fbb6b313..690851ad19adb 100644 --- a/tests/ui/typeck/struct-enum-wrong-args.stderr +++ b/tests/ui/typeck/struct-enum-wrong-args.stderr @@ -38,9 +38,8 @@ note: tuple variant defined here --> $SRC_DIR/core/src/result.rs:LL:COL help: provide the argument | -LL - let _ = Ok(); -LL + let _ = Ok(/* value */); - | +LL | let _ = Ok(/* value */); + | +++++++++++ error[E0061]: this struct takes 1 argument but 0 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:9:13 @@ -55,9 +54,8 @@ LL | struct Wrapper(i32); | ^^^^^^^ help: provide the argument | -LL - let _ = Wrapper(); -LL + let _ = Wrapper(/* i32 */); - | +LL | let _ = Wrapper(/* i32 */); + | +++++++++ error[E0061]: this struct takes 1 argument but 2 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:10:13 @@ -89,9 +87,8 @@ LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ help: provide the arguments | -LL - let _ = DoubleWrapper(); -LL + let _ = DoubleWrapper(/* i32 */, /* i32 */); - | +LL | let _ = DoubleWrapper(/* i32 */, /* i32 */); + | ++++++++++++++++++++ error[E0061]: this struct takes 2 arguments but 1 argument was supplied --> $DIR/struct-enum-wrong-args.rs:12:13 @@ -106,9 +103,8 @@ LL | struct DoubleWrapper(i32, i32); | ^^^^^^^^^^^^^ help: provide the argument | -LL - let _ = DoubleWrapper(5); -LL + let _ = DoubleWrapper(5, /* i32 */); - | +LL | let _ = DoubleWrapper(5, /* i32 */); + | +++++++++++ error[E0061]: this struct takes 2 arguments but 3 arguments were supplied --> $DIR/struct-enum-wrong-args.rs:13:13 diff --git a/tests/ui/unboxed-closures/existential-printing.rs b/tests/ui/unboxed-closures/existential-printing.rs new file mode 100644 index 0000000000000..f43373202091b --- /dev/null +++ b/tests/ui/unboxed-closures/existential-printing.rs @@ -0,0 +1,8 @@ +// Make sure we don't ICE printing `impl AsyncFnOnce<()>`. + +#![feature(unboxed_closures, fn_traits)] + +fn f() -> impl FnOnce<()> { || () } + +fn main() { () = f(); } +//~^ ERROR mismatched types diff --git a/tests/ui/unboxed-closures/existential-printing.stderr b/tests/ui/unboxed-closures/existential-printing.stderr new file mode 100644 index 0000000000000..95de98878affd --- /dev/null +++ b/tests/ui/unboxed-closures/existential-printing.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/existential-printing.rs:7:13 + | +LL | fn f() -> impl FnOnce<()> { || () } + | --------------- the expected opaque type +LL | +LL | fn main() { () = f(); } + | ^^ --- this expression has type `impl FnOnce<()>` + | | + | expected opaque type, found `()` + | + = note: expected opaque type `impl FnOnce<()>` + found unit type `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs new file mode 100644 index 0000000000000..2c2788a3e5642 --- /dev/null +++ b/tests/ui/uninhabited/uninhabited-transparent-return-abi.rs @@ -0,0 +1,33 @@ +//@ run-pass +//@ needs-unwind +// See https://github.com/rust-lang/rust/issues/135802 + +enum Void {} + +// Should be ABI-compatible with T, but wasn't prior to the PR adding this test. +#[repr(transparent)] +struct NoReturn(T, Void); + +// Returned by invisible reference (in most ABIs) +#[allow(dead_code)] +struct Large(u64, u64, u64); + +// Prior to the PR adding this test, this function had a different ABI than +// `fn() -> Large` (on `x86_64-unknown-linux-gnu` at least), so calling it as `fn() -> Large` +// would pass the return place pointer in rdi and `correct` in rsi, but the function +// would expect `correct` in rdi. +fn never(correct: &mut bool) -> NoReturn { + *correct = true; + panic!("catch this") +} + +fn main() { + let mut correct = false; + let never: fn(&mut bool) -> NoReturn = never; + // Safety: `NoReturn` is a `repr(transparent)` wrapper around `Large`, + // so they should be ABI-compatible. + let never: fn(&mut bool) -> Large = unsafe { std::mem::transmute(never) }; + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| never(&mut correct))); + assert!(result.is_err(), "function should have panicked"); + assert!(correct, "function should have stored `true` into `correct`"); +} diff --git a/tests/ui/unpretty/debug-fmt-hir.rs b/tests/ui/unpretty/debug-fmt-hir.rs new file mode 100644 index 0000000000000..c19f3c4c0c57e --- /dev/null +++ b/tests/ui/unpretty/debug-fmt-hir.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +use std::fmt; + +pub struct Bar { + a: String, + b: u8, +} + +impl fmt::Debug for Bar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + debug_struct_field2_finish(f, "Bar", "a", &self.a, "b", &&self.b) + } +} + +fn debug_struct_field2_finish<'a>( + name: &str, + name1: &str, + value1: &'a dyn fmt::Debug, + name2: &str, + value2: &'a dyn fmt::Debug, +) -> fmt::Result +{ + loop {} +} diff --git a/tests/ui/unpretty/debug-fmt-hir.stdout b/tests/ui/unpretty/debug-fmt-hir.stdout new file mode 100644 index 0000000000000..2c9c96de9d142 --- /dev/null +++ b/tests/ui/unpretty/debug-fmt-hir.stdout @@ -0,0 +1,25 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +use std::fmt; + +struct Bar { + a: String, + b: u8, +} + +impl fmt::Debug for Bar { + fn fmt(&self, f: &'_ mut fmt::Formatter<'_>) + -> + fmt::Result { + debug_struct_field2_finish(f, "Bar", "a", &self.a, "b", &&self.b) + } +} + +fn debug_struct_field2_finish<'a>(name: &'_ str, name1: &'_ str, + value1: &'a dyn fmt::Debug, name2: &'_ str, value2: &'a dyn fmt::Debug) + -> fmt::Result { loop { } } diff --git a/tests/ui/unpretty/self-hir.rs b/tests/ui/unpretty/self-hir.rs new file mode 100644 index 0000000000000..448d828d4446f --- /dev/null +++ b/tests/ui/unpretty/self-hir.rs @@ -0,0 +1,14 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +pub struct Bar { + a: String, + b: u8, +} + +impl Bar { + fn imm_self(self) {} + fn mut_self(mut self) {} + fn refimm_self(&self) {} + fn refmut_self(&mut self) {} +} diff --git a/tests/ui/unpretty/self-hir.stdout b/tests/ui/unpretty/self-hir.stdout new file mode 100644 index 0000000000000..4da080dc611e8 --- /dev/null +++ b/tests/ui/unpretty/self-hir.stdout @@ -0,0 +1,18 @@ +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +struct Bar { + a: String, + b: u8, +} + +impl Bar { + fn imm_self(self) { } + fn mut_self(mut self) { } + fn refimm_self(&self) { } + fn refmut_self(&mut self) { } +} diff --git a/tests/ui/wf/hir-wf-check-erase-regions.rs b/tests/ui/wf/hir-wf-check-erase-regions.rs index 01893044c278d..20cc1cfe73018 100644 --- a/tests/ui/wf/hir-wf-check-erase-regions.rs +++ b/tests/ui/wf/hir-wf-check-erase-regions.rs @@ -8,7 +8,9 @@ impl<'a, T, const N: usize> IntoIterator for &'a Table { //~^ ERROR `&'a T` is not an iterator type Item = &'a T; - fn into_iter(self) -> Self::IntoIter { //~ ERROR `&'a T` is not an iterator + fn into_iter(self) -> Self::IntoIter { + //~^ ERROR `&'a T` is not an iterator + //~| ERROR `&T` is not an iterator unimplemented!() } } diff --git a/tests/ui/wf/hir-wf-check-erase-regions.stderr b/tests/ui/wf/hir-wf-check-erase-regions.stderr index 4b696dc1d1dfe..e4d48bf82c000 100644 --- a/tests/ui/wf/hir-wf-check-erase-regions.stderr +++ b/tests/ui/wf/hir-wf-check-erase-regions.stderr @@ -34,6 +34,16 @@ LL | fn into_iter(self) -> Self::IntoIter { note: required by a bound in `Flatten` --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL -error: aborting due to 3 previous errors +error[E0277]: `&T` is not an iterator + --> $DIR/hir-wf-check-erase-regions.rs:11:27 + | +LL | fn into_iter(self) -> Self::IntoIter { + | ^^^^^^^^^^^^^^ `&T` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&T` + = help: the trait `Iterator` is implemented for `&mut I` + = note: required for `&T` to implement `IntoIterator` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/triagebot.toml b/triagebot.toml index 31061bd288ef9..f9eb09ff34381 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1081,7 +1081,6 @@ warn_non_default_branch.enable = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", - "workingjubilee", ] [[assign.warn_non_default_branch.exceptions]]