From ca7297b86673cf06c7089a962b763abb246ec4d5 Mon Sep 17 00:00:00 2001 From: Violet Date: Mon, 25 Oct 2021 21:35:45 -0400 Subject: remove requirement of T: Debug from Weak --- library/alloc/src/rc.rs | 2 +- library/alloc/src/sync.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 493cf3117ed..45333f38d8f 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2393,7 +2393,7 @@ impl Clone for Weak { } #[stable(feature = "rc_weak", since = "1.4.0")] -impl fmt::Debug for Weak { +impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(Weak)") } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b75e9a2f3c7..a3422fb93c8 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -303,7 +303,7 @@ impl, U: ?Sized> CoerceUnsized> for Weak {} impl, U: ?Sized> DispatchFromDyn> for Weak {} #[stable(feature = "arc_weak", since = "1.4.0")] -impl fmt::Debug for Weak { +impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(Weak)") } -- cgit 1.4.1-3-g733a5 From b8d560c19015b9d44f84d6f0396cf713b30f4db7 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sat, 15 Oct 2022 19:03:54 -0700 Subject: Stabilize `main_separator_str` Signed-off-by: Alex Saveau --- library/std/src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 9d63281627d..b3468e6234b 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -271,7 +271,7 @@ pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP; /// The primary separator of path components for the current platform. /// /// For example, `/` on Unix and `\` on Windows. -#[unstable(feature = "main_separator_str", issue = "94071")] +#[stable(feature = "main_separator_str", since = "CURRENT_RUSTC_VERSION")] pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR; //////////////////////////////////////////////////////////////////////////////// -- cgit 1.4.1-3-g733a5 From 72a9029b84d0c2dcf10cee08d39f8a64964df22d Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Sun, 6 Nov 2022 16:08:05 -0800 Subject: PhantomData layout guarantees --- library/core/src/marker.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index ae4ebf44442..26b7dddcd2e 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -621,6 +621,12 @@ impl !Sync for *mut T {} /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so /// as not to indicate ownership. /// +/// ## Layout +/// +/// For all `T`, the following are guaranteed: +/// * `size_of::>() == 0` +/// * `align_of::>() == 1` +/// /// [drop check]: ../../nomicon/dropck.html #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From ac583f18b75f005023b41d49298d4d343740648a Mon Sep 17 00:00:00 2001 From: Markus Everling Date: Thu, 1 Dec 2022 12:21:12 +0100 Subject: Add O(1) `Vec -> VecDeque` conversion guarantee --- library/alloc/src/collections/vec_deque/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4866c53e7d5..0645f2ae4da 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2794,9 +2794,9 @@ impl From> for VecDeque { /// [`Vec`]: crate::vec::Vec /// [`VecDeque`]: crate::collections::VecDeque /// - /// In its current implementation, this is a very cheap - /// conversion. This isn't yet a guarantee though, and - /// shouldn't be relied on. + /// This conversion is guaranteed to run in *O*(1) time + /// and to not re-allocate the `Vec`'s buffer or allocate + /// any additional memory. #[inline] fn from(other: Vec) -> Self { let (ptr, len, cap, alloc) = other.into_raw_parts_with_alloc(); -- cgit 1.4.1-3-g733a5 From 9553a4d439ffcf239c12142a78aa9923058e8a78 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 9 Dec 2022 17:23:09 -0800 Subject: Fix process-panic-after-fork.rs to pass on newer versions of Android. The test process-panic-after-fork.rs was checking that abort() resulted in SIGSEGV on Android. This non-standard behavior was fixed back in 2013, so let's fix the test to also accept the standard behavior on Android. --- src/test/ui/process/process-panic-after-fork.rs | 77 +++++++++++++------------ 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs index 6d4d2492225..da268312173 100644 --- a/src/test/ui/process/process-panic-after-fork.rs +++ b/src/test/ui/process/process-panic-after-fork.rs @@ -84,42 +84,47 @@ fn expect_aborted(status: ExitStatus) { #[cfg(target_os = "android")] { - // Android signals an abort() call with SIGSEGV at address 0xdeadbaad - // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc - assert!(signal == libc::SIGSEGV); - - // Additional checks performed: - // 1. Find last tombstone (similar to coredump but in text format) from the - // same executable (path) as we are (must be because of usage of fork): - // This ensures that we look into the correct tombstone. - // 2. Cause of crash is a SIGSEGV with address 0xdeadbaad. - // 3. libc::abort call is in one of top two functions on callstack. - // The last two steps distinguish between a normal SIGSEGV and one caused - // by libc::abort. - - let this_exe = std::env::current_exe().unwrap().into_os_string().into_string().unwrap(); - let exe_string = format!(">>> {this_exe} <<<"); - let tombstone = (0..100) - .map(|n| format!("/data/tombstones/tombstone_{n:02}")) - .filter(|f| std::path::Path::new(&f).exists()) - .map(|f| std::fs::read_to_string(&f).expect("Cannot read tombstone file")) - .filter(|f| f.contains(&exe_string)) - .last() - .expect("no tombstone found"); - - println!("Content of tombstone:\n{tombstone}"); - - assert!( - tombstone.contains("signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad") - ); - let abort_on_top = tombstone - .lines() - .skip_while(|l| !l.contains("backtrace:")) - .skip(1) - .take_while(|l| l.starts_with(" #")) - .take(2) - .any(|f| f.contains("/system/lib/libc.so (abort")); - assert!(abort_on_top); + assert!(signal == libc::SIGABRT || signal == libc::SIGSEGV); + + if signal == libc::SIGSEGV { + // Pre-KitKat versions of Android signal an abort() with SIGSEGV at address 0xdeadbaad + // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc + // + // This behavior was changed in KitKat to send a standard SIGABRT signal. + // See: https://r.android.com/60341 + // + // Additional checks performed: + // 1. Find last tombstone (similar to coredump but in text format) from the + // same executable (path) as we are (must be because of usage of fork): + // This ensures that we look into the correct tombstone. + // 2. Cause of crash is a SIGSEGV with address 0xdeadbaad. + // 3. libc::abort call is in one of top two functions on callstack. + // The last two steps distinguish between a normal SIGSEGV and one caused + // by libc::abort. + + let this_exe = std::env::current_exe().unwrap().into_os_string().into_string().unwrap(); + let exe_string = format!(">>> {this_exe} <<<"); + let tombstone = (0..100) + .map(|n| format!("/data/tombstones/tombstone_{n:02}")) + .filter(|f| std::path::Path::new(&f).exists()) + .map(|f| std::fs::read_to_string(&f).expect("Cannot read tombstone file")) + .filter(|f| f.contains(&exe_string)) + .last() + .expect("no tombstone found"); + + println!("Content of tombstone:\n{tombstone}"); + + assert!(tombstone + .contains("signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad")); + let abort_on_top = tombstone + .lines() + .skip_while(|l| !l.contains("backtrace:")) + .skip(1) + .take_while(|l| l.starts_with(" #")) + .take(2) + .any(|f| f.contains("/system/lib/libc.so (abort")); + assert!(abort_on_top); + } } } -- cgit 1.4.1-3-g733a5 From a3592695ce3b414d5dd44f098ed6362af9b7271b Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Wed, 14 Dec 2022 05:31:56 +0200 Subject: some fixes/improvements to mir::visit module --- compiler/rustc_middle/src/mir/visit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 2ee3f551529..0b806cdac66 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -3,15 +3,15 @@ //! ## Overview //! //! There are two visitors, one for immutable and one for mutable references, -//! but both are generated by the following macro. The code is written according -//! to the following conventions: +//! but both are generated by `make_mir_visitor` macro. +//! The code is written according to the following conventions: //! //! - introduce a `visit_foo` and a `super_foo` method for every MIR type //! - `visit_foo`, by default, calls `super_foo` //! - `super_foo`, by default, destructures the `foo` and calls `visit_foo` //! -//! This allows you as a user to override `visit_foo` for types are -//! interested in, and invoke (within that method) call +//! This allows you to override `visit_foo` for types you are +//! interested in, and invoke (within that method call) //! `self.super_foo` to get the default behavior. Just as in an OO //! language, you should never call `super` methods ordinarily except //! in that circumstance. -- cgit 1.4.1-3-g733a5 From 76430c39f0a78448bcad5a8cdabc0d48bdf3cf2f Mon Sep 17 00:00:00 2001 From: Andrés Martínez Date: Wed, 14 Dec 2022 19:39:16 +0100 Subject: Added PlayStation Vita support --- .../src/spec/armv7_sony_vita_newlibeabihf.rs | 40 +++++++ compiler/rustc_target/src/spec/mod.rs | 2 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../src/platform-support/armv7-sony-vita-eabihf.md | 127 +++++++++++++++++++++ src/test/ui/check-cfg/well-known-values.stderr | 2 +- 6 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_target/src/spec/armv7_sony_vita_newlibeabihf.rs create mode 100644 src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md diff --git a/compiler/rustc_target/src/spec/armv7_sony_vita_newlibeabihf.rs b/compiler/rustc_target/src/spec/armv7_sony_vita_newlibeabihf.rs new file mode 100644 index 00000000000..ebd2cca25ea --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7_sony_vita_newlibeabihf.rs @@ -0,0 +1,40 @@ +use crate::abi::Endian; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; + +/// A base target for PlayStation Vita devices using the VITASDK toolchain (using newlib). +/// +/// Requires the VITASDK toolchain on the host system. + +pub fn target() -> Target { + let pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,-q"]); + + Target { + llvm_target: "armv7a-vita-newlibeabihf".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: "arm".into(), + + options: TargetOptions { + os: "vita".into(), + endian: Endian::Little, + c_int_width: "32".into(), + dynamic_linking: false, + env: "newlib".into(), + vendor: "sony".into(), + abi: "eabihf".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), + no_default_libraries: false, + cpu: "cortex-a9".into(), + executables: true, + families: cvs!["unix"], + linker: Some("arm-vita-eabi-gcc".into()), + relocation_model: RelocModel::Static, + features: "+v7,+neon".into(), + pre_link_args, + exe_suffix: ".elf".into(), + panic_strategy: PanicStrategy::Abort, + max_atomic_width: Some(32), + ..Default::default() + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index be994eda14c..a6a7009a190 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1241,6 +1241,8 @@ supported_targets! { ("aarch64-nintendo-switch-freestanding", aarch64_nintendo_switch_freestanding), + ("armv7-sony-vita-newlibeabihf", armv7_sony_vita_newlibeabihf), + ("armv7-unknown-linux-uclibceabi", armv7_unknown_linux_uclibceabi), ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf), diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 2d3b8309461..da5d9a09486 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -22,6 +22,7 @@ - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md) - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md) - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) + - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d0c3ddf2606..8c710f8f6a2 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -235,6 +235,7 @@ target | std | host | notes `armv6-unknown-netbsd-eabihf` | ? | | [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 +[`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD diff --git a/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md b/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md new file mode 100644 index 00000000000..6619c90b849 --- /dev/null +++ b/src/doc/rustc/src/platform-support/armv7-sony-vita-eabihf.md @@ -0,0 +1,127 @@ +# armv7-sony-vita-eabihf + +**Tier: 3** + +This tier supports the ARM Cortex A9 processor running on a PlayStation Vita console. `armv7-vita-newlibeabihf` aims to have support for `std` crate using `newlib` as a bridge. + +## Designated Developers + +* [@amg98](https://github.com/amg98) + +## Requirements + +This target is cross compiled, and requires installing [VITASDK](https://vitasdk.org/) toolchain on your system. + +## Building + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml`: + +```toml +[build] +build-stage = 1 +target = ["armv7-sony-vita-newlibeabihf"] +``` + +## Cross-compilation + +This target can be cross-compiled from `x86_64` on either Windows, MacOS or Linux systems. Other hosts are not supported for cross-compilation. + +## Testing + +Currently there is no support to run the rustc test suite for this target. + +## Building and Running Rust Programs + +To test your developed rust programs for PlayStation Vita, first you have to prepare a proper executable for the device using the resulting ELF file you get from compilation step. The needed steps can be automated using tools like `cargo-make`. Use the example below as a template for your project: + +```toml +[env] +TITLE = "Rust Hello World" +TITLEID = "RUST00001" +# At least a "sce_sys" folder should be place there for app metadata (title, icons, description...) +# You can find sample assets for that on $VITASDK/share/gcc-arm-vita-eabi/samples/hello_world/sce_sys/ +STATIC_DIR = "static" # Folder where static assets should be placed (sce_sys folder is at $STATIC_DIR/sce_sys) +CARGO_TARGET_DIR = { script = ["echo ${CARGO_TARGET_DIR:=target}"] } +RUST_TARGET_PATH = { script = ["echo $(pwd)"]} +RUST_TARGET = "armv7-sony-vita-newlibeabihf" +CARGO_OUT_DIR = "${CARGO_TARGET_DIR}/${RUST_TARGET}/release" + +[tasks.xbuild] +# This is the command where you get the ELF executable file (e.g. call to cargo build) + +[tasks.strip] +description = "Strip the produced ELF executable." +dependencies = ["xbuild"] +command = "arm-vita-eabi-strip" +args = ["-g", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_FS_NAME}.elf'] + +[tasks.velf] +description = "Build an VELF executable from the obtained ELF file." +dependencies = ["strip"] +command = "vita-elf-create" +args = ['${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.elf', '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf'] + +[tasks.eboot-bin] +description = "Build an `eboot.bin` file from the obtained VELF file." +dependencies = ["velf"] +command = "vita-make-fself" +args = ["-s", '${CARGO_OUT_DIR}/${CARGO_MAKE_CRATE_NAME}.velf', '${CARGO_OUT_DIR}/eboot.bin'] + +[tasks.param-sfo] +description = "Build the `param.sfo` manifest using with given TITLE and TITLEID." +command = "vita-mksfoex" +args = ["-s", 'TITLE_ID=${TITLEID}', '${TITLE}', '${CARGO_OUT_DIR}/param.sfo'] + +[tasks.manifest] +description = "List all static resources into a manifest file." +script = [ + 'mkdir -p "${CARGO_OUT_DIR}"', + ''' + if [ -d "${STATIC_DIR}" ]; then + find "${STATIC_DIR}" -type f > "${CARGO_OUT_DIR}/MANIFEST" + else + touch "${CARGO_OUT_DIR}/MANIFEST" + fi + ''' +] + +[tasks.vpk] +description = "Build a VPK distribution of the project executable and resources." +dependencies = ["eboot-bin", "param-sfo", "manifest"] +script_runner = "@rust" +script = [ + ''' + use std::io::BufRead; + use std::fs::File; + + fn main() { + + let crate_name = env!("CARGO_MAKE_CRATE_NAME"); + let static_dir = env!("STATIC_DIR"); + let out_dir = std::path::PathBuf::from(env!("CARGO_OUT_DIR")); + + let mut cmd = ::std::process::Command::new("vita-pack-vpk"); + cmd.arg("-s").arg(out_dir.join("param.sfo")); + cmd.arg("-b").arg(out_dir.join("eboot.bin")); + + // Add files from MANIFEST + if let Ok(file) = File::open(out_dir.join("MANIFEST")) { + let mut reader = ::std::io::BufReader::new(file); + let mut lines = reader.lines(); + while let Some(Ok(line)) = lines.next() { + let p1 = ::std::path::PathBuf::from(line); // path on FS + let p2 = p1.strip_prefix(static_dir).unwrap(); // path in VPK + cmd.arg("--add").arg(format!("{}={}", p1.display(), p2.display())); + } + } + + cmd.arg(out_dir.join(format!("{}.vpk", crate_name))) + .output() + .expect("command failed."); + } + ''' +] +``` + +After running the above script, you should be able to get a *.vpk file in the same folder your *.elf executable resides. Now you can pick it and install it on your own PlayStation Vita using, for example, [VitaShell](https://github.com/TheOfficialFloW/VitaShell/releases) or you can use an emulator. For the time being, the most mature emulator for PlayStation Vita is [Vita3K](https://vita3k.org/), although I personally recommend testing your programs in real hardware, as the emulator is quite experimental. diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr index 29ececea5d3..69d799783a9 100644 --- a/src/test/ui/check-cfg/well-known-values.stderr +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target_os = "linuz")] | | | help: did you mean: `"linux"` | - = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous + = note: expected values for `target_os` are: aix, android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, nto, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vita, vxworks, wasi, watchos, windows, xous = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value -- cgit 1.4.1-3-g733a5 From ca4989eac278922a64139feb6c23e5e59da4dee2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 4 Apr 2022 16:45:09 +0400 Subject: SplitInternal: always set `finished` in `get_end` --- library/core/src/str/iter.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 24083ee6af4..21278c99316 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -585,16 +585,17 @@ where impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { #[inline] fn get_end(&mut self) -> Option<&'a str> { - if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { + if !self.finished { self.finished = true; - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. - unsafe { - let string = self.matcher.haystack().get_unchecked(self.start..self.end); - Some(string) + + if self.allow_trailing_empty || self.end - self.start > 0 { + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. + let string = unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }; + return Some(string); } - } else { - None } + + None } #[inline] -- cgit 1.4.1-3-g733a5 From b458a49f2664c6d8079a221f0710894d96704198 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 4 Apr 2022 17:04:58 +0400 Subject: Replace `Split*::as_str` with `remainder` This commit - Renames `Split*::{as_str -> remainder}` as it seems less confusing - Makes `remainder` return Option<&str> to distinguish between "iterator is exhausted" and "the tail is empty" --- library/core/src/lib.rs | 3 + library/core/src/str/iter.rs | 170 +++++++++++++++++++++++-------------------- 2 files changed, 96 insertions(+), 77 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1823fd30062..843c5050d6a 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -158,6 +158,7 @@ #![feature(const_unsafecell_get_mut)] #![feature(const_waker)] #![feature(core_panic)] +#![feature(char_indices_offset)] #![feature(duration_consts_float)] #![feature(maybe_uninit_uninit_array)] #![feature(ptr_alignment_type)] @@ -166,6 +167,8 @@ #![feature(slice_ptr_get)] #![feature(slice_split_at_unchecked)] #![feature(str_internals)] +#![feature(str_split_remainder)] +#![feature(str_split_inclusive_remainder)] #![feature(strict_provenance)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 21278c99316..d969475aa48 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -717,14 +717,14 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { } #[inline] - fn as_str(&self) -> &'a str { + fn remainder(&self) -> Option<&'a str> { // `Self::get_end` doesn't change `self.start` if self.finished { - return ""; + return None; } // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. - unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) } + Some(unsafe { self.matcher.haystack().get_unchecked(self.start..self.end) }) } } @@ -747,44 +747,48 @@ generate_pattern_iterators! { } impl<'a, P: Pattern<'a>> Split<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "Mary had a little lamb".split(' '); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// split.next(); - /// assert_eq!(split.as_str(), "had a little lamb"); + /// assert_eq!(split.remainder(), Some("had a little lamb")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } impl<'a, P: Pattern<'a>> RSplit<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "Mary had a little lamb".rsplit(' '); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// split.next(); - /// assert_eq!(split.as_str(), "Mary had a little"); + /// assert_eq!(split.remainder(), Some("Mary had a little")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } @@ -807,44 +811,48 @@ generate_pattern_iterators! { } impl<'a, P: Pattern<'a>> SplitTerminator<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "A..B..".split_terminator('.'); - /// assert_eq!(split.as_str(), "A..B.."); + /// assert_eq!(split.remainder(), Some("A..B..")); /// split.next(); - /// assert_eq!(split.as_str(), ".B.."); + /// assert_eq!(split.remainder(), Some(".B..")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } impl<'a, P: Pattern<'a>> RSplitTerminator<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "A..B..".rsplit_terminator('.'); - /// assert_eq!(split.as_str(), "A..B.."); + /// assert_eq!(split.remainder(), Some("A..B..")); /// split.next(); - /// assert_eq!(split.as_str(), "A..B"); + /// assert_eq!(split.remainder(), Some("A..B")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } @@ -906,8 +914,8 @@ impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> { } #[inline] - fn as_str(&self) -> &'a str { - self.iter.as_str() + fn remainder(&self) -> Option<&'a str> { + self.iter.remainder() } } @@ -930,44 +938,48 @@ generate_pattern_iterators! { } impl<'a, P: Pattern<'a>> SplitN<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "Mary had a little lamb".splitn(3, ' '); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// split.next(); - /// assert_eq!(split.as_str(), "had a little lamb"); + /// assert_eq!(split.remainder(), Some("had a little lamb")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } impl<'a, P: Pattern<'a>> RSplitN<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_as_str)] + /// #![feature(str_split_remainder)] /// let mut split = "Mary had a little lamb".rsplitn(3, ' '); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// split.next(); - /// assert_eq!(split.as_str(), "Mary had a little"); + /// assert_eq!(split.remainder(), Some("Mary had a little")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } @@ -1240,22 +1252,22 @@ impl<'a> SplitWhitespace<'a> { /// # Examples /// /// ``` - /// #![feature(str_split_whitespace_as_str)] + /// #![feature(str_split_whitespace_remainder)] /// /// let mut split = "Mary had a little lamb".split_whitespace(); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// /// split.next(); - /// assert_eq!(split.as_str(), "had a little lamb"); + /// assert_eq!(split.remainder(), Some("had a little lamb")); /// /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] #[must_use] - #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.inner.iter.as_str() + #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.inner.iter.remainder() } } @@ -1291,32 +1303,34 @@ impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { impl FusedIterator for SplitAsciiWhitespace<'_> {} impl<'a> SplitAsciiWhitespace<'a> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_whitespace_as_str)] + /// #![feature(str_split_whitespace_remainder)] /// /// let mut split = "Mary had a little lamb".split_ascii_whitespace(); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// /// split.next(); - /// assert_eq!(split.as_str(), "had a little lamb"); + /// assert_eq!(split.remainder(), Some("had a little lamb")); /// /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] #[must_use] - #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { + #[unstable(feature = "str_split_whitespace_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { if self.inner.iter.iter.finished { - return ""; + return None; } // SAFETY: Slice is created from str. - unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) } + Some(unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) }) } } @@ -1359,23 +1373,25 @@ impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator impl<'a, P: Pattern<'a>> FusedIterator for SplitInclusive<'a, P> {} impl<'a, P: Pattern<'a>> SplitInclusive<'a, P> { - /// Returns remainder of the split string + /// Returns remainder of the split string. + /// + /// If the iterator is empty, returns `None`. /// /// # Examples /// /// ``` - /// #![feature(str_split_inclusive_as_str)] + /// #![feature(str_split_inclusive_remainder)] /// let mut split = "Mary had a little lamb".split_inclusive(' '); - /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// assert_eq!(split.remainder(), Some("Mary had a little lamb")); /// split.next(); - /// assert_eq!(split.as_str(), "had a little lamb"); + /// assert_eq!(split.remainder(), Some("had a little lamb")); /// split.by_ref().for_each(drop); - /// assert_eq!(split.as_str(), ""); + /// assert_eq!(split.remainder(), None); /// ``` #[inline] - #[unstable(feature = "str_split_inclusive_as_str", issue = "77998")] - pub fn as_str(&self) -> &'a str { - self.0.as_str() + #[unstable(feature = "str_split_inclusive_remainder", issue = "77998")] + pub fn remainder(&self) -> Option<&'a str> { + self.0.remainder() } } -- cgit 1.4.1-3-g733a5 From 5a7e8f8b7970b21c40d28013800a6d4ae0c8374a Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 16 Dec 2022 16:24:14 +0200 Subject: accept review suggestion Co-authored-by: nils <48135649+Nilstrieb@users.noreply.github.com> --- compiler/rustc_middle/src/mir/visit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 0b806cdac66..1a264d2d5af 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -3,7 +3,7 @@ //! ## Overview //! //! There are two visitors, one for immutable and one for mutable references, -//! but both are generated by `make_mir_visitor` macro. +//! but both are generated by the `make_mir_visitor` macro. //! The code is written according to the following conventions: //! //! - introduce a `visit_foo` and a `super_foo` method for every MIR type -- cgit 1.4.1-3-g733a5 From 7df33a093c56d81f29914116df53fa0612b454eb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 17 Dec 2022 22:26:15 +0000 Subject: Account for RPITITs in opt_suggest_box_span --- compiler/rustc_hir_typeck/src/_match.rs | 14 +++++-- .../in-trait/box-coerce-span-in-default.rs | 49 ++++++++++++++++++++++ .../in-trait/box-coerce-span-in-default.stderr | 11 +++++ 3 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.rs create mode 100644 src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index ab12cae4e2b..7c56b8a9c7f 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -526,7 +526,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } })?; - let opaque_ty = self.tcx.mk_opaque(rpit_def_id, substs); if !self.can_coerce(first_ty, expected) || !self.can_coerce(second_ty, expected) { return None; @@ -540,13 +539,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let pred = pred.kind().rebind(match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => { - assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty); + // FIXME(rpitit): This will need to be fixed when we move to associated types + assert!(matches!( + *trait_pred.trait_ref.self_ty().kind(), + ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + if def_id == rpit_def_id && substs == substs + )); ty::PredicateKind::Clause(ty::Clause::Trait( trait_pred.with_self_ty(self.tcx, ty), )) } ty::PredicateKind::Clause(ty::Clause::Projection(mut proj_pred)) => { - assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty); + assert!(matches!( + *proj_pred.projection_ty.self_ty().kind(), + ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + if def_id == rpit_def_id && substs == substs + )); proj_pred = proj_pred.with_self_ty(self.tcx, ty); ty::PredicateKind::Clause(ty::Clause::Projection(proj_pred)) } diff --git a/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.rs b/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.rs new file mode 100644 index 00000000000..a4d483dee7a --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.rs @@ -0,0 +1,49 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete + +struct TestA {} +struct TestB {} + +impl TestTrait for TestA { + type Output = (); +} +impl TestTrait for TestB { + type Output = (); +} + +trait TestTrait { + type Output; +} + +impl TestTrait for GreeterOutput +where + A: TestTrait, + B: TestTrait, +{ + type Output = (); +} + +enum GreeterOutput +where + A: TestTrait, + B: TestTrait, +{ + SayHello(A), + SayGoodbye(B), +} + +trait Greeter { + fn test_func(&self, func: &str) -> impl TestTrait { + match func { + "SayHello" => GreeterOutput::SayHello(TestA {}), + "SayGoodbye" => GreeterOutput::SayGoodbye(TestB {}), + _ => GreeterOutput::SayHello(TestA {}), + } + } +} + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr b/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr new file mode 100644 index 00000000000..d681ecf25e8 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/box-coerce-span-in-default.rs:3:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + -- cgit 1.4.1-3-g733a5 From 5cccb36cfbc887da04dc367c24d2b4947c993ff9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 18 Dec 2022 03:04:21 +0000 Subject: higher-ranked lifetime message --- compiler/rustc_resolve/src/late.rs | 27 +++++++++++++++++----- src/test/ui/error-codes/E0637.stderr | 6 +++++ ...-incorrect-explicit-lifetime-name-needed.stderr | 6 +++++ ...-clause-inherent-impl-ampersand.rust2015.stderr | 6 +++++ ...-clause-inherent-impl-ampersand.rust2018.stderr | 6 +++++ .../where-clause-trait-impl-region.rust2015.stderr | 6 +++++ .../where-clause-trait-impl-region.rust2018.stderr | 6 +++++ 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5b7a00101e9..ef0f41223ea 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1512,7 +1512,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { count: 1, }; let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime); - for rib in self.lifetime_ribs.iter().rev() { + for (i, rib) in self.lifetime_ribs.iter().enumerate().rev() { debug!(?rib.kind); match rib.kind { LifetimeRibKind::AnonymousCreateParameter { binder, .. } => { @@ -1529,16 +1529,31 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } else { ("`'_` cannot be used here", "`'_` is a reserved lifetime name") }; - rustc_errors::struct_span_err!( + let mut diag = rustc_errors::struct_span_err!( self.r.session, lifetime.ident.span, E0637, "{}", msg, - ) - .span_label(lifetime.ident.span, note) - .emit(); - + ); + diag.span_label(lifetime.ident.span, note); + if elided { + for rib in self.lifetime_ribs[i..].iter().rev() { + if let LifetimeRibKind::Generics { + span, + kind: LifetimeBinderKind::PolyTrait | LifetimeBinderKind::WhereBound, + .. + } = &rib.kind + { + diag.span_help( + *span, + "consider introducing a higher-ranked lifetime here with `for<'a>`", + ); + break; + } + } + } + diag.emit(); self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate); return; } diff --git a/src/test/ui/error-codes/E0637.stderr b/src/test/ui/error-codes/E0637.stderr index 35a4b34fb0a..78341735e19 100644 --- a/src/test/ui/error-codes/E0637.stderr +++ b/src/test/ui/error-codes/E0637.stderr @@ -21,6 +21,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | T: Into<&u32>, | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/E0637.rs:13:8 + | +LL | T: Into<&u32>, + | ^ error: aborting due to 3 previous errors diff --git a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr index e45387acaf3..9d859fddf56 100644 --- a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr +++ b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr @@ -3,6 +3,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | fn should_error() where T : Into<&u32> {} | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:5:32 + | +LL | fn should_error() where T : Into<&u32> {} + | ^ error[E0106]: missing lifetime specifier --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:20 diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr index fe726cb49c7..f4d14b5f87b 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2015.stderr @@ -3,6 +3,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | T: WithType<&u32> | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/where-clause-inherent-impl-ampersand.rs:13:8 + | +LL | T: WithType<&u32> + | ^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr index fe726cb49c7..f4d14b5f87b 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rust2018.stderr @@ -3,6 +3,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | T: WithType<&u32> | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/where-clause-inherent-impl-ampersand.rs:13:8 + | +LL | T: WithType<&u32> + | ^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr index fbd14de2107..63fc1a19b93 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2015.stderr @@ -3,6 +3,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | T: WithType<&u32> | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/where-clause-trait-impl-region.rs:11:8 + | +LL | T: WithType<&u32> + | ^ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr index fbd14de2107..63fc1a19b93 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rust2018.stderr @@ -3,6 +3,12 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here | LL | T: WithType<&u32> | ^ explicit lifetime name needed here + | +help: consider introducing a higher-ranked lifetime here with `for<'a>` + --> $DIR/where-clause-trait-impl-region.rs:11:8 + | +LL | T: WithType<&u32> + | ^ error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 56aaf749b63824428348268dde37b84634647c4f Mon Sep 17 00:00:00 2001 From: Léo Lanteri Thauvin Date: Wed, 21 Dec 2022 16:29:35 +0100 Subject: Test the borrowck behavior of if-let guards --- src/test/ui/borrowck/borrowck-drop-from-guard.rs | 9 + .../ui/borrowck/borrowck-drop-from-guard.stderr | 21 ++- src/test/ui/borrowck/borrowck-mutate-in-guard.rs | 19 +- .../ui/borrowck/borrowck-mutate-in-guard.stderr | 23 ++- src/test/ui/borrowck/issue-31287-drop-in-guard.rs | 9 +- .../ui/borrowck/issue-31287-drop-in-guard.stderr | 20 ++- src/test/ui/issues/issue-29723.rs | 8 + src/test/ui/issues/issue-29723.stderr | 20 ++- ...ue-24535-allow-mutable-borrow-in-match-guard.rs | 8 + .../nll/issue-27282-move-match-input-into-guard.rs | 14 ++ .../issue-27282-move-match-input-into-guard.stderr | 17 +- .../ui/nll/issue-27282-move-ref-mut-into-guard.rs | 10 ++ .../nll/issue-27282-move-ref-mut-into-guard.stderr | 14 +- src/test/ui/nll/issue-27282-mutation-in-guard.rs | 13 ++ .../ui/nll/issue-27282-mutation-in-guard.stderr | 14 +- .../nll/issue-27282-reborrow-ref-mut-in-guard.rs | 14 +- .../issue-27282-reborrow-ref-mut-in-guard.stderr | 14 +- src/test/ui/nll/match-cfg-fake-edges.rs | 28 +++ src/test/ui/nll/match-cfg-fake-edges.stderr | 40 ++++- src/test/ui/nll/match-guards-always-borrow.rs | 27 ++- src/test/ui/nll/match-guards-always-borrow.stderr | 14 +- src/test/ui/nll/match-guards-partially-borrow.rs | 193 +++++++++++++++++++-- .../ui/nll/match-guards-partially-borrow.stderr | 103 +++++++++-- .../rfc-reject-double-move-across-arms.rs | 15 +- .../rfc-reject-double-move-across-arms.stderr | 12 +- .../rfc-reject-double-move-in-first-arm.rs | 16 +- .../rfc-reject-double-move-in-first-arm.stderr | 12 +- 27 files changed, 645 insertions(+), 62 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.rs b/src/test/ui/borrowck/borrowck-drop-from-guard.rs index 4995029a70f..0f320af2657 100644 --- a/src/test/ui/borrowck/borrowck-drop-from-guard.rs +++ b/src/test/ui/borrowck/borrowck-drop-from-guard.rs @@ -1,3 +1,5 @@ +#![feature(if_let_guard)] + fn foo(_:String) {} fn main() @@ -8,4 +10,11 @@ fn main() Some(_) => {} None => { foo(my_str); } //~ ERROR [E0382] } + + let my_str = "hello".to_owned(); + match Some(42) { + Some(_) if let Some(()) = { drop(my_str); None } => {} + Some(_) => {} + None => { foo(my_str); } //~ ERROR [E0382] + } } diff --git a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr index eaf4bb38bc5..9fa28efd855 100644 --- a/src/test/ui/borrowck/borrowck-drop-from-guard.stderr +++ b/src/test/ui/borrowck/borrowck-drop-from-guard.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `my_str` - --> $DIR/borrowck-drop-from-guard.rs:9:23 + --> $DIR/borrowck-drop-from-guard.rs:11:23 | LL | let my_str = "hello".to_owned(); | ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait @@ -15,6 +15,23 @@ help: consider cloning the value if the performance cost is acceptable LL | Some(_) if { drop(my_str.clone()); false } => {} | ++++++++ -error: aborting due to previous error +error[E0382]: use of moved value: `my_str` + --> $DIR/borrowck-drop-from-guard.rs:18:23 + | +LL | let my_str = "hello".to_owned(); + | ------ move occurs because `my_str` has type `String`, which does not implement the `Copy` trait +LL | match Some(42) { +LL | Some(_) if let Some(()) = { drop(my_str); None } => {} + | ------ value moved here +LL | Some(_) => {} +LL | None => { foo(my_str); } + | ^^^^^^ value used here after move + | +help: consider cloning the value if the performance cost is acceptable + | +LL | Some(_) if let Some(()) = { drop(my_str.clone()); None } => {} + | ++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs index 9cbceeb945c..d80a9e81576 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs @@ -1,9 +1,11 @@ +#![feature(if_let_guard)] + enum Enum<'a> { A(&'a isize), B(bool), } -fn foo() -> isize { +fn if_guard() -> isize { let mut n = 42; let mut x = Enum::A(&mut n); match x { @@ -16,6 +18,17 @@ fn foo() -> isize { } } -fn main() { - foo(); +fn if_let_guard() -> isize { + let mut n = 42; + let mut x = Enum::A(&mut n); + match x { + Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1, + //~^ ERROR cannot assign `x` in match guard + Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1, + //~^ ERROR cannot mutably borrow `x` in match guard + Enum::A(p) => *p, + Enum::B(_) => 2, + } } + +fn main() {} diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr index 6d05e97252d..dbb3272fdc3 100644 --- a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr +++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr @@ -1,5 +1,5 @@ error[E0510]: cannot assign `x` in match guard - --> $DIR/borrowck-mutate-in-guard.rs:10:25 + --> $DIR/borrowck-mutate-in-guard.rs:12:25 | LL | match x { | - value is immutable in match guard @@ -7,7 +7,7 @@ LL | Enum::A(_) if { x = Enum::B(false); false } => 1, | ^^^^^^^^^^^^^^^^^^ cannot assign error[E0510]: cannot mutably borrow `x` in match guard - --> $DIR/borrowck-mutate-in-guard.rs:12:33 + --> $DIR/borrowck-mutate-in-guard.rs:14:33 | LL | match x { | - value is immutable in match guard @@ -15,6 +15,23 @@ LL | match x { LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, | ^^^^^^ cannot mutably borrow -error: aborting due to 2 previous errors +error[E0510]: cannot assign `x` in match guard + --> $DIR/borrowck-mutate-in-guard.rs:25:40 + | +LL | match x { + | - value is immutable in match guard +LL | Enum::A(_) if let Some(()) = { x = Enum::B(false); None } => 1, + | ^^^^^^^^^^^^^^^^^^ cannot assign + +error[E0510]: cannot mutably borrow `x` in match guard + --> $DIR/borrowck-mutate-in-guard.rs:27:48 + | +LL | match x { + | - value is immutable in match guard +... +LL | Enum::A(_) if let Some(()) = { let y = &mut x; *y = Enum::B(false); None } => 1, + | ^^^^^^ cannot mutably borrow + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0510`. diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.rs b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs index 07125b98a1f..5b824adc6e2 100644 --- a/src/test/ui/borrowck/issue-31287-drop-in-guard.rs +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.rs @@ -1,8 +1,15 @@ +#![feature(if_let_guard)] + fn main() { let a = Some("...".to_owned()); let b = match a { Some(_) if { drop(a); false } => None, x => x, //~ ERROR use of moved value: `a` }; - println!("{:?}", b); + + let a = Some("...".to_owned()); + let b = match a { + Some(_) if let Some(()) = { drop(a); None } => None, + x => x, //~ ERROR use of moved value: `a` + }; } diff --git a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr index ad898fcabd9..18f371c2073 100644 --- a/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr +++ b/src/test/ui/borrowck/issue-31287-drop-in-guard.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a` - --> $DIR/issue-31287-drop-in-guard.rs:5:9 + --> $DIR/issue-31287-drop-in-guard.rs:7:9 | LL | let a = Some("...".to_owned()); | - move occurs because `a` has type `Option`, which does not implement the `Copy` trait @@ -14,6 +14,22 @@ help: consider cloning the value if the performance cost is acceptable LL | Some(_) if { drop(a.clone()); false } => None, | ++++++++ -error: aborting due to previous error +error[E0382]: use of moved value: `a` + --> $DIR/issue-31287-drop-in-guard.rs:13:9 + | +LL | let a = Some("...".to_owned()); + | - move occurs because `a` has type `Option`, which does not implement the `Copy` trait +LL | let b = match a { +LL | Some(_) if let Some(()) = { drop(a); None } => None, + | - value moved here +LL | x => x, + | ^ value used here after move + | +help: consider cloning the value if the performance cost is acceptable + | +LL | Some(_) if let Some(()) = { drop(a.clone()); None } => None, + | ++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/issues/issue-29723.rs b/src/test/ui/issues/issue-29723.rs index ce91022f093..399e9ba0df7 100644 --- a/src/test/ui/issues/issue-29723.rs +++ b/src/test/ui/issues/issue-29723.rs @@ -1,5 +1,7 @@ // test for https://github.com/rust-lang/rust/issues/29723 +#![feature(if_let_guard)] + fn main() { let s = String::new(); let _s = match 0 { @@ -11,4 +13,10 @@ fn main() { //~^ ERROR use of moved value: `s` } }; + + let s = String::new(); + let _s = match 0 { + 0 if let Some(()) = { drop(s); None } => String::from("oops"), + _ => s //~ ERROR use of moved value: `s` + }; } diff --git a/src/test/ui/issues/issue-29723.stderr b/src/test/ui/issues/issue-29723.stderr index 92ee5cf22b7..044d8a9b5dd 100644 --- a/src/test/ui/issues/issue-29723.stderr +++ b/src/test/ui/issues/issue-29723.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `s` - --> $DIR/issue-29723.rs:10:13 + --> $DIR/issue-29723.rs:12:13 | LL | let s = String::new(); | - move occurs because `s` has type `String`, which does not implement the `Copy` trait @@ -15,6 +15,22 @@ help: consider cloning the value if the performance cost is acceptable LL | 0 if { drop(s.clone()); false } => String::from("oops"), | ++++++++ -error: aborting due to previous error +error[E0382]: use of moved value: `s` + --> $DIR/issue-29723.rs:20:14 + | +LL | let s = String::new(); + | - move occurs because `s` has type `String`, which does not implement the `Copy` trait +LL | let _s = match 0 { +LL | 0 if let Some(()) = { drop(s); None } => String::from("oops"), + | - value moved here +LL | _ => s + | ^ value used here after move + | +help: consider cloning the value if the performance cost is acceptable + | +LL | 0 if let Some(()) = { drop(s.clone()); None } => String::from("oops"), + | ++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs index 7253d35ed2d..ccfc8937fd7 100644 --- a/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs +++ b/src/test/ui/nll/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -5,6 +5,8 @@ // See further discussion on rust-lang/rust#24535, // rust-lang/rfcs#1006, and rust-lang/rfcs#107 +#![feature(if_let_guard)] + fn main() { rust_issue_24535(); rfcs_issue_1006_1(); @@ -23,6 +25,12 @@ fn rust_issue_24535() { 3 if compare(&a, &mut 3) => (), _ => panic!("nope"), } + + match a { + 0 => panic!("nope"), + 3 if let true = compare(&a, &mut 3) => (), + _ => panic!("nope"), + } } fn rfcs_issue_1006_1() { diff --git a/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs index 4109c10e2e4..85feda5824b 100644 --- a/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs +++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.rs @@ -7,6 +7,8 @@ // reaches the panic code when executed, despite the compiler warning // about that match arm being unreachable. +#![feature(if_let_guard)] + fn main() { let b = &mut true; match b { @@ -17,4 +19,16 @@ fn main() { &mut true => { println!("You might think we should get here"); }, _ => panic!("surely we could never get here, since rustc warns it is unreachable."), } + + let b = &mut true; + match b { + //~^ ERROR use of moved value: `b` [E0382] + &mut false => {} + _ if let Some(()) = { + (|| { let bar = b; *bar = false; })(); + None + } => {} + &mut true => {} + _ => {} + } } diff --git a/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr index 9be1a927999..ae797800457 100644 --- a/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr +++ b/src/test/ui/nll/issue-27282-move-match-input-into-guard.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `b` - --> $DIR/issue-27282-move-match-input-into-guard.rs:12:5 + --> $DIR/issue-27282-move-match-input-into-guard.rs:14:5 | LL | let b = &mut true; | - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait @@ -11,6 +11,19 @@ LL | _ if { (|| { let bar = b; *bar = false; })(); | | | value moved into closure here -error: aborting due to previous error +error[E0382]: use of moved value: `b` + --> $DIR/issue-27282-move-match-input-into-guard.rs:24:5 + | +LL | let b = &mut true; + | - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait +LL | match b { + | ^^^^^^^ value used here after move +... +LL | (|| { let bar = b; *bar = false; })(); + | -- - variable moved due to use in closure + | | + | value moved into closure here + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs index afa0ba780de..833ca8afd61 100644 --- a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs +++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.rs @@ -2,6 +2,8 @@ // mutable borrows in match guards by hiding the mutable borrow in a // guard behind a move (of the ref mut pattern id) within a closure. +#![feature(if_let_guard)] + fn main() { match Some(&4) { None => {}, @@ -10,4 +12,12 @@ fn main() { //~^ ERROR cannot move out of `foo` in pattern guard [E0507] Some(s) => std::process::exit(*s), } + + match Some(&4) { + None => {}, + ref mut foo + if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {}, + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + Some(s) => std::process::exit(*s), + } } diff --git a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr index a0d32616f83..45119018d4e 100644 --- a/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr +++ b/src/test/ui/nll/issue-27282-move-ref-mut-into-guard.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/issue-27282-move-ref-mut-into-guard.rs:9:19 + --> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19 | LL | if { (|| { let bar = foo; bar.take() })(); false } => {}, | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait @@ -8,6 +8,16 @@ LL | if { (|| { let bar = foo; bar.take() })(); false } => {}, | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard -error: aborting due to previous error +error[E0507]: cannot move out of `foo` in pattern guard + --> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34 + | +LL | if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {}, + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait + | | + | move out of `foo` occurs here + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/nll/issue-27282-mutation-in-guard.rs b/src/test/ui/nll/issue-27282-mutation-in-guard.rs index 395c7d214d0..4f41fc23fc3 100644 --- a/src/test/ui/nll/issue-27282-mutation-in-guard.rs +++ b/src/test/ui/nll/issue-27282-mutation-in-guard.rs @@ -1,3 +1,5 @@ +#![feature(if_let_guard)] + fn main() { match Some(&4) { None => {}, @@ -10,4 +12,15 @@ fn main() { Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), _ => println!("Here is some supposedly unreachable code."), } + + match Some(&4) { + None => {}, + ref mut foo + if let Some(()) = { + (|| { let bar = foo; bar.take() })(); + //~^ ERROR cannot move out of `foo` in pattern guard + None + } => {}, + Some(_) => {}, + } } diff --git a/src/test/ui/nll/issue-27282-mutation-in-guard.stderr b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr index c4ce7e62fda..1ba696593af 100644 --- a/src/test/ui/nll/issue-27282-mutation-in-guard.stderr +++ b/src/test/ui/nll/issue-27282-mutation-in-guard.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/issue-27282-mutation-in-guard.rs:6:18 + --> $DIR/issue-27282-mutation-in-guard.rs:8:18 | LL | (|| { let bar = foo; bar.take() })(); | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait @@ -8,6 +8,16 @@ LL | (|| { let bar = foo; bar.take() })(); | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard -error: aborting due to previous error +error[E0507]: cannot move out of `foo` in pattern guard + --> $DIR/issue-27282-mutation-in-guard.rs:20:18 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait + | | + | move out of `foo` occurs here + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs index 82d8b9e9ed9..ac06b2b0102 100644 --- a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs +++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.rs @@ -3,7 +3,9 @@ // It reborrows instead of moving the `ref mut` pattern borrow. This // means that our conservative check for mutation in guards will // reject it. But I want to make sure that we continue to reject it -// (under NLL) even when that conservaive check goes away. +// (under NLL) even when that conservative check goes away. + +#![feature(if_let_guard)] fn main() { let mut b = &mut true; @@ -15,4 +17,14 @@ fn main() { &mut true => { println!("You might think we should get here"); }, _ => panic!("surely we could never get here, since rustc warns it is unreachable."), } + + let mut b = &mut true; + match b { + &mut false => {}, + ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })(); + //~^ ERROR cannot borrow `r` as mutable, as it is immutable for the pattern guard + None } => { &mut *r; }, + &mut true => {}, + _ => {}, + } } diff --git a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr index 48433432de1..5eb7a25bf9f 100644 --- a/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr +++ b/src/test/ui/nll/issue-27282-reborrow-ref-mut-in-guard.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard - --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25 + --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:14:25 | LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); | ^^ -- mutable borrow occurs due to use of `r` in closure @@ -8,6 +8,16 @@ LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); | = note: variables bound in patterns are immutable until the end of the pattern guard -error: aborting due to previous error +error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard + --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:24:40 + | +LL | ref mut r if let Some(()) = { (|| { let bar = &mut *r; **bar = false; })(); + | ^^ -- mutable borrow occurs due to use of `r` in closure + | | + | cannot borrow as mutable + | + = note: variables bound in patterns are immutable until the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs index 252f7f8ba07..1afc7931a6b 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.rs +++ b/src/test/ui/nll/match-cfg-fake-edges.rs @@ -1,6 +1,8 @@ // Test that we have enough false edges to avoid exposing the exact matching // algorithm in borrow checking. +#![feature(if_let_guard)] + fn guard_always_precedes_arm(y: i32) { let mut x; // x should always be initialized, as the only way to reach the arm is @@ -9,6 +11,12 @@ fn guard_always_precedes_arm(y: i32) { 0 | 2 if { x = 2; true } => x, _ => 2, }; + + let mut x; + match y { + 0 | 2 if let Some(()) = { x = 2; Some(()) } => x, + _ => 2, + }; } fn guard_may_be_skipped(y: i32) { @@ -23,6 +31,16 @@ fn guard_may_be_skipped(y: i32) { } => 2, _ => 3, }; + + let x; + match y { + _ if let Some(()) = { x = 2; Some(()) } => 1, + _ if let Some(()) = { + x; //~ ERROR E0381 + None + } => 2, + _ => 3, + }; } fn guard_may_be_taken(y: bool) { @@ -37,6 +55,16 @@ fn guard_may_be_taken(y: bool) { } false => 3, }; + + let x = String::new(); + match y { + false if let Some(()) = { drop(x); Some(()) } => 1, + true => { + x; //~ ERROR use of moved value: `x` + 2 + } + false => 3, + }; } fn main() {} diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index f72ed3af718..a6261345cea 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `x` isn't initialized - --> $DIR/match-cfg-fake-edges.rs:21:13 + --> $DIR/match-cfg-fake-edges.rs:29:13 | LL | let x; | - binding declared here but left uninitialized @@ -15,8 +15,25 @@ help: consider assigning a value LL | let x = 0; | +++ +error[E0381]: used binding `x` isn't initialized + --> $DIR/match-cfg-fake-edges.rs:39:13 + | +LL | let x; + | - binding declared here but left uninitialized +LL | match y { +LL | _ if let Some(()) = { x = 2; Some(()) } => 1, + | ----- binding initialized here in some conditions +LL | _ if let Some(()) = { +LL | x; + | ^ `x` used here but it isn't initialized + | +help: consider assigning a value + | +LL | let x = 0; + | +++ + error[E0382]: use of moved value: `x` - --> $DIR/match-cfg-fake-edges.rs:35:13 + --> $DIR/match-cfg-fake-edges.rs:53:13 | LL | let x = String::new(); | - move occurs because `x` has type `String`, which does not implement the `Copy` trait @@ -32,7 +49,24 @@ help: consider cloning the value if the performance cost is acceptable LL | false if { drop(x.clone()); true } => 1, | ++++++++ -error: aborting due to 2 previous errors +error[E0382]: use of moved value: `x` + --> $DIR/match-cfg-fake-edges.rs:63:13 + | +LL | let x = String::new(); + | - move occurs because `x` has type `String`, which does not implement the `Copy` trait +LL | match y { +LL | false if let Some(()) = { drop(x); Some(()) } => 1, + | - value moved here +LL | true => { +LL | x; + | ^ value used here after move + | +help: consider cloning the value if the performance cost is acceptable + | +LL | false if let Some(()) = { drop(x.clone()); Some(()) } => 1, + | ++++++++ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0381, E0382. For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/nll/match-guards-always-borrow.rs b/src/test/ui/nll/match-guards-always-borrow.rs index 87dba187ba2..ff63cc09273 100644 --- a/src/test/ui/nll/match-guards-always-borrow.rs +++ b/src/test/ui/nll/match-guards-always-borrow.rs @@ -1,3 +1,5 @@ +#![feature(if_let_guard)] + // Here is arielb1's basic example from rust-lang/rust#27282 // that AST borrowck is flummoxed by: @@ -10,6 +12,15 @@ fn should_reject_destructive_mutate_in_guard() { false } => { }, Some(s) => std::process::exit(*s), } + + match Some(&4) { + None => {}, + ref mut foo if let Some(()) = { + (|| { let bar = foo; bar.take() })(); + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + None } => { }, + Some(s) => std::process::exit(*s), + } } // Here below is a case that needs to keep working: we only use the @@ -18,7 +29,13 @@ fn should_reject_destructive_mutate_in_guard() { fn allow_mutate_in_arm_body() { match Some(&4) { None => {}, - ref mut foo if foo.is_some() && false => { foo.take(); () } + ref mut foo if foo.is_some() => { foo.take(); () } + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + ref mut foo if let Some(_) = foo => { foo.take(); () } Some(s) => std::process::exit(*s), } } @@ -29,7 +46,13 @@ fn allow_mutate_in_arm_body() { fn allow_move_into_arm_body() { match Some(&4) { None => {}, - mut foo if foo.is_some() && false => { foo.take(); () } + mut foo if foo.is_some() => { foo.unwrap(); () } + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + mut foo if let Some(_) = foo => { foo.unwrap(); () } Some(s) => std::process::exit(*s), } } diff --git a/src/test/ui/nll/match-guards-always-borrow.stderr b/src/test/ui/nll/match-guards-always-borrow.stderr index c0fb5f65382..fa01d3a6fd1 100644 --- a/src/test/ui/nll/match-guards-always-borrow.stderr +++ b/src/test/ui/nll/match-guards-always-borrow.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/match-guards-always-borrow.rs:8:14 + --> $DIR/match-guards-always-borrow.rs:10:14 | LL | (|| { let bar = foo; bar.take() })(); | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait @@ -8,6 +8,16 @@ LL | (|| { let bar = foo; bar.take() })(); | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard -error: aborting due to previous error +error[E0507]: cannot move out of `foo` in pattern guard + --> $DIR/match-guards-always-borrow.rs:19:14 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait + | | + | move out of `foo` occurs here + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/nll/match-guards-partially-borrow.rs b/src/test/ui/nll/match-guards-partially-borrow.rs index 81ae19ebf8a..3a9e1654b1c 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.rs +++ b/src/test/ui/nll/match-guards-partially-borrow.rs @@ -5,7 +5,9 @@ // Test that we don't allow mutating the value being matched on in a way that // changes which patterns it matches, until we have chosen an arm. -fn ok_mutation_in_guard(mut q: i32) { +#![feature(if_let_guard)] + +fn ok_mutation_in_if_guard(mut q: i32) { match q { // OK, mutation doesn't change which patterns g matches _ if { q = 1; false } => (), @@ -13,7 +15,15 @@ fn ok_mutation_in_guard(mut q: i32) { } } -fn ok_mutation_in_guard2(mut u: bool) { +fn ok_mutation_in_if_let_guard(mut q: i32) { + match q { + // OK, mutation doesn't change which patterns g matches + _ if let Some(()) = { q = 1; None } => (), + _ => (), + } +} + +fn ok_mutation_in_if_guard2(mut u: bool) { // OK value of u is unused before modification match u { _ => (), @@ -25,7 +35,19 @@ fn ok_mutation_in_guard2(mut u: bool) { } } -fn ok_mutation_in_guard4(mut w: (&mut bool,)) { +fn ok_mutation_in_if_let_guard2(mut u: bool) { + // OK value of u is unused before modification + match u { + _ => (), + _ if let Some(()) = { + u = true; + None + } => (), + x => (), + } +} + +fn ok_mutation_in_if_guard4(mut w: (&mut bool,)) { // OK value of u is unused before modification match w { _ => (), @@ -37,7 +59,19 @@ fn ok_mutation_in_guard4(mut w: (&mut bool,)) { } } -fn ok_indirect_mutation_in_guard(mut p: &bool) { +fn ok_mutation_in_if_let_guard4(mut w: (&mut bool,)) { + // OK value of u is unused before modification + match w { + _ => (), + _ if let Some(()) = { + *w.0 = true; + None + } => (), + x => (), + } +} + +fn ok_indirect_mutation_in_if_guard(mut p: &bool) { match *p { // OK, mutation doesn't change which patterns s matches _ if { @@ -48,7 +82,18 @@ fn ok_indirect_mutation_in_guard(mut p: &bool) { } } -fn mutation_invalidates_pattern_in_guard(mut q: bool) { +fn ok_indirect_mutation_in_if_let_guard(mut p: &bool) { + match *p { + // OK, mutation doesn't change which patterns s matches + _ if let Some(()) = { + p = &true; + None + } => (), + _ => (), + } +} + +fn mutation_invalidates_pattern_in_if_guard(mut q: bool) { match q { // q doesn't match the pattern with the guard by the end of the guard. false if { @@ -59,7 +104,18 @@ fn mutation_invalidates_pattern_in_guard(mut q: bool) { } } -fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) { +fn mutation_invalidates_pattern_in_if_let_guard(mut q: bool) { + match q { + // q doesn't match the pattern with the guard by the end of the guard. + false if let Some(()) = { + q = true; //~ ERROR + Some(()) + } => (), + _ => (), + } +} + +fn mutation_invalidates_previous_pattern_in_if_guard(mut r: bool) { match r { // r matches a previous pattern by the end of the guard. true => (), @@ -71,7 +127,19 @@ fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) { } } -fn match_on_borrowed_early_end(mut s: bool) { +fn mutation_invalidates_previous_pattern_in_if_let_guard(mut r: bool) { + match r { + // r matches a previous pattern by the end of the guard. + true => (), + _ if let Some(()) = { + r = true; //~ ERROR + Some(()) + } => (), + _ => (), + } +} + +fn match_on_borrowed_early_end_if_guard(mut s: bool) { let h = &mut s; // OK value of s is unused before modification. match s { @@ -84,7 +152,20 @@ fn match_on_borrowed_early_end(mut s: bool) { } } -fn bad_mutation_in_guard(mut t: bool) { +fn match_on_borrowed_early_end_if_let_guard(mut s: bool) { + let h = &mut s; + // OK value of s is unused before modification. + match s { + _ if let Some(()) = { + *h = !*h; + None + } => (), + true => (), + false => (), + } +} + +fn bad_mutation_in_if_guard(mut t: bool) { match t { true => (), false if { @@ -95,7 +176,18 @@ fn bad_mutation_in_guard(mut t: bool) { } } -fn bad_mutation_in_guard2(mut x: Option>) { +fn bad_mutation_in_if_let_guard(mut t: bool) { + match t { + true => (), + false if let Some(()) = { + t = true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_mutation_in_if_guard2(mut x: Option>) { // Check that nested patterns are checked. match x { None => (), @@ -111,7 +203,23 @@ fn bad_mutation_in_guard2(mut x: Option>) { } } -fn bad_mutation_in_guard3(mut t: bool) { +fn bad_mutation_in_if_let_guard2(mut x: Option>) { + // Check that nested patterns are checked. + match x { + None => (), + Some(None) => (), + _ if let Some(()) = { + match x { + Some(ref mut r) => *r = None, //~ ERROR + _ => return, + }; + None + } => (), + Some(Some(r)) => println!("{}", r), + } +} + +fn bad_mutation_in_if_guard3(mut t: bool) { match t { s if { t = !t; //~ ERROR @@ -121,7 +229,17 @@ fn bad_mutation_in_guard3(mut t: bool) { } } -fn bad_indirect_mutation_in_guard(mut y: &bool) { +fn bad_mutation_in_if_let_guard3(mut t: bool) { + match t { + s if let Some(()) = { + t = !t; //~ ERROR + None + } => (), // What value should `s` have in the arm? + _ => (), + } +} + +fn bad_indirect_mutation_in_if_guard(mut y: &bool) { match *y { true => (), false if { @@ -132,7 +250,18 @@ fn bad_indirect_mutation_in_guard(mut y: &bool) { } } -fn bad_indirect_mutation_in_guard2(mut z: &bool) { +fn bad_indirect_mutation_in_if_let_guard(mut y: &bool) { + match *y { + true => (), + false if let Some(()) = { + y = &true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_guard2(mut z: &bool) { match z { &true => (), &false if { @@ -143,8 +272,19 @@ fn bad_indirect_mutation_in_guard2(mut z: &bool) { } } -fn bad_indirect_mutation_in_guard3(mut a: &bool) { - // Same as bad_indirect_mutation_in_guard2, but using match ergonomics +fn bad_indirect_mutation_in_if_let_guard2(mut z: &bool) { + match z { + &true => (), + &false if let Some(()) = { + z = &true; //~ ERROR + None + } => (), + &false => (), + } +} + +fn bad_indirect_mutation_in_if_guard3(mut a: &bool) { + // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics match a { true => (), false if { @@ -155,7 +295,19 @@ fn bad_indirect_mutation_in_guard3(mut a: &bool) { } } -fn bad_indirect_mutation_in_guard4(mut b: &bool) { +fn bad_indirect_mutation_in_if_let_guard3(mut a: &bool) { + // Same as bad_indirect_mutation_in_if_guard2, but using match ergonomics + match a { + true => (), + false if let Some(()) = { + a = &true; //~ ERROR + None + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_if_guard4(mut b: &bool) { match b { &_ => (), &_ if { @@ -166,4 +318,15 @@ fn bad_indirect_mutation_in_guard4(mut b: &bool) { } } +fn bad_indirect_mutation_in_if_let_guard4(mut b: &bool) { + match b { + &_ => (), + &_ if let Some(()) = { + b = &true; //~ ERROR + None + } => (), + &b => (), + } +} + fn main() {} diff --git a/src/test/ui/nll/match-guards-partially-borrow.stderr b/src/test/ui/nll/match-guards-partially-borrow.stderr index 48e3a7c6993..60b8dee71a8 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.stderr +++ b/src/test/ui/nll/match-guards-partially-borrow.stderr @@ -1,5 +1,5 @@ error[E0510]: cannot assign `q` in match guard - --> $DIR/match-guards-partially-borrow.rs:55:13 + --> $DIR/match-guards-partially-borrow.rs:100:13 | LL | match q { | - value is immutable in match guard @@ -7,8 +7,26 @@ LL | match q { LL | q = true; | ^^^^^^^^ cannot assign +error[E0510]: cannot assign `q` in match guard + --> $DIR/match-guards-partially-borrow.rs:111:13 + | +LL | match q { + | - value is immutable in match guard +... +LL | q = true; + | ^^^^^^^^ cannot assign + +error[E0510]: cannot assign `r` in match guard + --> $DIR/match-guards-partially-borrow.rs:123:13 + | +LL | match r { + | - value is immutable in match guard +... +LL | r = true; + | ^^^^^^^^ cannot assign + error[E0510]: cannot assign `r` in match guard - --> $DIR/match-guards-partially-borrow.rs:67:13 + --> $DIR/match-guards-partially-borrow.rs:135:13 | LL | match r { | - value is immutable in match guard @@ -17,7 +35,16 @@ LL | r = true; | ^^^^^^^^ cannot assign error[E0510]: cannot assign `t` in match guard - --> $DIR/match-guards-partially-borrow.rs:91:13 + --> $DIR/match-guards-partially-borrow.rs:172:13 + | +LL | match t { + | - value is immutable in match guard +... +LL | t = true; + | ^^^^^^^^ cannot assign + +error[E0510]: cannot assign `t` in match guard + --> $DIR/match-guards-partially-borrow.rs:183:13 | LL | match t { | - value is immutable in match guard @@ -26,7 +53,16 @@ LL | t = true; | ^^^^^^^^ cannot assign error[E0510]: cannot mutably borrow `x.0` in match guard - --> $DIR/match-guards-partially-borrow.rs:105:22 + --> $DIR/match-guards-partially-borrow.rs:197:22 + | +LL | match x { + | - value is immutable in match guard +... +LL | Some(ref mut r) => *r = None, + | ^^^^^^^^^ cannot mutably borrow + +error[E0510]: cannot mutably borrow `x.0` in match guard + --> $DIR/match-guards-partially-borrow.rs:213:22 | LL | match x { | - value is immutable in match guard @@ -35,7 +71,7 @@ LL | Some(ref mut r) => *r = None, | ^^^^^^^^^ cannot mutably borrow error[E0506]: cannot assign to `t` because it is borrowed - --> $DIR/match-guards-partially-borrow.rs:117:13 + --> $DIR/match-guards-partially-borrow.rs:225:13 | LL | s if { | - borrow of `t` occurs here @@ -45,8 +81,28 @@ LL | false LL | } => (), // What value should `s` have in the arm? | - borrow later used here +error[E0506]: cannot assign to `t` because it is borrowed + --> $DIR/match-guards-partially-borrow.rs:235:13 + | +LL | s if let Some(()) = { + | - borrow of `t` occurs here +LL | t = !t; + | ^^^^^^ assignment to borrowed `t` occurs here +LL | None +LL | } => (), // What value should `s` have in the arm? + | - borrow later used here + +error[E0510]: cannot assign `y` in match guard + --> $DIR/match-guards-partially-borrow.rs:246:13 + | +LL | match *y { + | -- value is immutable in match guard +... +LL | y = &true; + | ^^^^^^^^^ cannot assign + error[E0510]: cannot assign `y` in match guard - --> $DIR/match-guards-partially-borrow.rs:128:13 + --> $DIR/match-guards-partially-borrow.rs:257:13 | LL | match *y { | -- value is immutable in match guard @@ -55,7 +111,16 @@ LL | y = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `z` in match guard - --> $DIR/match-guards-partially-borrow.rs:139:13 + --> $DIR/match-guards-partially-borrow.rs:268:13 + | +LL | match z { + | - value is immutable in match guard +... +LL | z = &true; + | ^^^^^^^^^ cannot assign + +error[E0510]: cannot assign `z` in match guard + --> $DIR/match-guards-partially-borrow.rs:279:13 | LL | match z { | - value is immutable in match guard @@ -64,7 +129,16 @@ LL | z = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `a` in match guard - --> $DIR/match-guards-partially-borrow.rs:151:13 + --> $DIR/match-guards-partially-borrow.rs:291:13 + | +LL | match a { + | - value is immutable in match guard +... +LL | a = &true; + | ^^^^^^^^^ cannot assign + +error[E0510]: cannot assign `a` in match guard + --> $DIR/match-guards-partially-borrow.rs:303:13 | LL | match a { | - value is immutable in match guard @@ -73,7 +147,16 @@ LL | a = &true; | ^^^^^^^^^ cannot assign error[E0510]: cannot assign `b` in match guard - --> $DIR/match-guards-partially-borrow.rs:162:13 + --> $DIR/match-guards-partially-borrow.rs:314:13 + | +LL | match b { + | - value is immutable in match guard +... +LL | b = &true; + | ^^^^^^^^^ cannot assign + +error[E0510]: cannot assign `b` in match guard + --> $DIR/match-guards-partially-borrow.rs:325:13 | LL | match b { | - value is immutable in match guard @@ -81,7 +164,7 @@ LL | match b { LL | b = &true; | ^^^^^^^^^ cannot assign -error: aborting due to 9 previous errors +error: aborting due to 18 previous errors Some errors have detailed explanations: E0506, E0510. For more information about an error, try `rustc --explain E0506`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs index d1f685f3e7a..6f0d2b04591 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs @@ -1,6 +1,8 @@ +#![feature(if_let_guard)] + enum VecWrapper { A(Vec) } -fn foo(x: VecWrapper) -> usize { +fn if_guard(x: VecWrapper) -> usize { match x { VecWrapper::A(v) if { drop(v); false } => 1, //~^ ERROR cannot move out of `v` in pattern guard @@ -8,6 +10,15 @@ fn foo(x: VecWrapper) -> usize { } } +fn if_let_guard(x: VecWrapper) -> usize { + match x { + VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1, + //~^ ERROR cannot move out of `v` in pattern guard + VecWrapper::A(v) => v.len() + } +} + fn main() { - foo(VecWrapper::A(vec![107])); + if_guard(VecWrapper::A(vec![107])); + if_let_guard(VecWrapper::A(vec![107])); } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr index 6c3d1caf807..a749361bf30 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr @@ -1,11 +1,19 @@ error[E0507]: cannot move out of `v` in pattern guard - --> $DIR/rfc-reject-double-move-across-arms.rs:5:36 + --> $DIR/rfc-reject-double-move-across-arms.rs:7:36 | LL | VecWrapper::A(v) if { drop(v); false } => 1, | ^ move occurs because `v` has type `Vec`, which does not implement the `Copy` trait | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard -error: aborting due to previous error +error[E0507]: cannot move out of `v` in pattern guard + --> $DIR/rfc-reject-double-move-across-arms.rs:15:51 + | +LL | VecWrapper::A(v) if let Some(()) = { drop(v); None } => 1, + | ^ move occurs because `v` has type `Vec`, which does not implement the `Copy` trait + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs index 571f51c9001..827335f6a84 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs @@ -1,6 +1,8 @@ +#![feature(if_let_guard)] + struct A { a: Box } -fn foo(n: i32) { +fn if_guard(n: i32) { let x = A { a: Box::new(n) }; let _y = match x { A { a: v } if { drop(v); true } => v, @@ -9,6 +11,16 @@ fn foo(n: i32) { }; } +fn if_let_guard(n: i32) { + let x = A { a: Box::new(n) }; + let _y = match x { + A { a: v } if let Some(()) = { drop(v); Some(()) } => v, + //~^ ERROR cannot move out of `v` in pattern guard + _ => Box::new(0), + }; +} + fn main() { - foo(107); + if_guard(107); + if_let_guard(107); } diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr index d1204bc2601..9285492b224 100644 --- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr +++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr @@ -1,11 +1,19 @@ error[E0507]: cannot move out of `v` in pattern guard - --> $DIR/rfc-reject-double-move-in-first-arm.rs:6:30 + --> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30 | LL | A { a: v } if { drop(v); true } => v, | ^ move occurs because `v` has type `Box`, which does not implement the `Copy` trait | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard -error: aborting due to previous error +error[E0507]: cannot move out of `v` in pattern guard + --> $DIR/rfc-reject-double-move-in-first-arm.rs:17:45 + | +LL | A { a: v } if let Some(()) = { drop(v); Some(()) } => v, + | ^ move occurs because `v` has type `Box`, which does not implement the `Copy` trait + | + = note: variables bound in patterns cannot be moved from until after the end of the pattern guard + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. -- cgit 1.4.1-3-g733a5 From 22e9e52c842a1fe4e259e8ac74f0388afdc29e28 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 4 Dec 2022 19:38:46 +0000 Subject: Make tests unit. --- src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir | 4 ++-- src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir | 4 ++-- src/test/mir-opt/const_allocation.rs | 1 + src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir | 4 ++-- src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir | 4 ++-- src/test/mir-opt/const_allocation2.rs | 1 + src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir | 4 ++-- src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir | 4 ++-- src/test/mir-opt/const_allocation3.rs | 1 + src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff | 2 +- src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff | 2 +- src/test/mir-opt/const_prop/ref_deref.rs | 1 + src/test/mir-opt/const_prop/ref_deref_project.rs | 2 +- src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff | 2 +- src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff | 2 +- src/test/mir-opt/const_prop/slice_len.rs | 1 + 16 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir index da5a64cac65..6140fc52f65 100644 --- a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 _2 = const {alloc1: &&[(Option, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation.rs:8:5: 8:8 + // + span: $DIR/const_allocation.rs:9:5: 9:8 // + literal: Const { ty: &&[(Option, &[&str])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir index febd990681e..b2ed23c6873 100644 --- a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 _2 = const {alloc1: &&[(Option, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation.rs:8:5: 8:8 + // + span: $DIR/const_allocation.rs:9:5: 9:8 // + literal: Const { ty: &&[(Option, &[&str])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation.rs b/src/test/mir-opt/const_allocation.rs index b0fcb86fcee..91a2455eb83 100644 --- a/src/test/mir-opt/const_allocation.rs +++ b/src/test/mir-opt/const_allocation.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-endian-big // EMIT_MIR_FOR_EACH_BIT_WIDTH static FOO: &[(Option, &[&str])] = diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir index 389641f20f4..aab005c52d6 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 _2 = const {alloc1: &&[(Option, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation2.rs:5:5: 5:8 + // + span: $DIR/const_allocation2.rs:6:5: 6:8 // + literal: Const { ty: &&[(Option, &[&u8])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir index ce3848e9216..0eff9474c20 100644 --- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 _2 = const {alloc1: &&[(Option, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation2.rs:5:5: 5:8 + // + span: $DIR/const_allocation2.rs:6:5: 6:8 // + literal: Const { ty: &&[(Option, &[&u8])], val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation2.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation2.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation2.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation2.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation2.rs b/src/test/mir-opt/const_allocation2.rs index 30afedffb39..f2870aa47c5 100644 --- a/src/test/mir-opt/const_allocation2.rs +++ b/src/test/mir-opt/const_allocation2.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-endian-big // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR const_allocation2.main.ConstProp.after.mir diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir index b72519159d7..55c6db5d0ce 100644 --- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation3.rs:5:5: 5:8 + // + span: $DIR/const_allocation3.rs:6:5: 6:8 // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir index 6bd047c7d9f..27492a7fd22 100644 --- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir +++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir @@ -10,12 +10,12 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 _2 = const {alloc1: &&Packed}; // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 // mir::Constant - // + span: $DIR/const_allocation3.rs:5:5: 5:8 + // + span: $DIR/const_allocation3.rs:6:5: 6:8 // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) } _1 = (*_2); // scope 0 at $DIR/const_allocation3.rs:+1:5: +1:8 StorageDead(_2); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 StorageDead(_1); // scope 0 at $DIR/const_allocation3.rs:+1:8: +1:9 - nop; // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 + _0 = const (); // scope 0 at $DIR/const_allocation3.rs:+0:11: +2:2 return; // scope 0 at $DIR/const_allocation3.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_allocation3.rs b/src/test/mir-opt/const_allocation3.rs index ddeb32ab9a5..da3fd089b02 100644 --- a/src/test/mir-opt/const_allocation3.rs +++ b/src/test/mir-opt/const_allocation3.rs @@ -1,3 +1,4 @@ +// unit-test: ConstProp // ignore-endian-big // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR const_allocation3.main.ConstProp.after.mir diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff index 09ce67ff15d..8a73f0390e1 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff @@ -13,7 +13,7 @@ StorageLive(_2); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 // mir::Constant - // + span: $DIR/ref_deref.rs:5:6: 5:10 + // + span: $DIR/ref_deref.rs:6:6: 6:10 // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } _2 = _4; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 - _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 diff --git a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff index 902cd785031..015ec4d078c 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.PromoteTemps.diff @@ -16,7 +16,7 @@ - _2 = &_3; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + _4 = const _; // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 + // mir::Constant -+ // + span: $DIR/ref_deref.rs:5:6: 5:10 ++ // + span: $DIR/ref_deref.rs:6:6: 6:10 + // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } + _2 = &(*_4); // scope 0 at $DIR/ref_deref.rs:+1:6: +1:10 _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:+1:5: +1:10 diff --git a/src/test/mir-opt/const_prop/ref_deref.rs b/src/test/mir-opt/const_prop/ref_deref.rs index 30ec9766367..d2549c8b6aa 100644 --- a/src/test/mir-opt/const_prop/ref_deref.rs +++ b/src/test/mir-opt/const_prop/ref_deref.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop // EMIT_MIR ref_deref.main.PromoteTemps.diff // EMIT_MIR ref_deref.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs index 659c11d9b0c..2fdd4e15319 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.rs +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -1,4 +1,4 @@ -// unit-test +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop // EMIT_MIR ref_deref_project.main.PromoteTemps.diff // EMIT_MIR ref_deref_project.main.ConstProp.diff diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff index 44445731e72..9017fd18e48 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff @@ -20,7 +20,7 @@ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 // mir::Constant - // + span: $DIR/slice_len.rs:5:6: 5:19 + // + span: $DIR/slice_len.rs:6:6: 6:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff index 44445731e72..9017fd18e48 100644 --- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff @@ -20,7 +20,7 @@ StorageLive(_4); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _9 = const _; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 // mir::Constant - // + span: $DIR/slice_len.rs:5:6: 5:19 + // + span: $DIR/slice_len.rs:6:6: 6:19 // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) } _4 = _9; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 _3 = _4; // scope 0 at $DIR/slice_len.rs:+1:6: +1:19 diff --git a/src/test/mir-opt/const_prop/slice_len.rs b/src/test/mir-opt/const_prop/slice_len.rs index fa9eafa8b0b..eaaf34b960e 100644 --- a/src/test/mir-opt/const_prop/slice_len.rs +++ b/src/test/mir-opt/const_prop/slice_len.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmir-enable-passes=-SimplifyLocals-before-const-prop // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR slice_len.main.ConstProp.diff -- cgit 1.4.1-3-g733a5 From 028b4745f4db7297c5082caabff986a477662375 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 4 Dec 2022 19:20:55 +0000 Subject: Move SimplifyLocals before ConstProp. --- .../src/dead_store_elimination.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 3 +- compiler/rustc_mir_transform/src/simplify.rs | 14 +- .../const_debuginfo.main.ConstDebugInfo.diff | 90 ++++++----- ...unsafe_oob_for_slices.main.ConstProp.32bit.diff | 39 +++-- ...unsafe_oob_for_slices.main.ConstProp.64bit.diff | 39 +++-- .../invalid_constant.main.ConstProp.diff | 16 +- .../const_prop/issue_66971.main.ConstProp.diff | 3 - .../mutable_variable_no_prop.main.ConstProp.diff | 29 ++-- ...able_variable_unprop_assign.main.ConstProp.diff | 47 +++--- ...timizes_into_variable.main.ConstProp.32bit.diff | 18 +-- ...timizes_into_variable.main.ConstProp.64bit.diff | 18 +-- ...iable.main.SimplifyLocals-final.after.32bit.mir | 27 ++++ ...iable.main.SimplifyLocals-final.after.64bit.mir | 27 ++++ ...to_variable.main.SimplifyLocals.after.32bit.mir | 27 ---- ...to_variable.main.SimplifyLocals.after.64bit.mir | 27 ---- .../mir-opt/const_prop/optimizes_into_variable.rs | 2 +- .../const_prop/reify_fn_ptr.main.ConstProp.diff | 20 +-- .../const_prop_miscompile.bar.ConstProp.diff | 31 ++-- .../inherit_overflow.main.DataflowConstProp.diff | 31 ++-- .../issue_73223.main.SimplifyArmIdentity.diff | 173 ++++++++++----------- ...ssue_76432.test.SimplifyComparisonIntegral.diff | 74 +++------ ..._locals.c.SimplifyLocals-before-const-prop.diff | 33 ++++ .../mir-opt/simplify_locals.c.SimplifyLocals.diff | 33 ---- ...locals.d1.SimplifyLocals-before-const-prop.diff | 19 +++ .../mir-opt/simplify_locals.d1.SimplifyLocals.diff | 19 --- ...locals.d2.SimplifyLocals-before-const-prop.diff | 29 ++++ .../mir-opt/simplify_locals.d2.SimplifyLocals.diff | 29 ---- ...pose_addr.SimplifyLocals-before-const-prop.diff | 21 +++ ...simplify_locals.expose_addr.SimplifyLocals.diff | 21 --- ..._locals.r.SimplifyLocals-before-const-prop.diff | 31 ++++ .../mir-opt/simplify_locals.r.SimplifyLocals.diff | 31 ---- src/test/mir-opt/simplify_locals.rs | 20 +-- ...locals.t1.SimplifyLocals-before-const-prop.diff | 22 +++ .../mir-opt/simplify_locals.t1.SimplifyLocals.diff | 22 --- ...locals.t2.SimplifyLocals-before-const-prop.diff | 22 +++ .../mir-opt/simplify_locals.t2.SimplifyLocals.diff | 22 --- ...locals.t3.SimplifyLocals-before-const-prop.diff | 26 ++++ .../mir-opt/simplify_locals.t3.SimplifyLocals.diff | 26 ---- ...locals.t4.SimplifyLocals-before-const-prop.diff | 22 +++ .../mir-opt/simplify_locals.t4.SimplifyLocals.diff | 22 --- ...locals_fixedpoint.foo.SimplifyLocals-final.diff | 62 ++++++++ ...plify_locals_fixedpoint.foo.SimplifyLocals.diff | 62 -------- src/test/mir-opt/simplify_locals_fixedpoint.rs | 2 +- ...nsts.main.SimplifyLocals-before-const-prop.diff | 109 +++++++++++++ ..._removes_unused_consts.main.SimplifyLocals.diff | 109 ------------- .../simplify_locals_removes_unused_consts.rs | 4 +- ...reads.map.SimplifyLocals-before-const-prop.diff | 52 +++++++ ...used_discriminant_reads.map.SimplifyLocals.diff | 52 ------- ...ify_locals_removes_unused_discriminant_reads.rs | 4 +- ...um.process_never.SimplifyLocals-final.after.mir | 16 ++ ...ted_enum.process_never.SimplifyLocals.after.mir | 16 -- ...num.process_void.SimplifyLocals-final.after.mir | 18 +++ ...ited_enum.process_void.SimplifyLocals.after.mir | 18 --- src/test/mir-opt/uninhabited_enum.rs | 4 +- ...while_let_loops.change_loop_body.ConstProp.diff | 27 ++-- .../while_storage.while_loop.PreCodegen.after.mir | 6 +- src/test/ui/consts/invalid-union.32bit.stderr | 6 - src/test/ui/consts/invalid-union.64bit.stderr | 6 - 59 files changed, 856 insertions(+), 944 deletions(-) create mode 100644 src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir create mode 100644 src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir delete mode 100644 src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir delete mode 100644 src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir create mode 100644 src/test/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff delete mode 100644 src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff create mode 100644 src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff delete mode 100644 src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff create mode 100644 src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir delete mode 100644 src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir create mode 100644 src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir delete mode 100644 src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 42c580c63f0..09546330cec 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -71,7 +71,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS bbs[block].statements[statement_index].make_nop(); } - crate::simplify::SimplifyLocals.run_pass(tcx, body) + crate::simplify::simplify_locals(body, tcx) } pub struct DeadStoreElimination; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index ae79c2290f6..43271b013ae 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -560,6 +560,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &multiple_return_terminators::MultipleReturnTerminators, &instcombine::InstCombine, &separate_const_switch::SeparateConstSwitch, + &simplify::SimplifyLocals::new("before-const-prop"), // // FIXME(#70073): This pass is responsible for both optimization as well as some lints. &const_prop::ConstProp, @@ -578,7 +579,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &o1(remove_noop_landing_pads::RemoveNoopLandingPads), &o1(simplify::SimplifyCfg::new("final")), &nrvo::RenameReturnPlace, - &simplify::SimplifyLocals, + &simplify::SimplifyLocals::new("final"), &multiple_return_terminators::MultipleReturnTerminators, &deduplicate_blocks::DeduplicateBlocks, // Some cleanup necessary at least for LLVM and potentially other codegen backends. diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 8212a7b523b..b7aa277ae5e 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -379,9 +379,21 @@ fn save_unreachable_coverage( )); } -pub struct SimplifyLocals; +pub struct SimplifyLocals { + label: String, +} + +impl SimplifyLocals { + pub fn new(label: &str) -> SimplifyLocals { + SimplifyLocals { label: format!("SimplifyLocals-{}", label) } + } +} impl<'tcx> MirPass<'tcx> for SimplifyLocals { + fn name(&self) -> &str { + &self.label + } + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { sess.mir_opt_level() > 0 } diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index e959e1b2f2c..20bad942c8d 100644 --- a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -8,8 +8,8 @@ let mut _6: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:15: +4:16 let mut _7: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:19: +4:20 let mut _8: u8; // in scope 0 at $DIR/const_debuginfo.rs:+4:23: +4:24 - let mut _14: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 - let mut _15: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 + let mut _12: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:13: +13:16 + let mut _13: u32; // in scope 0 at $DIR/const_debuginfo.rs:+13:19: +13:22 scope 1 { - debug x => _1; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 + debug x => const 1_u8; // in scope 1 at $DIR/const_debuginfo.rs:+1:9: +1:10 @@ -29,23 +29,21 @@ scope 5 { - debug s => _9; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 + debug s => const "hello, world!"; // in scope 5 at $DIR/const_debuginfo.rs:+6:9: +6:10 - let _10: (bool, bool, u32); // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _16: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _17: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _18: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _14: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _15: bool; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _16: u32; // in scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 scope 6 { - debug f => (bool, bool, u32){ .0 => _16, .1 => _17, .2 => _18, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 - let _11: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + debug f => (bool, bool, u32){ .0 => _14, .1 => _15, .2 => _16, }; // in scope 6 at $DIR/const_debuginfo.rs:+8:9: +8:10 + let _10: std::option::Option; // in scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 scope 7 { - debug o => _11; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 - let _12: Point; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _19: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _20: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + debug o => _10; // in scope 7 at $DIR/const_debuginfo.rs:+10:9: +10:10 + let _17: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _18: u32; // in scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 scope 8 { - debug p => Point{ .0 => _19, .1 => _20, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 - let _13: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug p => Point{ .0 => _17, .1 => _18, }; // in scope 8 at $DIR/const_debuginfo.rs:+12:9: +12:10 + let _11: u32; // in scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 scope 9 { -- debug a => _13; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 +- debug a => _11; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 + debug a => const 64_u32; // in scope 9 at $DIR/const_debuginfo.rs:+13:9: +13:10 } } @@ -83,41 +81,41 @@ // mir::Constant // + span: $DIR/const_debuginfo.rs:14:13: 14:28 // + literal: Const { ty: &str, val: Value(Slice(..)) } + StorageLive(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + StorageLive(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 StorageLive(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - StorageLive(_17); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 - StorageLive(_18); // scope 5 at $DIR/const_debuginfo.rs:+8:9: +8:10 + Deinit(_14); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + Deinit(_15); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 Deinit(_16); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - Deinit(_17); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - Deinit(_18); // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - _16 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - _17 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - _18 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 - StorageLive(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 - Deinit(_11); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 - ((_11 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 - discriminant(_11) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 - StorageLive(_19); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - StorageLive(_20); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 - Deinit(_19); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - Deinit(_20); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - _19 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - _20 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 - StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 - StorageLive(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 - _14 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 - StorageLive(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 - _15 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 - _13 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 - StorageDead(_15); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 - StorageDead(_14); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + _14 = const true; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _15 = const false; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + _16 = const 123_u32; // scope 5 at $DIR/const_debuginfo.rs:+8:13: +8:34 + StorageLive(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:9: +10:10 + Deinit(_10); // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + ((_10 as Some).0: u16) = const 99_u16; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + discriminant(_10) = 1; // scope 6 at $DIR/const_debuginfo.rs:+10:13: +10:24 + StorageLive(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + StorageLive(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:9: +12:10 + Deinit(_17); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + Deinit(_18); // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _17 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + _18 = const 32_u32; // scope 7 at $DIR/const_debuginfo.rs:+12:13: +12:35 + StorageLive(_11); // scope 8 at $DIR/const_debuginfo.rs:+13:9: +13:10 + StorageLive(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + _12 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:16 + StorageLive(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _13 = const 32_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:19: +13:22 + _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 + StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 + StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 nop; // scope 0 at $DIR/const_debuginfo.rs:+0:11: +14:2 - StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_19); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_20); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_11); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_17); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_18); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_10); // scope 6 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_14); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 + StorageDead(_15); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_16); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_17); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 - StorageDead(_18); // scope 5 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_9); // scope 4 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_4); // scope 3 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_3); // scope 2 at $DIR/const_debuginfo.rs:+14:1: +14:2 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index c27b19679a8..567f6ede8bc 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -6,17 +6,16 @@ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 - let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 scope 1 { debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 scope 2 { - let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + let _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 scope 3 { - debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + debug _b => _4; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 } } } @@ -25,30 +24,30 @@ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } - _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _3 = _8; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 - StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 - StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageLive(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 } bb1: { - _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 - StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 } diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index c27b19679a8..567f6ede8bc 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -6,17 +6,16 @@ let _1: *const [i32]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 let mut _2: *const [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 let _3: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - let _4: [i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:26: +1:35 - let _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - let mut _7: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _8: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - let mut _9: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + let _5: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + let mut _6: usize; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _7: bool; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + let mut _8: &[i32; 3]; // in scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 scope 1 { debug a => _1; // in scope 1 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 scope 2 { - let _5: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + let _4: i32; // in scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 scope 3 { - debug _b => _5; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + debug _b => _4; // in scope 3 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 } } } @@ -25,30 +24,30 @@ StorageLive(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:9: +1:10 StorageLive(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageLive(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 - _9 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _8 = const _; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 // mir::Constant // + span: $DIR/bad_op_unsafe_oob_for_slices.rs:5:25: 5:35 // + literal: Const { ty: &[i32; 3], val: Unevaluated(main, [], Some(promoted[0])) } - _3 = _9; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 + _3 = _8; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _2 = &raw const (*_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 _1 = move _2 as *const [i32] (Pointer(Unsize)); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:25: +1:35 StorageDead(_2); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:34: +1:35 StorageDead(_3); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+1:35: +1:36 - StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 - StorageLive(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _6 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 - _7 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- _8 = Lt(_6, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ _8 = Lt(const 3_usize, _7); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 -+ assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageLive(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:13: +3:15 + StorageLive(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _5 = const 3_usize; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:23: +3:24 + _6 = Len((*_1)); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- _7 = Lt(_5, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 +- assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, _5) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ _7 = Lt(const 3_usize, _6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 ++ assert(move _7, "index out of bounds: the length is {} but the index is {}", move _6, const 3_usize) -> bb1; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 } bb1: { - _5 = (*_1)[_6]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 - StorageDead(_6); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 + _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 + StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 - StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 + StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 } diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 67a4dc3c092..8dd0a08e319 100644 --- a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -7,8 +7,6 @@ let mut _2: main::InvalidChar; // in scope 0 at $DIR/invalid_constant.rs:+6:34: +6:63 let mut _4: E; // in scope 0 at $DIR/invalid_constant.rs:+13:25: +13:59 let mut _5: main::InvalidTag; // in scope 0 at $DIR/invalid_constant.rs:+13:34: +13:55 - let mut _7: Empty; // in scope 0 at $DIR/invalid_constant.rs:+20:35: +20:73 - let mut _8: main::NoVariants; // in scope 0 at $DIR/invalid_constant.rs:+20:44: +20:65 scope 1 { debug _invalid_char => _1; // in scope 1 at $DIR/invalid_constant.rs:+6:9: +6:22 let _3: [E; 1]; // in scope 1 at $DIR/invalid_constant.rs:+13:9: +13:21 @@ -17,9 +15,9 @@ let _6: [Empty; 1]; // in scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 scope 5 { debug _enum_without_variants => _6; // in scope 5 at $DIR/invalid_constant.rs:+20:9: +20:31 - let _9: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + let _7: main::Str<"���">; // in scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 scope 7 { - debug _non_utf8_str => _9; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22 + debug _non_utf8_str => _7; // in scope 7 at $DIR/invalid_constant.rs:+24:9: +24:22 } } scope 6 { @@ -57,17 +55,11 @@ StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60 StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61 StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 - StorageLive(_7); // scope 3 at $DIR/invalid_constant.rs:+20:35: +20:73 - StorageLive(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 - Deinit(_8); // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 - (_8.0: u32) = const 0_u32; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:65 nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71 nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74 - StorageDead(_7); // scope 3 at $DIR/invalid_constant.rs:+20:73: +20:74 - StorageDead(_8); // scope 3 at $DIR/invalid_constant.rs:+20:74: +20:75 - StorageLive(_9); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 + StorageLive(_7); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2 - StorageDead(_9); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2 + StorageDead(_7); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_1); // scope 0 at $DIR/invalid_constant.rs:+27:1: +27:2 diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff index 7d8e647cbce..1c07d5ec0a8 100644 --- a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff @@ -5,18 +5,15 @@ let mut _0: (); // return place in scope 0 at $DIR/issue_66971.rs:+0:11: +0:11 let _1: (); // in scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 let mut _2: ((), u8, u8); // in scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 - let mut _3: (); // in scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 bb0: { StorageLive(_1); // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 StorageLive(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 - StorageLive(_3); // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 nop; // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 Deinit(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 nop; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 - StorageDead(_3); // scope 0 at $DIR/issue_66971.rs:+1:21: +1:22 _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 // mir::Constant // + span: $DIR/issue_66971.rs:17:5: 17:11 diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff index eb3a7bc96d8..b34df3b877e 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff @@ -4,39 +4,36 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +0:11 let mut _1: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 - let _2: (); // in scope 0 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 - let mut _3: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 - let mut _4: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + let mut _2: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + let mut _3: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 scope 1 { debug x => _1; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 - let _5: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + let _4: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 scope 2 { } scope 3 { - debug y => _5; // in scope 3 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + debug y => _4; // in scope 3 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 } } bb0: { StorageLive(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:9: +1:14 _1 = const 42_u32; // scope 0 at $DIR/mutable_variable_no_prop.rs:+1:17: +1:19 - StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 + StorageLive(_2); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 - StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 - _4 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _3 = const {alloc1: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 // mir::Constant // + span: $DIR/mutable_variable_no_prop.rs:10:13: 10:19 // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) } - _3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 - _1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19 - StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19 - StorageDead(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20 + _2 = (*_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:13: +3:19 + _1 = move _2; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19 + StorageDead(_2); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20 nop; // scope 2 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 - StorageDead(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:+4:5: +4:6 - StorageLive(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 - _5 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14 + StorageLive(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 + _4 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14 nop; // scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +6:2 - StorageDead(_5); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 + StorageDead(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 return; // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:2: +6:2 } diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff index 2e4b0e79e9f..7485a0f9176 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -4,20 +4,19 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +0:11 let _1: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 - let mut _3: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + let mut _2: i32; // in scope 0 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 scope 1 { debug a => _1; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+1:9: +1:10 - let mut _2: (i32, i32); // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let mut _5: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 let mut _6: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 - let mut _7: i32; // in scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 scope 2 { - debug x => (i32, i32){ .0 => _6, .1 => _7, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 - let _4: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + debug x => (i32, i32){ .0 => _5, .1 => _6, }; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + let _3: i32; // in scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 scope 3 { - debug y => _4; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 - let _5: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + debug y => _3; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + let _4: i32; // in scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 scope 4 { - debug z => _5; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 + debug z => _4; // in scope 4 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 } } } @@ -32,26 +31,26 @@ } bb1: { + StorageLive(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 StorageLive(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 - StorageLive(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:9: +2:14 + Deinit(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 Deinit(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - Deinit(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - _6 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - _7 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 - StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - _3 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - _7 = move _3; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 - StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 - StorageLive(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 - _4 = _7; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 - StorageLive(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 -- _5 = _6; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 -+ _5 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 + _5 = const 1_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + _6 = const 2_i32; // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+2:29: +2:35 + StorageLive(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _2 = _1; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + _6 = move _2; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:5: +3:12 + StorageDead(_2); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+3:11: +3:12 + StorageLive(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:9: +4:10 + _3 = _6; // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+4:13: +4:16 + StorageLive(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 +- _4 = _5; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 ++ _4 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2 - StorageDead(_5); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 - StorageDead(_4); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 + StorageDead(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_6); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 - StorageDead(_7); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 return; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+6:2: +6:2 } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff index 7e8ebd31ad1..6e32c65921f 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -9,9 +9,7 @@ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 - let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -53,16 +51,12 @@ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -- _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = _9; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff index 7e8ebd31ad1..6e32c65921f 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -9,9 +9,7 @@ let _5: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:32: +2:33 let mut _6: usize; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 let mut _7: bool; // in scope 0 at $DIR/optimizes_into_variable.rs:+2:13: +2:34 - let mut _9: Point; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - let mut _10: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - let mut _11: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + let mut _9: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 let _3: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 @@ -53,16 +51,12 @@ StorageDead(_5); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageDead(_4); // scope 1 at $DIR/optimizes_into_variable.rs:+2:34: +2:35 StorageLive(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageLive(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - StorageLive(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - Deinit(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - Deinit(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _10 = const 12_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - _11 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 -- _8 = _11; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + StorageLive(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + Deinit(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 + _9 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 +- _8 = _9; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 - StorageDead(_10); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - StorageDead(_11); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 + StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir new file mode 100644 index 00000000000..d926b9df733 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir new file mode 100644 index 00000000000..d926b9df733 --- /dev/null +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -0,0 +1,27 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + scope 3 { + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir deleted file mode 100644 index 75cea8ad2ce..00000000000 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.32bit.mir +++ /dev/null @@ -1,27 +0,0 @@ -// MIR for `main` after SimplifyLocals - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir b/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir deleted file mode 100644 index 75cea8ad2ce..00000000000 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals.after.64bit.mir +++ /dev/null @@ -1,27 +0,0 @@ -// MIR for `main` after SimplifyLocals - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageLive(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - StorageDead(_3); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.rs b/src/test/mir-opt/const_prop/optimizes_into_variable.rs index 02566654818..abea07e2025 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.rs +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.rs @@ -9,7 +9,7 @@ struct Point { // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR optimizes_into_variable.main.ScalarReplacementOfAggregates.diff // EMIT_MIR optimizes_into_variable.main.ConstProp.diff -// EMIT_MIR optimizes_into_variable.main.SimplifyLocals.after.mir +// EMIT_MIR optimizes_into_variable.main.SimplifyLocals-final.after.mir // EMIT_MIR optimizes_into_variable.main.PreCodegen.after.mir fn main() { let x = 2 + 2; diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff index 237a6f94aa7..b93e9788a46 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff @@ -3,25 +3,21 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +0:11 - let mut _1: *const fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 - let mut _2: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - let mut _3: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + let mut _1: usize; // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + let mut _2: fn(); // in scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 scope 1 { } bb0: { - StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 - StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - StorageLive(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 - _3 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + StorageLive(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageLive(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 + _2 = main as fn() (Pointer(ReifyFnPointer)); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:17 // mir::Constant // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17 // + literal: Const { ty: fn() {main}, val: Value() } - _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 - StorageDead(_3); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 - _1 = move _2 as *const fn() (PointerFromExposedAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:41 - StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 - StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:41: +1:42 + _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 + StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 + StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 nop; // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2 return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2 } diff --git a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff index 459da2e3358..46df4744012 100644 --- a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff +++ b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff @@ -4,16 +4,15 @@ fn bar() -> () { let mut _0: (); // return place in scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +0:10 let mut _1: (i32,); // in scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 - let _2: (); // in scope 0 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 - let mut _3: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 - let mut _5: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 + let mut _2: *mut i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + let mut _4: i32; // in scope 0 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 scope 1 { debug v => _1; // in scope 1 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 - let _4: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + let _3: bool; // in scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 scope 2 { } scope 3 { - debug y => _4; // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + debug y => _3; // in scope 3 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 } } @@ -21,20 +20,18 @@ StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14 Deinit(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 (_1.0: i32) = const 1_i32; // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21 - StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 - StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 - _3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 - (*_3) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26 - StorageDead(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27 + StorageLive(_2); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + _2 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 + (*_2) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26 + StorageDead(_2); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27 nop; // scope 2 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 - StorageDead(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+4:5: +4:6 - StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 - StorageLive(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 - _5 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18 - _4 = Eq(move _5, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25 - StorageDead(_5); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25 + StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 + StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 + _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18 + _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25 + StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25 nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +6:2 - StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 + StorageDead(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 return; // scope 0 at $DIR/const_prop_miscompile.rs:+6:2: +6:2 } diff --git a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff index bf4557ed3d9..fe5be7d8a63 100644 --- a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff @@ -5,39 +5,34 @@ let mut _0: (); // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11 let mut _1: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 let mut _2: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - let mut _3: u8; // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 scope 1 { } scope 2 (inlined ::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47 - debug self => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - debug other => _3; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug self => _1; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + debug other => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _3: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - let mut _5: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - let mut _6: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + let mut _5: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL } bb0: { StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _1 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - _2 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - StorageLive(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - _3 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + _2 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _3 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL StorageLive(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - _4 = const u8::MAX; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - _5 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - _6 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - assert(!move (_6.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _4 = const 1_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + _5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL + assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL } bb1: { -- _1 = move (_6.0: u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL -+ _1 = const 0_u8; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL StorageDead(_4); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48 + StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 nop; // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2 return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 } diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff index 17b81633991..a67b49ee608 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -7,41 +7,36 @@ let mut _2: std::option::Option; // in scope 0 at $DIR/issue_73223.rs:+1:23: +1:30 let mut _3: isize; // in scope 0 at $DIR/issue_73223.rs:+2:9: +2:16 let _4: i32; // in scope 0 at $DIR/issue_73223.rs:+2:14: +2:15 - let mut _5: !; // in scope 0 at $DIR/issue_73223.rs:+3:17: +3:23 - let mut _7: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27 - let _8: (); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _9: (&i32, &i32); // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _10: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _11: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _12: i32; // in scope 0 at $DIR/issue_73223.rs:+7:23: +7:24 - let mut _15: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _16: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _17: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _18: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _19: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _21: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _22: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _23: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _6: i32; // in scope 0 at $DIR/issue_73223.rs:+6:22: +6:27 + let mut _7: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _8: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _11: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _12: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _13: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _14: i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _16: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _17: core::panicking::AssertKind; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _18: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _19: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _20: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _21: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: std::option::Option>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _24: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL let mut _25: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _26: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _27: std::option::Option>; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _29: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _30: &i32; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 1 { debug split => _1; // in scope 1 at $DIR/issue_73223.rs:+1:9: +1:14 - let _6: std::option::Option; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 + let _5: std::option::Option; // in scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 scope 3 { - debug _prev => _6; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14 - let _13: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _14: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _28: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug _prev => _5; // in scope 3 at $DIR/issue_73223.rs:+6:9: +6:14 + let _9: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _10: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _23: &i32; // in scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 4 { - debug left_val => _13; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - debug right_val => _14; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let _20: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug left_val => _9; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug right_val => _10; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let _15: core::panicking::AssertKind; // in scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL scope 5 { - debug kind => _20; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + debug kind => _15; // in scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } } } @@ -77,70 +72,69 @@ _1 = _4; // scope 2 at $DIR/issue_73223.rs:+2:20: +2:21 StorageDead(_4); // scope 0 at $DIR/issue_73223.rs:+2:20: +2:21 StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7 - StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 - StorageLive(_7); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 - _7 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 - Deinit(_6); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 - ((_6 as Some).0: i32) = move _7; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 - discriminant(_6) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 - StorageDead(_7); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28 + StorageLive(_5); // scope 1 at $DIR/issue_73223.rs:+6:9: +6:14 + StorageLive(_6); // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + _6 = _1; // scope 1 at $DIR/issue_73223.rs:+6:22: +6:27 + Deinit(_5); // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + ((_5 as Some).0: i32) = move _6; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + discriminant(_5) = 1; // scope 1 at $DIR/issue_73223.rs:+6:17: +6:28 + StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+6:27: +6:28 + StorageLive(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _7 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageLive(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _10 = &_1; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _28 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _23 = const _; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: &i32, val: Unevaluated(main, [], Some(promoted[0])) } - _11 = _28; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _29 = move _10; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _30 = move _11; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_11); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _13 = _29; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _14 = _30; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _17 = (*_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _18 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _16 = Eq(move _17, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_18); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_17); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _15 = Not(move _16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_16); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - switchInt(move _15) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _8 = _23; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _24 = move _7; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _25 = move _8; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_7); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _9 = _24; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _10 = _25; // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _13 = (*_9); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _14 = const 1_i32; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _12 = Eq(move _13, const 1_i32); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_14); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _11 = Not(move _12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + switchInt(move _11) -> [0: bb5, otherwise: bb4]; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } bb4: { - StorageLive(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_20); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_20) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _22 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_15) = 0; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_16); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_17); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _17 = const core::panicking::AssertKind::Eq; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: core::panicking::AssertKind, val: Value(Scalar(0x00)) } - StorageLive(_23); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_24); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _24 = _13; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _23 = _24; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_25); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_26); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _26 = _14; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _25 = _26; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageLive(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - Deinit(_27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - discriminant(_27) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _21 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _23, move _25, move _27); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_18); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_19); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _19 = _9; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _18 = _19; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_20); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_21); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _21 = _10; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _20 = _21; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + Deinit(_22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + discriminant(_22) = 0; // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + _16 = core::panicking::assert_failed::(const core::panicking::AssertKind::Eq, move _18, move _20, move _22); // scope 5 at $SRC_DIR/core/src/macros/mod.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL // + literal: Const { ty: for<'a, 'b, 'c> fn(core::panicking::AssertKind, &'a i32, &'b i32, Option>) -> ! {core::panicking::assert_failed::}, val: Value() } @@ -151,14 +145,13 @@ bb5: { nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_15); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_14); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_13); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_29); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_30); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - StorageDead(_8); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageDead(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL nop; // scope 0 at $DIR/issue_73223.rs:+0:11: +8:2 - StorageDead(_6); // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2 + StorageDead(_5); // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2 StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2 return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2 } diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index e97b46f6ecc..483d16775df 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -11,26 +11,19 @@ let mut _6: T; // in scope 0 at $DIR/issue_76432.rs:+1:21: +1:22 let mut _7: T; // in scope 0 at $DIR/issue_76432.rs:+1:24: +1:25 let mut _8: T; // in scope 0 at $DIR/issue_76432.rs:+1:27: +1:28 - let _9: [*const T; 3]; // in scope 0 at $DIR/issue_76432.rs:+2:5: +5:6 + let mut _9: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 let mut _10: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 - let mut _11: usize; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 - let mut _12: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 - let mut _16: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52 - let mut _17: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:38: +3:52 - let mut _18: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68 - let mut _19: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:54: +3:68 - let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 - let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84 - let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL + let mut _11: bool; // in scope 0 at $DIR/issue_76432.rs:+3:9: +3:33 + let mut _15: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL scope 1 { debug v => _2; // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10 - let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 - let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 - let _15: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + let _12: &T; // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + let _13: &T; // in scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + let _14: &T; // in scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 scope 2 { - debug v1 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 - debug v2 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 - debug v3 => _15; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 + debug v1 => _12; // in scope 2 at $DIR/issue_76432.rs:+3:10: +3:16 + debug v2 => _13; // in scope 2 at $DIR/issue_76432.rs:+3:18: +3:24 + debug v3 => _14; // in scope 2 at $DIR/issue_76432.rs:+3:26: +3:32 } } @@ -54,18 +47,17 @@ _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29 StorageDead(_3); // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29 StorageDead(_4); // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30 - StorageLive(_9); // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6 - _10 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 - _11 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 -- _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 -- switchInt(move _12) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _9 = Len((*_2)); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + _10 = const 3_usize; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- _11 = Eq(move _9, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 +- switchInt(move _11) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 + nop; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 -+ switchInt(move _10) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 ++ switchInt(move _9) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33 } bb1: { - StorageLive(_22); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL - _22 = core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + StorageLive(_15); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + _15 = core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/panic.rs:LL:COL // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value() } @@ -75,35 +67,15 @@ } bb2: { - StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 - _13 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 - StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 - _14 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 - StorageLive(_15); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 - _15 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 - StorageLive(_16); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 - StorageLive(_17); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 - _17 = &raw const (*_13); // scope 2 at $DIR/issue_76432.rs:+3:38: +3:40 - _16 = _17; // scope 2 at $DIR/issue_76432.rs:+3:38: +3:52 - StorageLive(_18); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 - StorageLive(_19); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 - _19 = &raw const (*_14); // scope 2 at $DIR/issue_76432.rs:+3:54: +3:56 - _18 = _19; // scope 2 at $DIR/issue_76432.rs:+3:54: +3:68 - StorageLive(_20); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 - StorageLive(_21); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 - _21 = &raw const (*_15); // scope 2 at $DIR/issue_76432.rs:+3:70: +3:72 - _20 = _21; // scope 2 at $DIR/issue_76432.rs:+3:70: +3:84 - _9 = [move _16, move _18, move _20]; // scope 2 at $DIR/issue_76432.rs:+3:37: +3:85 - StorageDead(_21); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_20); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_19); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_18); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_17); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_16); // scope 2 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_15); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 + StorageLive(_12); // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + _12 = &(*_2)[0 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:10: +3:16 + StorageLive(_13); // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + _13 = &(*_2)[1 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:18: +3:24 + StorageLive(_14); // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 + _14 = &(*_2)[2 of 3]; // scope 1 at $DIR/issue_76432.rs:+3:26: +3:32 StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 - StorageDead(_9); // scope 1 at $DIR/issue_76432.rs:+5:6: +5:7 + StorageDead(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 nop; // scope 0 at $DIR/issue_76432.rs:+0:44: +6:2 StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..1be27e96397 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.c.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,33 @@ +- // MIR for `c` before SimplifyLocals-before-const-prop ++ // MIR for `c` after SimplifyLocals-before-const-prop + + fn c() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 + let _1: [u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 +- let mut _2: &[u8]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 +- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 +- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 + scope 1 { + debug bytes => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 + scope 2 { + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 + _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:26 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageLive(_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _4 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _3 = &(*_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 +- StorageDead(_3); // scope 1 at $DIR/simplify_locals.rs:+3:25: +3:26 +- StorageDead(_4); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 +- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +4:2 + StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+4:1: +4:2 + return; // scope 0 at $DIR/simplify_locals.rs:+4:2: +4:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff deleted file mode 100644 index 1a5143aa0fa..00000000000 --- a/src/test/mir-opt/simplify_locals.c.SimplifyLocals.diff +++ /dev/null @@ -1,33 +0,0 @@ -- // MIR for `c` before SimplifyLocals -+ // MIR for `c` after SimplifyLocals - - fn c() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 - let _1: [u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 -- let mut _2: &[u8]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 -- let mut _3: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 -- let _4: &[u8; 10]; // in scope 0 at $DIR/simplify_locals.rs:+3:20: +3:26 - scope 1 { - debug bytes => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 - scope 2 { - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 - _1 = [const 0_u8; 10]; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:26 -- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- StorageLive(_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- _4 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- _3 = &(*_4); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- _2 = move _3 as &[u8] (Pointer(Unsize)); // scope 1 at $DIR/simplify_locals.rs:+3:20: +3:26 -- StorageDead(_3); // scope 1 at $DIR/simplify_locals.rs:+3:25: +3:26 -- StorageDead(_4); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 -- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:26: +3:27 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +4:2 - StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+4:1: +4:2 - return; // scope 0 at $DIR/simplify_locals.rs:+4:2: +4:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..98173803018 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,19 @@ +- // MIR for `d1` before SimplifyLocals-before-const-prop ++ // MIR for `d1` after SimplifyLocals-before-const-prop + + fn d1() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- discriminant(_1) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff deleted file mode 100644 index 6426bf926a4..00000000000 --- a/src/test/mir-opt/simplify_locals.d1.SimplifyLocals.diff +++ /dev/null @@ -1,19 +0,0 @@ -- // MIR for `d1` before SimplifyLocals -+ // MIR for `d1` after SimplifyLocals - - fn d1() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 -- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 - scope 1 { - } - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 -- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 -- discriminant(_1) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:13: +2:17 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..b152dc8cca3 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,29 @@ +- // MIR for `d2` before SimplifyLocals-before-const-prop ++ // MIR for `d2` after SimplifyLocals-before-const-prop + + fn d2() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- let mut _2: (i32, E); // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- let mut _3: E; // in scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- discriminant(_1) = 1; // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 +- StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- Deinit(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- discriminant(_3) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 +- Deinit(_2); // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- (_2.1: E) = move _3; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 +- (_2.1: E) = move _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:26 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:25: +2:26 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:26: +2:27 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff deleted file mode 100644 index db5ab182d6f..00000000000 --- a/src/test/mir-opt/simplify_locals.d2.SimplifyLocals.diff +++ /dev/null @@ -1,29 +0,0 @@ -- // MIR for `d2` before SimplifyLocals -+ // MIR for `d2` after SimplifyLocals - - fn d2() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 -- let mut _1: E; // in scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 -- let mut _2: (i32, E); // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 -- let mut _3: E; // in scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 -- Deinit(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 -- discriminant(_1) = 1; // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:26 -- StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 -- StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 -- Deinit(_3); // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 -- discriminant(_3) = 0; // scope 0 at $DIR/simplify_locals.rs:+2:11: +2:15 -- Deinit(_2); // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 -- (_2.0: i32) = const 10_i32; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 -- (_2.1: E) = move _3; // scope 0 at $DIR/simplify_locals.rs:+2:6: +2:16 -- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 -- (_2.1: E) = move _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:26 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:25: +2:26 -- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:26: +2:27 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..9ca1dbbd071 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,21 @@ +- // MIR for `expose_addr` before SimplifyLocals-before-const-prop ++ // MIR for `expose_addr` after SimplifyLocals-before-const-prop + + fn expose_addr(_1: *const usize) -> () { + debug p => _1; // in scope 0 at $DIR/simplify_locals.rs:+0:16: +0:17 + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:33: +0:33 + let _2: usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + let mut _3: *const usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 + _3 = _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 + _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 + StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:33: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff deleted file mode 100644 index c707b0da07e..00000000000 --- a/src/test/mir-opt/simplify_locals.expose_addr.SimplifyLocals.diff +++ /dev/null @@ -1,21 +0,0 @@ -- // MIR for `expose_addr` before SimplifyLocals -+ // MIR for `expose_addr` after SimplifyLocals - - fn expose_addr(_1: *const usize) -> () { - debug p => _1; // in scope 0 at $DIR/simplify_locals.rs:+0:16: +0:17 - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:33: +0:33 - let _2: usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 - let mut _3: *const usize; // in scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 - - bb0: { - StorageLive(_2); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 - StorageLive(_3); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 - _3 = _1; // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:6 - _2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:15 - StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 - StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:15: +2:16 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:33: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..19dacb427f5 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.r.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,31 @@ +- // MIR for `r` before SimplifyLocals-before-const-prop ++ // MIR for `r` after SimplifyLocals-before-const-prop + + fn r() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 + let mut _1: i32; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 +- let mut _2: &i32; // in scope 0 at $DIR/simplify_locals.rs:+3:13: +3:15 +- let mut _3: &mut i32; // in scope 0 at $DIR/simplify_locals.rs:+4:13: +4:19 + scope 1 { + debug a => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 + scope 2 { + scope 3 { + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 + _1 = const 1_i32; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:18 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 +- _2 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 +- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:15: +3:16 +- StorageLive(_3); // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 +- _3 = &mut _1; // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 +- StorageDead(_3); // scope 2 at $DIR/simplify_locals.rs:+4:19: +4:20 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +5:2 + StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_locals.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff deleted file mode 100644 index ff6eb2cff5e..00000000000 --- a/src/test/mir-opt/simplify_locals.r.SimplifyLocals.diff +++ /dev/null @@ -1,31 +0,0 @@ -- // MIR for `r` before SimplifyLocals -+ // MIR for `r` after SimplifyLocals - - fn r() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:8: +0:8 - let mut _1: i32; // in scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 -- let mut _2: &i32; // in scope 0 at $DIR/simplify_locals.rs:+3:13: +3:15 -- let mut _3: &mut i32; // in scope 0 at $DIR/simplify_locals.rs:+4:13: +4:19 - scope 1 { - debug a => _1; // in scope 1 at $DIR/simplify_locals.rs:+1:9: +1:14 - scope 2 { - scope 3 { - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+1:9: +1:14 - _1 = const 1_i32; // scope 0 at $DIR/simplify_locals.rs:+1:17: +1:18 -- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 -- _2 = &_1; // scope 1 at $DIR/simplify_locals.rs:+3:13: +3:15 -- StorageDead(_2); // scope 1 at $DIR/simplify_locals.rs:+3:15: +3:16 -- StorageLive(_3); // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 -- _3 = &mut _1; // scope 2 at $DIR/simplify_locals.rs:+4:13: +4:19 -- StorageDead(_3); // scope 2 at $DIR/simplify_locals.rs:+4:19: +4:20 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:8: +5:2 - StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+5:1: +5:2 - return; // scope 0 at $DIR/simplify_locals.rs:+5:2: +5:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.rs b/src/test/mir-opt/simplify_locals.rs index 89d9391f832..7bbc0481c68 100644 --- a/src/test/mir-opt/simplify_locals.rs +++ b/src/test/mir-opt/simplify_locals.rs @@ -1,4 +1,4 @@ -// unit-test: SimplifyLocals +// unit-test: SimplifyLocals-before-const-prop #![feature(thread_local)] @@ -9,26 +9,26 @@ enum E { B, } -// EMIT_MIR simplify_locals.c.SimplifyLocals.diff +// EMIT_MIR simplify_locals.c.SimplifyLocals-before-const-prop.diff fn c() { let bytes = [0u8; 10]; // Unused cast let _: &[u8] = &bytes; } -// EMIT_MIR simplify_locals.d1.SimplifyLocals.diff +// EMIT_MIR simplify_locals.d1.SimplifyLocals-before-const-prop.diff fn d1() { // Unused set discriminant let _ = E::A; } -// EMIT_MIR simplify_locals.d2.SimplifyLocals.diff +// EMIT_MIR simplify_locals.d2.SimplifyLocals-before-const-prop.diff fn d2() { // Unused set discriminant {(10, E::A)}.1 = E::B; } -// EMIT_MIR simplify_locals.r.SimplifyLocals.diff +// EMIT_MIR simplify_locals.r.SimplifyLocals-before-const-prop.diff fn r() { let mut a = 1; // Unused references @@ -38,31 +38,31 @@ fn r() { #[thread_local] static mut X: u32 = 0; -// EMIT_MIR simplify_locals.t1.SimplifyLocals.diff +// EMIT_MIR simplify_locals.t1.SimplifyLocals-before-const-prop.diff fn t1() { // Unused thread local unsafe { X }; } -// EMIT_MIR simplify_locals.t2.SimplifyLocals.diff +// EMIT_MIR simplify_locals.t2.SimplifyLocals-before-const-prop.diff fn t2() { // Unused thread local unsafe { &mut X }; } -// EMIT_MIR simplify_locals.t3.SimplifyLocals.diff +// EMIT_MIR simplify_locals.t3.SimplifyLocals-before-const-prop.diff fn t3() { // Unused thread local unsafe { *&mut X }; } -// EMIT_MIR simplify_locals.t4.SimplifyLocals.diff +// EMIT_MIR simplify_locals.t4.SimplifyLocals-before-const-prop.diff fn t4() -> u32 { // Used thread local unsafe { X + 1 } } -// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals.diff +// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff fn expose_addr(p: *const usize) { // Used pointer to address cast. Has a side effect of exposing the provenance. p as usize; diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..1b2e1158e45 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t1` before SimplifyLocals-before-const-prop ++ // MIR for `t1` after SimplifyLocals-before-const-prop + + fn t1() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff deleted file mode 100644 index 49db7747963..00000000000 --- a/src/test/mir-opt/simplify_locals.t1.SimplifyLocals.diff +++ /dev/null @@ -1,22 +0,0 @@ -- // MIR for `t1` before SimplifyLocals -+ // MIR for `t1` after SimplifyLocals - - fn t1() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 -- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 -- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 - scope 1 { - } - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:17 -- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 -- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 -- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 -- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:17: +2:18 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..cf019357be7 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t2` before SimplifyLocals-before-const-prop ++ // MIR for `t2` after SimplifyLocals-before-const-prop + + fn t2() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:20 +- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:19: +2:20 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:22 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 +- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 +- _1 = &mut (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:20 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff deleted file mode 100644 index e3f4ae3701b..00000000000 --- a/src/test/mir-opt/simplify_locals.t2.SimplifyLocals.diff +++ /dev/null @@ -1,22 +0,0 @@ -- // MIR for `t2` before SimplifyLocals -+ // MIR for `t2` after SimplifyLocals - - fn t2() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 -- let _1: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:20 -- let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:19: +2:20 - scope 1 { - } - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:22 -- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 -- _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:19: +2:20 -- _1 = &mut (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:20 -- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:22: +2:23 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..90ee215808c --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,26 @@ +- // MIR for `t3` before SimplifyLocals-before-const-prop ++ // MIR for `t3` after SimplifyLocals-before-const-prop + + fn t3() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 +- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:21 +- let mut _2: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:15: +2:21 +- let mut _3: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:20: +2:21 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:23 +- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 +- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 +- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 +- _2 = &mut (*_3); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 +- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:21 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 + _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff deleted file mode 100644 index f1ce7778e19..00000000000 --- a/src/test/mir-opt/simplify_locals.t3.SimplifyLocals.diff +++ /dev/null @@ -1,26 +0,0 @@ -- // MIR for `t3` before SimplifyLocals -+ // MIR for `t3` after SimplifyLocals - - fn t3() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals.rs:+0:9: +0:9 -- let _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:21 -- let mut _2: &mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:15: +2:21 -- let mut _3: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:20: +2:21 - scope 1 { - } - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals.rs:+2:5: +2:23 -- StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 -- StorageLive(_3); // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 -- _3 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:20: +2:21 -- _2 = &mut (*_3); // scope 1 at $DIR/simplify_locals.rs:+2:15: +2:21 -- _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:21 -- StorageDead(_3); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 -- StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals.rs:+2:23: +2:24 - _0 = const (); // scope 0 at $DIR/simplify_locals.rs:+0:9: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..9add9a6c5e0 --- /dev/null +++ b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,22 @@ +- // MIR for `t4` before SimplifyLocals-before-const-prop ++ // MIR for `t4` after SimplifyLocals-before-const-prop + + fn t4() -> u32 { + let mut _0: u32; // return place in scope 0 at $DIR/simplify_locals.rs:+0:12: +0:15 + let mut _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 + _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:19 + StorageDead(_1); // scope 1 at $DIR/simplify_locals.rs:+2:18: +2:19 + StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+3:1: +3:2 + return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff deleted file mode 100644 index 71cf9594b9e..00000000000 --- a/src/test/mir-opt/simplify_locals.t4.SimplifyLocals.diff +++ /dev/null @@ -1,22 +0,0 @@ -- // MIR for `t4` before SimplifyLocals -+ // MIR for `t4` after SimplifyLocals - - fn t4() -> u32 { - let mut _0: u32; // return place in scope 0 at $DIR/simplify_locals.rs:+0:12: +0:15 - let mut _1: u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 - let mut _2: *mut u32; // in scope 0 at $DIR/simplify_locals.rs:+2:14: +2:15 - scope 1 { - } - - bb0: { - StorageLive(_1); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 - StorageLive(_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 - _2 = &/*tls*/ mut X; // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 - _1 = (*_2); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:15 - _0 = Add(move _1, const 1_u32); // scope 1 at $DIR/simplify_locals.rs:+2:14: +2:19 - StorageDead(_1); // scope 1 at $DIR/simplify_locals.rs:+2:18: +2:19 - StorageDead(_2); // scope 0 at $DIR/simplify_locals.rs:+3:1: +3:2 - return; // scope 0 at $DIR/simplify_locals.rs:+3:2: +3:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff new file mode 100644 index 00000000000..f888c622d90 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff @@ -0,0 +1,62 @@ +- // MIR for `foo` before SimplifyLocals-final ++ // MIR for `foo` after SimplifyLocals-final + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+0:13: +0:13 + let mut _1: (std::option::Option, std::option::Option); // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + let mut _2: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + let mut _3: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + let mut _4: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:22: +1:26 + let mut _5: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:13: +1:20 +- let mut _7: bool; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- let mut _8: u8; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 + scope 1 { + debug a => _6; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + let _6: u8; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageLive(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + Deinit(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + discriminant(_2) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 + StorageLive(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + Deinit(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + discriminant(_3) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 + Deinit(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + (_1.0: std::option::Option) = move _2; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + (_1.1: std::option::Option) = move _3; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 + StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 + _5 = discriminant((_1.0: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + } + + bb1: { + _4 = discriminant((_1.1: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + switchInt(move _4) -> [0: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 + _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 +- StorageLive(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- StorageLive(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 +- _8 = _6; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 +- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 +- StorageDead(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:19: +2:20 +- StorageDead(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+4:9: +4:10 + StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6 + goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6 + } + + bb3: { + drop(_1) -> bb4; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 + return; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:2: +6:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff deleted file mode 100644 index a2b55229303..00000000000 --- a/src/test/mir-opt/simplify_locals_fixedpoint.foo.SimplifyLocals.diff +++ /dev/null @@ -1,62 +0,0 @@ -- // MIR for `foo` before SimplifyLocals -+ // MIR for `foo` after SimplifyLocals - - fn foo() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+0:13: +0:13 - let mut _1: (std::option::Option, std::option::Option); // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 - let mut _2: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 - let mut _3: std::option::Option; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 - let mut _4: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:22: +1:26 - let mut _5: isize; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:13: +1:20 -- let mut _7: bool; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 -- let mut _8: u8; // in scope 0 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 - scope 1 { - debug a => _6; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 - let _6: u8; // in scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 - } - - bb0: { - StorageLive(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 - StorageLive(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 - Deinit(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 - discriminant(_2) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:31: +1:49 - StorageLive(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 - Deinit(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 - discriminant(_3) = 0; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:51: +1:68 - Deinit(_1); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 - (_1.0: std::option::Option) = move _2; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 - (_1.1: std::option::Option) = move _3; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:30: +1:69 - StorageDead(_3); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 - StorageDead(_2); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:68: +1:69 - _5 = discriminant((_1.0: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - } - - bb1: { - _4 = discriminant((_1.1: std::option::Option)); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - switchInt(move _4) -> [0: bb2, otherwise: bb3]; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:12: +1:27 - } - - bb2: { - StorageLive(_6); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 - _6 = (((_1.0: std::option::Option) as Some).0: u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+1:18: +1:19 -- StorageLive(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 -- StorageLive(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 -- _8 = _6; // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:13 -- _7 = Gt(move _8, const 42_u8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:12: +2:20 -- StorageDead(_8); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+2:19: +2:20 -- StorageDead(_7); // scope 1 at $DIR/simplify_locals_fixedpoint.rs:+4:9: +4:10 - StorageDead(_6); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+5:5: +5:6 - goto -> bb3; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+1:5: +5:6 - } - - bb3: { - drop(_1) -> bb4; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 - } - - bb4: { - StorageDead(_1); // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:1: +6:2 - return; // scope 0 at $DIR/simplify_locals_fixedpoint.rs:+6:2: +6:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals_fixedpoint.rs b/src/test/mir-opt/simplify_locals_fixedpoint.rs index 78b1f9f55e5..1fdba6e99e3 100644 --- a/src/test/mir-opt/simplify_locals_fixedpoint.rs +++ b/src/test/mir-opt/simplify_locals_fixedpoint.rs @@ -12,4 +12,4 @@ fn main() { foo::<()>(); } -// EMIT_MIR simplify_locals_fixedpoint.foo.SimplifyLocals.diff +// EMIT_MIR simplify_locals_fixedpoint.foo.SimplifyLocals-final.diff diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..efb2b0961cc --- /dev/null +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,109 @@ +- // MIR for `main` before SimplifyLocals-before-const-prop ++ // MIR for `main` after SimplifyLocals-before-const-prop + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +0:11 +- let mut _1: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- let mut _2: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- let _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- let mut _5: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- let mut _6: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- let mut _7: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- let _8: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- let mut _9: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- let mut _10: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- let mut _11: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ let _1: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ let mut _2: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 + scope 1 { + } + + bb0: { +- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- Deinit(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 +- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 +- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 +- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 +- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29 +- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 +- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- Deinit(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 +- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 +- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 +- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 +- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 ++ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 ++ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 ++ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 ++ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 ++ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 + // mir::Constant + // + span: $DIR/simplify_locals_removes_unused_consts.rs:15:5: 15:12 + // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value() } + } + + bb1: { +- StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 +- StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 +- StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 +- StorageLive(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageLive(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- StorageLive(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 +- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 +- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 +- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 +- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 ++ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 ++ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 ++ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 ++ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 ++ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 ++ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 ++ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 + // mir::Constant + // + span: $DIR/simplify_locals_removes_unused_consts.rs:17:5: 17:11 + // + literal: Const { ty: fn(u8) {use_u8}, val: Value() } + } + + bb2: { +- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 +- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 + StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 ++ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 + _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff deleted file mode 100644 index 78272272b07..00000000000 --- a/src/test/mir-opt/simplify_locals_removes_unused_consts.main.SimplifyLocals.diff +++ /dev/null @@ -1,109 +0,0 @@ -- // MIR for `main` before SimplifyLocals -+ // MIR for `main` after SimplifyLocals - - fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +0:11 -- let mut _1: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 -- let mut _2: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 -- let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 -- let _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 -- let mut _5: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -- let mut _6: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -- let mut _7: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -- let _8: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 -- let mut _9: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -- let mut _10: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -- let mut _11: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -+ let _1: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 -+ let mut _2: ((), ()); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -+ let mut _3: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -+ let mut _4: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -+ let _5: (); // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 -+ let mut _6: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -+ let mut _7: u8; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -+ let mut _8: Temp; // in scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 - scope 1 { - } - - bb0: { -- StorageLive(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 -- StorageLive(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 -- Deinit(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:21: +1:23 -- StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 -- Deinit(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:25: +1:27 -- Deinit(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 -- (_1.0: ()) = move _2; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 -- (_1.1: ()) = move _3; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:20: +1:28 -- StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 -- StorageDead(_2); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:27: +1:28 -- StorageDead(_1); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+1:28: +1:29 -- StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 -- StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -- StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -- Deinit(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -- StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -- Deinit(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -- Deinit(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -- (_5.0: ()) = move _6; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -- (_5.1: ()) = move _7; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -- StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 -- StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 -- _4 = use_zst(move _5) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 -+ StorageLive(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 -+ StorageLive(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -+ StorageLive(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -+ Deinit(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:14: +2:16 -+ StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -+ Deinit(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:18: +2:20 -+ Deinit(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -+ (_2.0: ()) = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -+ (_2.1: ()) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:13: +2:21 -+ StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 -+ StorageDead(_3); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:20: +2:21 -+ _1 = use_zst(move _2) -> bb1; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:5: +2:22 - // mir::Constant - // + span: $DIR/simplify_locals_removes_unused_consts.rs:15:5: 15:12 - // + literal: Const { ty: fn(((), ())) {use_zst}, val: Value() } - } - - bb1: { -- StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 -- StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 -- StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 -- StorageLive(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -- StorageLive(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -- StorageLive(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -- Deinit(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -- (_11.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -- _10 = (_11.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -- _9 = Add(move _10, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -- StorageDead(_10); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 -- _8 = use_u8(move _9) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 -+ StorageDead(_2); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:21: +2:22 -+ StorageDead(_1); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+2:22: +2:23 -+ StorageLive(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 -+ StorageLive(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -+ StorageLive(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -+ StorageLive(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -+ Deinit(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -+ (_8.0: u8) = const 40_u8; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:28 -+ _7 = (_8.0: u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:30 -+ _6 = Add(move _7, const 2_u8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:12: +4:34 -+ StorageDead(_7); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:33: +4:34 -+ _5 = use_u8(move _6) -> bb2; // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:5: +4:35 - // mir::Constant - // + span: $DIR/simplify_locals_removes_unused_consts.rs:17:5: 17:11 - // + literal: Const { ty: fn(u8) {use_u8}, val: Value() } - } - - bb2: { -- StorageDead(_9); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 -- StorageDead(_11); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 -+ StorageDead(_6); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:34: +4:35 - StorageDead(_8); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 -+ StorageDead(_5); // scope 1 at $DIR/simplify_locals_removes_unused_consts.rs:+4:35: +4:36 - _0 = const (); // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+0:11: +5:2 - return; // scope 0 at $DIR/simplify_locals_removes_unused_consts.rs:+5:2: +5:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals_removes_unused_consts.rs b/src/test/mir-opt/simplify_locals_removes_unused_consts.rs index 39b7911d4ae..7a03a2837ae 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_consts.rs +++ b/src/test/mir-opt/simplify_locals_removes_unused_consts.rs @@ -1,4 +1,4 @@ -// unit-test: SimplifyLocals +// unit-test: SimplifyLocals-before-const-prop // compile-flags: -C overflow-checks=no fn use_zst(_: ((), ())) {} @@ -9,7 +9,7 @@ struct Temp { fn use_u8(_: u8) {} -// EMIT_MIR simplify_locals_removes_unused_consts.main.SimplifyLocals.diff +// EMIT_MIR simplify_locals_removes_unused_consts.main.SimplifyLocals-before-const-prop.diff fn main() { let ((), ()) = ((), ()); use_zst(((), ())); diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff new file mode 100644 index 00000000000..027c983e6b4 --- /dev/null +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff @@ -0,0 +1,52 @@ +- // MIR for `map` before SimplifyLocals-before-const-prop ++ // MIR for `map` after SimplifyLocals-before-const-prop + + fn map(_1: Option>) -> Option> { + debug x => _1; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:8: +0:9 + let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:31: +0:46 + let mut _2: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:9: +2:13 + let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 +- let mut _5: bool; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 +- let mut _6: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 +- let mut _7: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 + scope 1 { + debug x => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + } + + bb0: { +- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 +- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 + } + + bb1: { + StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 + StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 + Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + discriminant(_0) = 1; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 + StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 + } + + bb2: { + unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 + } + + bb3: { + Deinit(_0); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + discriminant(_0) = 0; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 + } + + bb4: { +- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 + return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2 + } + } + diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff deleted file mode 100644 index 9ec138dd82f..00000000000 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff +++ /dev/null @@ -1,52 +0,0 @@ -- // MIR for `map` before SimplifyLocals -+ // MIR for `map` after SimplifyLocals - - fn map(_1: Option>) -> Option> { - debug x => _1; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:8: +0:9 - let mut _0: std::option::Option>; // return place in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+0:31: +0:46 - let mut _2: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:9: +2:13 - let _3: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 - let mut _4: std::boxed::Box<()>; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 -- let mut _5: bool; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 -- let mut _6: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 -- let mut _7: isize; // in scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 - scope 1 { - debug x => _3; // in scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 - } - - bb0: { -- _5 = const false; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 -- _5 = const true; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 - _2 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 - switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:5: +1:12 - } - - bb1: { - StorageLive(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 - _3 = move ((_1 as Some).0: std::boxed::Box<()>); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:14: +3:15 - StorageLive(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 - _4 = move _3; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:25: +3:26 - Deinit(_0); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 - ((_0 as Some).0: std::boxed::Box<()>) = move _4; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 - discriminant(_0) = 1; // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:20: +3:27 - StorageDead(_4); // scope 1 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 - StorageDead(_3); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 - goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+3:26: +3:27 - } - - bb2: { - unreachable; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+1:11: +1:12 - } - - bb3: { - Deinit(_0); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 - discriminant(_0) = 0; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 - goto -> bb4; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+2:17: +2:21 - } - - bb4: { -- _6 = discriminant(_1); // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:1: +5:2 - return; // scope 0 at $DIR/simplify_locals_removes_unused_discriminant_reads.rs:+5:2: +5:2 - } - } - diff --git a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs index d09bd92c4e8..de65857412c 100644 --- a/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs +++ b/src/test/mir-opt/simplify_locals_removes_unused_discriminant_reads.rs @@ -1,4 +1,4 @@ -// unit-test: SimplifyLocals +// unit-test: SimplifyLocals-before-const-prop fn map(x: Option>) -> Option> { match x { @@ -11,4 +11,4 @@ fn main() { map(None); } -// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals.diff +// EMIT_MIR simplify_locals_removes_unused_discriminant_reads.map.SimplifyLocals-before-const-prop.diff diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir new file mode 100644 index 00000000000..b4fb330f3df --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir @@ -0,0 +1,16 @@ +// MIR for `process_never` after SimplifyLocals-final + +fn process_never(_1: *const !) -> () { + debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:22: +0:27 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:39: +0:39 + let _2: &!; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + scope 1 { + debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + } + scope 2 { + } + + bb0: { + unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir deleted file mode 100644 index 2c0fcc6621a..00000000000 --- a/src/test/mir-opt/uninhabited_enum.process_never.SimplifyLocals.after.mir +++ /dev/null @@ -1,16 +0,0 @@ -// MIR for `process_never` after SimplifyLocals - -fn process_never(_1: *const !) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:22: +0:27 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:39: +0:39 - let _2: &!; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - } - scope 2 { - } - - bb0: { - unreachable; // scope 0 at $DIR/uninhabited_enum.rs:+0:39: +2:2 - } -} diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir new file mode 100644 index 00000000000..2af864998cb --- /dev/null +++ b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir @@ -0,0 +1,18 @@ +// MIR for `process_void` after SimplifyLocals-final + +fn process_void(_1: *const Void) -> () { + debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26 + let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41 + let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + scope 1 { + debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + } + scope 2 { + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 + StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2 + return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2 + } +} diff --git a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir deleted file mode 100644 index ae341a7b97b..00000000000 --- a/src/test/mir-opt/uninhabited_enum.process_void.SimplifyLocals.after.mir +++ /dev/null @@ -1,18 +0,0 @@ -// MIR for `process_void` after SimplifyLocals - -fn process_void(_1: *const Void) -> () { - debug input => _1; // in scope 0 at $DIR/uninhabited_enum.rs:+0:21: +0:26 - let mut _0: (); // return place in scope 0 at $DIR/uninhabited_enum.rs:+0:41: +0:41 - let _2: &Void; // in scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - scope 1 { - debug _input => _2; // in scope 1 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - } - scope 2 { - } - - bb0: { - StorageLive(_2); // scope 0 at $DIR/uninhabited_enum.rs:+1:8: +1:14 - StorageDead(_2); // scope 0 at $DIR/uninhabited_enum.rs:+4:1: +4:2 - return; // scope 0 at $DIR/uninhabited_enum.rs:+4:2: +4:2 - } -} diff --git a/src/test/mir-opt/uninhabited_enum.rs b/src/test/mir-opt/uninhabited_enum.rs index 97c6e8cd531..19db548157a 100644 --- a/src/test/mir-opt/uninhabited_enum.rs +++ b/src/test/mir-opt/uninhabited_enum.rs @@ -2,13 +2,13 @@ pub enum Void {} -// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals.after.mir +// EMIT_MIR uninhabited_enum.process_never.SimplifyLocals-final.after.mir #[no_mangle] pub fn process_never(input: *const !) { let _input = unsafe { &*input }; } -// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals.after.mir +// EMIT_MIR uninhabited_enum.process_void.SimplifyLocals-final.after.mir #[no_mangle] pub fn process_void(input: *const Void) { let _input = unsafe { &*input }; diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff index 984ef476e10..8d74dc84cae 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff @@ -4,13 +4,8 @@ fn change_loop_body() -> () { let mut _0: (); // return place in scope 0 at $DIR/while_let_loops.rs:+0:27: +0:27 let mut _1: i32; // in scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 - let mut _2: (); // in scope 0 at $DIR/while_let_loops.rs:+0:1: +6:2 - let mut _3: std::option::Option; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 - let mut _4: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 - let mut _5: !; // in scope 0 at $DIR/while_let_loops.rs:+2:33: +5:6 - let mut _6: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 - let _7: (); // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 - let mut _8: !; // in scope 0 at $DIR/while_let_loops.rs:+2:5: +5:6 + let mut _2: std::option::Option; // in scope 0 at $DIR/while_let_loops.rs:+2:28: +2:32 + let mut _3: isize; // in scope 0 at $DIR/while_let_loops.rs:+2:15: +2:25 scope 1 { debug _x => _1; // in scope 1 at $DIR/while_let_loops.rs:+1:9: +1:15 scope 2 { @@ -20,17 +15,17 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/while_let_loops.rs:+1:9: +1:15 _1 = const 0_i32; // scope 0 at $DIR/while_let_loops.rs:+1:18: +1:19 - StorageLive(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 - Deinit(_3); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 - discriminant(_3) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 -- _4 = discriminant(_3); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -- switchInt(move _4) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 -+ _4 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + StorageLive(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + Deinit(_2); // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 + discriminant(_2) = 0; // scope 2 at $DIR/while_let_loops.rs:+2:28: +2:32 +- _3 = discriminant(_2); // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 +- switchInt(move _3) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 ++ _3 = const 0_isize; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + switchInt(const 0_isize) -> [1: bb1, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb1: { - switchInt(((_3 as Some).0: u32)) -> [0: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 + switchInt(((_2 as Some).0: u32)) -> [0: bb2, otherwise: bb3]; // scope 2 at $DIR/while_let_loops.rs:+2:15: +2:25 } bb2: { @@ -40,14 +35,12 @@ } bb3: { - StorageLive(_7); // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 - StorageDead(_7); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 goto -> bb4; // scope 1 at no-location } bb4: { - StorageDead(_3); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 + StorageDead(_2); // scope 1 at $DIR/while_let_loops.rs:+5:5: +5:6 StorageDead(_1); // scope 0 at $DIR/while_let_loops.rs:+6:1: +6:2 return; // scope 0 at $DIR/while_let_loops.rs:+6:2: +6:2 } diff --git a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir index 1556c240dc5..b95d91b13dd 100644 --- a/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while_storage.while_loop.PreCodegen.after.mir @@ -44,7 +44,7 @@ fn while_loop(_1: bool) -> () { bb5: { StorageDead(_4); // scope 0 at $DIR/while_storage.rs:+4:9: +4:10 - goto -> bb8; // scope 0 at no-location + goto -> bb7; // scope 0 at no-location } bb6: { @@ -54,10 +54,6 @@ fn while_loop(_1: bool) -> () { } bb7: { - goto -> bb8; // scope 0 at no-location - } - - bb8: { StorageDead(_2); // scope 0 at $DIR/while_storage.rs:+5:5: +5:6 return; // scope 0 at $DIR/while_storage.rs:+6:2: +6:2 } diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr index 4758ea4ae88..0dd18a55786 100644 --- a/src/test/ui/consts/invalid-union.32bit.stderr +++ b/src/test/ui/consts/invalid-union.32bit.stderr @@ -21,12 +21,6 @@ note: erroneous constant used LL | let _: &'static _ = &C; | ^^ -note: erroneous constant used - --> $DIR/invalid-union.rs:43:25 - | -LL | let _: &'static _ = &C; - | ^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index 22b85d20ce9..07f36ee2832 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -21,12 +21,6 @@ note: erroneous constant used LL | let _: &'static _ = &C; | ^^ -note: erroneous constant used - --> $DIR/invalid-union.rs:43:25 - | -LL | let _: &'static _ = &C; - | ^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. -- cgit 1.4.1-3-g733a5 From e300abb5931156de9d8c21700df203ee7814ccd8 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 4 Dec 2022 19:25:20 +0000 Subject: Remove Nop in simplify_locals. It's cheap and does not change anything. --- compiler/rustc_mir_transform/src/simplify.rs | 1 + src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff | 1 - .../mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff | 1 - .../bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff | 1 - .../bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff | 1 - .../const_prop/control_flow_simplification.hello.ConstProp.diff | 1 - src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff | 3 --- src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff | 3 --- src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff | 1 - .../const_prop/large_array_index.main.ConstProp.32bit.diff | 1 - .../const_prop/large_array_index.main.ConstProp.64bit.diff | 1 - src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff | 1 - .../const_prop/mutable_variable_aggregate.main.ConstProp.diff | 1 - .../mutable_variable_aggregate_mut_ref.main.ConstProp.diff | 1 - .../mutable_variable_aggregate_partial_read.main.ConstProp.diff | 1 - .../const_prop/mutable_variable_no_prop.main.ConstProp.diff | 2 -- .../const_prop/mutable_variable_unprop_assign.main.ConstProp.diff | 1 - .../const_prop/optimizes_into_variable.main.ConstProp.32bit.diff | 1 - .../const_prop/optimizes_into_variable.main.ConstProp.64bit.diff | 1 - .../mir-opt/const_prop/read_immutable_static.main.ConstProp.diff | 1 - src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff | 1 - src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff | 1 - src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff | 1 - .../const_prop/scalar_literal_propagation.main.ConstProp.diff | 1 - .../const_prop/tuple_literal_propagation.main.ConstProp.diff | 1 - src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff | 2 -- src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff | 1 - .../inherit_overflow.main.DataflowConstProp.diff | 1 - .../dead-store-elimination/cycle.cycle.DeadStoreElimination.diff | 8 -------- .../dead_stores_better.f.DestinationPropagation.after.mir | 1 - src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff | 3 --- src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff | 3 --- src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff | 1 - .../simplify_if.main.SimplifyConstCondition-after-const-prop.diff | 2 -- src/test/mir-opt/simplify_match.main.ConstProp.diff | 1 - src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff | 2 -- 36 files changed, 1 insertion(+), 54 deletions(-) diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index b7aa277ae5e..8f6abe7a912 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -569,6 +569,7 @@ fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>) StatementKind::SetDiscriminant { ref place, .. } | StatementKind::Deinit(ref place) => used_locals.is_used(place.local), + StatementKind::Nop => false, _ => true, }; diff --git a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff index 20bad942c8d..dd548adde7e 100644 --- a/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/src/test/mir-opt/const_debuginfo.main.ConstDebugInfo.diff @@ -108,7 +108,6 @@ _11 = const 64_u32; // scope 8 at $DIR/const_debuginfo.rs:+13:13: +13:22 StorageDead(_13); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 StorageDead(_12); // scope 8 at $DIR/const_debuginfo.rs:+13:21: +13:22 - nop; // scope 0 at $DIR/const_debuginfo.rs:+0:11: +14:2 StorageDead(_11); // scope 8 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_17); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 StorageDead(_18); // scope 7 at $DIR/const_debuginfo.rs:+14:1: +14:2 diff --git a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff index 22151304259..8485703e39f 100644 --- a/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/bad_op_mod_by_zero.main.ConstProp.diff @@ -45,7 +45,6 @@ - _2 = Rem(const 1_i32, move _3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 + _2 = Rem(const 1_i32, const 0_i32); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:14: +2:19 StorageDead(_3); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+2:18: +2:19 - nop; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+0:11: +3:2 StorageDead(_2); // scope 1 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 StorageDead(_1); // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:1: +3:2 return; // scope 0 at $DIR/bad_op_mod_by_zero.rs:+3:2: +3:2 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff index 567f6ede8bc..27e41d4869d 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.32bit.diff @@ -46,7 +46,6 @@ bb1: { _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 - nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 diff --git a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff index 567f6ede8bc..27e41d4869d 100644 --- a/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.ConstProp.64bit.diff @@ -46,7 +46,6 @@ bb1: { _4 = (*_1)[_5]; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:18: +3:25 StorageDead(_5); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+3:25: +3:26 - nop; // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+2:5: +4:6 StorageDead(_4); // scope 2 at $DIR/bad_op_unsafe_oob_for_slices.rs:+4:5: +4:6 StorageDead(_1); // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:1: +5:2 return; // scope 0 at $DIR/bad_op_unsafe_oob_for_slices.rs:+5:2: +5:2 diff --git a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff index 147670f8a91..f270ab8b69f 100644 --- a/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff @@ -25,7 +25,6 @@ } bb2: { - nop; // scope 0 at $DIR/control_flow_simplification.rs:+3:6: +3:6 StorageDead(_1); // scope 0 at $DIR/control_flow_simplification.rs:+3:5: +3:6 return; // scope 0 at $DIR/control_flow_simplification.rs:+4:2: +4:2 } diff --git a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff index 8dd0a08e319..6c4757c1a81 100644 --- a/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff @@ -55,10 +55,7 @@ StorageDead(_4); // scope 1 at $DIR/invalid_constant.rs:+13:59: +13:60 StorageDead(_5); // scope 1 at $DIR/invalid_constant.rs:+13:60: +13:61 StorageLive(_6); // scope 3 at $DIR/invalid_constant.rs:+20:9: +20:31 - nop; // scope 6 at $DIR/invalid_constant.rs:+20:44: +20:71 - nop; // scope 3 at $DIR/invalid_constant.rs:+20:34: +20:74 StorageLive(_7); // scope 5 at $DIR/invalid_constant.rs:+24:9: +24:22 - nop; // scope 0 at $DIR/invalid_constant.rs:+0:11: +27:2 StorageDead(_7); // scope 5 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_6); // scope 3 at $DIR/invalid_constant.rs:+27:1: +27:2 StorageDead(_3); // scope 1 at $DIR/invalid_constant.rs:+27:1: +27:2 diff --git a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff index 1c07d5ec0a8..488e772d0ea 100644 --- a/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_66971.main.ConstProp.diff @@ -9,9 +9,7 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 StorageLive(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 - nop; // scope 0 at $DIR/issue_66971.rs:+1:13: +1:15 Deinit(_2); // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 - nop; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 (_2.1: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 (_2.2: u8) = const 0_u8; // scope 0 at $DIR/issue_66971.rs:+1:12: +1:22 _1 = encode(move _2) -> bb1; // scope 0 at $DIR/issue_66971.rs:+1:5: +1:23 @@ -23,7 +21,6 @@ bb1: { StorageDead(_2); // scope 0 at $DIR/issue_66971.rs:+1:22: +1:23 StorageDead(_1); // scope 0 at $DIR/issue_66971.rs:+1:23: +1:24 - nop; // scope 0 at $DIR/issue_66971.rs:+0:11: +2:2 return; // scope 0 at $DIR/issue_66971.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff index 79cd8bf4839..cd53048597b 100644 --- a/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue_67019.main.ConstProp.diff @@ -27,7 +27,6 @@ bb1: { StorageDead(_2); // scope 0 at $DIR/issue_67019.rs:+1:19: +1:20 StorageDead(_1); // scope 0 at $DIR/issue_67019.rs:+1:20: +1:21 - nop; // scope 0 at $DIR/issue_67019.rs:+0:11: +2:2 return; // scope 0 at $DIR/issue_67019.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff index 96de39258e4..5331e5b8212 100644 --- a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.32bit.diff @@ -29,7 +29,6 @@ _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 - nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 } diff --git a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff index 96de39258e4..5331e5b8212 100644 --- a/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/large_array_index.main.ConstProp.64bit.diff @@ -29,7 +29,6 @@ _1 = _2[_3]; // scope 0 at $DIR/large_array_index.rs:+2:17: +2:32 StorageDead(_3); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 StorageDead(_2); // scope 0 at $DIR/large_array_index.rs:+2:32: +2:33 - nop; // scope 0 at $DIR/large_array_index.rs:+0:11: +3:2 StorageDead(_1); // scope 0 at $DIR/large_array_index.rs:+3:1: +3:2 return; // scope 0 at $DIR/large_array_index.rs:+3:2: +3:2 } diff --git a/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff index 3bbd6a87f97..a672c457a72 100644 --- a/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable.main.ConstProp.diff @@ -19,7 +19,6 @@ StorageLive(_2); // scope 1 at $DIR/mutable_variable.rs:+3:9: +3:10 - _2 = _1; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14 + _2 = const 99_i32; // scope 1 at $DIR/mutable_variable.rs:+3:13: +3:14 - nop; // scope 0 at $DIR/mutable_variable.rs:+0:11: +4:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/mutable_variable.rs:+4:2: +4:2 diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff index fed6a98b9f3..f6bf522065b 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate.main.ConstProp.diff @@ -21,7 +21,6 @@ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:9: +3:10 - _2 = _1; // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 + _2 = const (42_i32, 99_i32); // scope 1 at $DIR/mutable_variable_aggregate.rs:+3:13: +3:14 - nop; // scope 0 at $DIR/mutable_variable_aggregate.rs:+0:11: +4:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:1: +4:2 return; // scope 0 at $DIR/mutable_variable_aggregate.rs:+4:2: +4:2 diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff index 90eebd8feac..213a70227d8 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_mut_ref.main.ConstProp.diff @@ -26,7 +26,6 @@ ((*_2).1: i32) = const 99_i32; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+3:5: +3:13 StorageLive(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:9: +4:10 _3 = _1; // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+4:13: +4:14 - nop; // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+0:11: +5:2 StorageDead(_3); // scope 2 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_mut_ref.rs:+5:1: +5:2 diff --git a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff index 6eda503c1ee..149aa6290d0 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_aggregate_partial_read.main.ConstProp.diff @@ -26,7 +26,6 @@ StorageLive(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:9: +4:10 - _2 = (_1.1: i32); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 + _2 = const 99_i32; // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+4:13: +4:16 - nop; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+0:11: +5:2 StorageDead(_2); // scope 1 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:1: +5:2 return; // scope 0 at $DIR/mutable_variable_aggregate_partial_read.rs:+5:2: +5:2 diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff index b34df3b877e..b9d551c5e5f 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff @@ -29,10 +29,8 @@ _1 = move _2; // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:9: +3:19 StorageDead(_2); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:18: +3:19 StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:+3:19: +3:20 - nop; // scope 2 at $DIR/mutable_variable_no_prop.rs:+2:5: +4:6 StorageLive(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:9: +5:10 _4 = _1; // scope 1 at $DIR/mutable_variable_no_prop.rs:+5:13: +5:14 - nop; // scope 0 at $DIR/mutable_variable_no_prop.rs:+0:11: +6:2 StorageDead(_4); // scope 1 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:1: +6:2 return; // scope 0 at $DIR/mutable_variable_no_prop.rs:+6:2: +6:2 diff --git a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff index 7485a0f9176..c3f77b960a2 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_unprop_assign.main.ConstProp.diff @@ -46,7 +46,6 @@ StorageLive(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:9: +5:10 - _4 = _5; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 + _4 = const 1_i32; // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+5:13: +5:16 - nop; // scope 0 at $DIR/mutable_variable_unprop_assign.rs:+0:11: +6:2 StorageDead(_4); // scope 3 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_3); // scope 2 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 StorageDead(_5); // scope 1 at $DIR/mutable_variable_unprop_assign.rs:+6:1: +6:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff index 6e32c65921f..7c7aeac4c45 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff @@ -57,7 +57,6 @@ - _8 = _9; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff index 6e32c65921f..7c7aeac4c45 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff @@ -57,7 +57,6 @@ - _8 = _9; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 + _8 = const 42_u32; // scope 2 at $DIR/optimizes_into_variable.rs:+3:13: +3:38 StorageDead(_9); // scope 2 at $DIR/optimizes_into_variable.rs:+3:38: +3:39 - nop; // scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +4:2 StorageDead(_8); // scope 2 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_3); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff index b9c283a5482..388c6ca810b 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff @@ -36,7 +36,6 @@ StorageDead(_2); // scope 0 at $DIR/read_immutable_static.rs:+1:21: +1:22 StorageDead(_5); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/read_immutable_static.rs:+1:22: +1:23 - nop; // scope 0 at $DIR/read_immutable_static.rs:+0:11: +2:2 StorageDead(_1); // scope 0 at $DIR/read_immutable_static.rs:+2:1: +2:2 return; // scope 0 at $DIR/read_immutable_static.rs:+2:2: +2:2 } diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff index b93e9788a46..15c93f270d7 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff @@ -18,7 +18,6 @@ _1 = move _2 as usize (PointerExposeAddress); // scope 0 at $DIR/reify_fn_ptr.rs:+1:13: +1:26 StorageDead(_2); // scope 0 at $DIR/reify_fn_ptr.rs:+1:25: +1:26 StorageDead(_1); // scope 0 at $DIR/reify_fn_ptr.rs:+1:40: +1:41 - nop; // scope 0 at $DIR/reify_fn_ptr.rs:+0:11: +2:2 return; // scope 0 at $DIR/reify_fn_ptr.rs:+2:2: +2:2 } } diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff index 7c497799691..636032adb81 100644 --- a/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.32bit.diff @@ -35,7 +35,6 @@ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 - nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2 StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 } diff --git a/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff index 7c497799691..636032adb81 100644 --- a/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff +++ b/src/test/mir-opt/const_prop/repeat.main.ConstProp.64bit.diff @@ -35,7 +35,6 @@ StorageDead(_2); // scope 0 at $DIR/repeat.rs:+1:31: +1:32 StorageDead(_4); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 StorageDead(_3); // scope 0 at $DIR/repeat.rs:+1:32: +1:33 - nop; // scope 0 at $DIR/repeat.rs:+0:11: +2:2 StorageDead(_1); // scope 0 at $DIR/repeat.rs:+2:1: +2:2 return; // scope 0 at $DIR/repeat.rs:+2:2: +2:2 } diff --git a/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff index 5920937e0fd..d518eff04eb 100644 --- a/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/scalar_literal_propagation.main.ConstProp.diff @@ -27,7 +27,6 @@ bb1: { StorageDead(_3); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:14: +2:15 StorageDead(_2); // scope 1 at $DIR/scalar_literal_propagation.rs:+2:15: +2:16 - nop; // scope 0 at $DIR/scalar_literal_propagation.rs:+0:11: +3:2 StorageDead(_1); // scope 0 at $DIR/scalar_literal_propagation.rs:+3:1: +3:2 return; // scope 0 at $DIR/scalar_literal_propagation.rs:+3:2: +3:2 } diff --git a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff index a0603c60dc7..e4c92b617c6 100644 --- a/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/tuple_literal_propagation.main.ConstProp.diff @@ -28,7 +28,6 @@ bb1: { StorageDead(_3); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:14: +3:15 StorageDead(_2); // scope 1 at $DIR/tuple_literal_propagation.rs:+3:15: +3:16 - nop; // scope 0 at $DIR/tuple_literal_propagation.rs:+0:11: +4:2 StorageDead(_1); // scope 0 at $DIR/tuple_literal_propagation.rs:+4:1: +4:2 return; // scope 0 at $DIR/tuple_literal_propagation.rs:+4:2: +4:2 } diff --git a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff index 46df4744012..ea9fec0aa15 100644 --- a/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff +++ b/src/test/mir-opt/const_prop_miscompile.bar.ConstProp.diff @@ -24,13 +24,11 @@ _2 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22 (*_2) = const 5_i32; // scope 2 at $DIR/const_prop_miscompile.rs:+3:9: +3:26 StorageDead(_2); // scope 2 at $DIR/const_prop_miscompile.rs:+3:26: +3:27 - nop; // scope 2 at $DIR/const_prop_miscompile.rs:+2:5: +4:6 StorageLive(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+5:9: +5:10 StorageLive(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:20 _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:15: +5:18 _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+5:13: +5:25 StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+5:24: +5:25 - nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +6:2 StorageDead(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+6:1: +6:2 return; // scope 0 at $DIR/const_prop_miscompile.rs:+6:2: +6:2 diff --git a/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff index e8bd98cf8cb..043f4047417 100644 --- a/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff +++ b/src/test/mir-opt/const_prop_miscompile.foo.ConstProp.diff @@ -27,7 +27,6 @@ _4 = (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:15: +3:18 _3 = Eq(move _4, const 5_i32); // scope 1 at $DIR/const_prop_miscompile.rs:+3:13: +3:25 StorageDead(_4); // scope 1 at $DIR/const_prop_miscompile.rs:+3:24: +3:25 - nop; // scope 0 at $DIR/const_prop_miscompile.rs:+0:10: +4:2 StorageDead(_3); // scope 1 at $DIR/const_prop_miscompile.rs:+4:1: +4:2 StorageDead(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+4:1: +4:2 return; // scope 0 at $DIR/const_prop_miscompile.rs:+4:2: +4:2 diff --git a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff index fe5be7d8a63..02aafd7acc4 100644 --- a/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff +++ b/src/test/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff @@ -33,7 +33,6 @@ StorageDead(_3); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47 - nop; // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2 return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2 } } diff --git a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff index 80f8905adc9..cd3b792fb75 100644 --- a/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff +++ b/src/test/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination.diff @@ -59,14 +59,6 @@ - _4 = const (); // scope 0 at $DIR/cycle.rs:+3:18: +8:6 - StorageDead(_6); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + StorageLive(_5); // scope 0 at $DIR/cycle.rs:+4:13: +4:17 -+ nop; // scope 0 at $DIR/cycle.rs:+4:20: +4:21 -+ nop; // scope 1 at $DIR/cycle.rs:+5:13: +5:14 -+ nop; // scope 1 at $DIR/cycle.rs:+5:9: +5:14 -+ nop; // scope 1 at $DIR/cycle.rs:+6:13: +6:14 -+ nop; // scope 1 at $DIR/cycle.rs:+6:9: +6:14 -+ nop; // scope 1 at $DIR/cycle.rs:+7:13: +7:17 -+ nop; // scope 1 at $DIR/cycle.rs:+7:9: +7:17 -+ nop; // scope 0 at $DIR/cycle.rs:+3:18: +8:6 StorageDead(_5); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 + StorageDead(_4); // scope 0 at $DIR/cycle.rs:+8:5: +8:6 goto -> bb1; // scope 0 at $DIR/cycle.rs:+3:5: +8:6 diff --git a/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir b/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir index ba7f76d2841..26068931aaf 100644 --- a/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir +++ b/src/test/mir-opt/dest-prop/dead_stores_better.f.DestinationPropagation.after.mir @@ -13,7 +13,6 @@ fn f(_1: usize) -> usize { bb0: { nop; // scope 0 at $DIR/dead_stores_better.rs:+1:9: +1:10 nop; // scope 0 at $DIR/dead_stores_better.rs:+1:13: +1:14 - nop; // scope 1 at $DIR/dead_stores_better.rs:+2:5: +2:10 nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 nop; // scope 1 at $DIR/dead_stores_better.rs:+3:9: +3:10 nop; // scope 1 at $DIR/dead_stores_better.rs:+3:5: +3:10 diff --git a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff index 85d994bc8b9..fbed3178801 100644 --- a/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff +++ b/src/test/mir-opt/dest-prop/union.main.DestinationPropagation.diff @@ -25,11 +25,8 @@ } bb1: { - nop; // scope 0 at $DIR/union.rs:+5:14: +5:30 - nop; // scope 0 at $DIR/union.rs:+5:14: +5:30 StorageDead(_2); // scope 0 at $DIR/union.rs:+5:29: +5:30 StorageLive(_3); // scope 1 at $DIR/union.rs:+7:10: +7:26 - nop; // scope 2 at $DIR/union.rs:+7:19: +7:24 StorageDead(_3); // scope 1 at $DIR/union.rs:+7:26: +7:27 StorageDead(_1); // scope 0 at $DIR/union.rs:+8:1: +8:2 return; // scope 0 at $DIR/union.rs:+8:2: +8:2 diff --git a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff index a67b49ee608..bf3bcfdb594 100644 --- a/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/issue_73223.main.SimplifyArmIdentity.diff @@ -56,7 +56,6 @@ } bb1: { - nop; // scope 0 at $DIR/issue_73223.rs:+3:17: +3:23 StorageDead(_2); // scope 0 at $DIR/issue_73223.rs:+4:6: +4:7 StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2 return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2 @@ -144,13 +143,11 @@ } bb5: { - nop; // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_11); // scope 4 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_10); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_9); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_24); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL StorageDead(_25); // scope 3 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - nop; // scope 0 at $DIR/issue_73223.rs:+0:11: +8:2 StorageDead(_5); // scope 1 at $DIR/issue_73223.rs:+8:1: +8:2 StorageDead(_1); // scope 0 at $DIR/issue_73223.rs:+8:1: +8:2 return; // scope 0 at $DIR/issue_73223.rs:+8:2: +8:2 diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index 483d16775df..c24543daeac 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -76,7 +76,6 @@ StorageDead(_14); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 StorageDead(_13); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 StorageDead(_12); // scope 1 at $DIR/issue_76432.rs:+3:84: +3:85 - nop; // scope 0 at $DIR/issue_76432.rs:+0:44: +6:2 StorageDead(_5); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 StorageDead(_2); // scope 0 at $DIR/issue_76432.rs:+6:1: +6:2 return; // scope 0 at $DIR/issue_76432.rs:+6:2: +6:2 diff --git a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff index aea01147443..f9e22866bee 100644 --- a/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff +++ b/src/test/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.diff @@ -23,12 +23,10 @@ bb2: { StorageDead(_2); // scope 0 at $DIR/simplify_if.rs:+2:15: +2:16 - nop; // scope 0 at $DIR/simplify_if.rs:+1:14: +3:6 goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 } bb3: { - nop; // scope 0 at $DIR/simplify_if.rs:+3:6: +3:6 goto -> bb4; // scope 0 at $DIR/simplify_if.rs:+1:5: +3:6 } diff --git a/src/test/mir-opt/simplify_match.main.ConstProp.diff b/src/test/mir-opt/simplify_match.main.ConstProp.diff index f00ac5716a7..70bfbf1b3e3 100644 --- a/src/test/mir-opt/simplify_match.main.ConstProp.diff +++ b/src/test/mir-opt/simplify_match.main.ConstProp.diff @@ -21,7 +21,6 @@ } bb1: { - nop; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20 goto -> bb3; // scope 0 at $DIR/simplify_match.rs:+3:18: +3:20 } diff --git a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff index 8d74dc84cae..bb1de59d4a7 100644 --- a/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff +++ b/src/test/mir-opt/while_let_loops.change_loop_body.ConstProp.diff @@ -30,12 +30,10 @@ bb2: { _1 = const 1_i32; // scope 2 at $DIR/while_let_loops.rs:+3:9: +3:15 - nop; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 goto -> bb4; // scope 2 at $DIR/while_let_loops.rs:+4:9: +4:14 } bb3: { - nop; // scope 1 at $DIR/while_let_loops.rs:+2:5: +5:6 goto -> bb4; // scope 1 at no-location } -- cgit 1.4.1-3-g733a5 From b8ec86cabb10866b3c33c6e275b13e3709168ce8 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 6 Dec 2022 18:58:05 +0000 Subject: Adapt codegen test. --- src/test/codegen/zst-offset.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/codegen/zst-offset.rs b/src/test/codegen/zst-offset.rs index 29d2a1754a3..844d5870a84 100644 --- a/src/test/codegen/zst-offset.rs +++ b/src/test/codegen/zst-offset.rs @@ -15,7 +15,7 @@ pub fn helper(_: usize) { pub fn scalar_layout(s: &(u64, ())) { // CHECK: getelementptr i8, {{.+}}, [[USIZE]] 8 let x = &s.1; - &x; // keep variable in an alloca + witness(&x); // keep variable in an alloca } // Check that we correctly generate a GEP for a ZST that is not included in ScalarPair layout @@ -24,7 +24,7 @@ pub fn scalar_layout(s: &(u64, ())) { pub fn scalarpair_layout(s: &(u64, u32, ())) { // CHECK: getelementptr i8, {{.+}}, [[USIZE]] 12 let x = &s.2; - &x; // keep variable in an alloca + witness(&x); // keep variable in an alloca } #[repr(simd)] @@ -36,5 +36,8 @@ pub struct U64x4(u64, u64, u64, u64); pub fn vector_layout(s: &(U64x4, ())) { // CHECK: getelementptr i8, {{.+}}, [[USIZE]] 32 let x = &s.1; - &x; // keep variable in an alloca + witness(&x); // keep variable in an alloca } + +#[inline(never)] +fn witness(_: &impl Sized) {} -- cgit 1.4.1-3-g733a5 From a48127f0dc019e75b2e3c96d6c37b4c022f6edc6 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 6 Dec 2022 20:05:55 +0000 Subject: Bless incremental test. --- src/test/incremental/hashes/closure_expressions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index c769246b29b..ce9f1d5a9d2 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -45,9 +45,9 @@ pub fn add_parameter() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck")] #[rustc_clean(cfg="cfail6")] pub fn add_parameter() { let x = 0u32; -- cgit 1.4.1-3-g733a5 From 0817b1d3ed26898e7d9ed71f6a2218d912ea6de5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 Dec 2022 23:55:26 +0000 Subject: Don't deduce a signature that makes a closure cyclic --- compiler/rustc_hir_typeck/src/closure.rs | 38 ++++++++++--- src/test/ui/closures/supertrait-hint-cycle.rs | 65 ++++++++++++++++++++++ src/test/ui/issues/issue-25439.stderr | 21 ++++--- .../unboxed-closure-no-cyclic-sig.stderr | 21 ++++--- 4 files changed, 122 insertions(+), 23 deletions(-) create mode 100644 src/test/ui/closures/supertrait-hint-cycle.rs diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 5bd02dff73b..8167e7e070c 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -13,7 +13,7 @@ use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, Ty, TypeSuperVisitable, TypeVisitor}; use rustc_span::source_map::Span; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits; @@ -21,6 +21,7 @@ use rustc_trait_selection::traits::error_reporting::ArgKind; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use std::cmp; use std::iter; +use std::ops::ControlFlow; /// What signature do we *expect* the closure to have from context? #[derive(Debug, Clone, TypeFoldable, TypeVisitable)] @@ -54,7 +55,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // closure sooner rather than later, so first examine the expected // type, and see if can glean a closure kind from there. let (expected_sig, expected_kind) = match expected.to_option(self) { - Some(ty) => self.deduce_expectations_from_expected_type(ty), + Some(ty) => self.deduce_closure_signature(ty), None => (None, None), }; let body = self.tcx.hir().body(closure.body); @@ -162,13 +163,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given the expected type, figures out what it can about this closure we /// are about to type check: #[instrument(skip(self), level = "debug")] - fn deduce_expectations_from_expected_type( + fn deduce_closure_signature( &self, expected_ty: Ty<'tcx>, ) -> (Option>, Option) { match *expected_ty.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self - .deduce_signature_from_predicates( + .deduce_closure_signature_from_predicates( + expected_ty, self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), ), ty::Dynamic(ref object_type, ..) => { @@ -181,7 +183,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .and_then(|did| self.tcx.fn_trait_kind_from_def_id(did)); (sig, kind) } - ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates( + ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates( + self.tcx.mk_ty_var(self.root_var(vid)), self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)), ), ty::FnPtr(sig) => { @@ -192,8 +195,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn deduce_signature_from_predicates( + fn deduce_closure_signature_from_predicates( &self, + expected_ty: Ty<'tcx>, predicates: impl DoubleEndedIterator, Span)>, ) -> (Option>, Option) { let mut expected_sig = None; @@ -214,13 +218,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if expected_sig.is_none() && let ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) = bound_predicate.skip_binder() { - expected_sig = self.normalize( + let inferred_sig = self.normalize( obligation.cause.span, self.deduce_sig_from_projection( Some(obligation.cause.span), bound_predicate.rebind(proj_predicate), ), ); + // Make sure that we didn't infer a signature that mentions itself. + // This can happen when we elaborate certain supertrait bounds that + // mention projections containing the `Self` type. See + struct MentionsTy<'tcx> { + expected_ty: Ty<'tcx>, + } + impl<'tcx> TypeVisitor<'tcx> for MentionsTy<'tcx> { + type BreakTy = (); + + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + if t == self.expected_ty { + ControlFlow::BREAK + } else { + t.super_visit_with(self) + } + } + } + if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() { + expected_sig = inferred_sig; + } } // Even if we can't infer the full signature, we may be able to diff --git a/src/test/ui/closures/supertrait-hint-cycle.rs b/src/test/ui/closures/supertrait-hint-cycle.rs new file mode 100644 index 00000000000..dbb06b2ef7a --- /dev/null +++ b/src/test/ui/closures/supertrait-hint-cycle.rs @@ -0,0 +1,65 @@ +// edition:2021 +// check-pass + +#![feature(type_alias_impl_trait)] +#![feature(closure_lifetime_binder)] + +use std::future::Future; + +trait AsyncFn: FnMut(I) -> Self::Fut { + type Fut: Future; +} + +impl AsyncFn for F +where + Fut: Future, + F: FnMut(I) -> Fut, +{ + type Fut = Fut; +} + +async fn call(mut ctx: C, mut f: F) -> Result +where + F: for<'a> AsyncFn<&'a mut C, Result>, +{ + loop { + match f(&mut ctx).await { + Ok(val) => return Ok(val), + Err(_) => continue, + } + } +} + +trait Cap<'a> {} +impl Cap<'_> for T {} + +fn works(ctx: &mut usize) { + let mut inner = 0; + + type Ret<'a, 'b: 'a> = impl Future> + 'a + Cap<'b>; + + let callback = for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> { + inner += 1; + async move { + let _c = c; + Ok(1usize) + } + }; + call(ctx, callback); +} + +fn doesnt_work_but_should(ctx: &mut usize) { + let mut inner = 0; + + type Ret<'a, 'b: 'a> = impl Future> + 'a + Cap<'b>; + + call(ctx, for<'a, 'b> |c: &'a mut &'b mut usize| -> Ret<'a, 'b> { + inner += 1; + async move { + let _c = c; + Ok(1usize) + } + }); +} + +fn main() {} diff --git a/src/test/ui/issues/issue-25439.stderr b/src/test/ui/issues/issue-25439.stderr index 325c28c15e2..938c9d9f18c 100644 --- a/src/test/ui/issues/issue-25439.stderr +++ b/src/test/ui/issues/issue-25439.stderr @@ -1,14 +1,19 @@ -error[E0644]: closure/generator type that references itself - --> $DIR/issue-25439.rs:8:9 +error[E0631]: type mismatch in closure arguments + --> $DIR/issue-25439.rs:8:5 | LL | fix(|_, x| x); - | ^^^^^^^^ cyclic type of infinite size + | ^^^ ------ found signature defined here + | | + | expected due to this | - = note: closures cannot capture themselves or take themselves as argument; - this error may be the result of a recent compiler bug-fix, - see issue #46062 - for more information + = note: expected closure signature `for<'a> fn(Helper<'a, [closure@$DIR/issue-25439.rs:8:9: 8:15]>, i32) -> _` + found closure signature `fn(_, _) -> _` +note: required by a bound in `fix` + --> $DIR/issue-25439.rs:3:33 + | +LL | fn fix(f: F) -> i32 where F: Fn(Helper, i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `fix` error: aborting due to previous error -For more information about this error, try `rustc --explain E0644`. +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr b/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr index 167479270b5..cfea13c1127 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr @@ -1,14 +1,19 @@ -error[E0644]: closure/generator type that references itself - --> $DIR/unboxed-closure-no-cyclic-sig.rs:8:7 +error[E0631]: type mismatch in closure arguments + --> $DIR/unboxed-closure-no-cyclic-sig.rs:8:5 | LL | g(|_| { }); - | ^^^^^^^^ cyclic type of infinite size + | ^ --- found signature defined here + | | + | expected due to this | - = note: closures cannot capture themselves or take themselves as argument; - this error may be the result of a recent compiler bug-fix, - see issue #46062 - for more information + = note: expected closure signature `fn(Option<[closure@$DIR/unboxed-closure-no-cyclic-sig.rs:8:7: 8:10]>) -> _` + found closure signature `fn(_) -> _` +note: required by a bound in `g` + --> $DIR/unboxed-closure-no-cyclic-sig.rs:5:24 + | +LL | fn g(_: F) where F: FnOnce(Option) {} + | ^^^^^^^^^^^^^^^^^ required by this bound in `g` error: aborting due to previous error -For more information about this error, try `rustc --explain E0644`. +For more information about this error, try `rustc --explain E0631`. -- cgit 1.4.1-3-g733a5 From 9f59ab55e6e5e8825cfc36bd90ed4d5b387ecd70 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Dec 2022 03:03:35 +0000 Subject: Restore cyclic closure message --- compiler/rustc_hir_typeck/src/closure.rs | 2 +- .../src/traits/error_reporting/mod.rs | 21 ++++++++++++++++++++- src/test/ui/issues/issue-25439.stderr | 16 ++++++++-------- .../unboxed-closure-no-cyclic-sig.stderr | 16 ++++++++-------- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 8167e7e070c..3453da500b9 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -227,7 +227,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // Make sure that we didn't infer a signature that mentions itself. // This can happen when we elaborate certain supertrait bounds that - // mention projections containing the `Self` type. See + // mention projections containing the `Self` type. See #105401. struct MentionsTy<'tcx> { expected_ty: Ty<'tcx>, } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 8f317beaa77..fb7791879a1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -33,7 +33,7 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; -use rustc_middle::ty::error::ExpectedFound; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ @@ -1215,6 +1215,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } + OutputTypeParameterMismatch( + found_trait_ref, + expected_trait_ref, + terr @ TypeError::CyclicTy(_), + ) => { + let self_ty = found_trait_ref.self_ty().skip_binder(); + let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { + ( + ObligationCause::dummy_with_span(tcx.def_span(def_id)), + TypeError::CyclicTy(self_ty), + ) + } else { + (obligation.cause.clone(), terr) + }; + self.report_and_explain_type_error( + TypeTrace::poly_trait_refs(&cause, true, expected_trait_ref, found_trait_ref), + terr, + ) + } OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => { let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); diff --git a/src/test/ui/issues/issue-25439.stderr b/src/test/ui/issues/issue-25439.stderr index 938c9d9f18c..dadae23fdf3 100644 --- a/src/test/ui/issues/issue-25439.stderr +++ b/src/test/ui/issues/issue-25439.stderr @@ -1,13 +1,13 @@ -error[E0631]: type mismatch in closure arguments - --> $DIR/issue-25439.rs:8:5 +error[E0644]: closure/generator type that references itself + --> $DIR/issue-25439.rs:8:9 | LL | fix(|_, x| x); - | ^^^ ------ found signature defined here - | | - | expected due to this + | ^^^^^^ cyclic type of infinite size | - = note: expected closure signature `for<'a> fn(Helper<'a, [closure@$DIR/issue-25439.rs:8:9: 8:15]>, i32) -> _` - found closure signature `fn(_, _) -> _` + = note: closures cannot capture themselves or take themselves as argument; + this error may be the result of a recent compiler bug-fix, + see issue #46062 + for more information note: required by a bound in `fix` --> $DIR/issue-25439.rs:3:33 | @@ -16,4 +16,4 @@ LL | fn fix(f: F) -> i32 where F: Fn(Helper, i32) -> i32 { error: aborting due to previous error -For more information about this error, try `rustc --explain E0631`. +For more information about this error, try `rustc --explain E0644`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr b/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr index cfea13c1127..6d5dbca0558 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.stderr @@ -1,13 +1,13 @@ -error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closure-no-cyclic-sig.rs:8:5 +error[E0644]: closure/generator type that references itself + --> $DIR/unboxed-closure-no-cyclic-sig.rs:8:7 | LL | g(|_| { }); - | ^ --- found signature defined here - | | - | expected due to this + | ^^^ cyclic type of infinite size | - = note: expected closure signature `fn(Option<[closure@$DIR/unboxed-closure-no-cyclic-sig.rs:8:7: 8:10]>) -> _` - found closure signature `fn(_) -> _` + = note: closures cannot capture themselves or take themselves as argument; + this error may be the result of a recent compiler bug-fix, + see issue #46062 + for more information note: required by a bound in `g` --> $DIR/unboxed-closure-no-cyclic-sig.rs:5:24 | @@ -16,4 +16,4 @@ LL | fn g(_: F) where F: FnOnce(Option) {} error: aborting due to previous error -For more information about this error, try `rustc --explain E0631`. +For more information about this error, try `rustc --explain E0644`. -- cgit 1.4.1-3-g733a5 From fa2f31b97178c3a66d6e5f91fa597711f585fd3b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 7 Dec 2022 03:50:35 +0000 Subject: More tests --- src/test/ui/closures/supertrait-hint-cycle-2.rs | 18 ++++++++++++++++++ src/test/ui/closures/supertrait-hint-cycle-3.rs | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/closures/supertrait-hint-cycle-2.rs create mode 100644 src/test/ui/closures/supertrait-hint-cycle-3.rs diff --git a/src/test/ui/closures/supertrait-hint-cycle-2.rs b/src/test/ui/closures/supertrait-hint-cycle-2.rs new file mode 100644 index 00000000000..fda81b18d1e --- /dev/null +++ b/src/test/ui/closures/supertrait-hint-cycle-2.rs @@ -0,0 +1,18 @@ +// check-pass + +trait Foo<'a> { + type Input; +} + +impl Foo<'_> for F { + type Input = u32; +} + +trait SuperFn: for<'a> Foo<'a> + for<'a> Fn(>::Input) {} +impl SuperFn for T where T: for<'a> Fn(>::Input) + for<'a> Foo<'a> {} + +fn needs_super(_: impl SuperFn) {} + +fn main() { + needs_super(|_: u32| {}); +} diff --git a/src/test/ui/closures/supertrait-hint-cycle-3.rs b/src/test/ui/closures/supertrait-hint-cycle-3.rs new file mode 100644 index 00000000000..8149474df19 --- /dev/null +++ b/src/test/ui/closures/supertrait-hint-cycle-3.rs @@ -0,0 +1,16 @@ +// check-pass + + +trait Foo<'a> { + type Input; +} + +impl Foo<'_> for F { + type Input = u32; +} + +fn needs_super Fn(>::Input) + for<'a> Foo<'a>>(_: F) {} + +fn main() { + needs_super(|_: u32| {}); +} -- cgit 1.4.1-3-g733a5 From 82cf6f204aeb791c38463798e2edd6b4935f1296 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Wed, 16 Nov 2022 20:08:14 -0500 Subject: UPDATE - migrate base.rs to new diagnostics infrastructure --- compiler/rustc_codegen_ssa/src/base.rs | 16 +++++----------- compiler/rustc_codegen_ssa/src/errors.rs | 20 ++++++++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 7 +++++++ 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 8b34be38580..d318c15d342 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -5,6 +5,7 @@ use crate::back::write::{ submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen, }; use crate::common::{IntPredicate, RealPredicate, TypeKind}; +use crate::errors; use crate::meth; use crate::mir; use crate::mir::operand::OperandValue; @@ -451,10 +452,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let Some(llfn) = cx.declare_c_main(llfty) else { // FIXME: We should be smart and show a better diagnostic here. let span = cx.tcx().def_span(rust_main_def_id); - cx.sess() - .struct_span_err(span, "entry symbol `main` declared multiple times") - .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead") - .emit(); + cx.sess().emit_err(errors::MultipleMainFunctions { span }); cx.sess().abort_if_errors(); bug!(); }; @@ -595,8 +593,8 @@ pub fn codegen_crate( &metadata, &exported_symbols::metadata_symbol_name(tcx), ); - if let Err(err) = std::fs::write(&file_name, data) { - tcx.sess.fatal(&format!("error writing metadata object file: {}", err)); + if let Err(error) = std::fs::write(&file_name, data) { + tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error }); } Some(CompiledModule { name: metadata_cgu_name, @@ -815,11 +813,7 @@ impl CrateInfo { let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { - tcx.sess.fatal(&format!( - "invalid windows subsystem `{}`, only \ - `windows` and `console` are allowed", - subsystem - )); + tcx.sess.emit_fatal(errors::InvalidWindowsSubsystem { subsystem }); } subsystem.to_string() }); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 0620000201f..9179fe03d3f 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -555,3 +555,23 @@ pub struct ExpectedUsedSymbol { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_multiple_main_functions)] +#[help] +pub struct MultipleMainFunctions { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_metadata_object_file_write)] +pub struct MetadataObjectFileWrite { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_windows_subsystem)] +pub struct InvalidWindowsSubsystem { + pub subsystem: Symbol, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index db4c82b35c7..1863dae258f 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -194,3 +194,10 @@ codegen_ssa_unknown_archive_kind = Don't know how to build archive of type: {$kind} codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` + +codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times + .help = did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead + +codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error} + +codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed -- cgit 1.4.1-3-g733a5 From 78796ba637d9c8b575e977ddfc9351e4f1626319 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sat, 5 Nov 2022 23:54:42 -0400 Subject: ADD - fixme in type_names.rs until we are able to translate InterpError --- compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 3ae6c531b44..1599ccbb259 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -93,6 +93,7 @@ fn push_debuginfo_type_name<'tcx>( Err(e) => { // Computing the layout can still fail here, e.g. if the target architecture // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961. + // FIXME: migrate once `rustc_middle::mir::interpret::InterpError` is translatable. tcx.sess.fatal(&format!("{}", e)); } } -- cgit 1.4.1-3-g733a5 From d41112a8c5f0b85649b4f0e1663edf15f7f2601e Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 6 Nov 2022 10:09:24 -0500 Subject: UPDATE - migrate constant.rs to new diagnostics infrastructure --- compiler/rustc_codegen_ssa/src/errors.rs | 14 ++++++++++++++ compiler/rustc_codegen_ssa/src/mir/constant.rs | 5 +++-- .../rustc_error_messages/locales/en-US/codegen_ssa.ftl | 4 ++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 9179fe03d3f..de0a80280be 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -575,3 +575,17 @@ pub struct MetadataObjectFileWrite { pub struct InvalidWindowsSubsystem { pub subsystem: Symbol, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_erroneous_constant)] +pub struct ErroneousConstant { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_shuffle_indices_evaluation)] +pub struct ShuffleIndicesEvaluation { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 53ff3c24096..3cae19b241d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -1,3 +1,4 @@ +use crate::errors; use crate::mir::operand::OperandRef; use crate::traits::*; use rustc_middle::mir; @@ -44,7 +45,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| { match err { ErrorHandled::Reported(_) => { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + self.cx.tcx().sess.emit_err(errors::ErroneousConstant { span: constant.span }); } ErrorHandled::TooGeneric => { span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); @@ -87,7 +88,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (llval, c.ty()) }) .unwrap_or_else(|_| { - bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time"); + bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span }); // We've errored, so we don't have to produce working code. let ty = self.monomorphize(ty); let llty = bx.backend_type(bx.layout_of(ty)); diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 1863dae258f..88fb7ce8d9f 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -201,3 +201,7 @@ codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple time codegen_ssa_metadata_object_file_write = error writing metadata object file: {$error} codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed + +codegen_ssa_erroneous_constant = erroneous constant encountered + +codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time -- cgit 1.4.1-3-g733a5 From e26366ad99a6da4df5c9b476eff00c48e50d1774 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 13 Nov 2022 14:03:22 -0500 Subject: [WIP] UPDATE - migrate intrinsic.rs to new diagnostic infrastructure WIP - replacing span_invalid_monomorphization_error function. Still in progress due to its use in codegen_llvm inside macros --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 13 ++--- compiler/rustc_codegen_ssa/src/errors.rs | 43 +++++++++++++++ compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 64 ++++------------------ .../locales/en-US/codegen_ssa.ftl | 14 +++++ 4 files changed, 74 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1ce48f82e1c..82c6c389494 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -10,6 +10,7 @@ use crate::value::Value; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; +use rustc_codegen_ssa::errors::InvalidMonomorphization; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; @@ -284,15 +285,11 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => bug!(), }, None => { - span_invalid_monomorphization_error( - tcx.sess, + tcx.sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", - name, ty - ), - ); + name, + ty, + }); return; } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index de0a80280be..7303ab96797 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -6,6 +6,7 @@ use rustc_errors::{ IntoDiagnosticArg, }; use rustc_macros::Diagnostic; +use rustc_middle::ty::Ty; use rustc_span::{Span, Symbol}; use std::borrow::Cow; use std::io::Error; @@ -589,3 +590,45 @@ pub struct ShuffleIndicesEvaluation { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa_missing_memory_ordering)] +pub struct MissingMemoryOrdering; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unknown_atomic_ordering)] +pub struct UnknownAtomicOrdering; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_atomic_compare_exchange)] +pub struct AtomicCompareExchange; + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unknown_atomic_operation)] +pub struct UnknownAtomicOperation; + +#[derive(Diagnostic)] +pub enum InvalidMonomorphization<'tcx> { + #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = "E0511")] + BasicIntegerType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = "E0511")] + BasicFloatType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = "E0511")] + FloatToIntUnchecked { + #[primary_span] + span: Span, + ty: Ty<'tcx>, + }, +} diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index a75609260ed..766dc74cbbb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,7 +1,9 @@ use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; use super::FunctionCx; -use crate::common::{span_invalid_monomorphization_error, IntPredicate}; +use crate::common::IntPredicate; +use crate::errors; +use crate::errors::InvalidMonomorphization; use crate::glue; use crate::meth; use crate::traits::*; @@ -305,15 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!(), }, None => { - span_invalid_monomorphization_error( - bx.tcx().sess, - span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", - name, ty - ), - ); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); return; } } @@ -329,15 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!(), }, None => { - span_invalid_monomorphization_error( - bx.tcx().sess, - span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic float type, found `{}`", - name, arg_tys[0] - ), - ); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty: arg_tys[0] }); return; } } @@ -345,29 +331,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::float_to_int_unchecked => { if float_type_width(arg_tys[0]).is_none() { - span_invalid_monomorphization_error( - bx.tcx().sess, - span, - &format!( - "invalid monomorphization of `float_to_int_unchecked` \ - intrinsic: expected basic float type, \ - found `{}`", - arg_tys[0] - ), - ); + bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: arg_tys[0] }); return; } let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else { - span_invalid_monomorphization_error( - bx.tcx().sess, - span, - &format!( - "invalid monomorphization of `float_to_int_unchecked` \ - intrinsic: expected basic integer type, \ - found `{}`", - ret_ty - ), - ); + bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: ret_ty }); return; }; if signed { @@ -402,7 +370,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { use crate::common::{AtomicRmwBinOp, SynchronizationScope}; let Some((instruction, ordering)) = atomic.split_once('_') else { - bx.sess().fatal("Atomic intrinsic missing memory ordering"); + bx.sess().emit_fatal(errors::MissingMemoryOrdering); }; let parse_ordering = |bx: &Bx, s| match s { @@ -412,25 +380,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "release" => Release, "acqrel" => AcquireRelease, "seqcst" => SequentiallyConsistent, - _ => bx.sess().fatal("unknown ordering in atomic intrinsic"), + _ => bx.sess().emit_fatal(errors::UnknownAtomicOrdering), }; let invalid_monomorphization = |ty| { - span_invalid_monomorphization_error( - bx.tcx().sess, - span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", - name, ty - ), - ); + bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty }); }; match instruction { "cxchg" | "cxchgweak" => { let Some((success, failure)) = ordering.split_once('_') else { - bx.sess().fatal("Atomic compare-exchange intrinsic missing failure memory ordering"); + bx.sess().emit_fatal(errors::AtomicCompareExchange); }; let ty = substs.type_at(0); if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() { @@ -529,7 +489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { "min" => AtomicRmwBinOp::AtomicMin, "umax" => AtomicRmwBinOp::AtomicUMax, "umin" => AtomicRmwBinOp::AtomicUMin, - _ => bx.sess().fatal("unknown atomic operation"), + _ => bx.sess().emit_fatal(errors::UnknownAtomicOperation), }; let ty = substs.type_at(0); diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 88fb7ce8d9f..889d2900371 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -205,3 +205,17 @@ codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}` codegen_ssa_erroneous_constant = erroneous constant encountered codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time + +codegen_ssa_missing_memory_ordering = Atomic intrinsic missing memory ordering + +codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic + +codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering + +codegen_ssa_unknown_atomic_operation = unknown atomic operation + +codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` + +codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` + +codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}` -- cgit 1.4.1-3-g733a5 From d1030fab229d25d3ca14b1aaa2fc8e5a6ec932a8 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Thu, 17 Nov 2022 08:53:14 -0500 Subject: UPDATE - migrate fn simd_simple_float_intrinsic error messages --- Cargo.lock | 2 ++ compiler/rustc_codegen_llvm/src/intrinsic.rs | 41 +++++++--------------- compiler/rustc_codegen_ssa/Cargo.toml | 1 + compiler/rustc_codegen_ssa/src/errors.rs | 25 +++++++++++++ .../locales/en-US/codegen_ssa.ftl | 6 ++++ compiler/rustc_errors/Cargo.toml | 1 + compiler/rustc_errors/src/diagnostic_impls.rs | 7 ++++ 7 files changed, 55 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97148641670..6f630b479ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3636,6 +3636,7 @@ dependencies = [ "rustc_span", "rustc_symbol_mangling", "rustc_target", + "rustc_type_ir", "serde_json", "smallvec", "snap", @@ -3770,6 +3771,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "rustc_type_ir", "serde", "serde_json", "termcolor", diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 82c6c389494..032063d23b6 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1165,42 +1165,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span: Span, args: &[OperandRef<'tcx, &'ll Value>], ) -> Result<&'ll Value, ()> { - #[allow(unused_macro_rules)] - macro_rules! emit_error { - ($msg: tt) => { - emit_error!($msg, ) - }; - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } - macro_rules! return_error { - ($($fmt: tt)*) => { - { - emit_error!($($fmt)*); - return Err(()); - } - } - } - let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); match f.bit_width() { 32 => ("f32", elem_ty), 64 => ("f64", elem_ty), _ => { - return_error!( - "unsupported element type `{}` of floating-point vector `{}`", - f.name_str(), - in_ty - ); + bx.sess().emit_err(InvalidMonomorphization::FloatingPointVector { + span, + name, + f_ty: *f, + in_ty, + }); + return Err(()); } } } else { - return_error!("`{}` is not a floating-point type", in_ty); + bx.sess().emit_err(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); + return Err(()); }; let vec_ty = bx.type_vector(elem_ty, in_len); @@ -1222,7 +1204,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), - _ => return_error!("unrecognized intrinsic `{}`", name), + _ => { + bx.sess().emit_err(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }); + return Err(()); + } }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 345174fb595..d1ad687e6ae 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -27,6 +27,7 @@ rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } +rustc_type_ir = { path = "../rustc_type_ir" } rustc_attr = { path = "../rustc_attr" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 7303ab96797..5ecba6925fa 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -8,6 +8,7 @@ use rustc_errors::{ use rustc_macros::Diagnostic; use rustc_middle::ty::Ty; use rustc_span::{Span, Symbol}; +use rustc_type_ir::FloatTy; use std::borrow::Cow; use std::io::Error; use std::path::{Path, PathBuf}; @@ -631,4 +632,28 @@ pub enum InvalidMonomorphization<'tcx> { span: Span, ty: Ty<'tcx>, }, + + #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = "E0511")] + FloatingPointVector { + #[primary_span] + span: Span, + name: Symbol, + f_ty: FloatTy, + in_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = "E0511")] + FloatingPointType { + #[primary_span] + span: Span, + name: Symbol, + in_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = "E0511")] + UnrecognizedIntrinsic { + #[primary_span] + span: Span, + name: Symbol, + }, } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 889d2900371..0d9a9d851fc 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -219,3 +219,9 @@ codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphizati codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}` + +codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}` + +codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type + +codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index dee7a31ec20..cadd53fbd83 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -17,6 +17,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_target = { path = "../rustc_target" } rustc_hir = { path = "../rustc_hir" } rustc_lint_defs = { path = "../rustc_lint_defs" } +rustc_type_ir = { path = "../rustc_type_ir" } unicode-width = "0.1.4" termcolor = "1.0" annotate-snippets = "0.9" diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 628cb90903f..794b6efcc2b 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -9,6 +9,7 @@ use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; use rustc_target::abi::TargetDataLayoutErrors; use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; +use rustc_type_ir as type_ir; use std::borrow::Cow; use std::fmt; use std::num::ParseIntError; @@ -170,6 +171,12 @@ impl IntoDiagnosticArg for ast::token::TokenKind { } } +impl IntoDiagnosticArg for type_ir::FloatTy { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Borrowed(self.name_str())) + } +} + impl IntoDiagnosticArg for Level { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { DiagnosticArgValue::Str(Cow::Borrowed(match self { -- cgit 1.4.1-3-g733a5 From 27744460e2d0b960a55a28637ba46835484e4335 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Wed, 23 Nov 2022 01:07:36 -0500 Subject: ADD - create and emit Bug support for Diagnostics UPDATE - migrate constant span_bug to translatable diagnostic. --- compiler/rustc_codegen_ssa/src/errors.rs | 7 +++ compiler/rustc_codegen_ssa/src/mir/constant.rs | 6 ++- .../locales/en-US/codegen_ssa.ftl | 2 + compiler/rustc_errors/src/diagnostic_builder.rs | 55 +++++++++++++++++++++- compiler/rustc_errors/src/lib.rs | 14 ++++++ 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 5ecba6925fa..852925a1787 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -585,6 +585,13 @@ pub struct ErroneousConstant { pub span: Span, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_polymorphic_constant_too_generic)] +pub struct PolymorphicConstantTooGeneric { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_shuffle_indices_evaluation)] pub struct ShuffleIndicesEvaluation { diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 3cae19b241d..14fe84a146d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -48,7 +48,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.cx.tcx().sess.emit_err(errors::ErroneousConstant { span: constant.span }); } ErrorHandled::TooGeneric => { - span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); + self.cx + .tcx() + .sess + .diagnostic() + .emit_bug(errors::PolymorphicConstantTooGeneric { span: constant.span }); } } err diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 0d9a9d851fc..d10c399bb6a 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -225,3 +225,5 @@ codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphiz codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` + +codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index a2ed988643f..cbfee582d87 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -1,7 +1,7 @@ use crate::diagnostic::IntoDiagnosticArg; use crate::{ Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, - SubdiagnosticMessage, + ExplicitBug, SubdiagnosticMessage, }; use crate::{Handler, Level, MultiSpan, StashKey}; use rustc_lint_defs::Applicability; @@ -12,6 +12,7 @@ use std::borrow::Cow; use std::fmt::{self, Debug}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +use std::panic; use std::thread::panicking; /// Trait implemented by error types. This should not be implemented manually. Instead, use @@ -308,6 +309,58 @@ impl EmissionGuarantee for Noted { } } +/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for +/// bug struct diagnostics. +#[derive(Copy, Clone)] +pub struct Bug; + +impl<'a> DiagnosticBuilder<'a, Bug> { + /// Convenience function for internal use, clients should use one of the + /// `struct_*` methods on [`Handler`]. + #[track_caller] + pub(crate) fn new_bug(handler: &'a Handler, message: impl Into) -> Self { + let diagnostic = Diagnostic::new_with_code(Level::Bug, None, message); + Self::new_diagnostic_bug(handler, diagnostic) + } + + /// Creates a new `DiagnosticBuilder` with an already constructed + /// diagnostic. + pub(crate) fn new_diagnostic_bug(handler: &'a Handler, diagnostic: Diagnostic) -> Self { + debug!("Created new diagnostic bug"); + Self { + inner: DiagnosticBuilderInner { + state: DiagnosticBuilderState::Emittable(handler), + diagnostic: Box::new(diagnostic), + }, + _marker: PhantomData, + } + } +} + +impl EmissionGuarantee for Bug { + fn diagnostic_builder_emit_producing_guarantee(db: &mut DiagnosticBuilder<'_, Self>) -> Self { + match db.inner.state { + // First `.emit()` call, the `&Handler` is still available. + DiagnosticBuilderState::Emittable(handler) => { + db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; + + handler.emit_diagnostic(&mut db.inner.diagnostic); + } + // `.emit()` was previously called, disallowed from repeating it. + DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation => {} + } + // Then panic. No need to return the marker type. + panic::panic_any(ExplicitBug); + } + + fn make_diagnostic_builder( + handler: &Handler, + msg: impl Into, + ) -> DiagnosticBuilder<'_, Self> { + DiagnosticBuilder::new_bug(handler, msg) + } +} + impl<'a> DiagnosticBuilder<'a, !> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b03352d5fec..cf9741366a1 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1127,6 +1127,20 @@ impl Handler { self.create_fatal(fatal).emit() } + pub fn create_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> DiagnosticBuilder<'a, diagnostic_builder::Bug> { + bug.into_diagnostic(self) + } + + pub fn emit_bug<'a>( + &'a self, + bug: impl IntoDiagnostic<'a, diagnostic_builder::Bug>, + ) -> diagnostic_builder::Bug { + self.create_bug(bug).emit() + } + fn emit_diag_at_span( &self, mut diag: Diagnostic, -- cgit 1.4.1-3-g733a5 From 29d8c87fe88f51bdc7e6197e2e8eed7adc898f49 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sat, 26 Nov 2022 20:28:01 -0500 Subject: DELETE - fn span_invalid_monomorphization_error and localize intrinsics macros --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 529 +++++++++++---------- compiler/rustc_codegen_ssa/src/common.rs | 6 - compiler/rustc_codegen_ssa/src/errors.rs | 322 +++++++++++++ .../locales/en-US/codegen_ssa.ftl | 66 +++ 4 files changed, 670 insertions(+), 253 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 032063d23b6..680d810f78e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -8,9 +8,8 @@ use crate::va_arg::emit_va_arg; use crate::value::Value; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh}; -use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; -use rustc_codegen_ssa::errors::InvalidMonomorphization; +use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization}; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; @@ -835,40 +834,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>( llret_ty: &'ll Type, span: Span, ) -> Result<&'ll Value, ()> { - // macros for error handling: - #[allow(unused_macro_rules)] - macro_rules! emit_error { - ($msg: tt) => { - emit_error!($msg, ) - }; - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } - macro_rules! return_error { - ($($fmt: tt)*) => { - { - emit_error!($($fmt)*); - return Err(()); - } - } + ($diag: expr) => {{ + bx.sess().emit_err($diag); + return Err(()); + }}; } macro_rules! require { - ($cond: expr, $($fmt: tt)*) => { + ($cond: expr, $diag: expr) => { if !$cond { - return_error!($($fmt)*); + return_error!($diag); } }; } macro_rules! require_simd { - ($ty: expr, $position: expr) => { - require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) + ($ty: expr, $diag: expr) => { + require!($ty.is_simd(), $diag) }; } @@ -878,7 +861,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let arg_tys = sig.inputs(); if name == sym::simd_select_bitmask { - require_simd!(arg_tys[1], "argument"); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + ); + let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let expected_int_bits = (len.max(8) - 1).next_power_of_two(); @@ -899,12 +886,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty)); bx.load(int_ty, ptr, Align::ONE) } - _ => return_error!( - "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`", + _ => return_error!(InvalidMonomorphization::InvalidBitmask { + span, + name, mask_ty, expected_int_bits, expected_bytes - ), + }), }; let i1 = bx.type_i1(); @@ -916,7 +904,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } // every intrinsic below takes a SIMD vector as its first argument - require_simd!(arg_tys[0], "input"); + require_simd!(arg_tys[0], InvalidMonomorphization::SimdInput { span, name, ty: arg_tys[0] }); let in_ty = arg_tys[0]; let comparison = match name { @@ -931,23 +919,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx()); if let Some(cmp_op) = comparison { - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); + require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); require!( bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, - "expected return type with integer elements, found `{}` with non-integer `{}`", - ret_ty, - out_ty + InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty } ); return Ok(compare_simd_types( @@ -972,10 +961,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span_bug!(span, "could not evaluate shuffle index array length") }) } - _ => return_error!( - "simd_shuffle index must be an array of `u32`, got `{}`", - args[2].layout.ty - ), + _ => return_error!(InvalidMonomorphization::SimdShuffle { + span, + name, + ty: args[2].layout.ty + }), } } else { stripped.parse().unwrap_or_else(|_| { @@ -983,23 +973,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }) }; - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, - "expected return type of length {}, found `{}` with length {}", - n, - ret_ty, - out_len + InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len } ); require!( in_elem == out_ty, - "expected return element type `{}` (element of input `{}`), \ - found `{}` with element type `{}`", - in_elem, - in_ty, - ret_ty, - out_ty + InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } ); let total_len = u128::from(in_len) * 2; @@ -1012,15 +994,20 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let val = bx.const_get_elt(vector, i as u64); match bx.const_to_opt_u128(val, true) { None => { - emit_error!("shuffle index #{} is not a constant", arg_idx); + bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexNotConstant { + span, + name, + arg_idx, + }); None } Some(idx) if idx >= total_len => { - emit_error!( - "shuffle index #{} is out of bounds (limit {})", + bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds { + span, + name, arg_idx, - total_len - ); + total_len, + }); None } Some(idx) => Some(bx.const_i32(idx as i32)), @@ -1041,10 +1028,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_insert { require!( in_elem == arg_tys[2], - "expected inserted type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - arg_tys[2] + InvalidMonomorphization::InsertedType { + span, + name, + in_elem, + in_ty, + out_ty: arg_tys[2] + } ); return Ok(bx.insert_element( args[0].immediate(), @@ -1055,10 +1045,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_extract { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())); } @@ -1066,17 +1053,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::simd_select { let m_elem_ty = in_elem; let m_len = in_len; - require_simd!(arg_tys[1], "argument"); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] } + ); let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); require!( m_len == v_len, - "mismatched lengths: mask length `{}` != other vector length `{}`", - m_len, - v_len + InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); match m_elem_ty.kind() { ty::Int(_) => {} - _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), + _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }), } // truncate the mask to a vector of i1s let i1 = bx.type_i1(); @@ -1108,11 +1096,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>( args[0].immediate(), i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), ), - _ => return_error!( - "vector argument `{}`'s element type `{}`, expected integer element type", + _ => return_error!(InvalidMonomorphization::VectorArgument { + span, + name, in_ty, in_elem - ), + }), }; // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. @@ -1147,12 +1136,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty)); return Ok(bx.load(array_ty, ptr, Align::ONE)); } - _ => return_error!( - "cannot return `{}`, expected `u{}` or `[u8; {}]`", + _ => return_error!(InvalidMonomorphization::CannotReturn { + span, + name, ret_ty, expected_int_bits, expected_bytes - ), + }), } } @@ -1165,24 +1155,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>( span: Span, args: &[OperandRef<'tcx, &'ll Value>], ) -> Result<&'ll Value, ()> { + macro_rules! return_error { + ($diag: expr) => {{ + bx.sess().emit_err($diag); + return Err(()); + }}; + } + let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); match f.bit_width() { 32 => ("f32", elem_ty), 64 => ("f64", elem_ty), - _ => { - bx.sess().emit_err(InvalidMonomorphization::FloatingPointVector { - span, - name, - f_ty: *f, - in_ty, - }); - return Err(()); - } + _ => return_error!(InvalidMonomorphization::FloatingPointVector { + span, + name, + f_ty: *f, + in_ty, + }), } } else { - bx.sess().emit_err(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); - return Err(()); + return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; let vec_ty = bx.type_vector(elem_ty, in_len); @@ -1204,10 +1197,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), - _ => { - bx.sess().emit_err(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }); - return Err(()); - } + _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }), }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); @@ -1301,37 +1291,48 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // * M: any integer width is supported, will be truncated to i1 // All types must be simd vector types - require_simd!(in_ty, "first"); - require_simd!(arg_tys[1], "second"); - require_simd!(arg_tys[2], "third"); - require_simd!(ret_ty, "return"); + require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + ); + require_simd!( + arg_tys[2], + InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + ); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); // Of the same length: let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", - "second", - in_len, - in_ty, - arg_tys[1], - out_len + InvalidMonomorphization::SecondArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[1], + out_len + } ); require!( in_len == out_len2, - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", - "third", - in_len, - in_ty, - arg_tys[2], - out_len2 + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[2], + out_len: out_len2 + } ); // The return type must match the first argument type - require!(ret_ty == in_ty, "expected return type `{}`, found `{}`", in_ty, ret_ty); + require!( + ret_ty == in_ty, + InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty } + ); // This counts how many pointers fn ptr_count(t: Ty<'_>) -> usize { @@ -1358,15 +1359,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => { require!( false, - "expected element type `{}` of second argument `{}` \ - to be a pointer to the element type `{}` of the first \ - argument `{}`, found `{}` != `*_ {}`", - element_ty1, - arg_tys[1], - in_elem, - in_ty, - element_ty1, - in_elem + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: element_ty1, + second_arg: arg_tys[1], + in_elem, + in_ty, + mutability: ExpectedPointerMutability::Not, + } ); unreachable!(); } @@ -1382,10 +1383,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => { require!( false, - "expected element type `{}` of third argument `{}` \ - to be a signed integer type", - element_ty2, - arg_tys[2] + InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + } ); } } @@ -1434,32 +1437,40 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // * M: any integer width is supported, will be truncated to i1 // All types must be simd vector types - require_simd!(in_ty, "first"); - require_simd!(arg_tys[1], "second"); - require_simd!(arg_tys[2], "third"); + require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty }); + require_simd!( + arg_tys[1], + InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] } + ); + require_simd!( + arg_tys[2], + InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] } + ); // Of the same length: let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); require!( in_len == element_len1, - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", - "second", - in_len, - in_ty, - arg_tys[1], - element_len1 + InvalidMonomorphization::SecondArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[1], + out_len: element_len1 + } ); require!( in_len == element_len2, - "expected {} argument with length {} (same as input type `{}`), \ - found `{}` with length {}", - "third", - in_len, - in_ty, - arg_tys[2], - element_len2 + InvalidMonomorphization::ThirdArgumentLength { + span, + name, + in_len, + in_ty, + arg_ty: arg_tys[2], + out_len: element_len2 + } ); // This counts how many pointers @@ -1490,15 +1501,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => { require!( false, - "expected element type `{}` of second argument `{}` \ - to be a pointer to the element type `{}` of the first \ - argument `{}`, found `{}` != `*mut {}`", - element_ty1, - arg_tys[1], - in_elem, - in_ty, - element_ty1, - in_elem + InvalidMonomorphization::ExpectedElementType { + span, + name, + expected_element: element_ty1, + second_arg: arg_tys[1], + in_elem, + in_ty, + mutability: ExpectedPointerMutability::Mut, + } ); unreachable!(); } @@ -1513,10 +1524,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>( _ => { require!( false, - "expected element type `{}` of third argument `{}` \ - be a signed integer type", - element_ty2, - arg_tys[2] + InvalidMonomorphization::ThirdArgElementType { + span, + name, + expected_element: element_ty2, + third_arg: arg_tys[2] + } ); } } @@ -1563,10 +1576,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_) | ty::Uint(_) => { @@ -1589,25 +1599,28 @@ fn generic_simd_intrinsic<'ll, 'tcx>( 32 => bx.const_real(bx.type_f32(), $identity), 64 => bx.const_real(bx.type_f64(), $identity), v => return_error!( - r#" -unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, - sym::$name, - in_ty, - in_elem, - v, - ret_ty + InvalidMonomorphization::UnsupportedSymbolOfSize { + span, + name, + symbol: sym::$name, + in_ty, + in_elem, + size: v, + ret_ty + } ), } }; Ok(bx.$float_reduce(acc, args[0].immediate())) } - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, + _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { + span, + name, + symbol: sym::$name, in_ty, in_elem, ret_ty - ), + }), }; } }; @@ -1635,22 +1648,20 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)), ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)), ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())), - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, + _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { + span, + name, + symbol: sym::$name, in_ty, in_elem, ret_ty - ), + }), }; } }; @@ -1668,22 +1679,20 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, let input = if !$boolean { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty } ); args[0].immediate() } else { match in_elem.kind() { ty::Int(_) | ty::Uint(_) => {} - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, + _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { + span, + name, + symbol: sym::$name, in_ty, in_elem, ret_ty - ), + }), } // boolean reductions operate on vectors of i1s: @@ -1696,13 +1705,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, let r = bx.$red(input); Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) } - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, + _ => return_error!(InvalidMonomorphization::UnsupportedSymbol { + span, + name, + symbol: sym::$name, in_ty, in_elem, ret_ty - ), + }), }; } }; @@ -1715,16 +1725,18 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, bitwise_red!(simd_reduce_any: vector_reduce_or, true); if name == sym::simd_cast_ptr { - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); match in_elem.kind() { @@ -1733,9 +1745,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) }); assert!(!check_sized); // we are in codegen, so we shouldn't see these types - require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem) + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) } - _ => return_error!("expected pointer, got `{}`", in_elem), } match out_elem.kind() { ty::RawPtr(p) => { @@ -1743,9 +1760,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) }); assert!(!check_sized); // we are in codegen, so we shouldn't see these types - require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem) + require!( + metadata.is_unit(), + InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem } + ); + } + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) } - _ => return_error!("expected pointer, got `{}`", out_elem), } if in_elem == out_elem { @@ -1756,66 +1778,76 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, } if name == sym::simd_expose_addr { - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); match in_elem.kind() { ty::RawPtr(_) => {} - _ => return_error!("expected pointer, got `{}`", in_elem), + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem }) + } } match out_elem.kind() { ty::Uint(ty::UintTy::Usize) => {} - _ => return_error!("expected `usize`, got `{}`", out_elem), + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }), } return Ok(bx.ptrtoint(args[0].immediate(), llret_ty)); } if name == sym::simd_from_exposed_addr { - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); match in_elem.kind() { ty::Uint(ty::UintTy::Usize) => {} - _ => return_error!("expected `usize`, got `{}`", in_elem), + _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }), } match out_elem.kind() { ty::RawPtr(_) => {} - _ => return_error!("expected pointer, got `{}`", out_elem), + _ => { + return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem }) + } } return Ok(bx.inttoptr(args[0].immediate(), llret_ty)); } if name == sym::simd_cast || name == sym::simd_as { - require_simd!(ret_ty, "return"); + require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty }); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphization::ReturnLengthInputType { + span, + name, + in_len, + in_ty, + ret_ty, + out_len + } ); // casting cares about nominal type, not just structural type if in_elem == out_elem { @@ -1894,11 +1926,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, } require!( false, - "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", - in_ty, - in_elem, - ret_ty, - out_elem + InvalidMonomorphization::UnsupportedCast { + span, + name, + in_ty, + in_elem, + ret_ty, + out_elem + } ); } macro_rules! arith_binary { @@ -1910,10 +1945,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + require!( + false, + InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem } + ); })* } } @@ -1941,10 +1976,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + require!( + false, + InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem } + ); })* } } @@ -1982,12 +2017,12 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), _ => { - return_error!( - "expected element type `{}` of vector type `{}` \ - to be a signed or unsigned integer type", - arg_tys[0].simd_size_and_type(bx.tcx()).1, - arg_tys[0] - ); + return_error!(InvalidMonomorphization::ExpectedVectorElementType { + span, + name, + expected_element: arg_tys[0].simd_size_and_type(bx.tcx()).1, + vector_type: arg_tys[0] + }); } }; let llvm_intrinsic = &format!( diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 71f9179d02c..e1abb73a504 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -1,10 +1,8 @@ #![allow(non_camel_case_types)] -use rustc_errors::struct_span_err; use rustc_hir::LangItem; use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt}; -use rustc_session::Session; use rustc_span::Span; use crate::base; @@ -193,10 +191,6 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } -pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { - struct_span_err!(a, b, E0511, "{}", c).emit(); -} - pub fn asm_const_to_str<'tcx>( tcx: TyCtxt<'tcx>, sp: Span, diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 852925a1787..29876b95422 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -663,4 +663,326 @@ pub enum InvalidMonomorphization<'tcx> { span: Span, name: Symbol, }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = "E0511")] + SimdArgument { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = "E0511")] + SimdInput { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = "E0511")] + SimdFirst { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = "E0511")] + SimdSecond { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = "E0511")] + SimdThird { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = "E0511")] + SimdReturn { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = "E0511")] + InvalidBitmask { + #[primary_span] + span: Span, + name: Symbol, + mask_ty: Ty<'tcx>, + expected_int_bits: u64, + expected_bytes: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = "E0511")] + ReturnLengthInputType { + #[primary_span] + span: Span, + name: Symbol, + in_len: u64, + in_ty: Ty<'tcx>, + ret_ty: Ty<'tcx>, + out_len: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = "E0511")] + SecondArgumentLength { + #[primary_span] + span: Span, + name: Symbol, + in_len: u64, + in_ty: Ty<'tcx>, + arg_ty: Ty<'tcx>, + out_len: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = "E0511")] + ThirdArgumentLength { + #[primary_span] + span: Span, + name: Symbol, + in_len: u64, + in_ty: Ty<'tcx>, + arg_ty: Ty<'tcx>, + out_len: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = "E0511")] + ReturnIntegerType { + #[primary_span] + span: Span, + name: Symbol, + ret_ty: Ty<'tcx>, + out_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = "E0511")] + SimdShuffle { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_return_length, code = "E0511")] + ReturnLength { + #[primary_span] + span: Span, + name: Symbol, + in_len: u64, + ret_ty: Ty<'tcx>, + out_len: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_return_element, code = "E0511")] + ReturnElement { + #[primary_span] + span: Span, + name: Symbol, + in_elem: Ty<'tcx>, + in_ty: Ty<'tcx>, + ret_ty: Ty<'tcx>, + out_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = "E0511")] + ShuffleIndexNotConstant { + #[primary_span] + span: Span, + name: Symbol, + arg_idx: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = "E0511")] + ShuffleIndexOutOfBounds { + #[primary_span] + span: Span, + name: Symbol, + arg_idx: u64, + total_len: u128, + }, + + #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = "E0511")] + InsertedType { + #[primary_span] + span: Span, + name: Symbol, + in_elem: Ty<'tcx>, + in_ty: Ty<'tcx>, + out_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_return_type, code = "E0511")] + ReturnType { + #[primary_span] + span: Span, + name: Symbol, + in_elem: Ty<'tcx>, + in_ty: Ty<'tcx>, + ret_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = "E0511")] + ExpectedReturnType { + #[primary_span] + span: Span, + name: Symbol, + in_ty: Ty<'tcx>, + ret_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = "E0511")] + MismatchedLengths { + #[primary_span] + span: Span, + name: Symbol, + m_len: u64, + v_len: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = "E0511")] + MaskType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = "E0511")] + VectorArgument { + #[primary_span] + span: Span, + name: Symbol, + in_ty: Ty<'tcx>, + in_elem: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = "E0511")] + CannotReturn { + #[primary_span] + span: Span, + name: Symbol, + ret_ty: Ty<'tcx>, + expected_int_bits: u64, + expected_bytes: u64, + }, + + #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = "E0511")] + ExpectedElementType { + #[primary_span] + span: Span, + name: Symbol, + expected_element: Ty<'tcx>, + second_arg: Ty<'tcx>, + in_elem: Ty<'tcx>, + in_ty: Ty<'tcx>, + mutability: ExpectedPointerMutability, + }, + + #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = "E0511")] + ThirdArgElementType { + #[primary_span] + span: Span, + name: Symbol, + expected_element: Ty<'tcx>, + third_arg: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = "E0511")] + UnsupportedSymbolOfSize { + #[primary_span] + span: Span, + name: Symbol, + symbol: Symbol, + in_ty: Ty<'tcx>, + in_elem: Ty<'tcx>, + size: u64, + ret_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = "E0511")] + UnsupportedSymbol { + #[primary_span] + span: Span, + name: Symbol, + symbol: Symbol, + in_ty: Ty<'tcx>, + in_elem: Ty<'tcx>, + ret_ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = "E0511")] + CastFatPointer { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = "E0511")] + ExpectedPointer { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = "E0511")] + ExpectedUsize { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = "E0511")] + UnsupportedCast { + #[primary_span] + span: Span, + name: Symbol, + in_ty: Ty<'tcx>, + in_elem: Ty<'tcx>, + ret_ty: Ty<'tcx>, + out_elem: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = "E0511")] + UnsupportedOperation { + #[primary_span] + span: Span, + name: Symbol, + in_ty: Ty<'tcx>, + in_elem: Ty<'tcx>, + }, + + #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = "E0511")] + ExpectedVectorElementType { + #[primary_span] + span: Span, + name: Symbol, + expected_element: Ty<'tcx>, + vector_type: Ty<'tcx>, + }, +} + +pub enum ExpectedPointerMutability { + Mut, + Not, +} + +impl IntoDiagnosticArg for ExpectedPointerMutability { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + match self { + ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")), + ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")), + } + } } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index d10c399bb6a..c59c992afb2 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -226,4 +226,70 @@ codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphizat codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` +codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}` + +codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` + codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric + +codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len} + +codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} + +codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} + +codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}` + +codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}` + +codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len} + +codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}` + +codegen_ssa_invalid_monomorphization_shuffle_index_not_constant = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is not a constant + +codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is out of bounds (limit {$total_len}) + +codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}` + +codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` + +codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}` + +codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` + +codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_` + +codegen_ssa_invalid_monomorphization_vector_argument = invalid monomorphization of `{$name}` intrinsic: vector argument `{$in_ty}`'s element type `{$in_elem}`, expected integer element type + +codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` + +codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}` + +codegen_ssa_invalid_monomorphization_third_arg_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of third argument `{$third_arg}` to be a signed integer type + +codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}` + +codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` + +codegen_ssa_invalid_monomorphization_cast_fat_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast fat pointer `{$ty}` + +codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}` + +codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}` + +codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}` + +codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}` + +codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type -- cgit 1.4.1-3-g733a5 From 4d63d7d91c984342afd5bca0c5cf4cb1761973bf Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sat, 26 Nov 2022 21:12:44 -0500 Subject: UPDATE - migrate outstanding diagnostic in link.rs --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index edde1537b81..5324214ac78 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2612,7 +2612,7 @@ fn add_static_crate<'a>( sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum); let mut archive = archive_builder_builder.new_archive_builder(sess); - if let Err(e) = archive.add_archive( + if let Err(error) = archive.add_archive( cratepath, Box::new(move |f| { if f == METADATA_FILENAME { @@ -2652,7 +2652,7 @@ fn add_static_crate<'a>( false }), ) { - sess.fatal(&format!("failed to build archive from rlib: {}", e)); + sess.emit_fatal(errors::RlibArchiveBuildFailure { error }); } if archive.build(&dst) { link_upstream(&dst); -- cgit 1.4.1-3-g733a5 From 8360a40a8a2ff2098eed561dd89c577349dbbb76 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 8 Sep 2022 22:28:00 +0300 Subject: Migrate named_anon_conflict.rs --- .../rustc_error_messages/locales/en-US/infer.ftl | 11 +++++++ compiler/rustc_infer/src/errors/mod.rs | 24 ++++++++++++-- .../nice_region_error/named_anon_conflict.rs | 38 ++++++++-------------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index c9d83746d54..40ca2c1cd16 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -172,3 +172,14 @@ infer_msl_unmet_req = because this has an unmet lifetime requirement infer_msl_trait_note = this has an implicit `'static` lifetime requirement infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement infer_suggest_add_let_for_letchains = consider adding `let` + +infer_explicit_lifetime_required = explicit lifetime required in {$ident_kind -> + [ident] the type of `{$simple_ident}` + *[param_type] parameter type +} + .label = lifetime `{$named}` required + +infer_explicit_lifetime_required_sugg = add explicit lifetime `{$named}` to {$ident_kind -> + [ident] the type of `{$simple_ident}` + *[param_type] type +} diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index c4f11472d55..99112397c7f 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -357,8 +357,8 @@ impl AddToDiagnostic for LifetimeMismatchLabels { pub struct AddLifetimeParamsSuggestion<'a> { pub tcx: TyCtxt<'a>, pub sub: Region<'a>, - pub ty_sup: &'a Ty<'a>, - pub ty_sub: &'a Ty<'a>, + pub ty_sup: &'a hir::Ty<'a>, + pub ty_sub: &'a hir::Ty<'a>, pub add_note: bool, } @@ -520,3 +520,23 @@ pub struct MismatchedStaticLifetime<'a> { #[subdiagnostic] pub implicit_static_lifetimes: Vec, } + +#[derive(SessionDiagnostic)] +#[diag(infer::explicit_lifetime_required, code = "E0621")] +pub struct ExplicitLifetimeRequired<'a> { + #[primary_span] + #[label] + pub span: Span, + pub ident_kind: &'static str, + pub simple_ident: String, + pub named: String, + + #[suggestion( + infer::explicit_lifetime_required_sugg, + code = "{new_ty}", + applicability = "unspecified" + )] + pub new_ty_span: Span, + #[skip_arg] + pub new_ty: Ty<'a>, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 3fe7c1598fc..d7751158902 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -1,8 +1,11 @@ //! Error Reporting for Anonymous Region Lifetime Errors //! where one region is named and the other is anonymous. -use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type; use crate::infer::error_reporting::nice_region_error::NiceRegionError; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use crate::{ + errors::ExplicitLifetimeRequired, + infer::error_reporting::nice_region_error::find_anon_type::find_anon_type, +}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_middle::ty; use rustc_span::symbol::kw; @@ -87,30 +90,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { return None; } - let (error_var, span_label_var) = match param.pat.simple_ident() { - Some(simple_ident) => ( - format!("the type of `{}`", simple_ident), - format!("the type of `{}`", simple_ident), - ), - None => ("parameter type".to_owned(), "type".to_owned()), + let simple_ident = param.pat.simple_ident(); + let (ident_kind, simple_ident) = match simple_ident { + Some(ident) => ("ident", ident.to_string()), + None => ("param_type", String::new()), }; - let mut diag = struct_span_err!( - self.tcx().sess, - span, - E0621, - "explicit lifetime required in {}", - error_var - ); - - diag.span_label(span, format!("lifetime `{}` required", named)); - diag.span_suggestion( - new_ty_span, - &format!("add explicit lifetime `{}` to {}", named, span_label_var), - new_ty, - Applicability::Unspecified, - ); + let named = named.to_string(); - Some(diag) + let err = + ExplicitLifetimeRequired { span, ident_kind, simple_ident, named, new_ty_span, new_ty }; + let err = self.tcx().sess.parse_sess.create_err(err); + Some(err) } } -- cgit 1.4.1-3-g733a5 From 2118ff401f64789b6a9e64134d6d2797efee4be9 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 11 Sep 2022 00:45:38 +0300 Subject: Migrate placeholder_error.rs --- .../rustc_error_messages/locales/en-US/infer.ftl | 28 +++ compiler/rustc_infer/src/errors/mod.rs | 41 ++++ .../nice_region_error/placeholder_error.rs | 243 ++++++++++----------- 3 files changed, 186 insertions(+), 126 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 40ca2c1cd16..a52ac133946 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -183,3 +183,31 @@ infer_explicit_lifetime_required_sugg = add explicit lifetime `{$named}` to {$id [ident] the type of `{$simple_ident}` *[param_type] type } + +infer_actual_impl_expl_1 = {$leading_ellipsis -> + [true] ... + *[false] {""} +}{$kind -> + [signature] closure with signature `{$ty_or_sig}` must implement `{$trait_path}` + [passive] `{$trait_path}` would have to be implemented for the type `{$ty_or_sig}` + *[other] `{$ty_or_sig}` must implement `{$trait_path}` +}{$lt_kind -> + [two] , for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`... + [any] , for any lifetime `'{$lifetime_1}`... + [some] , for some specific lifetime `'{lifetime_1}`... + *[nothing] {""} +} + +infer_actual_impl_expl_2 = {$kind_2 -> + [implements_trait] ...but it actually implements `{$trait_path_2}` + [implemented_for_ty] ...but `{$trait_path_2}` is actually implemented for the type `{$ty}` + *[ty_implements] ...but `{$ty}` actually implements `{$trait_path_2}` +}{$has_lifetime -> + [true] , for some specific lifetime `'{$lifetime}` + *[false] {""} +} + +infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not general enough + .label_satisfy = doesn't satisfy where-clause + .label_where = due to a where-clause on `{$def_id}`... + .label_dup = implementation of `{$trait_def_id}` is not general enough diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 99112397c7f..f694c5ca409 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -540,3 +540,44 @@ pub struct ExplicitLifetimeRequired<'a> { #[skip_arg] pub new_ty: Ty<'a>, } + +#[derive(SessionSubdiagnostic)] +pub enum ActualImplExplNotes { + // Field names have to be different across all variants + #[note(infer::actual_impl_expl_1)] + NoteOne { + leading_ellipsis: bool, + kind: &'static str, + ty_or_sig: String, + trait_path: String, + lt_kind: &'static str, + lifetime_1: usize, + lifetime_2: usize, + }, + #[note(infer::actual_impl_expl_2)] + NoteTwo { + kind_2: &'static str, + trait_path_2: String, + has_lifetime: bool, + lifetime: usize, + ty: String, + }, +} + +#[derive(SessionDiagnostic)] +#[diag(infer::trait_placeholder_mismatch)] +pub struct TraitPlaceholderMismatch { + #[primary_span] + pub span: Span, + #[label(infer::label_satisfy)] + pub satisfy_span: Option, + #[label(infer::label_where)] + pub where_span: Option, + #[label(infer::label_dup)] + pub dup_span: Option, + pub def_id: String, + pub trait_def_id: String, + + #[subdiagnostic] + pub actual_impl_expl_notes: Vec, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index fed9fda74bf..d9fc2ec243f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,10 +1,11 @@ +use crate::errors::{ActualImplExplNotes, TraitPlaceholderMismatch}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; -use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::error::ExpectedFound; @@ -12,7 +13,7 @@ use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, RePlaceholder, ReVar, Region, TyCtxt}; -use std::fmt::{self, Write}; +use std::fmt; impl<'tcx> NiceRegionError<'_, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and @@ -205,26 +206,21 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { actual_substs: SubstsRef<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let span = cause.span(); - let msg = format!( - "implementation of `{}` is not general enough", - self.tcx().def_path_str(trait_def_id), - ); - let mut err = self.tcx().sess.struct_span_err(span, &msg); - let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) - | ObligationCauseCode::ExprItemObligation(def_id, ..) = - *cause.code() - { - err.span_label(span, "doesn't satisfy where-clause"); - err.span_label( - self.tcx().def_span(def_id), - &format!("due to a where-clause on `{}`...", self.tcx().def_path_str(def_id)), - ); - true - } else { - err.span_label(span, &msg); - false - }; + let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = + if let ObligationCauseCode::ItemObligation(def_id) + | ObligationCauseCode::ExprItemObligation(def_id, ..) = *cause.code() + { + ( + true, + Some(span), + Some(self.tcx().def_span(def_id)), + None, + self.tcx().def_path_str(def_id), + ) + } else { + (false, None, None, Some(span), String::new()) + }; let expected_trait_ref = self .cx @@ -284,8 +280,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { ?expected_self_ty_has_vid, ); - self.explain_actual_impl_that_was_found( - &mut err, + let actual_impl_expl_notes = self.explain_actual_impl_that_was_found( sub_placeholder, sup_placeholder, has_sub, @@ -299,7 +294,17 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { leading_ellipsis, ); - err + let diag = TraitPlaceholderMismatch { + span, + satisfy_span, + where_span, + dup_span, + def_id, + trait_def_id: self.tcx().def_path_str(trait_def_id), + actual_impl_expl_notes, + }; + + self.tcx().sess.create_err(diag) } /// Add notes with details about the expected and actual trait refs, with attention to cases @@ -309,7 +314,6 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { /// due to the number of combinations we have to deal with. fn explain_actual_impl_that_was_found( &self, - err: &mut Diagnostic, sub_placeholder: Option>, sup_placeholder: Option>, has_sub: Option, @@ -321,7 +325,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { actual_has_vid: Option, any_self_ty_has_vid: bool, leading_ellipsis: bool, - ) { + ) -> Vec { // HACK(eddyb) maybe move this in a more central location. #[derive(Copy, Clone)] struct Highlighted<'tcx, T> { @@ -380,120 +384,107 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref); expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub); expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup); - err.note(&{ - let passive_voice = match (has_sub, has_sup) { - (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid, - (None, None) => { - expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid); - match expected_has_vid { - Some(_) => true, - None => any_self_ty_has_vid, - } - } - }; - let mut note = if same_self_type { - let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty()); - self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid); - - if self_ty.value.is_closure() - && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) - { - let closure_sig = self_ty.map(|closure| { - if let ty::Closure(_, substs) = closure.kind() { - self.tcx().signature_unclosure( - substs.as_closure().sig(), - rustc_hir::Unsafety::Normal, - ) - } else { - bug!("type is not longer closure"); - } - }); - - format!( - "{}closure with signature `{}` must implement `{}`", - if leading_ellipsis { "..." } else { "" }, - closure_sig, - expected_trait_ref.map(|tr| tr.print_only_trait_path()), - ) - } else { - format!( - "{}`{}` must implement `{}`", - if leading_ellipsis { "..." } else { "" }, - self_ty, - expected_trait_ref.map(|tr| tr.print_only_trait_path()), - ) + let passive_voice = match (has_sub, has_sup) { + (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid, + (None, None) => { + expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid); + match expected_has_vid { + Some(_) => true, + None => any_self_ty_has_vid, } - } else if passive_voice { - format!( - "{}`{}` would have to be implemented for the type `{}`", - if leading_ellipsis { "..." } else { "" }, - expected_trait_ref.map(|tr| tr.print_only_trait_path()), - expected_trait_ref.map(|tr| tr.self_ty()), + } + }; + + let (kind, ty_or_sig, trait_path) = if same_self_type { + let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty()); + self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid); + + if self_ty.value.is_closure() + && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) + { + let closure_sig = self_ty.map(|closure| { + if let ty::Closure(_, substs) = closure.kind() { + self.tcx().signature_unclosure( + substs.as_closure().sig(), + rustc_hir::Unsafety::Normal, + ) + } else { + bug!("type is not longer closure"); + } + }); + ( + "signature", + closure_sig.to_string(), + expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) } else { - format!( - "{}`{}` must implement `{}`", - if leading_ellipsis { "..." } else { "" }, - expected_trait_ref.map(|tr| tr.self_ty()), - expected_trait_ref.map(|tr| tr.print_only_trait_path()), + ( + "other", + self_ty.to_string(), + expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) - }; + } + } else if passive_voice { + ( + "passive", + expected_trait_ref.map(|tr| tr.self_ty()).to_string(), + expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + ) + } else { + ( + "other", + expected_trait_ref.map(|tr| tr.self_ty()).to_string(), + expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + ) + }; - match (has_sub, has_sup) { - (Some(n1), Some(n2)) => { - let _ = write!( - note, - ", for any two lifetimes `'{}` and `'{}`...", - std::cmp::min(n1, n2), - std::cmp::max(n1, n2), - ); - } - (Some(n), _) | (_, Some(n)) => { - let _ = write!(note, ", for any lifetime `'{}`...", n,); - } - (None, None) => { - if let Some(n) = expected_has_vid { - let _ = write!(note, ", for some specific lifetime `'{}`...", n,); - } + let (lt_kind, lifetime_1, lifetime_2) = match (has_sub, has_sup) { + (Some(n1), Some(n2)) => ("two", std::cmp::min(n1, n2), std::cmp::max(n1, n2)), + (Some(n), _) | (_, Some(n)) => ("any", n, 0), + (None, None) => { + if let Some(n) = expected_has_vid { + ("some", n, 0) + } else { + ("nothing", 0, 0) } } + }; - note - }); + let note_1 = ActualImplExplNotes::NoteOne { + leading_ellipsis, + kind, + ty_or_sig, + trait_path, + lt_kind, + lifetime_1, + lifetime_2, + }; let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref); actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid); - err.note(&{ - let passive_voice = match actual_has_vid { - Some(_) => any_self_ty_has_vid, - None => true, - }; - let mut note = if same_self_type { - format!( - "...but it actually implements `{}`", - actual_trait_ref.map(|tr| tr.print_only_trait_path()), - ) - } else if passive_voice { - format!( - "...but `{}` is actually implemented for the type `{}`", - actual_trait_ref.map(|tr| tr.print_only_trait_path()), - actual_trait_ref.map(|tr| tr.self_ty()), - ) - } else { - format!( - "...but `{}` actually implements `{}`", - actual_trait_ref.map(|tr| tr.self_ty()), - actual_trait_ref.map(|tr| tr.print_only_trait_path()), - ) - }; + let passive_voice = match actual_has_vid { + Some(_) => any_self_ty_has_vid, + None => true, + }; - if let Some(n) = actual_has_vid { - let _ = write!(note, ", for some specific lifetime `'{}`", n); - } + let trait_path_2 = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(); + let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string(); + let kind_2 = if same_self_type { + "implements_trait" + } else if passive_voice { + "implemented_for_ty" + } else { + "ty_implements" + }; - note - }); + let has_lifetime = actual_has_vid.is_some(); + let lifetime = actual_has_vid.unwrap_or_default(); + + let note_2 = + ActualImplExplNotes::NoteTwo { kind_2, trait_path_2, ty, has_lifetime, lifetime }; + + vec![note_1, note_2] } } -- cgit 1.4.1-3-g733a5 From 3935a81d473167387123f8d48087f5ee446f92c4 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 13 Sep 2022 20:11:42 +0300 Subject: Migrate trait_impl_difference.rs --- .../rustc_error_messages/locales/en-US/infer.ftl | 10 ++++++ compiler/rustc_infer/src/errors/mod.rs | 38 ++++++++++++++++++++ .../nice_region_error/trait_impl_difference.rs | 40 +++++++--------------- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index a52ac133946..d28608cf47d 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -211,3 +211,13 @@ infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not ge .label_satisfy = doesn't satisfy where-clause .label_where = due to a where-clause on `{$def_id}`... .label_dup = implementation of `{$trait_def_id}` is not general enough + +infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signature + .found = found `{$found}` + .expected = expected `{$expected}` + .expected_found = expected `{$expected}` + {" "}found `{$found}` + +infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output +infer_tid_consider_borriwing = consider borrowing this type parameter in the trait +infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index f694c5ca409..e2579ab7b7c 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -581,3 +581,41 @@ pub struct TraitPlaceholderMismatch { #[subdiagnostic] pub actual_impl_expl_notes: Vec, } + +pub struct ConsiderBorrowingParamHelp { + pub spans: Vec, +} + +impl AddSubdiagnostic for ConsiderBorrowingParamHelp { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + let mut type_param_span: MultiSpan = self.spans.clone().into(); + for &span in &self.spans { + type_param_span.push_span_label(span, fluent::infer::tid_consider_borriwing); + } + diag.span_help(type_param_span, fluent::infer::tid_param_help); + } +} + +#[derive(SessionSubdiagnostic)] +#[help(infer::tid_rel_help)] +pub struct RelationshipHelp; + +#[derive(SessionDiagnostic)] +#[diag(infer::trait_impl_diff)] +pub struct TraitImplDiff { + #[primary_span] + #[label(infer::found)] + pub sp: Span, + #[label(infer::expected)] + pub trait_sp: Span, + #[note(infer::expected_found)] + pub note: (), + #[subdiagnostic] + pub param_help: ConsiderBorrowingParamHelp, + #[subdiagnostic] + // Seems like subdiagnostics are always pushed to the end, so this one + // also has to be a subdiagnostic to maintain order. + pub rel_help: Option, + pub expected: String, + pub found: String, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 5d536e982ed..bacd8894a0f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -1,10 +1,11 @@ //! Error Reporting for `impl` items that do not match the obligations from their `trait`. +use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::Subtype; use crate::traits::ObligationCauseCode::CompareImplItemObligation; -use rustc_errors::{ErrorGuaranteed, MultiSpan}; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; @@ -51,10 +52,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { trait_def_id: DefId, ) -> ErrorGuaranteed { let trait_sp = self.tcx().def_span(trait_def_id); - let mut err = self - .tcx() - .sess - .struct_span_err(sp, "`impl` item signature doesn't match `trait` item signature"); // Mark all unnamed regions in the type with a number. // This diagnostic is called in response to lifetime errors, so be informative. @@ -91,9 +88,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let found = self.cx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name; - err.span_label(sp, &format!("found `{}`", found)); - err.span_label(trait_sp, &format!("expected `{}`", expected)); - // Get the span of all the used type parameters in the method. let assoc_item = self.tcx().associated_item(trait_def_id); let mut visitor = TypeParamSpanVisitor { tcx: self.tcx(), types: vec![] }; @@ -110,26 +104,18 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } _ => {} } - let mut type_param_span: MultiSpan = visitor.types.to_vec().into(); - for &span in &visitor.types { - type_param_span - .push_span_label(span, "consider borrowing this type parameter in the trait"); - } - err.note(&format!("expected `{}`\n found `{}`", expected, found)); - - err.span_help( - type_param_span, - "the lifetime requirements from the `impl` do not correspond to the requirements in \ - the `trait`", - ); - if visitor.types.is_empty() { - err.help( - "verify the lifetime relationships in the `trait` and `impl` between the `self` \ - argument, the other inputs and its output", - ); - } - err.emit() + let diag = TraitImplDiff { + sp, + trait_sp, + note: (), + param_help: ConsiderBorrowingParamHelp { spans: visitor.types.to_vec() }, + rel_help: visitor.types.is_empty().then_some(RelationshipHelp), + expected, + found, + }; + + self.tcx().sess.emit_err(diag) } } -- cgit 1.4.1-3-g733a5 From 0634b0119cadbf4fcc90d8a399b1c46e1442a5b5 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sat, 17 Sep 2022 02:54:59 +0300 Subject: Partial work on static_impl_trait.rs --- .../rustc_error_messages/locales/en-US/infer.ftl | 52 ++++++ compiler/rustc_infer/src/errors/mod.rs | 97 +++++++++++ .../nice_region_error/static_impl_trait.rs | 183 ++++++++------------- 3 files changed, 221 insertions(+), 111 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index d28608cf47d..7a10f4b7bc5 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -221,3 +221,55 @@ infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signatu infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output infer_tid_consider_borriwing = consider borrowing this type parameter in the trait infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + +infer_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement +infer_dtcs_introduces_requirement = calling this method introduces the `impl`'s 'static` requirement +infer_dtcs_has_req_note = the used `impl` has a `'static` requirement +infer_dtcs_suggestion = consider relaxing the implicit `'static` requirement + +infer_but_calling_introduces = {$has_param_name -> + [true] `{$param_name}` + *[false] `fn` parameter +} has {$lifetime_kind -> + [named] lifetime `{lifetime}` + *[anon] an anonymous lifetime `'_` +} but calling `{assoc_item}` introduces an implicit `'static` lifetime requirement + .label1 = {$has_lifetime -> + [named] lifetime `{lifetime}` + *[anon] an anonymous lifetime `'_` + } + .label2 = ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the {$has_impl_path -> + [named] `impl` of `{$impl_path}` + *[anon] inherent `impl` + } + +infer_but_needs_to_satisfy = {$has_param_name -> + [true] `{$param_name}` + *[false] `fn` parameter +} has {$has_lifetime -> + [named] lifetime `{lifetime}` + *[anon] an anonymous lifetime `'_` +} but it needs to satisfy a `'static` lifetime requirement + .influencer = this data with {$has_lifetime -> + [named] lifetime `{lifetime}` + *[anon] an anonymous lifetime `'_` + }... + .require = {$spans_empty -> + *[true] ...is used and required to live as long as `'static` here + [false] ...and is required to live as long as `'static` here + } + .used_here = ...is used here... + .introduced_by_bound = 'static` lifetime requirement introduced by this bound + +infer_more_targeted = {$has_param_name -> + [true] `{$param_name}` + *[false] `fn` parameter +} has {$has_lifetime -> + [named] lifetime `{lifetime}` + *[anon] an anonymous lifetime `'_` +} but calling `{$ident}` introduces an implicit `'static` lifetime requirement + +infer_ril_introduced_here = `'static` requirement introduced here +infer_ril_introduced_by = requirement introduced by this return type +infer_ril_because_of = because of this returned expression +infer_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index e2579ab7b7c..dc79c725951 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -8,6 +8,7 @@ use rustc_hir::{FnRetTy, Ty}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::{Region, TyCtxt}; use rustc_span::symbol::kw; +use rustc_span::Symbol; use rustc_span::{symbol::Ident, BytePos, Span}; use crate::infer::error_reporting::{ @@ -619,3 +620,99 @@ pub struct TraitImplDiff { pub expected: String, pub found: String, } + +pub struct DynTraitConstraintSuggestion { + pub span: Span, + pub ident: Ident, +} + +impl AddSubdiagnostic for DynTraitConstraintSuggestion { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + let mut multi_span: MultiSpan = vec![self.span].into(); + multi_span.push_span_label(self.span, fluent::infer::dtcs_has_lifetime_req_label); + multi_span.push_span_label(self.ident.span, fluent::infer::dtcs_introduces_requirement); + diag.span_note(multi_span, fluent::infer::dtcs_has_req_note); + diag.span_suggestion_verbose( + self.span.shrink_to_hi(), + fluent::infer::dtcs_suggestion, + " + '_", + Applicability::MaybeIncorrect, + ); + } +} + +#[derive(SessionDiagnostic)] +#[diag(infer::but_calling_introduces, code = "E0772")] +pub struct ButCallingIntroduces { + #[label(infer::label1)] + pub param_ty_span: Span, + #[primary_span] + #[label(infer::label2)] + pub cause_span: Span, + + pub has_param_name: bool, + pub param_name: String, + pub has_lifetime: bool, + pub lifetime: String, + pub assoc_item: Symbol, + pub has_impl_path: bool, + pub impl_path: String, +} + +pub struct ReqIntroducedLocations { + pub span: MultiSpan, + pub spans: Vec, + pub fn_decl_span: Span, + pub cause_span: Span, + pub add_label: bool, +} + +impl AddSubdiagnostic for ReqIntroducedLocations { + fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { + for sp in self.spans { + self.span.push_span_label(sp, fluent::infer::ril_introduced_here); + } + + if self.add_label { + self.span.push_span_label(self.fn_decl_span, fluent::infer::ril_introduced_by); + } + self.span.push_span_label(self.cause_span, fluent::infer::ril_because_of); + diag.span_note(self.span, fluent::infer::ril_static_introduced_by); + } +} + +pub struct MoreTargeted { + pub ident: Symbol, +} + +impl AddSubdiagnostic for MoreTargeted { + fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + diag.code(rustc_errors::error_code!(E0772)); + diag.set_primary_message(fluent::infer::more_targeted); + diag.set_arg("ident", self.ident); + } +} + +#[derive(SessionDiagnostic)] +#[diag(infer::but_needs_to_satisfy, code = "E0759")] +pub struct ButNeedsToSatisfy { + #[primary_span] + pub sp: Span, + #[label(infer::influencer)] + pub influencer_point: Span, + #[label(infer::used_here)] + pub spans: Vec, + #[label(infer::require)] + pub require_span_as_label: Option, + #[note(infer::require)] + pub require_span_as_note: Option, + #[note(infer::introduced_by_bound)] + pub bound: Option, + + #[subdiagnostic] + pub req_introduces_loc: Option, + + pub spans_empty: bool, + pub has_lifetime: bool, + pub lifetime: String, +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9bd2202d260..b76f7e7689f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -1,11 +1,15 @@ //! Error Reporting for static impl Traits. +use crate::errors::{ + ButCallingIntroduces, ButNeedsToSatisfy, DynTraitConstraintSuggestion, MoreTargeted, + ReqIntroducedLocations, +}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; -use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::{AddSubdiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; @@ -49,46 +53,33 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } let param = self.find_param_with_region(*sup_r, *sub_r)?; - let lifetime = if sup_r.has_name() { - format!("lifetime `{}`", sup_r) - } else { - "an anonymous lifetime `'_`".to_string() + let simple_ident = param.param.pat.simple_ident(); + + let (has_impl_path, impl_path) = match ctxt.assoc_item.container { + AssocItemContainer::TraitContainer => { + let id = ctxt.assoc_item.container_id(tcx); + (true, tcx.def_path_str(id)) + } + AssocItemContainer::ImplContainer => (false, String::new()), }; - let mut err = struct_span_err!( - tcx.sess, - cause.span, - E0772, - "{} has {} but calling `{}` introduces an implicit `'static` lifetime \ - requirement", - param - .param - .pat - .simple_ident() - .map(|s| format!("`{}`", s)) - .unwrap_or_else(|| "`fn` parameter".to_string()), - lifetime, - ctxt.assoc_item.name, - ); - err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime)); - err.span_label( - cause.span, - &format!( - "...is used and required to live as long as `'static` here \ - because of an implicit lifetime bound on the {}", - match ctxt.assoc_item.container { - AssocItemContainer::TraitContainer => { - let id = ctxt.assoc_item.container_id(tcx); - format!("`impl` of `{}`", tcx.def_path_str(id)) - } - AssocItemContainer::ImplContainer => "inherent `impl`".to_string(), - }, - ), - ); + + let diag = 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, + }; + let mut err = self.tcx().sess.create_err(diag); if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) { let reported = err.emit(); return Some(reported); } else { - err.cancel(); + err.cancel() } } return None; @@ -104,25 +95,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let sp = var_origin.span(); let return_sp = sub_origin.span(); let param = self.find_param_with_region(*sup_r, *sub_r)?; - let (lifetime_name, lifetime) = if sup_r.has_name() { - (sup_r.to_string(), format!("lifetime `{}`", sup_r)) - } else { - ("'_".to_owned(), "an anonymous lifetime `'_`".to_string()) - }; - let param_name = param - .param - .pat - .simple_ident() - .map(|s| format!("`{}`", s)) - .unwrap_or_else(|| "`fn` parameter".to_string()); - let mut err = struct_span_err!( - tcx.sess, - sp, - E0759, - "{} has {} but it needs to satisfy a `'static` lifetime requirement", - param_name, - lifetime, - ); + let lifetime_name = if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() }; let (mention_influencer, influencer_point) = if sup_origin.span().overlaps(param.param_ty_span) { @@ -141,7 +114,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } else { (!sup_origin.span().overlaps(return_sp), param.param_ty_span) }; - err.span_label(influencer_point, &format!("this data with {}...", lifetime)); debug!("try_report_static_impl_trait: param_info={:?}", param); @@ -155,31 +127,19 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { spans.dedup_by_key(|span| (span.lo(), span.hi())); // We try to make the output have fewer overlapping spans if possible. - let require_msg = if spans.is_empty() { - "...is used and required to live as long as `'static` here" - } else { - "...and is required to live as long as `'static` here" - }; let require_span = if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp }; - for span in &spans { - err.span_label(*span, "...is used here..."); - } - - if spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp) { - // If any of the "captured here" labels appears on the same line or after - // `require_span`, we put it on a note to ensure the text flows by appearing - // always at the end. - err.span_note(require_span, require_msg); + let spans_empty = spans.is_empty(); + let require_as_note = spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp); + let bound = if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { + Some(*bound) } else { - // We don't need a note, it's already at the end, it can be shown as a `span_label`. - err.span_label(require_span, require_msg); - } + None + }; + + let mut subdiag = None; - if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { - err.span_note(*bound, "`'static` lifetime requirement introduced by this bound"); - } if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin { if let ObligationCauseCode::ReturnValue(hir_id) | ObligationCauseCode::BlockTailExpression(hir_id) = cause.code() @@ -187,33 +147,50 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { 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(ty); if !v.0.is_empty() { span = v.0.clone().into(); - for sp in v.0 { - span.push_span_label(sp, "`'static` requirement introduced here"); - } + spans = v.0; add_label = false; } } - if add_label { - span.push_span_label( - fn_decl.output.span(), - "requirement introduced by this return type", - ); - } - span.push_span_label(cause.span, "because of this returned expression"); - err.span_note( + let fn_decl_span = fn_decl.output.span(); + + subdiag = Some(ReqIntroducedLocations { span, - "`'static` lifetime requirement introduced by the return type", - ); + spans, + fn_decl_span, + cause_span: cause.span, + add_label, + }); } } } + let diag = ButNeedsToSatisfy { + sp, + influencer_point, + spans: spans.clone(), + // If any of the "captured here" labels appears on the same line or after + // `require_span`, we put it on a note to ensure the text flows by appearing + // always at the end. + 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: sup_r.to_string(), + spans_empty, + bound, + }; + + let mut err = self.tcx().sess.create_err(diag); + let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); let mut override_error_code = None; @@ -247,12 +224,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) { // Provide a more targeted error code and description. - err.code(rustc_errors::error_code!(E0772)); - err.set_primary_message(&format!( - "{} has {} but calling `{}` introduces an implicit `'static` lifetime \ - requirement", - param_name, lifetime, ident, - )); + let retarget_subdiag = MoreTargeted { ident }; + retarget_subdiag.add_to_diagnostic(&mut err); } let arg = match param.param.pat.simple_ident() { @@ -513,21 +486,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut traits = vec![]; let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did); hir_v.visit_ty(&self_ty); - for span in &traits { - let mut multi_span: MultiSpan = vec![*span].into(); - multi_span - .push_span_label(*span, "this has an implicit `'static` lifetime requirement"); - multi_span.push_span_label( - ident.span, - "calling this method introduces the `impl`'s 'static` requirement", - ); - err.span_note(multi_span, "the used `impl` has a `'static` requirement"); - err.span_suggestion_verbose( - span.shrink_to_hi(), - "consider relaxing the implicit `'static` requirement", - " + '_", - Applicability::MaybeIncorrect, - ); + for &span in &traits { + let subdiag = DynTraitConstraintSuggestion { span, ident }; + subdiag.add_to_diagnostic(err); suggested = true; } } -- cgit 1.4.1-3-g733a5 From 57fdd196aeda1e0fa5829248bd4afb8e6f06d7e5 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 22 Sep 2022 17:29:21 +0300 Subject: Rebase and fix --- compiler/rustc_infer/src/errors/mod.rs | 26 +++++++++++----------- .../nice_region_error/static_impl_trait.rs | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index dc79c725951..55df63075d2 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -4,9 +4,9 @@ use rustc_errors::{ MultiSpan, SubdiagnosticMessage, }; use rustc_hir as hir; -use rustc_hir::{FnRetTy, Ty}; +use rustc_hir::FnRetTy; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::{Region, TyCtxt}; +use rustc_middle::ty::{Region, Ty, TyCtxt}; use rustc_span::symbol::kw; use rustc_span::Symbol; use rustc_span::{symbol::Ident, BytePos, Span}; @@ -522,7 +522,7 @@ pub struct MismatchedStaticLifetime<'a> { pub implicit_static_lifetimes: Vec, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(infer::explicit_lifetime_required, code = "E0621")] pub struct ExplicitLifetimeRequired<'a> { #[primary_span] @@ -542,7 +542,7 @@ pub struct ExplicitLifetimeRequired<'a> { pub new_ty: Ty<'a>, } -#[derive(SessionSubdiagnostic)] +#[derive(Subdiagnostic)] pub enum ActualImplExplNotes { // Field names have to be different across all variants #[note(infer::actual_impl_expl_1)] @@ -565,7 +565,7 @@ pub enum ActualImplExplNotes { }, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(infer::trait_placeholder_mismatch)] pub struct TraitPlaceholderMismatch { #[primary_span] @@ -587,7 +587,7 @@ pub struct ConsiderBorrowingParamHelp { pub spans: Vec, } -impl AddSubdiagnostic for ConsiderBorrowingParamHelp { +impl AddToDiagnostic for ConsiderBorrowingParamHelp { fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { let mut type_param_span: MultiSpan = self.spans.clone().into(); for &span in &self.spans { @@ -597,11 +597,11 @@ impl AddSubdiagnostic for ConsiderBorrowingParamHelp { } } -#[derive(SessionSubdiagnostic)] +#[derive(Subdiagnostic)] #[help(infer::tid_rel_help)] pub struct RelationshipHelp; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(infer::trait_impl_diff)] pub struct TraitImplDiff { #[primary_span] @@ -626,7 +626,7 @@ pub struct DynTraitConstraintSuggestion { pub ident: Ident, } -impl AddSubdiagnostic for DynTraitConstraintSuggestion { +impl AddToDiagnostic for DynTraitConstraintSuggestion { fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { let mut multi_span: MultiSpan = vec![self.span].into(); multi_span.push_span_label(self.span, fluent::infer::dtcs_has_lifetime_req_label); @@ -641,7 +641,7 @@ impl AddSubdiagnostic for DynTraitConstraintSuggestion { } } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(infer::but_calling_introduces, code = "E0772")] pub struct ButCallingIntroduces { #[label(infer::label1)] @@ -667,7 +667,7 @@ pub struct ReqIntroducedLocations { pub add_label: bool, } -impl AddSubdiagnostic for ReqIntroducedLocations { +impl AddToDiagnostic for ReqIntroducedLocations { fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { for sp in self.spans { self.span.push_span_label(sp, fluent::infer::ril_introduced_here); @@ -685,7 +685,7 @@ pub struct MoreTargeted { pub ident: Symbol, } -impl AddSubdiagnostic for MoreTargeted { +impl AddToDiagnostic for MoreTargeted { fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { diag.code(rustc_errors::error_code!(E0772)); diag.set_primary_message(fluent::infer::more_targeted); @@ -693,7 +693,7 @@ impl AddSubdiagnostic for MoreTargeted { } } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(infer::but_needs_to_satisfy, code = "E0759")] pub struct ButNeedsToSatisfy { #[primary_span] diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index b76f7e7689f..fbc71bd7e01 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -9,7 +9,7 @@ use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{AddSubdiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; -- cgit 1.4.1-3-g733a5 From 6c19c08140b7c0c5a9f9f9a434036b460167c87d Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sun, 25 Sep 2022 10:55:42 +0300 Subject: More descriptive names for ActualImplExplNotes variants --- compiler/rustc_error_messages/locales/en-US/infer.ftl | 4 ++-- compiler/rustc_infer/src/errors/mod.rs | 8 ++++---- .../infer/error_reporting/nice_region_error/placeholder_error.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 7a10f4b7bc5..8cfd20c6eda 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -184,7 +184,7 @@ infer_explicit_lifetime_required_sugg = add explicit lifetime `{$named}` to {$id *[param_type] type } -infer_actual_impl_expl_1 = {$leading_ellipsis -> +infer_actual_impl_expl_expected = {$leading_ellipsis -> [true] ... *[false] {""} }{$kind -> @@ -198,7 +198,7 @@ infer_actual_impl_expl_1 = {$leading_ellipsis -> *[nothing] {""} } -infer_actual_impl_expl_2 = {$kind_2 -> +infer_actual_impl_expl_but_actually = {$kind_2 -> [implements_trait] ...but it actually implements `{$trait_path_2}` [implemented_for_ty] ...but `{$trait_path_2}` is actually implemented for the type `{$ty}` *[ty_implements] ...but `{$ty}` actually implements `{$trait_path_2}` diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 55df63075d2..edd9eca24cb 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -545,8 +545,8 @@ pub struct ExplicitLifetimeRequired<'a> { #[derive(Subdiagnostic)] pub enum ActualImplExplNotes { // Field names have to be different across all variants - #[note(infer::actual_impl_expl_1)] - NoteOne { + #[note(infer::actual_impl_expl_expected)] + Expected { leading_ellipsis: bool, kind: &'static str, ty_or_sig: String, @@ -555,8 +555,8 @@ pub enum ActualImplExplNotes { lifetime_1: usize, lifetime_2: usize, }, - #[note(infer::actual_impl_expl_2)] - NoteTwo { + #[note(infer::actual_impl_expl_but_actually)] + ButActually { kind_2: &'static str, trait_path_2: String, has_lifetime: bool, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index d9fc2ec243f..cf1032f7006 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -451,7 +451,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { } }; - let note_1 = ActualImplExplNotes::NoteOne { + let note_1 = ActualImplExplNotes::Expected { leading_ellipsis, kind, ty_or_sig, @@ -483,7 +483,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let lifetime = actual_has_vid.unwrap_or_default(); let note_2 = - ActualImplExplNotes::NoteTwo { kind_2, trait_path_2, ty, has_lifetime, lifetime }; + ActualImplExplNotes::ButActually { kind_2, trait_path_2, ty, has_lifetime, lifetime }; vec![note_1, note_2] } -- cgit 1.4.1-3-g733a5 From 71d24da665c122fe885d0f62917c01b7f8e8d77f Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 29 Sep 2022 17:10:43 +0300 Subject: Split into several messages --- .../rustc_error_messages/locales/en-US/infer.ftl | 71 +++++++-- compiler/rustc_infer/src/errors/mod.rs | 168 ++++++++++++++++++++- .../nice_region_error/placeholder_error.rs | 58 ++++--- 3 files changed, 250 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 8cfd20c6eda..4a43d150968 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -184,25 +184,64 @@ infer_explicit_lifetime_required_sugg = add explicit lifetime `{$named}` to {$id *[param_type] type } -infer_actual_impl_expl_expected = {$leading_ellipsis -> +infer_actual_impl_expl_expected_signature_two = {$leading_ellipsis -> [true] ... *[false] {""} -}{$kind -> - [signature] closure with signature `{$ty_or_sig}` must implement `{$trait_path}` - [passive] `{$trait_path}` would have to be implemented for the type `{$ty_or_sig}` - *[other] `{$ty_or_sig}` must implement `{$trait_path}` -}{$lt_kind -> - [two] , for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`... - [any] , for any lifetime `'{$lifetime_1}`... - [some] , for some specific lifetime `'{lifetime_1}`... - *[nothing] {""} -} +}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`... +infer_actual_impl_expl_expected_signature_any = {$leading_ellipsis -> + [true] ... + *[false] {""} +}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`... +infer_actual_impl_expl_expected_signature_some = {$leading_ellipsis -> + [true] ... + *[false] {""} +}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{lifetime_1}`... +infer_actual_impl_expl_expected_signature_nothing = {$leading_ellipsis -> + [true] ... + *[false] {""} +}closure with signature `{$ty_or_sig}` must implement `{$trait_path}` +infer_actual_impl_expl_expected_passive_two = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`... +infer_actual_impl_expl_expected_passive_any = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`... +infer_actual_impl_expl_expected_passive_some = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{lifetime_1}`... +infer_actual_impl_expl_expected_passive_nothing = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}` +infer_actual_impl_expl_expected_other_two = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`... +infer_actual_impl_expl_expected_other_any = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`... +infer_actual_impl_expl_expected_other_some = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{lifetime_1}`... +infer_actual_impl_expl_expected_other_nothing = {$leading_ellipsis -> + [true] ... + *[false] {""} +}`{$ty_or_sig}` must implement `{$trait_path}` -infer_actual_impl_expl_but_actually = {$kind_2 -> - [implements_trait] ...but it actually implements `{$trait_path_2}` - [implemented_for_ty] ...but `{$trait_path_2}` is actually implemented for the type `{$ty}` - *[ty_implements] ...but `{$ty}` actually implements `{$trait_path_2}` -}{$has_lifetime -> +infer_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path_2}`{$has_lifetime -> + [true] , for some specific lifetime `'{$lifetime}` + *[false] {""} +} +infer_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path_2}` is actually implemented for the type `{$ty}`{$has_lifetime -> + [true] , for some specific lifetime `'{$lifetime}` + *[false] {""} +} +infer_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path_2}`{$has_lifetime -> [true] , for some specific lifetime `'{$lifetime}` *[false] {""} } diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index edd9eca24cb..69fc3be2bc3 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -544,20 +544,90 @@ pub struct ExplicitLifetimeRequired<'a> { #[derive(Subdiagnostic)] pub enum ActualImplExplNotes { - // Field names have to be different across all variants - #[note(infer::actual_impl_expl_expected)] - Expected { + // Field names have to be different across Expected* and ButActually variants + #[note(infer::actual_impl_expl_expected_signature_two)] + ExpectedSignatureTwo { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + lifetime_2: usize, + }, + #[note(infer::actual_impl_expl_expected_signature_any)] + ExpectedSignatureAny { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_signature_some)] + ExpectedSignatureSome { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_signature_nothing)] + ExpectedSignatureNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + #[note(infer::actual_impl_expl_expected_passive_two)] + ExpectedPassiveTwo { leading_ellipsis: bool, - kind: &'static str, ty_or_sig: String, trait_path: String, - lt_kind: &'static str, lifetime_1: usize, lifetime_2: usize, }, - #[note(infer::actual_impl_expl_but_actually)] - ButActually { - kind_2: &'static str, + #[note(infer::actual_impl_expl_expected_passive_any)] + ExpectedPassiveAny { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_passive_some)] + ExpectedPassiveSome { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_passive_nothing)] + ExpectedPassiveNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + #[note(infer::actual_impl_expl_expected_other_two)] + ExpectedOtherTwo { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + lifetime_2: usize, + }, + #[note(infer::actual_impl_expl_expected_other_any)] + ExpectedOtherAny { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_other_some)] + ExpectedOtherSome { + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + }, + #[note(infer::actual_impl_expl_expected_other_nothing)] + ExpectedOtherNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + #[note(infer::actual_impl_expl_but_actually_implements_trait)] + ButActuallyImplementsTrait { trait_path_2: String, has_lifetime: bool, lifetime: usize }, + #[note(infer::actual_impl_expl_but_actually_implemented_for_ty)] + ButActuallyImplementedForTy { + trait_path_2: String, + has_lifetime: bool, + lifetime: usize, + ty: String, + }, + #[note(infer::actual_impl_expl_but_actually_ty_implements)] + ButActuallyTyImplements { trait_path_2: String, has_lifetime: bool, lifetime: usize, @@ -565,6 +635,88 @@ pub enum ActualImplExplNotes { }, } +pub enum ActualImplExpectedKind { + Signature, + Passive, + Other, +} + +pub enum ActualImplExpectedLifetimeKind { + Two, + Any, + Some, + Nothing, +} + +impl ActualImplExplNotes { + pub fn new_expected( + kind: ActualImplExpectedKind, + lt_kind: ActualImplExpectedLifetimeKind, + leading_ellipsis: bool, + ty_or_sig: String, + trait_path: String, + lifetime_1: usize, + lifetime_2: usize, + ) -> Self { + match (kind, lt_kind) { + (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => { + Self::ExpectedSignatureTwo { + leading_ellipsis, + ty_or_sig, + trait_path, + lifetime_1, + lifetime_2, + } + } + (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => { + Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => { + Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => { + Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path } + } + (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => { + Self::ExpectedPassiveTwo { + leading_ellipsis, + ty_or_sig, + trait_path, + lifetime_1, + lifetime_2, + } + } + (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => { + Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => { + Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => { + Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path } + } + (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => { + Self::ExpectedOtherTwo { + leading_ellipsis, + ty_or_sig, + trait_path, + lifetime_1, + lifetime_2, + } + } + (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => { + Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => { + Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 } + } + (ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => { + Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path } + } + } + } +} + #[derive(Diagnostic)] #[diag(infer::trait_placeholder_mismatch)] pub struct TraitPlaceholderMismatch { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index cf1032f7006..d2fd4f6cd7c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,4 +1,7 @@ -use crate::errors::{ActualImplExplNotes, TraitPlaceholderMismatch}; +use crate::errors::{ + ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes, + TraitPlaceholderMismatch, +}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::ValuePairs; @@ -414,52 +417,54 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { } }); ( - "signature", + ActualImplExpectedKind::Signature, closure_sig.to_string(), expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) } else { ( - "other", + ActualImplExpectedKind::Other, self_ty.to_string(), expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) } } else if passive_voice { ( - "passive", + ActualImplExpectedKind::Passive, expected_trait_ref.map(|tr| tr.self_ty()).to_string(), expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) } else { ( - "other", + ActualImplExpectedKind::Other, expected_trait_ref.map(|tr| tr.self_ty()).to_string(), expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), ) }; let (lt_kind, lifetime_1, lifetime_2) = match (has_sub, has_sup) { - (Some(n1), Some(n2)) => ("two", std::cmp::min(n1, n2), std::cmp::max(n1, n2)), - (Some(n), _) | (_, Some(n)) => ("any", n, 0), + (Some(n1), Some(n2)) => { + (ActualImplExpectedLifetimeKind::Two, std::cmp::min(n1, n2), std::cmp::max(n1, n2)) + } + (Some(n), _) | (_, Some(n)) => (ActualImplExpectedLifetimeKind::Any, n, 0), (None, None) => { if let Some(n) = expected_has_vid { - ("some", n, 0) + (ActualImplExpectedLifetimeKind::Some, n, 0) } else { - ("nothing", 0, 0) + (ActualImplExpectedLifetimeKind::Nothing, 0, 0) } } }; - let note_1 = ActualImplExplNotes::Expected { - leading_ellipsis, + let note_1 = ActualImplExplNotes::new_expected( kind, + lt_kind, + leading_ellipsis, ty_or_sig, trait_path, - lt_kind, lifetime_1, lifetime_2, - }; + ); let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref); actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid); @@ -471,19 +476,26 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let trait_path_2 = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(); let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string(); - let kind_2 = if same_self_type { - "implements_trait" - } else if passive_voice { - "implemented_for_ty" - } else { - "ty_implements" - }; - let has_lifetime = actual_has_vid.is_some(); let lifetime = actual_has_vid.unwrap_or_default(); - let note_2 = - ActualImplExplNotes::ButActually { kind_2, trait_path_2, ty, has_lifetime, lifetime }; + let note_2 = if same_self_type { + ActualImplExplNotes::ButActuallyImplementsTrait { trait_path_2, has_lifetime, lifetime } + } else if passive_voice { + ActualImplExplNotes::ButActuallyImplementedForTy { + trait_path_2, + ty, + has_lifetime, + lifetime, + } + } else { + ActualImplExplNotes::ButActuallyTyImplements { + trait_path_2, + ty, + has_lifetime, + lifetime, + } + }; vec![note_1, note_2] } -- cgit 1.4.1-3-g733a5 From eb7ce1703bb719c1d038be6572a349a3e70f7ca2 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Fri, 14 Oct 2022 21:50:06 +0300 Subject: Use eager translation --- .../rustc_error_messages/locales/en-US/infer.ftl | 2 +- compiler/rustc_infer/src/errors/mod.rs | 38 +++++++++++++++------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 4a43d150968..4219964a877 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -258,7 +258,7 @@ infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signatu {" "}found `{$found}` infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output -infer_tid_consider_borriwing = consider borrowing this type parameter in the trait +infer_tid_consider_borrowing = consider borrowing this type parameter in the trait infer_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` infer_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 69fc3be2bc3..9092874dfae 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -544,7 +544,6 @@ pub struct ExplicitLifetimeRequired<'a> { #[derive(Subdiagnostic)] pub enum ActualImplExplNotes { - // Field names have to be different across Expected* and ButActually variants #[note(infer::actual_impl_expl_expected_signature_two)] ExpectedSignatureTwo { leading_ellipsis: bool, @@ -731,7 +730,7 @@ pub struct TraitPlaceholderMismatch { pub def_id: String, pub trait_def_id: String, - #[subdiagnostic] + #[subdiagnostic(eager)] pub actual_impl_expl_notes: Vec, } @@ -740,12 +739,17 @@ pub struct ConsiderBorrowingParamHelp { } impl AddToDiagnostic for ConsiderBorrowingParamHelp { - fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, f: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { let mut type_param_span: MultiSpan = self.spans.clone().into(); for &span in &self.spans { - type_param_span.push_span_label(span, fluent::infer::tid_consider_borriwing); + // Seems like we can't call f() here as Into is required + type_param_span.push_span_label(span, fluent::infer::tid_consider_borrowing); } - diag.span_help(type_param_span, fluent::infer::tid_param_help); + let msg = f(diag, fluent::infer::tid_param_help.into()); + diag.span_help(type_param_span, msg); } } @@ -779,14 +783,19 @@ pub struct DynTraitConstraintSuggestion { } impl AddToDiagnostic for DynTraitConstraintSuggestion { - fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, f: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { let mut multi_span: MultiSpan = vec![self.span].into(); multi_span.push_span_label(self.span, fluent::infer::dtcs_has_lifetime_req_label); multi_span.push_span_label(self.ident.span, fluent::infer::dtcs_introduces_requirement); - diag.span_note(multi_span, fluent::infer::dtcs_has_req_note); + let msg = f(diag, fluent::infer::dtcs_has_req_note.into()); + diag.span_note(multi_span, msg); + let msg = f(diag, fluent::infer::dtcs_suggestion.into()); diag.span_suggestion_verbose( self.span.shrink_to_hi(), - fluent::infer::dtcs_suggestion, + msg, " + '_", Applicability::MaybeIncorrect, ); @@ -820,7 +829,10 @@ pub struct ReqIntroducedLocations { } impl AddToDiagnostic for ReqIntroducedLocations { - fn add_to_diagnostic(mut self, diag: &mut rustc_errors::Diagnostic) { + fn add_to_diagnostic_with(mut self, diag: &mut Diagnostic, f: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { for sp in self.spans { self.span.push_span_label(sp, fluent::infer::ril_introduced_here); } @@ -829,7 +841,8 @@ impl AddToDiagnostic for ReqIntroducedLocations { self.span.push_span_label(self.fn_decl_span, fluent::infer::ril_introduced_by); } self.span.push_span_label(self.cause_span, fluent::infer::ril_because_of); - diag.span_note(self.span, fluent::infer::ril_static_introduced_by); + let msg = f(diag, fluent::infer::ril_static_introduced_by.into()); + diag.span_note(self.span, msg); } } @@ -838,7 +851,10 @@ pub struct MoreTargeted { } impl AddToDiagnostic for MoreTargeted { - fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _f: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { diag.code(rustc_errors::error_code!(E0772)); diag.set_primary_message(fluent::infer::more_targeted); diag.set_arg("ident", self.ident); -- cgit 1.4.1-3-g733a5 From 40b221814ea00a9d279474188d81b9a063eb3f68 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Sat, 15 Oct 2022 13:16:51 +0300 Subject: Rename subdiagnostic fields that do not need to be unique now --- compiler/rustc_error_messages/locales/en-US/infer.ftl | 6 +++--- compiler/rustc_infer/src/errors/mod.rs | 11 +++-------- .../error_reporting/nice_region_error/placeholder_error.rs | 13 ++++--------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 4219964a877..f74af62702e 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -233,15 +233,15 @@ infer_actual_impl_expl_expected_other_nothing = {$leading_ellipsis -> *[false] {""} }`{$ty_or_sig}` must implement `{$trait_path}` -infer_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path_2}`{$has_lifetime -> +infer_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path}`{$has_lifetime -> [true] , for some specific lifetime `'{$lifetime}` *[false] {""} } -infer_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path_2}` is actually implemented for the type `{$ty}`{$has_lifetime -> +infer_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime -> [true] , for some specific lifetime `'{$lifetime}` *[false] {""} } -infer_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path_2}`{$has_lifetime -> +infer_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime -> [true] , for some specific lifetime `'{$lifetime}` *[false] {""} } diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 9092874dfae..1733b6e148f 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -617,21 +617,16 @@ pub enum ActualImplExplNotes { #[note(infer::actual_impl_expl_expected_other_nothing)] ExpectedOtherNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, #[note(infer::actual_impl_expl_but_actually_implements_trait)] - ButActuallyImplementsTrait { trait_path_2: String, has_lifetime: bool, lifetime: usize }, + ButActuallyImplementsTrait { trait_path: String, has_lifetime: bool, lifetime: usize }, #[note(infer::actual_impl_expl_but_actually_implemented_for_ty)] ButActuallyImplementedForTy { - trait_path_2: String, + trait_path: String, has_lifetime: bool, lifetime: usize, ty: String, }, #[note(infer::actual_impl_expl_but_actually_ty_implements)] - ButActuallyTyImplements { - trait_path_2: String, - has_lifetime: bool, - lifetime: usize, - ty: String, - }, + ButActuallyTyImplements { trait_path: String, has_lifetime: bool, lifetime: usize, ty: String }, } pub enum ActualImplExpectedKind { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index d2fd4f6cd7c..904723c4da9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -474,27 +474,22 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { None => true, }; - let trait_path_2 = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(); + let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(); let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string(); let has_lifetime = actual_has_vid.is_some(); let lifetime = actual_has_vid.unwrap_or_default(); let note_2 = if same_self_type { - ActualImplExplNotes::ButActuallyImplementsTrait { trait_path_2, has_lifetime, lifetime } + ActualImplExplNotes::ButActuallyImplementsTrait { trait_path, has_lifetime, lifetime } } else if passive_voice { ActualImplExplNotes::ButActuallyImplementedForTy { - trait_path_2, + trait_path, ty, has_lifetime, lifetime, } } else { - ActualImplExplNotes::ButActuallyTyImplements { - trait_path_2, - ty, - has_lifetime, - lifetime, - } + ActualImplExplNotes::ButActuallyTyImplements { trait_path, ty, has_lifetime, lifetime } }; vec![note_1, note_2] -- cgit 1.4.1-3-g733a5 From 19b8579803979dd3b1e83f7aa9655920eef14b98 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Mon, 24 Oct 2022 19:06:45 +0300 Subject: Address changes of pr 103345 --- compiler/rustc_infer/src/errors/mod.rs | 92 +++++++++++++++++----------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 1733b6e148f..51b04eb0df0 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -523,7 +523,7 @@ pub struct MismatchedStaticLifetime<'a> { } #[derive(Diagnostic)] -#[diag(infer::explicit_lifetime_required, code = "E0621")] +#[diag(infer_explicit_lifetime_required, code = "E0621")] pub struct ExplicitLifetimeRequired<'a> { #[primary_span] #[label] @@ -533,7 +533,7 @@ pub struct ExplicitLifetimeRequired<'a> { pub named: String, #[suggestion( - infer::explicit_lifetime_required_sugg, + infer_explicit_lifetime_required_sugg, code = "{new_ty}", applicability = "unspecified" )] @@ -544,7 +544,7 @@ pub struct ExplicitLifetimeRequired<'a> { #[derive(Subdiagnostic)] pub enum ActualImplExplNotes { - #[note(infer::actual_impl_expl_expected_signature_two)] + #[note(infer_actual_impl_expl_expected_signature_two)] ExpectedSignatureTwo { leading_ellipsis: bool, ty_or_sig: String, @@ -552,23 +552,23 @@ pub enum ActualImplExplNotes { lifetime_1: usize, lifetime_2: usize, }, - #[note(infer::actual_impl_expl_expected_signature_any)] + #[note(infer_actual_impl_expl_expected_signature_any)] ExpectedSignatureAny { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_signature_some)] + #[note(infer_actual_impl_expl_expected_signature_some)] ExpectedSignatureSome { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_signature_nothing)] + #[note(infer_actual_impl_expl_expected_signature_nothing)] ExpectedSignatureNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, - #[note(infer::actual_impl_expl_expected_passive_two)] + #[note(infer_actual_impl_expl_expected_passive_two)] ExpectedPassiveTwo { leading_ellipsis: bool, ty_or_sig: String, @@ -576,23 +576,23 @@ pub enum ActualImplExplNotes { lifetime_1: usize, lifetime_2: usize, }, - #[note(infer::actual_impl_expl_expected_passive_any)] + #[note(infer_actual_impl_expl_expected_passive_any)] ExpectedPassiveAny { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_passive_some)] + #[note(infer_actual_impl_expl_expected_passive_some)] ExpectedPassiveSome { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_passive_nothing)] + #[note(infer_actual_impl_expl_expected_passive_nothing)] ExpectedPassiveNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, - #[note(infer::actual_impl_expl_expected_other_two)] + #[note(infer_actual_impl_expl_expected_other_two)] ExpectedOtherTwo { leading_ellipsis: bool, ty_or_sig: String, @@ -600,32 +600,32 @@ pub enum ActualImplExplNotes { lifetime_1: usize, lifetime_2: usize, }, - #[note(infer::actual_impl_expl_expected_other_any)] + #[note(infer_actual_impl_expl_expected_other_any)] ExpectedOtherAny { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_other_some)] + #[note(infer_actual_impl_expl_expected_other_some)] ExpectedOtherSome { leading_ellipsis: bool, ty_or_sig: String, trait_path: String, lifetime_1: usize, }, - #[note(infer::actual_impl_expl_expected_other_nothing)] + #[note(infer_actual_impl_expl_expected_other_nothing)] ExpectedOtherNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, - #[note(infer::actual_impl_expl_but_actually_implements_trait)] + #[note(infer_actual_impl_expl_but_actually_implements_trait)] ButActuallyImplementsTrait { trait_path: String, has_lifetime: bool, lifetime: usize }, - #[note(infer::actual_impl_expl_but_actually_implemented_for_ty)] + #[note(infer_actual_impl_expl_but_actually_implemented_for_ty)] ButActuallyImplementedForTy { trait_path: String, has_lifetime: bool, lifetime: usize, ty: String, }, - #[note(infer::actual_impl_expl_but_actually_ty_implements)] + #[note(infer_actual_impl_expl_but_actually_ty_implements)] ButActuallyTyImplements { trait_path: String, has_lifetime: bool, lifetime: usize, ty: String }, } @@ -712,15 +712,15 @@ impl ActualImplExplNotes { } #[derive(Diagnostic)] -#[diag(infer::trait_placeholder_mismatch)] +#[diag(infer_trait_placeholder_mismatch)] pub struct TraitPlaceholderMismatch { #[primary_span] pub span: Span, - #[label(infer::label_satisfy)] + #[label(label_satisfy)] pub satisfy_span: Option, - #[label(infer::label_where)] + #[label(label_where)] pub where_span: Option, - #[label(infer::label_dup)] + #[label(label_dup)] pub dup_span: Option, pub def_id: String, pub trait_def_id: String, @@ -741,26 +741,26 @@ impl AddToDiagnostic for ConsiderBorrowingParamHelp { let mut type_param_span: MultiSpan = self.spans.clone().into(); for &span in &self.spans { // Seems like we can't call f() here as Into is required - type_param_span.push_span_label(span, fluent::infer::tid_consider_borrowing); + type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing); } - let msg = f(diag, fluent::infer::tid_param_help.into()); + let msg = f(diag, fluent::infer_tid_param_help.into()); diag.span_help(type_param_span, msg); } } #[derive(Subdiagnostic)] -#[help(infer::tid_rel_help)] +#[help(infer_tid_rel_help)] pub struct RelationshipHelp; #[derive(Diagnostic)] -#[diag(infer::trait_impl_diff)] +#[diag(infer_trait_impl_diff)] pub struct TraitImplDiff { #[primary_span] - #[label(infer::found)] + #[label(found)] pub sp: Span, - #[label(infer::expected)] + #[label(expected)] pub trait_sp: Span, - #[note(infer::expected_found)] + #[note(expected_found)] pub note: (), #[subdiagnostic] pub param_help: ConsiderBorrowingParamHelp, @@ -783,11 +783,11 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion { F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { let mut multi_span: MultiSpan = vec![self.span].into(); - multi_span.push_span_label(self.span, fluent::infer::dtcs_has_lifetime_req_label); - multi_span.push_span_label(self.ident.span, fluent::infer::dtcs_introduces_requirement); - let msg = f(diag, fluent::infer::dtcs_has_req_note.into()); + multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label); + multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement); + let msg = f(diag, fluent::infer_dtcs_has_req_note.into()); diag.span_note(multi_span, msg); - let msg = f(diag, fluent::infer::dtcs_suggestion.into()); + let msg = f(diag, fluent::infer_dtcs_suggestion.into()); diag.span_suggestion_verbose( self.span.shrink_to_hi(), msg, @@ -798,12 +798,12 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion { } #[derive(Diagnostic)] -#[diag(infer::but_calling_introduces, code = "E0772")] +#[diag(infer_but_calling_introduces, code = "E0772")] pub struct ButCallingIntroduces { - #[label(infer::label1)] + #[label(label1)] pub param_ty_span: Span, #[primary_span] - #[label(infer::label2)] + #[label(label2)] pub cause_span: Span, pub has_param_name: bool, @@ -829,14 +829,14 @@ impl AddToDiagnostic for ReqIntroducedLocations { F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { for sp in self.spans { - self.span.push_span_label(sp, fluent::infer::ril_introduced_here); + self.span.push_span_label(sp, fluent::infer_ril_introduced_here); } if self.add_label { - self.span.push_span_label(self.fn_decl_span, fluent::infer::ril_introduced_by); + self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by); } - self.span.push_span_label(self.cause_span, fluent::infer::ril_because_of); - let msg = f(diag, fluent::infer::ril_static_introduced_by.into()); + self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of); + let msg = f(diag, fluent::infer_ril_static_introduced_by.into()); diag.span_note(self.span, msg); } } @@ -851,25 +851,25 @@ impl AddToDiagnostic for MoreTargeted { F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { diag.code(rustc_errors::error_code!(E0772)); - diag.set_primary_message(fluent::infer::more_targeted); + diag.set_primary_message(fluent::infer_more_targeted); diag.set_arg("ident", self.ident); } } #[derive(Diagnostic)] -#[diag(infer::but_needs_to_satisfy, code = "E0759")] +#[diag(infer_but_needs_to_satisfy, code = "E0759")] pub struct ButNeedsToSatisfy { #[primary_span] pub sp: Span, - #[label(infer::influencer)] + #[label(influencer)] pub influencer_point: Span, - #[label(infer::used_here)] + #[label(used_here)] pub spans: Vec, - #[label(infer::require)] + #[label(require)] pub require_span_as_label: Option, - #[note(infer::require)] + #[note(require)] pub require_span_as_note: Option, - #[note(infer::introduced_by_bound)] + #[note(introduced_by_bound)] pub bound: Option, #[subdiagnostic] -- cgit 1.4.1-3-g733a5 From 7ecd064bbe32419eb473b28cdc8e41dd34f20aa9 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 3 Nov 2022 20:45:14 +0300 Subject: Split infer_explicit_lifetime_required into several diags --- .../rustc_error_messages/locales/en-US/infer.ftl | 15 ++++--- compiler/rustc_infer/src/errors/mod.rs | 49 ++++++++++++++-------- .../nice_region_error/named_anon_conflict.rs | 23 +++++----- 3 files changed, 50 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index f74af62702e..52babec4f9e 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -173,16 +173,15 @@ infer_msl_trait_note = this has an implicit `'static` lifetime requirement infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement infer_suggest_add_let_for_letchains = consider adding `let` -infer_explicit_lifetime_required = explicit lifetime required in {$ident_kind -> - [ident] the type of `{$simple_ident}` - *[param_type] parameter type -} +infer_explicit_lifetime_required_with_ident = explicit lifetime required in the type of `{$simple_ident}` .label = lifetime `{$named}` required -infer_explicit_lifetime_required_sugg = add explicit lifetime `{$named}` to {$ident_kind -> - [ident] the type of `{$simple_ident}` - *[param_type] type -} +infer_explicit_lifetime_required_with_param_type = explicit lifetime required in parameter type + .label = lifetime `{$named}` required + +infer_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}` + +infer_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type infer_actual_impl_expl_expected_signature_two = {$leading_ellipsis -> [true] ... diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 51b04eb0df0..9e3def93a6d 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -523,23 +523,38 @@ pub struct MismatchedStaticLifetime<'a> { } #[derive(Diagnostic)] -#[diag(infer_explicit_lifetime_required, code = "E0621")] -pub struct ExplicitLifetimeRequired<'a> { - #[primary_span] - #[label] - pub span: Span, - pub ident_kind: &'static str, - pub simple_ident: String, - pub named: String, - - #[suggestion( - infer_explicit_lifetime_required_sugg, - code = "{new_ty}", - applicability = "unspecified" - )] - pub new_ty_span: Span, - #[skip_arg] - pub new_ty: Ty<'a>, +pub enum ExplicitLifetimeRequired<'a> { + #[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")] + WithIdent { + #[primary_span] + #[label] + span: Span, + simple_ident: Ident, + named: String, + #[suggestion( + infer_explicit_lifetime_required_sugg_with_ident, + code = "{new_ty}", + applicability = "unspecified" + )] + new_ty_span: Span, + #[skip_arg] + new_ty: Ty<'a>, + }, + #[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")] + WithParamType { + #[primary_span] + #[label] + span: Span, + named: String, + #[suggestion( + infer_explicit_lifetime_required_sugg_with_param_type, + code = "{new_ty}", + applicability = "unspecified" + )] + new_ty_span: Span, + #[skip_arg] + new_ty: Ty<'a>, + }, } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index d7751158902..4e13ec90228 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -89,18 +89,17 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { { return None; } - - let simple_ident = param.pat.simple_ident(); - let (ident_kind, simple_ident) = match simple_ident { - Some(ident) => ("ident", ident.to_string()), - None => ("param_type", String::new()), - }; - let named = named.to_string(); - - let err = - ExplicitLifetimeRequired { span, ident_kind, simple_ident, named, new_ty_span, new_ty }; - let err = self.tcx().sess.parse_sess.create_err(err); - Some(err) + let err = match param.pat.simple_ident() { + Some(simple_ident) => ExplicitLifetimeRequired::WithIdent { + span, + simple_ident, + named, + new_ty_span, + new_ty, + }, + None => ExplicitLifetimeRequired::WithParamType { span, named, new_ty_span, new_ty }, + }; + Some(self.tcx().sess.parse_sess.create_err(err)) } } -- cgit 1.4.1-3-g733a5 From 62f9962eafbf4cf1196d256cf6c559ac397261e1 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 3 Nov 2022 21:50:52 +0300 Subject: Made ty_or_sig and trait_path use their actual types instead of String --- compiler/rustc_infer/src/errors/mod.rs | 101 ++++++++++++++------- .../infer/error_reporting/nice_region_error/mod.rs | 2 +- .../nice_region_error/placeholder_error.rs | 92 ++++++++++--------- 3 files changed, 118 insertions(+), 77 deletions(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 9e3def93a6d..388ddd09905 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1,16 +1,18 @@ use hir::GenericParamKind; use rustc_errors::{ fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, - MultiSpan, SubdiagnosticMessage, + IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage, }; use rustc_hir as hir; use rustc_hir::FnRetTy; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::{Region, Ty, TyCtxt}; +use rustc_middle::ty::print::TraitRefPrintOnlyTraitPath; +use rustc_middle::ty::{Binder, FnSig, Region, Ty, TyCtxt}; use rustc_span::symbol::kw; use rustc_span::Symbol; use rustc_span::{symbol::Ident, BytePos, Span}; +use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted; use crate::infer::error_reporting::{ need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind}, ObligationCauseAsDiagArg, @@ -557,91 +559,126 @@ pub enum ExplicitLifetimeRequired<'a> { }, } +pub enum TyOrSig<'tcx> { + Ty(Highlighted<'tcx, Ty<'tcx>>), + ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>), +} + +impl IntoDiagnosticArg for TyOrSig<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + match self { + TyOrSig::Ty(ty) => ty.into_diagnostic_arg(), + TyOrSig::ClosureSig(sig) => sig.into_diagnostic_arg(), + } + } +} + #[derive(Subdiagnostic)] -pub enum ActualImplExplNotes { +pub enum ActualImplExplNotes<'tcx> { #[note(infer_actual_impl_expl_expected_signature_two)] ExpectedSignatureTwo { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, lifetime_2: usize, }, #[note(infer_actual_impl_expl_expected_signature_any)] ExpectedSignatureAny { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_signature_some)] ExpectedSignatureSome { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_signature_nothing)] - ExpectedSignatureNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + ExpectedSignatureNothing { + leading_ellipsis: bool, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + }, #[note(infer_actual_impl_expl_expected_passive_two)] ExpectedPassiveTwo { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, lifetime_2: usize, }, #[note(infer_actual_impl_expl_expected_passive_any)] ExpectedPassiveAny { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_passive_some)] ExpectedPassiveSome { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_passive_nothing)] - ExpectedPassiveNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + ExpectedPassiveNothing { + leading_ellipsis: bool, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + }, #[note(infer_actual_impl_expl_expected_other_two)] ExpectedOtherTwo { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, lifetime_2: usize, }, #[note(infer_actual_impl_expl_expected_other_any)] ExpectedOtherAny { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_other_some)] ExpectedOtherSome { leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, }, #[note(infer_actual_impl_expl_expected_other_nothing)] - ExpectedOtherNothing { leading_ellipsis: bool, ty_or_sig: String, trait_path: String }, + ExpectedOtherNothing { + leading_ellipsis: bool, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + }, #[note(infer_actual_impl_expl_but_actually_implements_trait)] - ButActuallyImplementsTrait { trait_path: String, has_lifetime: bool, lifetime: usize }, + ButActuallyImplementsTrait { + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + has_lifetime: bool, + lifetime: usize, + }, #[note(infer_actual_impl_expl_but_actually_implemented_for_ty)] ButActuallyImplementedForTy { - trait_path: String, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, has_lifetime: bool, lifetime: usize, ty: String, }, #[note(infer_actual_impl_expl_but_actually_ty_implements)] - ButActuallyTyImplements { trait_path: String, has_lifetime: bool, lifetime: usize, ty: String }, + ButActuallyTyImplements { + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, + has_lifetime: bool, + lifetime: usize, + ty: String, + }, } pub enum ActualImplExpectedKind { @@ -657,13 +694,13 @@ pub enum ActualImplExpectedLifetimeKind { Nothing, } -impl ActualImplExplNotes { +impl<'tcx> ActualImplExplNotes<'tcx> { pub fn new_expected( kind: ActualImplExpectedKind, lt_kind: ActualImplExpectedLifetimeKind, leading_ellipsis: bool, - ty_or_sig: String, - trait_path: String, + ty_or_sig: TyOrSig<'tcx>, + trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, lifetime_1: usize, lifetime_2: usize, ) -> Self { @@ -728,7 +765,7 @@ impl ActualImplExplNotes { #[derive(Diagnostic)] #[diag(infer_trait_placeholder_mismatch)] -pub struct TraitPlaceholderMismatch { +pub struct TraitPlaceholderMismatch<'tcx> { #[primary_span] pub span: Span, #[label(label_satisfy)] @@ -741,7 +778,7 @@ pub struct TraitPlaceholderMismatch { pub trait_def_id: String, #[subdiagnostic(eager)] - pub actual_impl_expl_notes: Vec, + pub actual_impl_expl_notes: Vec>, } pub struct ConsiderBorrowingParamHelp { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 8a0e332f9c7..59fb74eb543 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -9,7 +9,7 @@ mod different_lifetimes; pub mod find_anon_type; mod mismatched_static_lifetime; mod named_anon_conflict; -mod placeholder_error; +pub(crate) mod placeholder_error; mod placeholder_relation; mod static_impl_trait; mod trait_impl_difference; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 904723c4da9..2ff2d1926a2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -1,6 +1,6 @@ use crate::errors::{ ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes, - TraitPlaceholderMismatch, + TraitPlaceholderMismatch, TyOrSig, }; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; @@ -8,7 +8,7 @@ use crate::infer::ValuePairs; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; -use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::error::ExpectedFound; @@ -18,6 +18,42 @@ use rustc_middle::ty::{self, RePlaceholder, ReVar, Region, TyCtxt}; use std::fmt; +// HACK(eddyb) maybe move this in a more central location. +#[derive(Copy, Clone)] +pub struct Highlighted<'tcx, T> { + tcx: TyCtxt<'tcx>, + highlight: RegionHighlightMode<'tcx>, + value: T, +} + +impl<'tcx, T> IntoDiagnosticArg for Highlighted<'tcx, T> +where + T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>, +{ + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + rustc_errors::DiagnosticArgValue::Str(self.to_string().into()) + } +} + +impl<'tcx, T> Highlighted<'tcx, T> { + fn map(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> { + Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value) } + } +} + +impl<'tcx, T> fmt::Display for Highlighted<'tcx, T> +where + T: for<'a> Print<'tcx, FmtPrinter<'a, 'tcx>, Error = fmt::Error, Output = FmtPrinter<'a, 'tcx>>, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS); + printer.region_highlight_mode = self.highlight; + + let s = self.value.print(printer)?.into_buffer(); + f.write_str(&s) + } +} + impl<'tcx> NiceRegionError<'_, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and /// an anonymous region, emit a descriptive diagnostic error. @@ -328,39 +364,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { actual_has_vid: Option, any_self_ty_has_vid: bool, leading_ellipsis: bool, - ) -> Vec { - // HACK(eddyb) maybe move this in a more central location. - #[derive(Copy, Clone)] - struct Highlighted<'tcx, T> { - tcx: TyCtxt<'tcx>, - highlight: RegionHighlightMode<'tcx>, - value: T, - } - - impl<'tcx, T> Highlighted<'tcx, T> { - fn map(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> { - Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value) } - } - } - - impl<'tcx, T> fmt::Display for Highlighted<'tcx, T> - where - T: for<'a> Print< - 'tcx, - FmtPrinter<'a, 'tcx>, - Error = fmt::Error, - Output = FmtPrinter<'a, 'tcx>, - >, - { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS); - printer.region_highlight_mode = self.highlight; - - let s = self.value.print(printer)?.into_buffer(); - f.write_str(&s) - } - } - + ) -> Vec> { // The weird thing here with the `maybe_highlighting_region` calls and the // the match inside is meant to be like this: // @@ -418,27 +422,27 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { }); ( ActualImplExpectedKind::Signature, - closure_sig.to_string(), - expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + TyOrSig::ClosureSig(closure_sig), + expected_trait_ref.map(|tr| tr.print_only_trait_path()), ) } else { ( ActualImplExpectedKind::Other, - self_ty.to_string(), - expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + TyOrSig::Ty(self_ty), + expected_trait_ref.map(|tr| tr.print_only_trait_path()), ) } } else if passive_voice { ( ActualImplExpectedKind::Passive, - expected_trait_ref.map(|tr| tr.self_ty()).to_string(), - expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())), + expected_trait_ref.map(|tr| tr.print_only_trait_path()), ) } else { ( ActualImplExpectedKind::Other, - expected_trait_ref.map(|tr| tr.self_ty()).to_string(), - expected_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(), + TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())), + expected_trait_ref.map(|tr| tr.print_only_trait_path()), ) }; @@ -474,7 +478,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { None => true, }; - let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path()).to_string(); + let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path()); let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string(); let has_lifetime = actual_has_vid.is_some(); let lifetime = actual_has_vid.unwrap_or_default(); -- cgit 1.4.1-3-g733a5 From a86173766c113fdde95c2510de5909d4f9469833 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Thu, 3 Nov 2022 21:56:15 +0300 Subject: Fix nits --- .../infer/error_reporting/nice_region_error/placeholder_error.rs | 6 ++---- .../infer/error_reporting/nice_region_error/static_impl_trait.rs | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 2ff2d1926a2..a5e5f953856 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -333,7 +333,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { leading_ellipsis, ); - let diag = TraitPlaceholderMismatch { + self.tcx().sess.create_err(TraitPlaceholderMismatch { span, satisfy_span, where_span, @@ -341,9 +341,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { def_id, trait_def_id: self.tcx().def_path_str(trait_def_id), actual_impl_expl_notes, - }; - - self.tcx().sess.create_err(diag) + }) } /// Add notes with details about the expected and actual trait refs, with attention to cases diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fbc71bd7e01..ae3f174c72e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -63,7 +63,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { AssocItemContainer::ImplContainer => (false, String::new()), }; - let diag = ButCallingIntroduces { + let mut err = self.tcx().sess.create_err(ButCallingIntroduces { param_ty_span: param.param_ty_span, cause_span: cause.span, has_param_name: simple_ident.is_some(), @@ -73,8 +73,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { assoc_item: ctxt.assoc_item.name, has_impl_path, impl_path, - }; - let mut err = self.tcx().sess.create_err(diag); + }); if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) { let reported = err.emit(); return Some(reported); -- cgit 1.4.1-3-g733a5 From dda3ebad0a2b26ee35e2f4f3d26f529b092edfc4 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Mon, 7 Nov 2022 15:56:52 +0300 Subject: Fix broken rebase --- .../src/infer/error_reporting/nice_region_error/static_impl_trait.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index ae3f174c72e..8a6dadf935f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -8,7 +8,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; use crate::infer::{SubregionOrigin, TypeTrace}; use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, Visitor}; -- cgit 1.4.1-3-g733a5 From 2a8b17dbc5489ee085cf1587cf3c63a3fd2746aa Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Tue, 29 Nov 2022 19:19:26 +0300 Subject: Fix formatting --- .../src/infer/error_reporting/nice_region_error/placeholder_error.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index a5e5f953856..202f39521e9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -405,8 +405,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty()); self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid); - if self_ty.value.is_closure() - && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) + if self_ty.value.is_closure() && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) { let closure_sig = self_ty.map(|closure| { if let ty::Closure(_, substs) = closure.kind() { -- cgit 1.4.1-3-g733a5 From 0c50e1f146efc594eb84146c598d577c9f8a27d2 Mon Sep 17 00:00:00 2001 From: Nikita Tomashevich Date: Wed, 28 Dec 2022 15:24:18 +0300 Subject: eager is the default now --- compiler/rustc_infer/src/errors/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 388ddd09905..9cd053694fe 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -777,7 +777,7 @@ pub struct TraitPlaceholderMismatch<'tcx> { pub def_id: String, pub trait_def_id: String, - #[subdiagnostic(eager)] + #[subdiagnostic] pub actual_impl_expl_notes: Vec>, } -- cgit 1.4.1-3-g733a5 From 0b54782cc8261f8e5d6e0b23785ca259a9eef6bf Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 28 Dec 2022 17:24:10 +0000 Subject: Don't translate --print native-static-libs output This breaks tools that depend on the prefix --- compiler/rustc_codegen_ssa/src/back/link.rs | 3 ++- compiler/rustc_codegen_ssa/src/errors.rs | 6 ------ compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index edde1537b81..1fbccfd96cf 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1354,7 +1354,8 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { if !lib_args.is_empty() { sess.emit_note(errors::StaticLibraryNativeArtifacts); // Prefix for greppability - sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") }); + // Note: This must not be translated as tools are allowed to depend on this exact string. + sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" "))); } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 0620000201f..277612c30fc 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -444,12 +444,6 @@ pub struct LinkerFileStem; #[diag(codegen_ssa_static_library_native_artifacts)] pub struct StaticLibraryNativeArtifacts; -#[derive(Diagnostic)] -#[diag(codegen_ssa_native_static_libs)] -pub struct NativeStaticLibs { - pub arguments: String, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_link_script_unavailable)] pub struct LinkScriptUnavailable; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index db4c82b35c7..f97943b9bd7 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -157,8 +157,6 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. -codegen_ssa_native_static_libs = native-static-libs: {$arguments} - codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} -- cgit 1.4.1-3-g733a5 From ed77a61901df19dd452e2414897ad9a99ef08203 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 28 Dec 2022 17:45:06 +0000 Subject: Explicitly pass in which crate type to use to each_linked_rlib Otherwise we may pick the dependency formats for say a dylib when linking a staticlib. --- compiler/rustc_codegen_ssa/src/back/link.rs | 150 +++++++++++++-------------- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1fbccfd96cf..71589e9993b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -11,7 +11,7 @@ use rustc_metadata::find_native_static_library; use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME}; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; -use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip}; +use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip}; use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind}; use rustc_session::cstore::DllImport; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; @@ -208,16 +208,16 @@ pub fn link_binary<'a>( Ok(()) } +// Crate type is not passed when calculating the dylibs to include for LTO. In that case all +// crate types must use the same dependency formats. pub fn each_linked_rlib( - sess: &Session, info: &CrateInfo, + crate_type: Option, f: &mut dyn FnMut(CrateNum, &Path), ) -> Result<(), errors::LinkRlibError> { let crates = info.used_crates.iter(); - let mut fmts = None; - let lto_active = matches!(sess.lto(), Lto::Fat | Lto::Thin); - if lto_active { + let fmts = if crate_type.is_none() { for combination in info.dependency_formats.iter().combinations(2) { let (ty1, list1) = &combination[0]; let (ty2, list2) = &combination[1]; @@ -230,27 +230,20 @@ pub fn each_linked_rlib( }); } } - } + &info.dependency_formats[0].1 + } else { + let fmts = info + .dependency_formats + .iter() + .find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None }); - for (ty, list) in info.dependency_formats.iter() { - match ty { - CrateType::Executable - | CrateType::Staticlib - | CrateType::Cdylib - | CrateType::ProcMacro => { - fmts = Some(list); - break; - } - CrateType::Dylib if lto_active => { - fmts = Some(list); - break; - } - _ => {} - } - } - let Some(fmts) = fmts else { - return Err(errors::LinkRlibError::MissingFormat); + let Some(fmts) = fmts else { + return Err(errors::LinkRlibError::MissingFormat); + }; + + fmts }; + for &cnum in crates { match fmts.get(cnum.as_usize() - 1) { Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue, @@ -516,64 +509,71 @@ fn link_staticlib<'a>( )?; let mut all_native_libs = vec![]; - let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| { - let name = codegen_results.crate_info.crate_name[&cnum]; - let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; - - // Here when we include the rlib into our staticlib we need to make a - // decision whether to include the extra object files along the way. - // These extra object files come from statically included native - // libraries, but they may be cfg'd away with #[link(cfg(..))]. - // - // This unstable feature, though, only needs liblibc to work. The only - // use case there is where musl is statically included in liblibc.rlib, - // so if we don't want the included version we just need to skip it. As - // a result the logic here is that if *any* linked library is cfg'd away - // we just skip all object files. - // - // Clearly this is not sufficient for a general purpose feature, and - // we'd want to read from the library's metadata to determine which - // object files come from where and selectively skip them. - let skip_object_files = native_libs.iter().any(|lib| { - matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. }) - && !relevant_lib(sess, lib) - }); + let res = each_linked_rlib( + &codegen_results.crate_info, + Some(CrateType::Staticlib), + &mut |cnum, path| { + let name = codegen_results.crate_info.crate_name[&cnum]; + let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; + + // Here when we include the rlib into our staticlib we need to make a + // decision whether to include the extra object files along the way. + // These extra object files come from statically included native + // libraries, but they may be cfg'd away with #[link(cfg(..))]. + // + // This unstable feature, though, only needs liblibc to work. The only + // use case there is where musl is statically included in liblibc.rlib, + // so if we don't want the included version we just need to skip it. As + // a result the logic here is that if *any* linked library is cfg'd away + // we just skip all object files. + // + // Clearly this is not sufficient for a general purpose feature, and + // we'd want to read from the library's metadata to determine which + // object files come from where and selectively skip them. + let skip_object_files = native_libs.iter().any(|lib| { + matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. }) + && !relevant_lib(sess, lib) + }); - let lto = are_upstream_rust_objects_already_included(sess) - && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); + let lto = are_upstream_rust_objects_already_included(sess) + && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); - // Ignoring obj file starting with the crate name - // as simple comparison is not enough - there - // might be also an extra name suffix - let obj_start = name.as_str().to_owned(); + // Ignoring obj file starting with the crate name + // as simple comparison is not enough - there + // might be also an extra name suffix + let obj_start = name.as_str().to_owned(); - ab.add_archive( - path, - Box::new(move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } + ab.add_archive( + path, + Box::new(move |fname: &str| { + // Ignore metadata files, no matter the name. + if fname == METADATA_FILENAME { + return true; + } - // Don't include Rust objects if LTO is enabled - if lto && looks_like_rust_object_file(fname) { - return true; - } + // Don't include Rust objects if LTO is enabled + if lto && looks_like_rust_object_file(fname) { + return true; + } - // Otherwise if this is *not* a rust object and we're skipping - // objects then skip this file - if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { - return true; - } + // Otherwise if this is *not* a rust object and we're skipping + // objects then skip this file + if skip_object_files + && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) + { + return true; + } - // ok, don't skip this - false - }), - ) - .unwrap(); + // ok, don't skip this + false + }), + ) + .unwrap(); - all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); - }); + all_native_libs + .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); + }, + ); if let Err(e) = res { sess.emit_fatal(e); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 1a7de1a184a..7aadcdd2228 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1002,7 +1002,7 @@ fn start_executing_work( let sess = tcx.sess; let mut each_linked_rlib_for_lto = Vec::new(); - drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| { + drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| { if link::ignored_for_lto(sess, crate_info, cnum) { return; } -- cgit 1.4.1-3-g733a5 From 520b5fac10eb9f7c096e0b6ca8e92b30eacba619 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 26 Dec 2022 04:19:27 +0000 Subject: Rework hir Bounds collection --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 93 +++++++++++++++------- compiler/rustc_hir_analysis/src/bounds.rs | 93 +++++++++------------- .../rustc_hir_analysis/src/collect/item_bounds.rs | 10 +-- .../src/collect/predicates_of.rs | 9 ++- compiler/rustc_privacy/src/lib.rs | 29 ++++--- 5 files changed, 127 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6f0c5d36a5f..5d38f9eaafa 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -682,7 +682,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::Binder::bind_with_vars(tcx.mk_trait_ref(trait_def_id, substs), bound_vars); debug!(?poly_trait_ref, ?assoc_bindings); - bounds.trait_bounds.push((poly_trait_ref, span, constness)); + bounds.push_trait_bound(tcx, poly_trait_ref, span, constness); let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { @@ -853,18 +853,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } /// Sets `implicitly_sized` to true on `Bounds` if necessary - pub(crate) fn add_implicitly_sized<'hir>( + pub(crate) fn add_implicitly_sized( &self, - bounds: &mut Bounds<'hir>, - ast_bounds: &'hir [hir::GenericBound<'hir>], - self_ty_where_predicates: Option<(LocalDefId, &'hir [hir::WherePredicate<'hir>])>, + bounds: &mut Bounds<'tcx>, + self_ty: Ty<'tcx>, + ast_bounds: &'tcx [hir::GenericBound<'tcx>], + self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>, span: Span, ) { let tcx = self.tcx(); // Try to find an unbound in bounds. let mut unbound = None; - let mut search_bounds = |ast_bounds: &'hir [hir::GenericBound<'hir>]| { + let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| { for ab in ast_bounds { if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab { if unbound.is_none() { @@ -912,7 +913,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // No lang item for `Sized`, so we can't add it as a bound. return; } - bounds.implicitly_sized = Some(span); + bounds.push_sized(tcx, self_ty, span); } /// This helper takes a *converted* parameter type (`param_ty`) @@ -963,10 +964,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } hir::GenericBound::Outlives(lifetime) => { let region = self.ast_region_to_region(lifetime, None); - bounds.region_bounds.push(( - ty::Binder::bind_with_vars(region, bound_vars), + bounds.push_region_bound( + self.tcx(), + ty::Binder::bind_with_vars( + ty::OutlivesPredicate(param_ty, region), + bound_vars, + ), lifetime.ident.span, - )); + ); } } } @@ -1225,13 +1230,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }; } } - bounds.projection_bounds.push(( - projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate { - projection_ty, - term: term, - }), + bounds.push_projection_bound( + tcx, + projection_ty + .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }), binding.span, - )); + ); } ConvertedBindingKind::Constraint(ast_bounds) => { // "Desugar" a constraint like `T: Iterator` to @@ -1260,7 +1264,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn conv_object_ty_poly_trait_ref( &self, span: Span, - trait_bounds: &[hir::PolyTraitRef<'_>], + hir_trait_bounds: &[hir::PolyTraitRef<'_>], lifetime: &hir::Lifetime, borrowed: bool, representation: DynKind, @@ -1270,7 +1274,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut bounds = Bounds::default(); let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; - for trait_bound in trait_bounds.iter().rev() { + for trait_bound in hir_trait_bounds.iter().rev() { if let GenericArgCountResult { correct: Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }), @@ -1287,10 +1291,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } + let mut trait_bounds = vec![]; + let mut projection_bounds = vec![]; + for (pred, span) in bounds.predicates() { + let bound_pred = pred.kind(); + match bound_pred.skip_binder() { + ty::PredicateKind::Clause(clause) => match clause { + ty::Clause::Trait(trait_pred) => { + assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive); + trait_bounds.push(( + bound_pred.rebind(trait_pred.trait_ref), + span, + trait_pred.constness, + )); + } + ty::Clause::Projection(proj) => { + projection_bounds.push((bound_pred.rebind(proj), span)); + } + ty::Clause::TypeOutlives(_) => { + // Do nothing, we deal with regions separately + } + ty::Clause::RegionOutlives(_) => bug!(), + }, + ty::PredicateKind::WellFormed(_) + | ty::PredicateKind::ObjectSafe(_) + | ty::PredicateKind::ClosureKind(_, _, _) + | ty::PredicateKind::Subtype(_) + | ty::PredicateKind::Coerce(_) + | ty::PredicateKind::ConstEvaluatable(_) + | ty::PredicateKind::ConstEquate(_, _) + | ty::PredicateKind::TypeWellFormedFromEnv(_) + | ty::PredicateKind::Ambiguous => bug!(), + } + } + // Expand trait aliases recursively and check that only one regular (non-auto) trait // is used and no 'maybe' bounds are used. let expanded_traits = - traits::expand_trait_aliases(tcx, bounds.trait_bounds.iter().map(|&(a, b, _)| (a, b))); + traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b, _)| (a, b))); + let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self) .partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); @@ -1327,8 +1366,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } if regular_traits.is_empty() && auto_traits.is_empty() { - let trait_alias_span = bounds - .trait_bounds + let trait_alias_span = trait_bounds .iter() .map(|&(trait_ref, _, _)| trait_ref.def_id()) .find(|&trait_ref| tcx.is_trait_alias(trait_ref)) @@ -1359,8 +1397,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Use a `BTreeSet` to keep output in a more consistent order. let mut associated_types: FxHashMap> = FxHashMap::default(); - let regular_traits_refs_spans = bounds - .trait_bounds + let regular_traits_refs_spans = trait_bounds .into_iter() .filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id())); @@ -1414,7 +1451,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // the discussion in #56288 for alternatives. if !references_self { // Include projections defined on supertraits. - bounds.projection_bounds.push((pred, span)); + projection_bounds.push((pred, span)); } } _ => (), @@ -1422,7 +1459,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - for (projection_bound, _) in &bounds.projection_bounds { + for (projection_bound, _) in &projection_bounds { for def_ids in associated_types.values_mut() { def_ids.remove(&projection_bound.projection_def_id()); } @@ -1431,7 +1468,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.complain_about_missing_associated_types( associated_types, potential_assoc_types, - trait_bounds, + hir_trait_bounds, ); // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as @@ -1473,7 +1510,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let substs = tcx.intern_substs(&substs[..]); let span = i.bottom().1; - let empty_generic_args = trait_bounds.iter().any(|hir_bound| { + let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id) && hir_bound.span.contains(span) }); @@ -1505,7 +1542,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) }); - let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| { + let existential_projections = projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|mut b| { assert_eq!(b.projection_ty.self_ty(), dummy_self); diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 3e3544ce666..0880c8c15f2 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -1,6 +1,7 @@ //! Bounds are restrictions applied to some types after they've been converted into the //! `ty` form from the HIR. +use rustc_hir::LangItem; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; @@ -15,73 +16,53 @@ use rustc_span::Span; /// ^^^^^^^^^ bounding the type parameter `T` /// /// impl dyn Bar + Baz -/// ^^^^^^^^^ bounding the forgotten dynamic type +/// ^^^^^^^^^ 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 struct Bounds<'tcx> { - /// A list of region bounds on the (implicit) self type. So if you - /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but - /// the `T` is not explicitly included). - pub region_bounds: Vec<(ty::Binder<'tcx, ty::Region<'tcx>>, Span)>, - - /// A list of trait bounds. So if you had `T: Debug` this would be - /// `T: Debug`. Note that the self-type is explicit here. - pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span, ty::BoundConstness)>, - - /// A list of projection equality bounds. So if you had `T: - /// Iterator` this would include `::Item => u32`. Note that the self-type is explicit - /// here. - pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, - - /// `Some` if there is *no* `?Sized` predicate. The `span` - /// is the location in the source of the `T` declaration which can - /// be cited as the source of the `T: Sized` requirement. - pub implicitly_sized: Option, + pub predicates: Vec<(ty::Predicate<'tcx>, Span)>, } impl<'tcx> Bounds<'tcx> { - /// Converts a bounds list into a flat set of predicates (like - /// where-clauses). Because some of our bounds listings (e.g., - /// regions) don't include the self-type, you must supply the - /// self-type here (the `param_ty` parameter). - pub fn predicates<'out, 's>( - &'s self, + pub fn push_region_bound( + &mut self, tcx: TyCtxt<'tcx>, - param_ty: Ty<'tcx>, - // the output must live shorter than the duration of the borrow of self and 'tcx. - ) -> impl Iterator, Span)> + 'out - where - 'tcx: 'out, - 's: 'out, - { - // If it could be sized, and is, add the `Sized` predicate. - let sized_predicate = self.implicitly_sized.and_then(|span| { - // FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write. - let sized = tcx.lang_items().sized_trait()?; - let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty])); - Some((trait_ref.without_const().to_predicate(tcx), span)) - }); + region: ty::PolyTypeOutlivesPredicate<'tcx>, + span: Span, + ) { + self.predicates.push((region.to_predicate(tcx), span)); + } - let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| { - let pred = region_bound - .map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound)) - .to_predicate(tcx); - (pred, span) - }); - let trait_bounds = - self.trait_bounds.iter().map(move |&(bound_trait_ref, span, constness)| { - let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx); - (predicate, span) - }); - let projection_bounds = self - .projection_bounds - .iter() - .map(move |&(projection, span)| (projection.to_predicate(tcx), span)); + pub fn push_trait_bound( + &mut self, + tcx: TyCtxt<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + span: Span, + constness: ty::BoundConstness, + ) { + self.predicates.push((trait_ref.with_constness(constness).to_predicate(tcx), span)); + } + + pub fn push_projection_bound( + &mut self, + tcx: TyCtxt<'tcx>, + projection: ty::PolyProjectionPredicate<'tcx>, + span: Span, + ) { + self.predicates.push((projection.to_predicate(tcx), span)); + } + + pub 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::Binder::dummy(tcx.mk_trait_ref(sized_def_id, [ty])); + // Preferrable to put this obligation first, since we report better errors for sized ambiguity. + self.predicates.insert(0, (trait_ref.without_const().to_predicate(tcx), span)); + } - sized_predicate.into_iter().chain(region_preds).chain(trait_bounds).chain(projection_bounds) + pub fn predicates(&self) -> impl Iterator, Span)> + '_ { + self.predicates.iter().cloned() } } diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 0542e2c8f50..093e9560ccd 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -28,7 +28,7 @@ fn associated_type_bounds<'tcx>( let icx = ItemCtxt::new(tcx, assoc_item_def_id); let mut bounds = >::compute_bounds(&icx, item_ty, ast_bounds); // Associated types are implicitly sized unless a `?Sized` bound is found - >::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span); + >::add_implicitly_sized(&icx, &mut bounds, item_ty, ast_bounds, None, span); let trait_def_id = tcx.parent(assoc_item_def_id); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local()); @@ -44,9 +44,7 @@ fn associated_type_bounds<'tcx>( } }); - let all_bounds = tcx - .arena - .alloc_from_iter(bounds.predicates(tcx, item_ty).into_iter().chain(bounds_from_parent)); + let all_bounds = tcx.arena.alloc_from_iter(bounds.predicates().chain(bounds_from_parent)); debug!("associated_type_bounds({}) = {:?}", tcx.def_path_str(assoc_item_def_id), all_bounds); all_bounds } @@ -74,10 +72,10 @@ fn opaque_type_bounds<'tcx>( let icx = ItemCtxt::new(tcx, opaque_def_id); let mut bounds = >::compute_bounds(&icx, item_ty, ast_bounds); // Opaque types are implicitly sized unless a `?Sized` bound is found - >::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span); + >::add_implicitly_sized(&icx, &mut bounds, item_ty, ast_bounds, None, span); debug!(?bounds); - tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty)) + tcx.arena.alloc_from_iter(bounds.predicates()) }) } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 0943350e2d4..024b3beada0 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -165,12 +165,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP >::add_implicitly_sized( &icx, &mut bounds, + param_ty, &[], Some((param.def_id, ast_generics.predicates)), param.span, ); trace!(?bounds); - predicates.extend(bounds.predicates(tcx, param_ty)); + predicates.extend(bounds.predicates()); trace!(?predicates); } GenericParamKind::Const { .. } => { @@ -217,7 +218,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP &mut bounds, bound_vars, ); - predicates.extend(bounds.predicates(tcx, ty)); + predicates.extend(bounds.predicates()); } hir::WherePredicate::RegionPredicate(region_pred) => { @@ -536,7 +537,7 @@ pub(super) fn super_predicates_that_define_assoc_type( >::compute_bounds(&icx, self_param_ty, bounds) }; - let superbounds1 = superbounds1.predicates(tcx, self_param_ty); + let superbounds1 = superbounds1.predicates(); // Convert any explicit superbounds in the where-clause, // e.g., `trait Foo where Self: Bar`. @@ -745,5 +746,5 @@ fn predicates_from_bound<'tcx>( ) -> Vec<(ty::Predicate<'tcx>, Span)> { let mut bounds = Bounds::default(); astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); - bounds.predicates(astconv.tcx(), param_ty).collect() + bounds.predicates().collect() } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 72d38aeac7a..2438fce606c 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1223,19 +1223,22 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { self.tcx.types.never, ); - for (trait_predicate, _, _) in bounds.trait_bounds { - if self.visit_trait(trait_predicate.skip_binder()).is_break() { - return; - } - } - - for (poly_predicate, _) in bounds.projection_bounds { - let pred = poly_predicate.skip_binder(); - let poly_pred_term = self.visit(pred.term); - if poly_pred_term.is_break() - || self.visit_projection_ty(pred.projection_ty).is_break() - { - return; + for (pred, _) in bounds.predicates() { + match pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => { + if self.visit_trait(trait_predicate.trait_ref).is_break() { + return; + } + } + ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) => { + let term = self.visit(proj_predicate.term); + if term.is_break() + || self.visit_projection_ty(proj_predicate.projection_ty).is_break() + { + return; + } + } + _ => {} } } } -- cgit 1.4.1-3-g733a5 From 2675848b0a5248afeee552aee0c473bad9b4d9a3 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Fri, 30 Dec 2022 16:06:55 +0100 Subject: Add codegen test for `Box::new(uninit)` of big arrays --- src/test/codegen/box-maybe-uninit-llvm14.rs | 14 +++++++++++--- src/test/codegen/box-maybe-uninit.rs | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/test/codegen/box-maybe-uninit-llvm14.rs b/src/test/codegen/box-maybe-uninit-llvm14.rs index bd1a6599c33..7b5ae894311 100644 --- a/src/test/codegen/box-maybe-uninit-llvm14.rs +++ b/src/test/codegen/box-maybe-uninit-llvm14.rs @@ -2,7 +2,7 @@ // Once we're done with llvm 14 and earlier, this test can be deleted. -#![crate_type="lib"] +#![crate_type = "lib"] use std::mem::MaybeUninit; @@ -17,8 +17,16 @@ pub fn box_uninitialized() -> Box> { Box::new(MaybeUninit::uninit()) } -// FIXME: add a test for a bigger box. Currently broken, see -// https://github.com/rust-lang/rust/issues/58201. +// https://github.com/rust-lang/rust/issues/58201 +#[no_mangle] +pub fn box_uninitialized2() -> Box> { + // CHECK-LABEL: @box_uninitialized2 + // CHECK-NOT: store + // CHECK-NOT: alloca + // CHECK-NOT: memcpy + // CHECK-NOT: memset + Box::new(MaybeUninit::uninit()) +} // Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc // from the CHECK-NOT above. We don't check the attributes here because we can't rely diff --git a/src/test/codegen/box-maybe-uninit.rs b/src/test/codegen/box-maybe-uninit.rs index e105e26f16a..c82b56a71f5 100644 --- a/src/test/codegen/box-maybe-uninit.rs +++ b/src/test/codegen/box-maybe-uninit.rs @@ -1,6 +1,6 @@ // compile-flags: -O // min-llvm-version: 15.0 -#![crate_type="lib"] +#![crate_type = "lib"] use std::mem::MaybeUninit; @@ -15,8 +15,16 @@ pub fn box_uninitialized() -> Box> { Box::new(MaybeUninit::uninit()) } -// FIXME: add a test for a bigger box. Currently broken, see -// https://github.com/rust-lang/rust/issues/58201. +// https://github.com/rust-lang/rust/issues/58201 +#[no_mangle] +pub fn box_uninitialized2() -> Box> { + // CHECK-LABEL: @box_uninitialized2 + // CHECK-NOT: store + // CHECK-NOT: alloca + // CHECK-NOT: memcpy + // CHECK-NOT: memset + Box::new(MaybeUninit::uninit()) +} // Hide the `allocalign` attribute in the declaration of __rust_alloc // from the CHECK-NOT above, and also verify the attributes got set reasonably. -- cgit 1.4.1-3-g733a5 From 0047e250909dd4739fcd20e77a49685f45490987 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Fri, 30 Dec 2022 13:38:34 +0100 Subject: Add some docs to `bug`, `span_bug` and `delay_span_bug` --- compiler/rustc_errors/src/lib.rs | 2 ++ compiler/rustc_middle/src/macros.rs | 18 ++++++++++++++++++ compiler/rustc_middle/src/util/bug.rs | 3 +-- compiler/rustc_session/src/session.rs | 14 +++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b03352d5fec..9ed31d9419c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -973,6 +973,7 @@ impl Handler { self.inner.borrow_mut().span_bug(span, msg) } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] pub fn delay_span_bug( &self, @@ -1518,6 +1519,7 @@ impl HandlerInner { self.emit_diagnostic(diag.set_span(sp)); } + /// For documentation on this, see `Session::delay_span_bug`. #[track_caller] fn delay_span_bug( &mut self, diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 01fe72de612..5ca4d260179 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -1,3 +1,13 @@ +/// A macro for triggering an ICE. +/// Calling `bug` instead of panicking will result in a nicer error message and should +/// therefore be prefered over `panic`/`unreachable` or others. +/// +/// If you have a span available, you should use [`span_bug`] instead. +/// +/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// +/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug +/// [`span_bug`]: crate::span_bug #[macro_export] macro_rules! bug { () => ( $crate::bug!("impossible case reached") ); @@ -8,6 +18,14 @@ macro_rules! bug { }); } +/// A macro for triggering an ICE with a span. +/// Calling `span_bug!` instead of panicking will result in a nicer error message and point +/// at the code the compiler was compiling when it ICEd. This is the preferred way to trigger +/// ICEs. +/// +/// If the bug should only be emitted when compilation didn't fail, [`Session::delay_span_bug`] may be useful. +/// +/// [`Session::delay_span_bug`]: rustc_session::Session::delay_span_bug #[macro_export] macro_rules! span_bug { ($span:expr, $msg:expr) => ({ $crate::util::bug::span_bug_fmt($span, ::std::format_args!($msg)) }); diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index fd7045d6a03..b73ae593905 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -35,8 +35,7 @@ fn opt_span_bug_fmt>( (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), (None, _) => panic_any(msg), } - }); - unreachable!(); + }) } /// A query to trigger a `delay_span_bug`. Clearly, if one has a `tcx` one can already trigger a diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4a3d29414d6..1b2e8d9dc70 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -590,7 +590,19 @@ impl Session { pub fn warn(&self, msg: impl Into) { self.diagnostic().warn(msg) } - /// Delay a span_bug() call until abort_if_errors() + + /// Ensures that compilation cannot succeed. + /// + /// If this function has been called but no errors have been emitted and + /// compilation succeeds, it will cause an internal compiler error (ICE). + /// + /// This can be used in code paths that should never run on successful compilations. + /// For example, it can be used to create an [`ErrorGuaranteed`] + /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission directly). + /// + /// If no span is available, use [`DUMMY_SP`]. + /// + /// [`DUMMY_SP`]: rustc_span::DUMMY_SP #[track_caller] pub fn delay_span_bug>( &self, -- cgit 1.4.1-3-g733a5 From cc2881391a1f1e01faa2f7ff21a172a15fbbaacd Mon Sep 17 00:00:00 2001 From: gimbles Date: Sat, 31 Dec 2022 15:32:09 +0530 Subject: Add tidy check for dbg --- library/std/src/macros.rs | 1 + src/tools/tidy/src/style.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 6e4ba1404e5..fcc5cfafd80 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -3,6 +3,7 @@ //! This module contains a set of macros which are exported from the standard //! library. Each macro is available for use when linking against the standard //! library. +// ignore-tidy-dbg #[doc = include_str!("../../core/src/macros/panic.md")] #[macro_export] diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index f91e38262f6..f409a86db26 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -15,6 +15,7 @@ //! //! A number of these checks can be opted-out of with various directives of the form: //! `// ignore-tidy-CHECK-NAME`. +// ignore-tidy-dbg use crate::walk::{filter_dirs, walk}; use regex::{Regex, RegexSet}; @@ -278,6 +279,7 @@ pub fn check(path: &Path, bad: &mut bool) { let mut skip_leading_newlines = contains_ignore_directive(can_contain, &contents, "leading-newlines"); let mut skip_copyright = contains_ignore_directive(can_contain, &contents, "copyright"); + let mut skip_dbg = contains_ignore_directive(can_contain, &contents, "dbg"); let mut leading_new_lines = false; let mut trailing_new_lines = 0; let mut lines = 0; @@ -306,6 +308,21 @@ pub fn check(path: &Path, bad: &mut bool) { let mut err = |msg: &str| { tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg); }; + + if trimmed.contains("dbg!") + && !trimmed.starts_with("//") + && !file + .ancestors() + .any(|a| a.ends_with("src/test") || a.ends_with("library/alloc/tests")) + && filename != "tests.rs" + { + suppressible_tidy_err!( + err, + skip_dbg, + "`dbg!` macro is intended as a debugging tool. It should not be in version control." + ) + } + if !under_rustfmt && line.chars().count() > max_columns && !long_line_is_ok(&extension, is_error_code, max_columns, line) -- cgit 1.4.1-3-g733a5 From c49555821f9735239bf12281b9151eac3b4596d4 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Thu, 17 Nov 2022 13:21:36 -0700 Subject: warn when there's a newer version of the x tool available --- src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 20 +++++++++++++++++++- src/tools/tidy/src/x.rs | 19 +++++++++++++++++++ src/tools/x/src/main.rs | 8 ++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/tools/tidy/src/x.rs diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index ce7e7ac5cd4..bfcf0907365 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -69,3 +69,4 @@ pub mod ui_tests; pub mod unit_tests; pub mod unstable_book; pub mod walk; +pub mod x; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 6714c63ee62..f01d4673368 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -53,6 +53,21 @@ fn main() { VecDeque::with_capacity(concurrency.get()); macro_rules! check { + ($p:ident) => { + while handles.len() >= concurrency.get() { + handles.pop_front().unwrap().join().unwrap(); + } + + let handle = s.spawn(|| { + let mut flag = false; + $p::check(&mut flag); + if (flag) { + bad.store(true, Ordering::Relaxed); + } + }); + handles.push_back(handle); + }; + ($p:ident $(, $args:expr)* ) => { drain_handles(&mut handles); @@ -64,7 +79,8 @@ fn main() { } }); handles.push_back(handle); - } + }; + } check!(target_specific_tests, &src_path); @@ -107,6 +123,8 @@ fn main() { check!(alphabetical, &compiler_path); check!(alphabetical, &library_path); + check!(x); + let collected = { drain_handles(&mut handles); diff --git a/src/tools/tidy/src/x.rs b/src/tools/tidy/src/x.rs new file mode 100644 index 00000000000..2cbbde8de82 --- /dev/null +++ b/src/tools/tidy/src/x.rs @@ -0,0 +1,19 @@ +use std::process::Command; + +pub fn check(_bad: &mut bool) { + let result = Command::new("x") + .arg("--version") + .output(); + let output = match result { + Ok(output) => output, + Err(_e) => todo!(), + }; + + if output.status.success() { + let version = String::from_utf8_lossy(&output.stdout); + assert_eq!("0.1.0", version.trim_end()); + } + // FIXME: throw some kind of tidy error when the version of x isn't + // greater than or equal to the version we'd expect. + //tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`") +} diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index f07ff43efe9..db5d03710d7 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -52,6 +52,14 @@ fn exec_or_status(command: &mut Command) -> io::Result { } fn main() { + match env::args().skip(1).next().as_deref() { + Some("--version") => { + let version = env!("CARGO_PKG_VERSION"); + println!("{}", version); + return; + } + _ => {} + } let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { -- cgit 1.4.1-3-g733a5 From b2cd3374e9a7ed637b1b5f1a85cb92a7928d712d Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 28 Nov 2022 16:08:00 -0700 Subject: remove leading comma from macro expansion --- src/bootstrap/bootstrap.py | 4 ++-- src/tools/tidy/src/lib.rs | 2 +- src/tools/tidy/src/main.rs | 22 +++------------------- src/tools/tidy/src/x.rs | 19 ------------------- src/tools/tidy/src/x_version.rs | 17 +++++++++++++++++ 5 files changed, 23 insertions(+), 41 deletions(-) delete mode 100644 src/tools/tidy/src/x.rs create mode 100644 src/tools/tidy/src/x_version.rs diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9cf43fc7a21..d7ba015982a 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -934,8 +934,8 @@ def main(): if len(sys.argv) > 1 and sys.argv[1] == 'help': sys.argv = [sys.argv[0], '-h'] + sys.argv[2:] - help_triggered = ( - '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) + # help_triggered = ('-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) + help_triggered = len(sys.argv) == 1 or any(x in ["-h", "--help", "--version"] for x in sys.argv) try: bootstrap(help_triggered) if not help_triggered: diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index bfcf0907365..4075f2616b0 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -69,4 +69,4 @@ pub mod ui_tests; pub mod unit_tests; pub mod unstable_book; pub mod walk; -pub mod x; +pub mod x_version; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f01d4673368..56fcc561a3f 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -53,34 +53,18 @@ fn main() { VecDeque::with_capacity(concurrency.get()); macro_rules! check { - ($p:ident) => { - while handles.len() >= concurrency.get() { - handles.pop_front().unwrap().join().unwrap(); - } - - let handle = s.spawn(|| { - let mut flag = false; - $p::check(&mut flag); - if (flag) { - bad.store(true, Ordering::Relaxed); - } - }); - handles.push_back(handle); - }; - ($p:ident $(, $args:expr)* ) => { drain_handles(&mut handles); let handle = s.spawn(|| { let mut flag = false; - $p::check($($args),* , &mut flag); + $p::check($($args, )* &mut flag); if (flag) { bad.store(true, Ordering::Relaxed); } }); handles.push_back(handle); - }; - + } } check!(target_specific_tests, &src_path); @@ -123,7 +107,7 @@ fn main() { check!(alphabetical, &compiler_path); check!(alphabetical, &library_path); - check!(x); + check!(x_version); let collected = { drain_handles(&mut handles); diff --git a/src/tools/tidy/src/x.rs b/src/tools/tidy/src/x.rs deleted file mode 100644 index 2cbbde8de82..00000000000 --- a/src/tools/tidy/src/x.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::process::Command; - -pub fn check(_bad: &mut bool) { - let result = Command::new("x") - .arg("--version") - .output(); - let output = match result { - Ok(output) => output, - Err(_e) => todo!(), - }; - - if output.status.success() { - let version = String::from_utf8_lossy(&output.stdout); - assert_eq!("0.1.0", version.trim_end()); - } - // FIXME: throw some kind of tidy error when the version of x isn't - // greater than or equal to the version we'd expect. - //tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`") -} diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs new file mode 100644 index 00000000000..148f97176f9 --- /dev/null +++ b/src/tools/tidy/src/x_version.rs @@ -0,0 +1,17 @@ +use std::process::Command; + +pub fn check(_bad: &mut bool) { + let result = Command::new("x").arg("--version").output(); + let output = match result { + Ok(output) => output, + Err(_e) => todo!(), + }; + + if output.status.success() { + let version = String::from_utf8_lossy(&output.stdout); + assert_eq!("0.1.0", version.trim_end()); + } + // FIXME: throw some kind of tidy error when the version of x isn't + // greater than or equal to the version we'd expect. + //tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`") +} -- cgit 1.4.1-3-g733a5 From b9b33d983d83fde3067a28fdd126fd84061e74c8 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 5 Dec 2022 16:18:43 -0700 Subject: spawn x command and compare semvers --- Cargo.lock | 5 +++-- src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/x_version.rs | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f99e58e59b8..8cafdc83d4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4805,9 +4805,9 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" [[package]] name = "semver" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" +checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" dependencies = [ "serde", ] @@ -5309,6 +5309,7 @@ dependencies = [ "lazy_static", "miropt-test-tools", "regex", + "semver", "termcolor", "walkdir", ] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index fff83a1d097..5f5ae3a65ef 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -11,6 +11,7 @@ miropt-test-tools = { path = "../miropt-test-tools" } lazy_static = "1" walkdir = "2" ignore = "0.4.18" +semver = "1.0.14" termcolor = "1.1.3" [[bin]] diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 148f97176f9..bbb2662bdcf 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -1,17 +1,36 @@ -use std::process::Command; +use semver::{BuildMetadata, Prerelease, Version}; +use std::io::ErrorKind; +use std::process::{Command, Stdio}; -pub fn check(_bad: &mut bool) { - let result = Command::new("x").arg("--version").output(); - let output = match result { - Ok(output) => output, - Err(_e) => todo!(), +pub fn check(bad: &mut bool) { + let result = Command::new("x") + .arg("--version") + .stdout(Stdio::piped()) + .spawn(); + let child = match result { + Ok(child) => child, + Err(e) => match e.kind() { + ErrorKind::NotFound => return (), + _ => return tidy_error!(bad, "{}", e), + }, }; + let output = child.wait_with_output().unwrap(); + if output.status.success() { let version = String::from_utf8_lossy(&output.stdout); - assert_eq!("0.1.0", version.trim_end()); + let version = Version::parse(version.trim_end()).unwrap(); + let expected = Version { + major: 0, + minor: 1, + patch: 0, + pre: Prerelease::new("").unwrap(), + build: BuildMetadata::EMPTY, + }; + if version < expected { + return tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`"); + } + } else { + return tidy_error!(bad, "{}", output.status); } - // FIXME: throw some kind of tidy error when the version of x isn't - // greater than or equal to the version we'd expect. - //tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`") } -- cgit 1.4.1-3-g733a5 From a917308d9180b3203c1e65a394c28c7e7d92b9bb Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 5 Dec 2022 16:19:10 -0700 Subject: remove commented out old code --- src/bootstrap/bootstrap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d7ba015982a..f3998e98583 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -934,7 +934,6 @@ def main(): if len(sys.argv) > 1 and sys.argv[1] == 'help': sys.argv = [sys.argv[0], '-h'] + sys.argv[2:] - # help_triggered = ('-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) help_triggered = len(sys.argv) == 1 or any(x in ["-h", "--help", "--version"] for x in sys.argv) try: bootstrap(help_triggered) -- cgit 1.4.1-3-g733a5 From 7fe2f73ecdde41ec3bc0bd9bfdee5cd064536d53 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 5 Dec 2022 16:42:08 -0700 Subject: formatting --- src/tools/tidy/src/x_version.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index bbb2662bdcf..c54414836ed 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -3,14 +3,11 @@ use std::io::ErrorKind; use std::process::{Command, Stdio}; pub fn check(bad: &mut bool) { - let result = Command::new("x") - .arg("--version") - .stdout(Stdio::piped()) - .spawn(); + let result = Command::new("x").arg("--version").stdout(Stdio::piped()).spawn(); let child = match result { Ok(child) => child, Err(e) => match e.kind() { - ErrorKind::NotFound => return (), + ErrorKind::NotFound => return, _ => return tidy_error!(bad, "{}", e), }, }; @@ -28,7 +25,10 @@ pub fn check(bad: &mut bool) { build: BuildMetadata::EMPTY, }; if version < expected { - return tidy_error!(bad, "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`"); + return tidy_error!( + bad, + "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`" + ); } } else { return tidy_error!(bad, "{}", output.status); -- cgit 1.4.1-3-g733a5 From 02173f6ab514cf98b73f053cbc0e7b9881c18783 Mon Sep 17 00:00:00 2001 From: J Haigh Date: Wed, 7 Dec 2022 13:28:57 -0700 Subject: Update error message Co-authored-by: Joshua Nelson --- src/tools/tidy/src/x_version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index c54414836ed..df9d780ea14 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -8,7 +8,7 @@ pub fn check(bad: &mut bool) { Ok(child) => child, Err(e) => match e.kind() { ErrorKind::NotFound => return, - _ => return tidy_error!(bad, "{}", e), + _ => return tidy_error!(bad, "failed to run `x`: {}", e), }, }; -- cgit 1.4.1-3-g733a5 From 430ea8d440f5fc22dec7c4b6bda0536ae38baa00 Mon Sep 17 00:00:00 2001 From: J Haigh Date: Wed, 7 Dec 2022 13:29:10 -0700 Subject: Update error message Co-authored-by: Joshua Nelson --- src/tools/tidy/src/x_version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index df9d780ea14..f0c7a308cfa 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -31,6 +31,6 @@ pub fn check(bad: &mut bool) { ); } } else { - return tidy_error!(bad, "{}", output.status); + return tidy_error!(bad, "failed to check version of `x`: {}", output.status); } } -- cgit 1.4.1-3-g733a5 From f50ad6cd8ce48c8f159bee064ba9ae9dd28f6868 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Wed, 7 Dec 2022 14:00:40 -0700 Subject: rename wrapper-version argument for x to differentiate it from the bootstrap version --- src/tools/tidy/src/x_version.rs | 2 +- src/tools/x/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index f0c7a308cfa..dddf72f4747 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -3,7 +3,7 @@ use std::io::ErrorKind; use std::process::{Command, Stdio}; pub fn check(bad: &mut bool) { - let result = Command::new("x").arg("--version").stdout(Stdio::piped()).spawn(); + let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); let child = match result { Ok(child) => child, Err(e) => match e.kind() { diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index db5d03710d7..01f7187851e 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -53,7 +53,7 @@ fn exec_or_status(command: &mut Command) -> io::Result { fn main() { match env::args().skip(1).next().as_deref() { - Some("--version") => { + Some("--wrapper-version") => { let version = env!("CARGO_PKG_VERSION"); println!("{}", version); return; -- cgit 1.4.1-3-g733a5 From 04b9038610606313cf023e59fc6a0ef4d5d22340 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Thu, 29 Dec 2022 19:08:59 +1300 Subject: refactor: clean up `errors.rs` and `error_codes_check.rs` Move them into new `error_codes.rs` tidy check. --- compiler/rustc_error_codes/src/error_codes.rs | 1 - .../rustc_error_codes/src/error_codes/E0729.md | 30 -- src/tools/tidy/src/error_codes.rs | 397 +++++++++++++++++++++ src/tools/tidy/src/error_codes_check.rs | 305 ---------------- src/tools/tidy/src/errors.rs | 77 ---- src/tools/tidy/src/lib.rs | 3 +- src/tools/tidy/src/main.rs | 4 +- 7 files changed, 400 insertions(+), 417 deletions(-) delete mode 100644 compiler/rustc_error_codes/src/error_codes/E0729.md create mode 100644 src/tools/tidy/src/error_codes.rs delete mode 100644 src/tools/tidy/src/error_codes_check.rs delete mode 100644 src/tools/tidy/src/errors.rs diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 3fba2cf5749..137325e6fab 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -443,7 +443,6 @@ E0725: include_str!("./error_codes/E0725.md"), E0726: include_str!("./error_codes/E0726.md"), E0727: include_str!("./error_codes/E0727.md"), E0728: include_str!("./error_codes/E0728.md"), -E0729: include_str!("./error_codes/E0729.md"), E0730: include_str!("./error_codes/E0730.md"), E0731: include_str!("./error_codes/E0731.md"), E0732: include_str!("./error_codes/E0732.md"), diff --git a/compiler/rustc_error_codes/src/error_codes/E0729.md b/compiler/rustc_error_codes/src/error_codes/E0729.md deleted file mode 100644 index 74f89080b91..00000000000 --- a/compiler/rustc_error_codes/src/error_codes/E0729.md +++ /dev/null @@ -1,30 +0,0 @@ -Support for Non-Lexical Lifetimes (NLL) has been included in the Rust compiler -since 1.31, and has been enabled on the 2015 edition since 1.36. The new borrow -checker for NLL uncovered some bugs in the old borrow checker, which in some -cases allowed unsound code to compile, resulting in memory safety issues. - -### What do I do? - -Change your code so the warning does no longer trigger. For backwards -compatibility, this unsound code may still compile (with a warning) right now. -However, at some point in the future, the compiler will no longer accept this -code and will throw a hard error. - -### Shouldn't you fix the old borrow checker? - -The old borrow checker has known soundness issues that are basically impossible -to fix. The new NLL-based borrow checker is the fix. - -### Can I turn these warnings into errors by denying a lint? - -No. - -### When are these warnings going to turn into errors? - -No formal timeline for turning the warnings into errors has been set. See -[GitHub issue 58781](https://github.com/rust-lang/rust/issues/58781) for more -information. - -### Why do I get this message with code that doesn't involve borrowing? - -There are some known bugs that trigger this message. diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs new file mode 100644 index 00000000000..f4aebbf2277 --- /dev/null +++ b/src/tools/tidy/src/error_codes.rs @@ -0,0 +1,397 @@ +//! Tidy check to ensure error codes are properly documented and tested. +//! +//! Overview of check: +//! +//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/error_codes.rs`. +//! +//! 2. We check that the error code has a long-form explanation in `compiler/rustc_error_codes/src/error_codes/`. +//! - The explanation is expected to contain a `doctest` that fails with the correct error code. (`EXEMPT_FROM_DOCTEST` *currently* bypasses this check) +//! - Note that other stylistic conventions for markdown files are checked in the `style.rs` tidy check. +//! +//! 3. We check that the error code has a UI test in `src/test/ui/error-codes/`. +//! - We ensure that there is both a `Exxxx.rs` file and a corresponding `Exxxx.stderr` file. +//! - We also ensure that the error code is used in the tests. +//! - *Currently*, it is possible to opt-out of this check with the `EXEMPTED_FROM_TEST` constant. +//! +//! 4. We check that the error code is actually emitted by the compiler. +//! - This is done by searching `compiler/` with a regex. +//! +//! This tidy check was merged and refactored from two others. See #PR_NUM for information about linting changes that occurred during this refactor. + +use std::{ffi::OsStr, fs, path::Path}; + +use regex::Regex; + +use crate::walk::{filter_dirs, walk, walk_many}; + +const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/error_codes.rs"; +const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/"; +const ERROR_TESTS_PATH: &str = "src/test/ui/error-codes/"; + +// Error codes that (for some reason) can't have a doctest in their explanation. Error codes are still expected to provide a code example, even if untested. +const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0729"]; + +// Error codes that don't yet have a UI test. This list will eventually be removed. +const IGNORE_UI_TEST_CHECK: &[&str] = &[ + "E0313", "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", + "E0729", "E0789", +]; + +pub fn check(root_path: &Path, search_paths: &[&Path], bad: &mut bool) { + let mut errors = Vec::new(); + + // Stage 1: create list + let error_codes = extract_error_codes(root_path, &mut errors); + println!("Found {} error codes", error_codes.len()); + + // Stage 2: check list has docs + let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors); + + // Stage 3: check list has UI tests + check_error_codes_tests(root_path, &error_codes, &mut errors); + + // Stage 4: check list is emitted by compiler + check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted); + + // Print any errors. + for error in errors { + tidy_error!(bad, "{}", error); + } +} + +/// Stage 1: Parses a list of error codes from `error_codes.rs`. +fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec { + let file = fs::read_to_string(root_path.join(Path::new(ERROR_CODES_PATH))) + .unwrap_or_else(|e| panic!("failed to read `error_codes.rs`: {e}")); + + let mut error_codes = Vec::new(); + let mut reached_undocumented_codes = false; + + let mut undocumented_count = 0; + + for line in file.lines() { + let line = line.trim(); + + if !reached_undocumented_codes && line.starts_with('E') { + let split_line = line.split_once(':'); + + // Extract the error code from the line, emitting a fatal error if it is not in a correct format. + let err_code = if let Some(err_code) = split_line { + err_code.0.to_owned() + } else { + errors.push(format!( + "Expected a line with the format `Exxxx: include_str!(\"..\")`, but got \"{}\" \ + without a `:` delimiter", + line, + )); + continue; + }; + + // If this is a duplicate of another error code, emit a fatal error. + if error_codes.contains(&err_code) { + errors.push(format!("Found duplicate error code: `{}`", err_code)); + continue; + } + + // Ensure that the line references the correct markdown file. + let expected_filename = format!(" include_str!(\"./error_codes/{}.md\"),", err_code); + if expected_filename != split_line.unwrap().1 { + errors.push(format!( + "Error code `{}` expected to reference docs with `{}` but instead found `{}`", + err_code, + expected_filename, + split_line.unwrap().1, + )); + continue; + } + + error_codes.push(err_code); + } else if reached_undocumented_codes && line.starts_with('E') { + let err_code = match line.split_once(',') { + None => line, + Some((err_code, _)) => err_code, + } + .to_string(); + + undocumented_count += 1; + + if error_codes.contains(&err_code) { + errors.push(format!("Found duplicate error code: `{}`", err_code)); + } + + error_codes.push(err_code); + } else if line == ";" { + // Once we reach the undocumented error codes, adapt to different syntax. + reached_undocumented_codes = true; + } + } + + println!( + "WARNING: {} error codes are undocumented. This *will* become a hard error.", + undocumented_count + ); + + error_codes +} + +/// Stage 2: Checks that long-form error code explanations exist and have doctests. +fn check_error_codes_docs( + root_path: &Path, + error_codes: &[String], + errors: &mut Vec, +) -> Vec { + let docs_path = root_path.join(Path::new(ERROR_DOCS_PATH)); + + let mut emit_ignore_warning = 0; + let mut emit_no_longer_warning = 0; + let mut emit_no_code_warning = 0; + + let mut no_longer_emitted_codes = Vec::new(); + + walk(&docs_path, &mut |_| false, &mut |entry, contents| { + let path = entry.path(); + + // Error if the file isn't markdown. + if path.extension() != Some(OsStr::new("md")) { + errors.push(format!( + "Found unexpected non-markdown file in error code docs directory: {}", + path.display() + )); + return; + } + + // Make sure that the file is referenced in `error_codes.rs` + let filename = path.file_name().unwrap().to_str().unwrap().split_once('.'); + let err_code = filename.unwrap().0; // `unwrap` is ok because we know the filename is in the correct format. + + if error_codes.iter().all(|e| e != err_code) { + errors.push(format!( + "Found valid file `{}` in error code docs directory without corresponding \ + entry in `error_code.rs`", + path.display() + )); + return; + } + + // `has_test.0` checks whether the error code has any (potentially untested) code example. + // `has_test.1` checks whether the error code has a proper (definitely tested) doctest. + let has_test = check_explanation_has_doctest(&contents, &err_code); + if has_test.2 { + emit_ignore_warning += 1; + } + if has_test.3 { + no_longer_emitted_codes.push(err_code.to_owned()); + emit_no_longer_warning += 1; + } + if !has_test.0 { + emit_no_code_warning += 1; + } + + let test_ignored = IGNORE_DOCTEST_CHECK.contains(&err_code); + + // Check that the explanation has a doctest, and if it shouldn't, that it doesn't + if !has_test.1 && !test_ignored { + errors.push(format!( + "`{}` doesn't use its own error code in compile_fail example", + path.display(), + )); + } else if has_test.1 && test_ignored { + errors.push(format!( + "`{}` has a compile_fail doctest with its own error code, it shouldn't \ + be listed in `IGNORE_DOCTEST_CHECK`", + path.display(), + )); + } + }); + + if emit_ignore_warning > 0 { + println!( + "WARNING: {emit_ignore_warning} error codes use the ignore header. This should not be used, add the error codes to the \ + `IGNORE_DOCTEST_CHECK` constant instead. This *will* become a hard error." + ); + } + if emit_no_code_warning > 0 { + println!( + "WARNING: {emit_ignore_warning} error codes don't have a code example, all error codes are expected \ + to have one (even if untested). This *will* become a hard error." + ); + } + if emit_no_longer_warning > 0 { + println!( + "WARNING: {emit_no_longer_warning} error codes are no longer emitted and should be removed entirely. \ + This *will* become a hard error." + ); + } + + no_longer_emitted_codes +} + +/// This function returns a tuple indicating whether the provided explanation: +/// a) has a code example, tested or not. +/// b) has a valid doctest +fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bool, bool, bool) { + let mut found_code_example = false; + let mut found_proper_doctest = false; + + let mut emit_ignore_warning = false; + let mut emit_no_longer_warning = false; + + for line in explanation.lines() { + let line = line.trim(); + + if line.starts_with("```") { + found_code_example = true; + + // Check for the `rustdoc` doctest headers. + if line.contains("compile_fail") && line.contains(err_code) { + found_proper_doctest = true; + } + + if line.contains("ignore") { + emit_ignore_warning = true; + found_proper_doctest = true; + } + } else if line + .starts_with("#### Note: this error code is no longer emitted by the compiler") + { + emit_no_longer_warning = true; + found_code_example = true; + found_proper_doctest = true; + } + } + + (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) +} + +// Stage 3: Checks that each error code has a UI test in the correct directory +fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mut Vec) { + let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH)); + + // Some warning counters, this whole thing is clunky but'll be removed eventually. + let mut no_ui_test = 0; + let mut no_error_code_in_test = 0; + + for code in error_codes { + let test_path = tests_path.join(format!("{}.stderr", code)); + + if !test_path.exists() && !IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { + no_ui_test += 1; + continue; + } + if IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { + if test_path.exists() { + errors.push(format!( + "Error code `{code}` has a UI test, it shouldn't be listed in `EXEMPTED_FROM_TEST`!" + )); + } + continue; + } + + let file = match fs::read_to_string(test_path) { + Ok(file) => file, + Err(err) => { + println!( + "WARNING: Failed to read UI test file for `{code}` but the file exists. The test is assumed to work:\n{err}" + ); + continue; + } + }; + + let mut found_code = false; + + for line in file.lines() { + let s = line.trim(); + // Assuming the line starts with `error[E`, we can substring the error code out. + if s.starts_with("error[E") { + if &s[6..11] == code { + found_code = true; + break; + } + }; + } + + if !found_code { + no_error_code_in_test += 1; + } + } + + if no_error_code_in_test > 0 { + println!( + "WARNING: {no_error_code_in_test} error codes have a UI test file, but don't contain their own error code!" + ); + } + + if no_ui_test > 0 { + println!( + "WARNING: {no_ui_test} error codes need to have at least one UI test in the `src/test/ui/error-codes/` directory`! \ + This *will* become a hard error." + ); + } +} + +/// Stage 4: Search `compiler/` and ensure that every error code is actually used by the compiler and that no undocumented error codes exist. +fn check_error_codes_used( + search_paths: &[&Path], + error_codes: &[String], + errors: &mut Vec, + no_longer_emitted: &[String], +) { + // We want error codes which match the following cases: + // + // * foo(a, E0111, a) + // * foo(a, E0111) + // * foo(E0111, a) + // * #[error = "E0111"] + let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap(); + + let mut found_codes = Vec::new(); + + walk_many(search_paths, &mut filter_dirs, &mut |entry, contents| { + let path = entry.path(); + + // Return early if we aren't looking at a source file. + if path.extension() != Some(OsStr::new("rs")) { + return; + } + + for line in contents.lines() { + // We want to avoid parsing error codes in comments. + if line.trim_start().starts_with("//") { + continue; + } + + for cap in regex.captures_iter(line) { + if let Some(error_code) = cap.get(1) { + let error_code = error_code.as_str().to_owned(); + + if !error_codes.contains(&error_code) { + // This error code isn't properly defined, we must error. + errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/error_codes.rs`.", error_code)); + continue; + } + + // This error code can now be marked as used. + found_codes.push(error_code); + } + } + } + }); + + let mut used_when_shouldnt = 0; + + for code in error_codes { + if !found_codes.contains(code) && !no_longer_emitted.contains(code) { + errors.push(format!("Error code `{code}` exists, but is not emitted by the compiler!")) + } + + if found_codes.contains(code) && no_longer_emitted.contains(code) { + used_when_shouldnt += 1; + } + } + + if used_when_shouldnt > 0 { + println!( + "WARNING: {used_when_shouldnt} error codes are used when they are marked as \"no longer emitted\"" + ); + } +} diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs deleted file mode 100644 index 3f060e437ac..00000000000 --- a/src/tools/tidy/src/error_codes_check.rs +++ /dev/null @@ -1,305 +0,0 @@ -//! Checks that all error codes have at least one test to prevent having error -//! codes that are silently not thrown by the compiler anymore. - -use crate::walk::{filter_dirs, walk}; -use std::collections::{HashMap, HashSet}; -use std::ffi::OsStr; -use std::fs::read_to_string; -use std::path::Path; - -use regex::Regex; - -// A few of those error codes can't be tested but all the others can and *should* be tested! -const EXEMPTED_FROM_TEST: &[&str] = &[ - "E0313", "E0461", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729", - "E0789", -]; - -// Some error codes don't have any tests apparently... -const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0729"]; - -// If the file path contains any of these, we don't want to try to extract error codes from it. -// -// We need to declare each path in the windows version (with backslash). -const PATHS_TO_IGNORE_FOR_EXTRACTION: &[&str] = - &["src/test/", "src\\test\\", "src/doc/", "src\\doc\\", "src/tools/", "src\\tools\\"]; - -#[derive(Default, Debug)] -struct ErrorCodeStatus { - has_test: bool, - has_explanation: bool, - is_used: bool, -} - -fn check_error_code_explanation( - f: &str, - error_codes: &mut HashMap, - err_code: String, -) -> bool { - let mut invalid_compile_fail_format = false; - let mut found_error_code = false; - - for line in f.lines() { - let s = line.trim(); - if s.starts_with("```") { - if s.contains("compile_fail") && s.contains('E') { - if !found_error_code { - error_codes.get_mut(&err_code).map(|x| x.has_test = true); - found_error_code = true; - } - } else if s.contains("compile-fail") { - invalid_compile_fail_format = true; - } - } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") { - if !found_error_code { - error_codes.get_mut(&err_code).map(|x| x.has_test = true); - found_error_code = true; - } - } - } - invalid_compile_fail_format -} - -fn check_if_error_code_is_test_in_explanation(f: &str, err_code: &str) -> bool { - let mut ignore_found = false; - - for line in f.lines() { - let s = line.trim(); - if s.starts_with("#### Note: this error code is no longer emitted by the compiler") { - return true; - } - if s.starts_with("```") { - if s.contains("compile_fail") && s.contains(err_code) { - return true; - } else if s.contains("ignore") { - // It's very likely that we can't actually make it fail compilation... - ignore_found = true; - } - } - } - ignore_found -} - -fn extract_error_codes( - f: &str, - error_codes: &mut HashMap, - path: &Path, - errors: &mut Vec, -) { - let mut reached_no_explanation = false; - - for line in f.lines() { - let s = line.trim(); - if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") { - let err_code = s - .split_once(':') - .expect( - format!( - "Expected a line with the format `E0xxx: include_str!(\"..\")`, but got {} \ - without a `:` delimiter", - s, - ) - .as_str(), - ) - .0 - .to_owned(); - error_codes.entry(err_code.clone()).or_default().has_explanation = true; - - // Now we extract the tests from the markdown file! - let md_file_name = match s.split_once("include_str!(\"") { - None => continue, - Some((_, md)) => match md.split_once("\")") { - None => continue, - Some((file_name, _)) => file_name, - }, - }; - - let Some(parent) = path.parent() else { - continue; - }; - - let path = parent - .join(md_file_name) - .canonicalize() - .expect("failed to canonicalize error explanation file path"); - - match read_to_string(&path) { - Ok(content) => { - let has_test = check_if_error_code_is_test_in_explanation(&content, &err_code); - if !has_test && !IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) { - errors.push(format!( - "`{}` doesn't use its own error code in compile_fail example", - path.display(), - )); - } else if has_test && IGNORE_EXPLANATION_CHECK.contains(&err_code.as_str()) { - errors.push(format!( - "`{}` has a compile_fail example with its own error code, it shouldn't \ - be listed in IGNORE_EXPLANATION_CHECK!", - path.display(), - )); - } - if check_error_code_explanation(&content, error_codes, err_code) { - errors.push(format!( - "`{}` uses invalid tag `compile-fail` instead of `compile_fail`", - path.display(), - )); - } - } - Err(e) => { - eprintln!("Couldn't read `{}`: {}", path.display(), e); - } - } - } else if reached_no_explanation && s.starts_with('E') { - let err_code = match s.split_once(',') { - None => s, - Some((err_code, _)) => err_code, - } - .to_string(); - if !error_codes.contains_key(&err_code) { - // this check should *never* fail! - error_codes.insert(err_code, ErrorCodeStatus::default()); - } - } else if s == ";" { - reached_no_explanation = true; - } - } -} - -fn extract_error_codes_from_tests(f: &str, error_codes: &mut HashMap) { - for line in f.lines() { - let s = line.trim(); - if s.starts_with("error[E") || s.starts_with("warning[E") { - let err_code = match s.split_once(']') { - None => continue, - Some((err_code, _)) => match err_code.split_once('[') { - None => continue, - Some((_, err_code)) => err_code, - }, - }; - error_codes.entry(err_code.to_owned()).or_default().has_test = true; - } - } -} - -fn extract_error_codes_from_source( - f: &str, - error_codes: &mut HashMap, - regex: &Regex, -) { - for line in f.lines() { - if line.trim_start().starts_with("//") { - continue; - } - for cap in regex.captures_iter(line) { - if let Some(error_code) = cap.get(1) { - error_codes.entry(error_code.as_str().to_owned()).or_default().is_used = true; - } - } - } -} - -pub fn check(paths: &[&Path], bad: &mut bool) { - let mut errors = Vec::new(); - let mut found_explanations = 0; - let mut found_tests = 0; - let mut error_codes: HashMap = HashMap::new(); - let mut explanations: HashSet = HashSet::new(); - // We want error codes which match the following cases: - // - // * foo(a, E0111, a) - // * foo(a, E0111) - // * foo(E0111, a) - // * #[error = "E0111"] - let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap(); - - for path in paths { - walk(path, &mut filter_dirs, &mut |entry, contents| { - let file_name = entry.file_name(); - let entry_path = entry.path(); - - if file_name == "error_codes.rs" { - extract_error_codes(contents, &mut error_codes, entry.path(), &mut errors); - found_explanations += 1; - } else if entry_path.extension() == Some(OsStr::new("stderr")) { - extract_error_codes_from_tests(contents, &mut error_codes); - found_tests += 1; - } else if entry_path.extension() == Some(OsStr::new("rs")) { - let path = entry.path().to_string_lossy(); - if PATHS_TO_IGNORE_FOR_EXTRACTION.iter().all(|c| !path.contains(c)) { - extract_error_codes_from_source(contents, &mut error_codes, ®ex); - } - } else if entry_path - .parent() - .and_then(|p| p.file_name()) - .map(|p| p == "error_codes") - .unwrap_or(false) - && entry_path.extension() == Some(OsStr::new("md")) - { - explanations.insert(file_name.to_str().unwrap().replace(".md", "")); - } - }); - } - if found_explanations == 0 { - tidy_error!(bad, "No error code explanation was tested!"); - } - if found_tests == 0 { - tidy_error!(bad, "No error code was found in compilation errors!"); - } - if explanations.is_empty() { - tidy_error!(bad, "No error code explanation was found!"); - } - if errors.is_empty() { - for (err_code, error_status) in &error_codes { - if !error_status.has_test && !EXEMPTED_FROM_TEST.contains(&err_code.as_str()) { - errors.push(format!("Error code {err_code} needs to have at least one UI test!")); - } else if error_status.has_test && EXEMPTED_FROM_TEST.contains(&err_code.as_str()) { - errors.push(format!( - "Error code {} has a UI test, it shouldn't be listed into EXEMPTED_FROM_TEST!", - err_code - )); - } - if !error_status.is_used && !error_status.has_explanation { - errors.push(format!( - "Error code {} isn't used and doesn't have an error explanation, it should be \ - commented in error_codes.rs file", - err_code - )); - } - } - } - if errors.is_empty() { - // Checking if local constants need to be cleaned. - for err_code in EXEMPTED_FROM_TEST { - match error_codes.get(err_code.to_owned()) { - Some(status) => { - if status.has_test { - errors.push(format!( - "{} error code has a test and therefore should be \ - removed from the `EXEMPTED_FROM_TEST` constant", - err_code - )); - } - } - None => errors.push(format!( - "{} error code isn't used anymore and therefore should be removed \ - from `EXEMPTED_FROM_TEST` constant", - err_code - )), - } - } - } - if errors.is_empty() { - for explanation in explanations { - if !error_codes.contains_key(&explanation) { - errors.push(format!( - "{} error code explanation should be listed in `error_codes.rs`", - explanation - )); - } - } - } - errors.sort(); - for err in &errors { - tidy_error!(bad, "{err}"); - } -} diff --git a/src/tools/tidy/src/errors.rs b/src/tools/tidy/src/errors.rs deleted file mode 100644 index fe5fd72b91a..00000000000 --- a/src/tools/tidy/src/errors.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Tidy check to verify the validity of long error diagnostic codes. -//! -//! This ensures that error codes are used at most once and also prints out some -//! statistics about the error codes. - -use crate::walk::{filter_dirs, walk}; -use std::collections::HashMap; -use std::path::Path; - -pub fn check(path: &Path, bad: &mut bool) { - let mut map: HashMap<_, Vec<_>> = HashMap::new(); - walk( - path, - &mut |path| filter_dirs(path) || path.ends_with("src/test"), - &mut |entry, contents| { - let file = entry.path(); - let filename = file.file_name().unwrap().to_string_lossy(); - if filename != "error_codes.rs" { - return; - } - - // In the `register_long_diagnostics!` macro, entries look like this: - // - // ``` - // EXXXX: r##" - // - // "##, - // ``` - // - // and these long messages often have error codes themselves inside - // them, but we don't want to report duplicates in these cases. This - // variable keeps track of whether we're currently inside one of these - // long diagnostic messages. - let mut inside_long_diag = false; - for (num, line) in contents.lines().enumerate() { - if inside_long_diag { - inside_long_diag = !line.contains("\"##"); - continue; - } - - let mut search = line; - while let Some(i) = search.find('E') { - search = &search[i + 1..]; - let code = if search.len() > 4 { search[..4].parse::() } else { continue }; - let code = match code { - Ok(n) => n, - Err(..) => continue, - }; - map.entry(code).or_default().push((file.to_owned(), num + 1, line.to_owned())); - break; - } - - inside_long_diag = line.contains("r##\""); - } - }, - ); - - let mut max = 0; - for (&code, entries) in map.iter() { - if code > max { - max = code; - } - if entries.len() == 1 { - continue; - } - - tidy_error!(bad, "duplicate error code: {}", code); - for &(ref file, line_num, ref line) in entries.iter() { - tidy_error!(bad, "{}:{}: {}", file.display(), line_num, line); - } - } - - if !*bad { - println!("* {} error codes", map.len()); - println!("* highest error code: E{:04}", max); - } -} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index ce7e7ac5cd4..bf6e2cc250f 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -56,8 +56,7 @@ pub mod bins; pub mod debug_artifacts; pub mod deps; pub mod edition; -pub mod error_codes_check; -pub mod errors; +pub mod error_codes; pub mod extdeps; pub mod features; pub mod mir_opt_tests; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 6714c63ee62..8bb79bab147 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -27,6 +27,7 @@ fn main() { let src_path = root_path.join("src"); let library_path = root_path.join("library"); let compiler_path = root_path.join("compiler"); + let librustdoc_path = src_path.join("librustdoc"); let args: Vec = env::args().skip(1).collect(); @@ -79,8 +80,7 @@ fn main() { check!(mir_opt_tests, &src_path, bless); // Checks that only make sense for the compiler. - check!(errors, &compiler_path); - check!(error_codes_check, &[&src_path, &compiler_path]); + check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path]); // Checks that only make sense for the std libs. check!(pal, &library_path); -- cgit 1.4.1-3-g733a5 From 035d854947d5899388f77f6d00fc488caad86b5c Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sun, 1 Jan 2023 18:48:14 +0100 Subject: reduce spans for `unsafe impl` errors --- compiler/rustc_hir_analysis/src/coherence/unsafety.rs | 6 +++--- .../ui/coherence/coherence-default-trait-impl.stderr | 4 ++-- .../dropck/dropck-eyepatch-implies-unsafe-impl.stderr | 18 ++++-------------- src/test/ui/error-codes/E0199.stderr | 2 +- src/test/ui/error-codes/E0200.stderr | 2 +- src/test/ui/traits/safety-trait-impl-cc.stderr | 8 ++------ src/test/ui/traits/safety-trait-impl.stderr | 4 ++-- 7 files changed, 15 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index a34815b45b3..70cc15b2f8c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -21,7 +21,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { struct_span_err!( tcx.sess, - item.span, + tcx.def_span(def_id), E0199, "implementing the trait `{}` is not unsafe", trait_ref.print_only_trait_path() @@ -38,7 +38,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => { struct_span_err!( tcx.sess, - item.span, + tcx.def_span(def_id), E0200, "the trait `{}` requires an `unsafe impl` declaration", trait_ref.print_only_trait_path() @@ -61,7 +61,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { (Unsafety::Normal, Some(attr_name), Unsafety::Normal, hir::ImplPolarity::Positive) => { struct_span_err!( tcx.sess, - item.span, + tcx.def_span(def_id), E0569, "requires an `unsafe impl` declaration due to `#[{}]` attribute", attr_name diff --git a/src/test/ui/coherence/coherence-default-trait-impl.stderr b/src/test/ui/coherence/coherence-default-trait-impl.stderr index 63201878272..7be5b92a7de 100644 --- a/src/test/ui/coherence/coherence-default-trait-impl.stderr +++ b/src/test/ui/coherence/coherence-default-trait-impl.stderr @@ -2,7 +2,7 @@ error[E0199]: implementing the trait `MySafeTrait` is not unsafe --> $DIR/coherence-default-trait-impl.rs:8:1 | LL | unsafe impl MySafeTrait for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `unsafe` from this trait implementation | @@ -14,7 +14,7 @@ error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration --> $DIR/coherence-default-trait-impl.rs:13:1 | LL | impl MyUnsafeTrait for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `MyUnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr index 82169ee01be..5cec2bcb038 100644 --- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr @@ -1,13 +1,8 @@ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:21:1 | -LL | / impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { -LL | | -LL | | -LL | | // (unsafe to access self.1 due to #[may_dangle] on A) -LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } -LL | | } - | |_^ +LL | impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation @@ -18,13 +13,8 @@ LL | unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:27:1 | -LL | / impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { -LL | | -LL | | -LL | | // (unsafe to access self.1 due to #[may_dangle] on 'a) -LL | | fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } -LL | | } - | |_^ +LL | impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `Drop` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation diff --git a/src/test/ui/error-codes/E0199.stderr b/src/test/ui/error-codes/E0199.stderr index 99d808c0d4b..68c308b15cc 100644 --- a/src/test/ui/error-codes/E0199.stderr +++ b/src/test/ui/error-codes/E0199.stderr @@ -2,7 +2,7 @@ error[E0199]: implementing the trait `Bar` is not unsafe --> $DIR/E0199.rs:6:1 | LL | unsafe impl Bar for Foo { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `unsafe` from this trait implementation | diff --git a/src/test/ui/error-codes/E0200.stderr b/src/test/ui/error-codes/E0200.stderr index 1fd86aecee1..c70a2d4f3d1 100644 --- a/src/test/ui/error-codes/E0200.stderr +++ b/src/test/ui/error-codes/E0200.stderr @@ -2,7 +2,7 @@ error[E0200]: the trait `Bar` requires an `unsafe impl` declaration --> $DIR/E0200.rs:5:1 | LL | impl Bar for Foo { } - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = note: the trait `Bar` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation diff --git a/src/test/ui/traits/safety-trait-impl-cc.stderr b/src/test/ui/traits/safety-trait-impl-cc.stderr index 0b1fb30478f..0ca565787f6 100644 --- a/src/test/ui/traits/safety-trait-impl-cc.stderr +++ b/src/test/ui/traits/safety-trait-impl-cc.stderr @@ -1,12 +1,8 @@ error[E0200]: the trait `Foo` requires an `unsafe impl` declaration --> $DIR/safety-trait-impl-cc.rs:9:1 | -LL | / impl lib::Foo for Bar { -LL | | fn foo(&self) -> isize { -LL | | panic!(); -LL | | } -LL | | } - | |_^ +LL | impl lib::Foo for Bar { + | ^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `Foo` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation diff --git a/src/test/ui/traits/safety-trait-impl.stderr b/src/test/ui/traits/safety-trait-impl.stderr index 721e2b48b95..e78e0e3a6ba 100644 --- a/src/test/ui/traits/safety-trait-impl.stderr +++ b/src/test/ui/traits/safety-trait-impl.stderr @@ -2,7 +2,7 @@ error[E0200]: the trait `UnsafeTrait` requires an `unsafe impl` declaration --> $DIR/safety-trait-impl.rs:14:1 | LL | impl UnsafeTrait for u16 { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the trait `UnsafeTrait` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword help: add `unsafe` to this trait implementation @@ -14,7 +14,7 @@ error[E0199]: implementing the trait `SafeTrait` is not unsafe --> $DIR/safety-trait-impl.rs:16:1 | LL | unsafe impl SafeTrait for u32 { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: remove `unsafe` from this trait implementation | -- cgit 1.4.1-3-g733a5 From ce28b4d408d260dab1bbcef4851506bb3089f4bc Mon Sep 17 00:00:00 2001 From: LegionMammal978 Date: Sun, 1 Jan 2023 13:47:11 -0500 Subject: Deallocate ThinBox even if the value unwinds on drop --- library/alloc/src/boxed/thin.rs | 47 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index c477c44906c..c1a82e452f6 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -226,24 +226,45 @@ impl WithHeader { // - Assumes that either `value` can be dereferenced, or is the // `NonNull::dangling()` we use when both `T` and `H` are ZSTs. unsafe fn drop(&self, value: *mut T) { + struct DropGuard { + ptr: NonNull, + value_layout: Layout, + _marker: PhantomData, + } + + impl Drop for DropGuard { + fn drop(&mut self) { + unsafe { + // SAFETY: Layout must have been computable if we're in drop + let (layout, value_offset) = + WithHeader::::alloc_layout(self.value_layout).unwrap_unchecked(); + + // Note: Don't deallocate if the layout size is zero, because the pointer + // didn't come from the allocator. + if layout.size() != 0 { + alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); + } else { + debug_assert!( + value_offset == 0 + && mem::size_of::() == 0 + && self.value_layout.size() == 0 + ); + } + } + } + } + unsafe { - let value_layout = Layout::for_value_raw(value); - // SAFETY: Layout must have been computable if we're in drop - let (layout, value_offset) = Self::alloc_layout(value_layout).unwrap_unchecked(); + // `_guard` will deallocate the memory when dropped, even if `drop_in_place` unwinds. + let _guard = DropGuard { + ptr: self.0, + value_layout: Layout::for_value_raw(value), + _marker: PhantomData::, + }; // We only drop the value because the Pointee trait requires that the metadata is copy // aka trivially droppable. ptr::drop_in_place::(value); - - // Note: Don't deallocate if the layout size is zero, because the pointer - // didn't come from the allocator. - if layout.size() != 0 { - alloc::dealloc(self.0.as_ptr().sub(value_offset), layout); - } else { - debug_assert!( - value_offset == 0 && mem::size_of::() == 0 && value_layout.size() == 0 - ); - } } } -- cgit 1.4.1-3-g733a5 From 9618f646b314f934fe4ff92d6424255573c65a1c Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 09:11:36 +1300 Subject: docs: revert removal of `E0729` --- compiler/rustc_error_codes/src/error_codes.rs | 1 + .../rustc_error_codes/src/error_codes/E0729.md | 32 ++++++++++++++++++++++ src/tools/tidy/src/error_codes.rs | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0729.md diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 137325e6fab..3fba2cf5749 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -443,6 +443,7 @@ E0725: include_str!("./error_codes/E0725.md"), E0726: include_str!("./error_codes/E0726.md"), E0727: include_str!("./error_codes/E0727.md"), E0728: include_str!("./error_codes/E0728.md"), +E0729: include_str!("./error_codes/E0729.md"), E0730: include_str!("./error_codes/E0730.md"), E0731: include_str!("./error_codes/E0731.md"), E0732: include_str!("./error_codes/E0732.md"), diff --git a/compiler/rustc_error_codes/src/error_codes/E0729.md b/compiler/rustc_error_codes/src/error_codes/E0729.md new file mode 100644 index 00000000000..3891745b500 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0729.md @@ -0,0 +1,32 @@ +#### Note: this error code is no longer emitted by the compiler + +Support for Non-Lexical Lifetimes (NLL) has been included in the Rust compiler +since 1.31, and has been enabled on the 2015 edition since 1.36. The new borrow +checker for NLL uncovered some bugs in the old borrow checker, which in some +cases allowed unsound code to compile, resulting in memory safety issues. + +### What do I do? + +Change your code so the warning does no longer trigger. For backwards +compatibility, this unsound code may still compile (with a warning) right now. +However, at some point in the future, the compiler will no longer accept this +code and will throw a hard error. + +### Shouldn't you fix the old borrow checker? + +The old borrow checker has known soundness issues that are basically impossible +to fix. The new NLL-based borrow checker is the fix. + +### Can I turn these warnings into errors by denying a lint? + +No. + +### When are these warnings going to turn into errors? + +No formal timeline for turning the warnings into errors has been set. See +[GitHub issue 58781](https://github.com/rust-lang/rust/issues/58781) for more +information. + +### Why do I get this message with code that doesn't involve borrowing? + +There are some known bugs that trigger this message. diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index f4aebbf2277..b766f166718 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -29,7 +29,7 @@ const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/"; const ERROR_TESTS_PATH: &str = "src/test/ui/error-codes/"; // Error codes that (for some reason) can't have a doctest in their explanation. Error codes are still expected to provide a code example, even if untested. -const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E0729"]; +const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602"]; // Error codes that don't yet have a UI test. This list will eventually be removed. const IGNORE_UI_TEST_CHECK: &[&str] = &[ -- cgit 1.4.1-3-g733a5 From 24671b7fd5daf16a39d6c9c62a457ace0b9c3ff6 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 09:15:36 +1300 Subject: use more paths in error codes --- src/tools/tidy/src/error_codes.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index b766f166718..026f7d87418 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -61,8 +61,9 @@ pub fn check(root_path: &Path, search_paths: &[&Path], bad: &mut bool) { /// Stage 1: Parses a list of error codes from `error_codes.rs`. fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec { - let file = fs::read_to_string(root_path.join(Path::new(ERROR_CODES_PATH))) - .unwrap_or_else(|e| panic!("failed to read `error_codes.rs`: {e}")); + let path = root_path.join(Path::new(ERROR_CODES_PATH)); + let file = + fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); let mut error_codes = Vec::new(); let mut reached_undocumented_codes = false; @@ -97,7 +98,8 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec file, Err(err) => { println!( - "WARNING: Failed to read UI test file for `{code}` but the file exists. The test is assumed to work:\n{err}" + "WARNING: Failed to read UI test file (`{test_path}`) for `{code}` but the file exists. The test is assumed to work:\n{err}" ); continue; } -- cgit 1.4.1-3-g733a5 From 5e67ce6803c5d1d67ccfce653a80257aba41f43a Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Sun, 1 Jan 2023 13:20:32 -0700 Subject: handle error case where --wrapper-version argument doesn't exist --- src/tools/tidy/src/x_version.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index dddf72f4747..1505775c6cc 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -4,15 +4,29 @@ use std::process::{Command, Stdio}; pub fn check(bad: &mut bool) { let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); - let child = match result { - Ok(child) => child, - Err(e) => match e.kind() { + // This runs the command inside a temporarily directory. + // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. + let temp_result = Command::new("x").arg("--wrapper-version").current_dir(std::env::temp_dir()).stdout(Stdio::piped()).spawn(); + + let (child, temp_child) = match (result, temp_result) { + (Ok(child), Ok(temp_child)) => (child, temp_child), + // what would it mean if the temp cmd error'd? + (Ok(_child), Err(_e)) => todo!(), + (Err(e), _) => match e.kind() { ErrorKind::NotFound => return, _ => return tidy_error!(bad, "failed to run `x`: {}", e), }, }; let output = child.wait_with_output().unwrap(); + let temp_output = temp_child.wait_with_output().unwrap(); + + if output != temp_output { + return tidy_error!( + bad, + "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" + ) + } if output.status.success() { let version = String::from_utf8_lossy(&output.stdout); -- cgit 1.4.1-3-g733a5 From def1b7cb9ab99565cb3dc08d88035fd9cdb3c22a Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 09:20:41 +1300 Subject: fix CI error --- src/tools/tidy/src/error_codes.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 026f7d87418..4498666da1e 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -289,11 +289,12 @@ fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mu continue; } - let file = match fs::read_to_string(test_path) { + let file = match fs::read_to_string(&test_path) { Ok(file) => file, Err(err) => { println!( - "WARNING: Failed to read UI test file (`{test_path}`) for `{code}` but the file exists. The test is assumed to work:\n{err}" + "WARNING: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n{err}", + test_path.display() ); continue; } -- cgit 1.4.1-3-g733a5 From e94354e3632e76c6ccff91f40fa054f68e2e87f4 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Sun, 1 Jan 2023 13:41:47 -0700 Subject: fix formatting --- src/tools/tidy/src/x_version.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 1505775c6cc..9cb762b9419 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -6,7 +6,11 @@ pub fn check(bad: &mut bool) { let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); // This runs the command inside a temporarily directory. // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. - let temp_result = Command::new("x").arg("--wrapper-version").current_dir(std::env::temp_dir()).stdout(Stdio::piped()).spawn(); + let temp_result = Command::new("x") + .arg("--wrapper-version") + .current_dir(std::env::temp_dir()) + .stdout(Stdio::piped()) + .spawn(); let (child, temp_child) = match (result, temp_result) { (Ok(child), Ok(temp_child)) => (child, temp_child), @@ -23,9 +27,9 @@ pub fn check(bad: &mut bool) { if output != temp_output { return tidy_error!( - bad, - "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" - ) + bad, + "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" + ); } if output.status.success() { -- cgit 1.4.1-3-g733a5 From fafb18e0c45b60bacd08e2d8c8932401181dafbc Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 09:44:10 +1300 Subject: fixup warnings --- src/tools/tidy/src/error_codes.rs | 123 ++++++++++++++++---------------------- src/tools/tidy/src/main.rs | 2 +- 2 files changed, 53 insertions(+), 72 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 4498666da1e..ac87e4797c5 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -37,21 +37,29 @@ const IGNORE_UI_TEST_CHECK: &[&str] = &[ "E0729", "E0789", ]; -pub fn check(root_path: &Path, search_paths: &[&Path], bad: &mut bool) { +macro_rules! verbose_print { + ($verbose:expr, $($fmt:tt)*) => { + if $verbose { + println!("{}", format_args!($($fmt)*)); + } + }; +} + +pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut bool) { let mut errors = Vec::new(); // Stage 1: create list - let error_codes = extract_error_codes(root_path, &mut errors); + let error_codes = extract_error_codes(root_path, &mut errors, verbose); println!("Found {} error codes", error_codes.len()); // Stage 2: check list has docs - let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors); + let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose); // Stage 3: check list has UI tests - check_error_codes_tests(root_path, &error_codes, &mut errors); + check_error_codes_tests(root_path, &error_codes, &mut errors, verbose); // Stage 4: check list is emitted by compiler - check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted); + check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted, verbose); // Print any errors. for error in errors { @@ -60,7 +68,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], bad: &mut bool) { } /// Stage 1: Parses a list of error codes from `error_codes.rs`. -fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec { +fn extract_error_codes(root_path: &Path, errors: &mut Vec, verbose: bool) -> Vec { let path = root_path.join(Path::new(ERROR_CODES_PATH)); let file = fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); @@ -68,8 +76,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec) -> Vec) -> Vec, + verbose: bool, ) -> Vec { let docs_path = root_path.join(Path::new(ERROR_DOCS_PATH)); - let mut emit_ignore_warning = 0; - let mut emit_no_longer_warning = 0; - let mut emit_no_code_warning = 0; - let mut no_longer_emitted_codes = Vec::new(); walk(&docs_path, &mut |_| false, &mut |entry, contents| { @@ -179,14 +177,25 @@ fn check_error_codes_docs( // `has_test.1` checks whether the error code has a proper (definitely tested) doctest. let has_test = check_explanation_has_doctest(&contents, &err_code); if has_test.2 { - emit_ignore_warning += 1; + verbose_print!( + verbose, + "warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \ + `IGNORE_DOCTEST_CHECK` constant instead." + ); } if has_test.3 { no_longer_emitted_codes.push(err_code.to_owned()); - emit_no_longer_warning += 1; + verbose_print!( + verbose, + "warning: Error code `{err_code}` is no longer emitted and should be removed entirely." + ); } if !has_test.0 { - emit_no_code_warning += 1; + verbose_print!( + verbose, + "warning: Error code `{err_code}` doesn't have a code example, all error codes are expected to have one \ + (even if untested)." + ); } let test_ignored = IGNORE_DOCTEST_CHECK.contains(&err_code); @@ -206,25 +215,6 @@ fn check_error_codes_docs( } }); - if emit_ignore_warning > 0 { - println!( - "WARNING: {emit_ignore_warning} error codes use the ignore header. This should not be used, add the error codes to the \ - `IGNORE_DOCTEST_CHECK` constant instead. This *will* become a hard error." - ); - } - if emit_no_code_warning > 0 { - println!( - "WARNING: {emit_ignore_warning} error codes don't have a code example, all error codes are expected \ - to have one (even if untested). This *will* become a hard error." - ); - } - if emit_no_longer_warning > 0 { - println!( - "WARNING: {emit_no_longer_warning} error codes are no longer emitted and should be removed entirely. \ - This *will* become a hard error." - ); - } - no_longer_emitted_codes } @@ -266,18 +256,22 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo } // Stage 3: Checks that each error code has a UI test in the correct directory -fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mut Vec) { +fn check_error_codes_tests( + root_path: &Path, + error_codes: &[String], + errors: &mut Vec, + verbose: bool, +) { let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH)); - // Some warning counters, this whole thing is clunky but'll be removed eventually. - let mut no_ui_test = 0; - let mut no_error_code_in_test = 0; - for code in error_codes { let test_path = tests_path.join(format!("{}.stderr", code)); if !test_path.exists() && !IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { - no_ui_test += 1; + verbose_print!( + verbose, + "warning: Error code `{code}` needs to have at least one UI test in the `src/test/ui/error-codes/` directory`!" + ); continue; } if IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { @@ -292,8 +286,9 @@ fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mu let file = match fs::read_to_string(&test_path) { Ok(file) => file, Err(err) => { - println!( - "WARNING: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n{err}", + verbose_print!( + verbose, + "warning: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n{err}", test_path.display() ); continue; @@ -314,22 +309,12 @@ fn check_error_codes_tests(root_path: &Path, error_codes: &[String], errors: &mu } if !found_code { - no_error_code_in_test += 1; + verbose_print!( + verbose, + "warning: Error code {code}`` has a UI test file, but doesn't contain its own error code!" + ); } } - - if no_error_code_in_test > 0 { - println!( - "WARNING: {no_error_code_in_test} error codes have a UI test file, but don't contain their own error code!" - ); - } - - if no_ui_test > 0 { - println!( - "WARNING: {no_ui_test} error codes need to have at least one UI test in the `src/test/ui/error-codes/` directory`! \ - This *will* become a hard error." - ); - } } /// Stage 4: Search `compiler/` and ensure that every error code is actually used by the compiler and that no undocumented error codes exist. @@ -338,6 +323,7 @@ fn check_error_codes_used( error_codes: &[String], errors: &mut Vec, no_longer_emitted: &[String], + verbose: bool, ) { // We want error codes which match the following cases: // @@ -380,21 +366,16 @@ fn check_error_codes_used( } }); - let mut used_when_shouldnt = 0; - for code in error_codes { if !found_codes.contains(code) && !no_longer_emitted.contains(code) { errors.push(format!("Error code `{code}` exists, but is not emitted by the compiler!")) } if found_codes.contains(code) && no_longer_emitted.contains(code) { - used_when_shouldnt += 1; + verbose_print!( + verbose, + "warning: Error code `{code}` is used when it's marked as \"no longer emitted\"" + ); } } - - if used_when_shouldnt > 0 { - println!( - "WARNING: {used_when_shouldnt} error codes are used when they are marked as \"no longer emitted\"" - ); - } } diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 8bb79bab147..a7b7cc9fa6c 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -80,7 +80,7 @@ fn main() { check!(mir_opt_tests, &src_path, bless); // Checks that only make sense for the compiler. - check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path]); + check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose); // Checks that only make sense for the std libs. check!(pal, &library_path); -- cgit 1.4.1-3-g733a5 From d7cac976dc3ce23fcd119e8194b1cb824e1800df Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Sun, 1 Jan 2023 14:34:40 -0700 Subject: combine error branches --- src/tools/tidy/src/x_version.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 9cb762b9419..0a5055f6191 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -14,9 +14,7 @@ pub fn check(bad: &mut bool) { let (child, temp_child) = match (result, temp_result) { (Ok(child), Ok(temp_child)) => (child, temp_child), - // what would it mean if the temp cmd error'd? - (Ok(_child), Err(_e)) => todo!(), - (Err(e), _) => match e.kind() { + (Err(e), _) | (_, Err(e)) => match e.kind() { ErrorKind::NotFound => return, _ => return tidy_error!(bad, "failed to run `x`: {}", e), }, -- cgit 1.4.1-3-g733a5 From e62258ebf45840721ff1aed0e3edb378205af0d3 Mon Sep 17 00:00:00 2001 From: J Haigh Date: Sun, 1 Jan 2023 14:36:11 -0700 Subject: fix typo Co-authored-by: Joshua Nelson --- src/tools/tidy/src/x_version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 0a5055f6191..cf91749b9a4 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -4,7 +4,7 @@ use std::process::{Command, Stdio}; pub fn check(bad: &mut bool) { let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); - // This runs the command inside a temporarily directory. + // This runs the command inside a temporary directory. // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. let temp_result = Command::new("x") .arg("--wrapper-version") -- cgit 1.4.1-3-g733a5 From 9aebb1e09950591413103545d5bc1a40ec46bd9e Mon Sep 17 00:00:00 2001 From: J Haigh Date: Sun, 1 Jan 2023 14:36:51 -0700 Subject: improve error message Co-authored-by: Joshua Nelson --- src/tools/tidy/src/x_version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index cf91749b9a4..868b3d925d3 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -43,7 +43,7 @@ pub fn check(bad: &mut bool) { if version < expected { return tidy_error!( bad, - "Current version of x is {version} Consider updating to the newer version of x by running `cargo install --path src/tools/x`" + "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" ); } } else { -- cgit 1.4.1-3-g733a5 From 74cdf933078d9a936ab5103b6c29148d61fe4b16 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 15 Dec 2022 19:21:39 +0800 Subject: code refactor report_method_error --- compiler/rustc_hir_typeck/src/method/suggest.rs | 1799 +++++++++++------------ 1 file changed, 894 insertions(+), 905 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7053c180685..d391e318207 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn report_method_error( &self, - mut span: Span, + span: Span, rcvr_ty: Ty<'tcx>, item_name: Ident, source: SelfSource<'tcx>, @@ -114,144 +114,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - let report_candidates = |span: Span, - err: &mut Diagnostic, - sources: &mut Vec, - sugg_span: Option| { - sources.sort(); - sources.dedup(); - // Dynamic limit to avoid hiding just one candidate, which is silly. - let limit = if sources.len() == 5 { 5 } else { 4 }; - - for (idx, source) in sources.iter().take(limit).enumerate() { - match *source { - CandidateSource::Impl(impl_did) => { - // Provide the best span we can. Use the item, if local to crate, else - // the impl, if local to crate (item may be defaulted), else nothing. - let Some(item) = self.associated_value(impl_did, item_name).or_else(|| { - let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; - self.associated_value(impl_trait_ref.def_id, item_name) - }) else { - continue; - }; - - let note_span = if item.def_id.is_local() { - Some(self.tcx.def_span(item.def_id)) - } else if impl_did.is_local() { - Some(self.tcx.def_span(impl_did)) - } else { - None - }; - - let impl_ty = self.tcx.at(span).type_of(impl_did); - - let insertion = match self.tcx.impl_trait_ref(impl_did) { - None => String::new(), - Some(trait_ref) => format!( - " of the trait `{}`", - self.tcx.def_path_str(trait_ref.def_id) - ), - }; - - let (note_str, idx) = if sources.len() > 1 { - ( - format!( - "candidate #{} is defined in an impl{} for the type `{}`", - idx + 1, - insertion, - impl_ty, - ), - Some(idx + 1), - ) - } else { - ( - format!( - "the candidate is defined in an impl{} for the type `{}`", - insertion, impl_ty, - ), - None, - ) - }; - if let Some(note_span) = note_span { - // We have a span pointing to the method. Show note with snippet. - err.span_note(note_span, ¬e_str); - } else { - err.note(¬e_str); - } - if let Some(sugg_span) = sugg_span - && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { - let path = self.tcx.def_path_str(trait_ref.def_id); - - let ty = match item.kind { - ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, - ty::AssocKind::Fn => self - .tcx - .fn_sig(item.def_id) - .inputs() - .skip_binder() - .get(0) - .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr()) - .copied() - .unwrap_or(rcvr_ty), - }; - print_disambiguation_help( - item_name, - args, - err, - path, - ty, - item.kind, - item.def_id, - sugg_span, - idx, - self.tcx.sess.source_map(), - item.fn_has_self_parameter, - ); - } - } - CandidateSource::Trait(trait_did) => { - let Some(item) = self.associated_value(trait_did, item_name) else { continue }; - let item_span = self.tcx.def_span(item.def_id); - let idx = if sources.len() > 1 { - let msg = &format!( - "candidate #{} is defined in the trait `{}`", - idx + 1, - self.tcx.def_path_str(trait_did) - ); - err.span_note(item_span, msg); - Some(idx + 1) - } else { - let msg = &format!( - "the candidate is defined in the trait `{}`", - self.tcx.def_path_str(trait_did) - ); - err.span_note(item_span, msg); - None - }; - if let Some(sugg_span) = sugg_span { - let path = self.tcx.def_path_str(trait_did); - print_disambiguation_help( - item_name, - args, - err, - path, - rcvr_ty, - item.kind, - item.def_id, - sugg_span, - idx, - self.tcx.sess.source_map(), - item.fn_has_self_parameter, - ); - } - } - } - } - if sources.len() > limit { - err.note(&format!("and {} others", sources.len() - limit)); - } - }; - let sugg_span = if let SelfSource::MethodCall(expr) = source { // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing. self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span @@ -260,843 +122,970 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; match error { - MethodError::NoMatch(NoMatchData { - mut static_candidates, - unsatisfied_predicates, - out_of_scope_traits, - lev_candidate, - mode, - }) => { - let tcx = self.tcx; - - let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); - let ty_str = with_forced_trimmed_paths!(self.ty_to_string(rcvr_ty)); - let is_method = mode == Mode::MethodCall; - let item_kind = if is_method { - "method" - } else if rcvr_ty.is_enum() { - "variant or associated item" - } else { - match (item_name.as_str().chars().next(), rcvr_ty.is_fresh_ty()) { - (Some(name), false) if name.is_lowercase() => "function or associated item", - (Some(_), false) => "associated item", - (Some(_), true) | (None, false) => "variant or associated item", - (None, true) => "variant", - } - }; - - if self.suggest_wrapping_range_with_parens( - tcx, rcvr_ty, source, span, item_name, &ty_str, - ) || self.suggest_constraining_numerical_ty( - tcx, rcvr_ty, source, span, item_kind, item_name, &ty_str, - ) { - return None; - } - span = item_name.span; - - // Don't show generic arguments when the method can't be found in any implementation (#81576). - let mut ty_str_reported = ty_str.clone(); - if let ty::Adt(_, generics) = rcvr_ty.kind() { - if generics.len() > 0 { - let mut autoderef = self.autoderef(span, rcvr_ty); - let candidate_found = autoderef.any(|(ty, _)| { - if let ty::Adt(adt_def, _) = ty.kind() { - self.tcx - .inherent_impls(adt_def.did()) - .iter() - .filter_map(|def_id| self.associated_value(*def_id, item_name)) - .count() - >= 1 - } else { - false - } - }); - let has_deref = autoderef.step_count() > 0; - if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { - if let Some((path_string, _)) = ty_str.split_once('<') { - ty_str_reported = path_string.to_string(); - } - } - } - } + MethodError::NoMatch(mut no_match_data) => { + return self.report_no_match_method_error( + span, + rcvr_ty, + item_name, + source, + args, + sugg_span, + &mut no_match_data, + ); + } + MethodError::Ambiguity(mut sources) => { let mut err = struct_span_err!( - tcx.sess, - span, - E0599, - "no {} named `{}` found for {} `{}` in the current scope", - item_kind, + self.sess(), + item_name.span, + E0034, + "multiple applicable items in scope" + ); + err.span_label(item_name.span, format!("multiple `{}` found", item_name)); + + self.note_candidates_on_method_error( + rcvr_ty, item_name, - rcvr_ty.prefix_string(self.tcx), - ty_str_reported, + args, + span, + &mut err, + &mut sources, + Some(sugg_span), ); - if rcvr_ty.references_error() { - err.downgrade_to_delayed_bug(); - } + err.emit(); + } - if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source { - self.suggest_await_before_method( - &mut err, item_name, rcvr_ty, cal, span, - ); - } - if let Some(span) = - tcx.resolutions(()).confused_type_with_std_module.get(&span.with_parent(None)) - { - err.span_suggestion( - span.shrink_to_lo(), - "you are looking for the module in `std`, not the primitive type", - "std::", - Applicability::MachineApplicable, - ); - } - if let ty::RawPtr(_) = &rcvr_ty.kind() { - err.note( - "try using `<*const T>::as_ref()` to get a reference to the \ - type behind the pointer: https://doc.rust-lang.org/std/\ - primitive.pointer.html#method.as_ref", - ); - err.note( - "using `<*const T>::as_ref()` on a pointer which is unaligned or points \ - to invalid or uninitialized memory is undefined behavior", - ); - } + MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { + let kind = kind.descr(def_id); + let mut err = struct_span_err!( + self.tcx.sess, + item_name.span, + E0624, + "{} `{}` is private", + kind, + item_name + ); + err.span_label(item_name.span, &format!("private {}", kind)); + let sp = self + .tcx + .hir() + .span_if_local(def_id) + .unwrap_or_else(|| self.tcx.def_span(def_id)); + err.span_label(sp, &format!("private {} defined here", kind)); + self.suggest_valid_traits(&mut err, out_of_scope_traits); + err.emit(); + } - let ty_span = match rcvr_ty.kind() { - ty::Param(param_type) => Some( - param_type.span_from_generics(self.tcx, self.body_id.owner.to_def_id()), - ), - ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), - _ => None, - }; - if let Some(span) = ty_span { - err.span_label( - span, - format!( - "{item_kind} `{item_name}` not found for this {}", - rcvr_ty.prefix_string(self.tcx) - ), + MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => { + let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); + let mut err = self.sess().struct_span_err(span, &msg); + err.span_label(bound_span, "this has a `Sized` requirement"); + if !candidates.is_empty() { + let help = format!( + "{an}other candidate{s} {were} found in the following trait{s}, perhaps \ + add a `use` for {one_of_them}:", + an = if candidates.len() == 1 { "an" } else { "" }, + s = pluralize!(candidates.len()), + were = pluralize!("was", candidates.len()), + one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" }, ); + self.suggest_use_candidates(&mut err, help, candidates); } - - if let SelfSource::MethodCall(rcvr_expr) = source { - self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { - let call_expr = self - .tcx - .hir() - .expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id)); - let probe = self.lookup_probe( - item_name, - output_ty, - call_expr, - ProbeScope::AllTraits, + if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() { + if needs_mut { + let trait_type = self.tcx.mk_ref( + *region, + ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() }, ); - probe.is_ok() - }); + err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty)); + } } + err.emit(); + } - let mut custom_span_label = false; - - if !static_candidates.is_empty() { - err.note( - "found the following associated functions; to be used as methods, \ - functions must have a `self` parameter", - ); - err.span_label(span, "this is an associated function, not a method"); - custom_span_label = true; - } - if static_candidates.len() == 1 { - self.suggest_associated_call_syntax( - &mut err, - &static_candidates, - rcvr_ty, - source, - item_name, - args, - sugg_span, - ); + MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), + } + None + } - report_candidates(span, &mut err, &mut static_candidates, None); - } else if static_candidates.len() > 1 { - report_candidates(span, &mut err, &mut static_candidates, Some(sugg_span)); - } + pub fn report_no_match_method_error( + &self, + mut span: Span, + rcvr_ty: Ty<'tcx>, + item_name: Ident, + source: SelfSource<'tcx>, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + sugg_span: Span, + no_match_data: &mut NoMatchData<'tcx>, + ) -> Option> { + let mode = no_match_data.mode; + let tcx = self.tcx; + let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); + let ty_str = self.ty_to_string(rcvr_ty); + let is_method = mode == Mode::MethodCall; + let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; + let lev_candidate = no_match_data.lev_candidate; + let item_kind = if is_method { + "method" + } else if rcvr_ty.is_enum() { + "variant or associated item" + } else { + match (item_name.as_str().chars().next(), rcvr_ty.is_fresh_ty()) { + (Some(name), false) if name.is_lowercase() => "function or associated item", + (Some(_), false) => "associated item", + (Some(_), true) | (None, false) => "variant or associated item", + (None, true) => "variant", + } + }; - let mut bound_spans = vec![]; - let mut restrict_type_params = false; - let mut unsatisfied_bounds = false; - if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) { - let msg = "consider using `len` instead"; - if let SelfSource::MethodCall(_expr) = source { - err.span_suggestion_short( - span, - msg, - "len", - Applicability::MachineApplicable, - ); + if self.suggest_wrapping_range_with_parens(tcx, rcvr_ty, source, span, item_name, &ty_str) + || self.suggest_constraining_numerical_ty( + tcx, rcvr_ty, source, span, item_kind, item_name, &ty_str, + ) + { + return None; + } + span = item_name.span; + + // Don't show generic arguments when the method can't be found in any implementation (#81576). + let mut ty_str_reported = ty_str.clone(); + if let ty::Adt(_, generics) = rcvr_ty.kind() { + if generics.len() > 0 { + let mut autoderef = self.autoderef(span, rcvr_ty); + let candidate_found = autoderef.any(|(ty, _)| { + if let ty::Adt(adt_def, _) = ty.kind() { + self.tcx + .inherent_impls(adt_def.did()) + .iter() + .filter_map(|def_id| self.associated_value(*def_id, item_name)) + .count() + >= 1 } else { - err.span_label(span, msg); - } - if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) { - let iterator_trait = self.tcx.def_path_str(iterator_trait); - err.note(&format!("`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement")); + false } - } else if !unsatisfied_predicates.is_empty() { - let mut type_params = FxHashMap::default(); - - // Pick out the list of unimplemented traits on the receiver. - // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute. - let mut unimplemented_traits = FxHashMap::default(); - let mut unimplemented_traits_only = true; - for (predicate, _parent_pred, cause) in &unsatisfied_predicates { - if let (ty::PredicateKind::Clause(ty::Clause::Trait(p)), Some(cause)) = - (predicate.kind().skip_binder(), cause.as_ref()) - { - if p.trait_ref.self_ty() != rcvr_ty { - // This is necessary, not just to keep the errors clean, but also - // because our derived obligations can wind up with a trait ref that - // requires a different param_env to be correctly compared. - continue; - } - unimplemented_traits.entry(p.trait_ref.def_id).or_insert(( - predicate.kind().rebind(p.trait_ref), - Obligation { - cause: cause.clone(), - param_env: self.param_env, - predicate: *predicate, - recursion_depth: 0, - }, - )); - } + }); + let has_deref = autoderef.step_count() > 0; + if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() { + if let Some((path_string, _)) = ty_str.split_once('<') { + ty_str_reported = path_string.to_string(); } + } + } + } - // Make sure that, if any traits other than the found ones were involved, - // we don't don't report an unimplemented trait. - // We don't want to say that `iter::Cloned` is not an iterator, just - // because of some non-Clone item being iterated over. - for (predicate, _parent_pred, _cause) in &unsatisfied_predicates { - match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(p)) - if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {} - _ => { - unimplemented_traits_only = false; - break; - } - } - } + let mut err = struct_span_err!( + tcx.sess, + span, + E0599, + "no {} named `{}` found for {} `{}` in the current scope", + item_kind, + item_name, + rcvr_ty.prefix_string(self.tcx), + ty_str_reported, + ); + if rcvr_ty.references_error() { + err.downgrade_to_delayed_bug(); + } - let mut collect_type_param_suggestions = - |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| { - // We don't care about regions here, so it's fine to skip the binder here. - if let (ty::Param(_), ty::PredicateKind::Clause(ty::Clause::Trait(p))) = - (self_ty.kind(), parent_pred.kind().skip_binder()) - { - let hir = self.tcx.hir(); - let node = match p.trait_ref.self_ty().kind() { - ty::Param(_) => { - // Account for `fn` items like in `issue-35677.rs` to - // suggest restricting its type params. - let parent_body = - hir.body_owner(hir::BodyId { hir_id: self.body_id }); - Some(hir.get(parent_body)) - } - ty::Adt(def, _) => { - def.did().as_local().map(|def_id| hir.get_by_def_id(def_id)) - } - _ => None, - }; - if let Some(hir::Node::Item(hir::Item { kind, .. })) = node { - if let Some(g) = kind.generics() { - let key = ( - g.tail_span_for_predicate_suggestion(), - g.add_where_or_trailing_comma(), - ); - type_params - .entry(key) - .or_insert_with(FxHashSet::default) - .insert(obligation.to_owned()); - } - } - } - }; - let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { - let msg = format!( - "doesn't satisfy `{}`", - if obligation.len() > 50 { quiet } else { obligation } - ); - match &self_ty.kind() { - // Point at the type that couldn't satisfy the bound. - ty::Adt(def, _) => { - bound_spans.push((self.tcx.def_span(def.did()), msg)) - } - // Point at the trait object that couldn't satisfy the bound. - ty::Dynamic(preds, _, _) => { - for pred in preds.iter() { - match pred.skip_binder() { - ty::ExistentialPredicate::Trait(tr) => bound_spans - .push((self.tcx.def_span(tr.def_id), msg.clone())), - ty::ExistentialPredicate::Projection(_) - | ty::ExistentialPredicate::AutoTrait(_) => {} - } - } - } - // Point at the closure that couldn't satisfy the bound. - ty::Closure(def_id, _) => bound_spans.push(( - tcx.def_span(*def_id), - format!("doesn't satisfy `{}`", quiet), - )), - _ => {} - } - }; - let mut format_pred = |pred: ty::Predicate<'tcx>| { - let bound_predicate = pred.kind(); - match bound_predicate.skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => { - let pred = bound_predicate.rebind(pred); - // `::Item = String`. - let projection_ty = pred.skip_binder().projection_ty; - - let substs_with_infer_self = tcx.mk_substs( - iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into()) - .chain(projection_ty.substs.iter().skip(1)), - ); + if let Mode::MethodCall = mode && let SelfSource::MethodCall(cal) = source { + self.suggest_await_before_method( + &mut err, item_name, rcvr_ty, cal, span, + ); + } + if let Some(span) = + tcx.resolutions(()).confused_type_with_std_module.get(&span.with_parent(None)) + { + err.span_suggestion( + span.shrink_to_lo(), + "you are looking for the module in `std`, not the primitive type", + "std::", + Applicability::MachineApplicable, + ); + } + if let ty::RawPtr(_) = &rcvr_ty.kind() { + err.note( + "try using `<*const T>::as_ref()` to get a reference to the \ + type behind the pointer: https://doc.rust-lang.org/std/\ + primitive.pointer.html#method.as_ref", + ); + err.note( + "using `<*const T>::as_ref()` on a pointer which is unaligned or points \ + to invalid or uninitialized memory is undefined behavior", + ); + } - let quiet_projection_ty = - tcx.mk_alias_ty(projection_ty.def_id, substs_with_infer_self); + let ty_span = match rcvr_ty.kind() { + ty::Param(param_type) => { + Some(param_type.span_from_generics(self.tcx, self.body_id.owner.to_def_id())) + } + ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())), + _ => None, + }; + if let Some(span) = ty_span { + err.span_label( + span, + format!( + "{item_kind} `{item_name}` not found for this {}", + rcvr_ty.prefix_string(self.tcx) + ), + ); + } - let term = pred.skip_binder().term; + if let SelfSource::MethodCall(rcvr_expr) = source { + self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { + let call_expr = + self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id)); + let probe = + self.lookup_probe(item_name, output_ty, call_expr, ProbeScope::AllTraits); + probe.is_ok() + }); + } - let obligation = format!("{} = {}", projection_ty, term); - let quiet = with_forced_trimmed_paths!(format!( - "{} = {}", - quiet_projection_ty, term - )); + let mut custom_span_label = false; - bound_span_label(projection_ty.self_ty(), &obligation, &quiet); - Some((obligation, projection_ty.self_ty())) - } - ty::PredicateKind::Clause(ty::Clause::Trait(poly_trait_ref)) => { - let p = poly_trait_ref.trait_ref; - let self_ty = p.self_ty(); - let path = p.print_only_trait_path(); - let obligation = format!("{}: {}", self_ty, path); - let quiet = with_forced_trimmed_paths!(format!("_: {}", path)); - bound_span_label(self_ty, &obligation, &quiet); - Some((obligation, self_ty)) - } - _ => None, - } - }; + let static_candidates = &mut no_match_data.static_candidates; + if !static_candidates.is_empty() { + err.note( + "found the following associated functions; to be used as methods, \ + functions must have a `self` parameter", + ); + err.span_label(span, "this is an associated function, not a method"); + custom_span_label = true; + } + if static_candidates.len() == 1 { + self.suggest_associated_call_syntax( + &mut err, + &static_candidates, + rcvr_ty, + source, + item_name, + args, + sugg_span, + ); - // Find all the requirements that come from a local `impl` block. - let mut skip_list: FxHashSet<_> = Default::default(); - let mut spanned_predicates: FxHashMap = Default::default(); - for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates - .iter() - .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) - .filter_map(|(p, parent, c)| match c.code() { - ObligationCauseCode::ImplDerivedObligation(data) => { - Some((&data.derived, p, parent, data.impl_def_id, data)) - } - _ => None, - }) - { - let parent_trait_ref = data.parent_trait_pred; - let path = parent_trait_ref.print_modifiers_and_trait_path(); - let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); - let unsatisfied_msg = "unsatisfied trait bound introduced here"; - let derive_msg = - "unsatisfied trait bound introduced in this `derive` macro"; - match self.tcx.hir().get_if_local(impl_def_id) { - // Unmet obligation comes from a `derive` macro, point at it once to - // avoid multiple span labels pointing at the same place. - Some(Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), - .. - })) if matches!( - self_ty.span.ctxt().outer_expn_data().kind, - ExpnKind::Macro(MacroKind::Derive, _) - ) || matches!( - of_trait.as_ref().map(|t| t - .path - .span - .ctxt() - .outer_expn_data() - .kind), - Some(ExpnKind::Macro(MacroKind::Derive, _)) - ) => - { - let span = self_ty.span.ctxt().outer_expn_data().call_site; - let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg); - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); - } + self.note_candidates_on_method_error( + rcvr_ty, + item_name, + args, + span, + &mut err, + static_candidates, + None, + ); + } else if static_candidates.len() > 1 { + self.note_candidates_on_method_error( + rcvr_ty, + item_name, + args, + span, + &mut err, + static_candidates, + Some(sugg_span), + ); + } - // Unmet obligation coming from an `impl`. - Some(Node::Item(hir::Item { - kind: - hir::ItemKind::Impl(hir::Impl { - of_trait, self_ty, generics, .. - }), - span: item_span, - .. - })) => { - let sized_pred = - unsatisfied_predicates.iter().any(|(pred, _, _)| { - match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { - Some(pred.def_id()) - == self.tcx.lang_items().sized_trait() - && pred.polarity == ty::ImplPolarity::Positive - } - _ => false, - } - }); - for param in generics.params { - if param.span == cause.span && sized_pred { - let (sp, sugg) = match param.colon_span { - Some(sp) => (sp.shrink_to_hi(), " ?Sized +"), - None => (param.span.shrink_to_hi(), ": ?Sized"), - }; - err.span_suggestion_verbose( - sp, - "consider relaxing the type parameter's implicit \ - `Sized` bound", - sugg, - Applicability::MachineApplicable, - ); - } - } - if let Some(pred) = parent_p { - // Done to add the "doesn't satisfy" `span_label`. - let _ = format_pred(*pred); - } - skip_list.insert(p); - let mut spans = if cause.span != *item_span { - let mut spans: MultiSpan = cause.span.into(); - spans.push_span_label(cause.span, unsatisfied_msg); - spans - } else { - let mut spans = Vec::with_capacity(2); - if let Some(trait_ref) = of_trait { - spans.push(trait_ref.path.span); - } - spans.push(self_ty.span); - spans.into() - }; - if let Some(trait_ref) = of_trait { - spans.push_span_label(trait_ref.path.span, ""); - } - spans.push_span_label(self_ty.span, ""); + let mut bound_spans = vec![]; + let mut restrict_type_params = false; + let mut unsatisfied_bounds = false; + if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) { + let msg = "consider using `len` instead"; + if let SelfSource::MethodCall(_expr) = source { + err.span_suggestion_short(span, msg, "len", Applicability::MachineApplicable); + } else { + err.span_label(span, msg); + } + if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) { + let iterator_trait = self.tcx.def_path_str(iterator_trait); + err.note(&format!( + "`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement" + )); + } + } else if !unsatisfied_predicates.is_empty() { + let mut type_params = FxHashMap::default(); + + // Pick out the list of unimplemented traits on the receiver. + // This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute. + let mut unimplemented_traits = FxHashMap::default(); + let mut unimplemented_traits_only = true; + for (predicate, _parent_pred, cause) in unsatisfied_predicates { + if let (ty::PredicateKind::Clause(ty::Clause::Trait(p)), Some(cause)) = + (predicate.kind().skip_binder(), cause.as_ref()) + { + if p.trait_ref.self_ty() != rcvr_ty { + // This is necessary, not just to keep the errors clean, but also + // because our derived obligations can wind up with a trait ref that + // requires a different param_env to be correctly compared. + continue; + } + unimplemented_traits.entry(p.trait_ref.def_id).or_insert(( + predicate.kind().rebind(p.trait_ref), + Obligation { + cause: cause.clone(), + param_env: self.param_env, + predicate: *predicate, + recursion_depth: 0, + }, + )); + } + } - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + // Make sure that, if any traits other than the found ones were involved, + // we don't don't report an unimplemented trait. + // We don't want to say that `iter::Cloned` is not an iterator, just + // because of some non-Clone item being iterated over. + for (predicate, _parent_pred, _cause) in unsatisfied_predicates { + match predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Trait(p)) + if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {} + _ => { + unimplemented_traits_only = false; + break; + } + } + } + + let mut collect_type_param_suggestions = + |self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| { + // We don't care about regions here, so it's fine to skip the binder here. + if let (ty::Param(_), ty::PredicateKind::Clause(ty::Clause::Trait(p))) = + (self_ty.kind(), parent_pred.kind().skip_binder()) + { + let hir = self.tcx.hir(); + let node = match p.trait_ref.self_ty().kind() { + ty::Param(_) => { + // Account for `fn` items like in `issue-35677.rs` to + // suggest restricting its type params. + let parent_body = + hir.body_owner(hir::BodyId { hir_id: self.body_id }); + Some(hir.get(parent_body)) } - Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..), - span: item_span, - .. - })) => { - tcx.sess.delay_span_bug( - *item_span, - "auto trait is invoked with no method error, but no error reported?", - ); + ty::Adt(def, _) => { + def.did().as_local().map(|def_id| hir.get_by_def_id(def_id)) + } + _ => None, + }; + if let Some(hir::Node::Item(hir::Item { kind, .. })) = node { + if let Some(g) = kind.generics() { + let key = ( + g.tail_span_for_predicate_suggestion(), + g.add_where_or_trailing_comma(), + ); + type_params + .entry(key) + .or_insert_with(FxHashSet::default) + .insert(obligation.to_owned()); } - Some(_) => unreachable!(), - None => (), } } - let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); - spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span()); - for (span, (_path, _self_ty, preds)) in spanned_predicates { - let mut preds: Vec<_> = preds - .into_iter() - .filter_map(|pred| format_pred(*pred)) - .map(|(p, _)| format!("`{}`", p)) - .collect(); - preds.sort(); - preds.dedup(); - let msg = if let [pred] = &preds[..] { - format!("trait bound {} was not satisfied", pred) - } else { - format!( - "the following trait bounds were not satisfied:\n{}", - preds.join("\n"), - ) - }; - err.span_note(span, &msg); - unsatisfied_bounds = true; + }; + let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| { + let msg = format!( + "doesn't satisfy `{}`", + if obligation.len() > 50 { quiet } else { obligation } + ); + match &self_ty.kind() { + // Point at the type that couldn't satisfy the bound. + ty::Adt(def, _) => bound_spans.push((self.tcx.def_span(def.did()), msg)), + // Point at the trait object that couldn't satisfy the bound. + ty::Dynamic(preds, _, _) => { + for pred in preds.iter() { + match pred.skip_binder() { + ty::ExistentialPredicate::Trait(tr) => { + bound_spans.push((self.tcx.def_span(tr.def_id), msg.clone())) + } + ty::ExistentialPredicate::Projection(_) + | ty::ExistentialPredicate::AutoTrait(_) => {} + } + } } - - // The requirements that didn't have an `impl` span to show. - let mut bound_list = unsatisfied_predicates - .iter() - .filter_map(|(pred, parent_pred, _cause)| { - format_pred(*pred).map(|(p, self_ty)| { - collect_type_param_suggestions(self_ty, *pred, &p); - ( - match parent_pred { - None => format!("`{}`", &p), - Some(parent_pred) => match format_pred(*parent_pred) { - None => format!("`{}`", &p), - Some((parent_p, _)) => { - collect_type_param_suggestions( - self_ty, - *parent_pred, - &p, - ); - format!( - "`{}`\nwhich is required by `{}`", - p, parent_p - ) - } - }, - }, - *pred, - ) - }) - }) - .filter(|(_, pred)| !skip_list.contains(&pred)) - .map(|(t, _)| t) - .enumerate() - .collect::>(); - - for ((span, add_where_or_comma), obligations) in type_params.into_iter() { - restrict_type_params = true; - // #74886: Sort here so that the output is always the same. - let mut obligations = obligations.into_iter().collect::>(); - obligations.sort(); - err.span_suggestion_verbose( - span, - &format!( - "consider restricting the type parameter{s} to satisfy the \ - trait bound{s}", - s = pluralize!(obligations.len()) - ), - format!("{} {}", add_where_or_comma, obligations.join(", ")), - Applicability::MaybeIncorrect, + // Point at the closure that couldn't satisfy the bound. + ty::Closure(def_id, _) => bound_spans + .push((tcx.def_span(*def_id), format!("doesn't satisfy `{}`", quiet))), + _ => {} + } + }; + let mut format_pred = |pred: ty::Predicate<'tcx>| { + let bound_predicate = pred.kind(); + match bound_predicate.skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => { + let pred = bound_predicate.rebind(pred); + // `::Item = String`. + let projection_ty = pred.skip_binder().projection_ty; + + let substs_with_infer_self = tcx.mk_substs( + iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into()) + .chain(projection_ty.substs.iter().skip(1)), ); - } - bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically. - bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677 - bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order. + let quiet_projection_ty = + tcx.mk_alias_ty(projection_ty.def_id, substs_with_infer_self); - if !bound_list.is_empty() || !skip_list.is_empty() { - let bound_list = bound_list - .into_iter() - .map(|(_, path)| path) - .collect::>() - .join("\n"); - let actual_prefix = rcvr_ty.prefix_string(self.tcx); - info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); - let (primary_message, label) = - if unimplemented_traits.len() == 1 && unimplemented_traits_only { - unimplemented_traits - .into_iter() - .next() - .map(|(_, (trait_ref, obligation))| { - if trait_ref.self_ty().references_error() - || rcvr_ty.references_error() - { - // Avoid crashing. - return (None, None); - } - let OnUnimplementedNote { message, label, .. } = self - .err_ctxt() - .on_unimplemented_note(trait_ref, &obligation); - (message, label) - }) - .unwrap() - } else { - (None, None) - }; - let primary_message = primary_message.unwrap_or_else(|| format!( - "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, \ - but its trait bounds were not satisfied" - )); - err.set_primary_message(&primary_message); - if let Some(label) = label { - custom_span_label = true; - err.span_label(span, label); - } - if !bound_list.is_empty() { - err.note(&format!( - "the following trait bounds were not satisfied:\n{bound_list}" - )); - } - self.suggest_derive(&mut err, &unsatisfied_predicates); + let term = pred.skip_binder().term; + + let obligation = format!("{} = {}", projection_ty, term); + let quiet = format!("{} = {}", quiet_projection_ty, term); - unsatisfied_bounds = true; + bound_span_label(projection_ty.self_ty(), &obligation, &quiet); + Some((obligation, projection_ty.self_ty())) } + ty::PredicateKind::Clause(ty::Clause::Trait(poly_trait_ref)) => { + let p = poly_trait_ref.trait_ref; + let self_ty = p.self_ty(); + let path = p.print_only_trait_path(); + let obligation = format!("{}: {}", self_ty, path); + let quiet = format!("_: {}", path); + bound_span_label(self_ty, &obligation, &quiet); + Some((obligation, self_ty)) + } + _ => None, } + }; - let label_span_not_found = |err: &mut Diagnostic| { - if unsatisfied_predicates.is_empty() { - err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); - let is_string_or_ref_str = match rcvr_ty.kind() { - ty::Ref(_, ty, _) => { - ty.is_str() - || matches!( - ty.kind(), - ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string() - ) - } - ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(), - _ => false, - }; - if is_string_or_ref_str && item_name.name == sym::iter { - err.span_suggestion_verbose( - item_name.span, - "because of the in-memory representation of `&str`, to obtain \ - an `Iterator` over each of its codepoint use method `chars`", - "chars", - Applicability::MachineApplicable, - ); - } - if let ty::Adt(adt, _) = rcvr_ty.kind() { - let mut inherent_impls_candidate = self - .tcx - .inherent_impls(adt.did()) - .iter() - .copied() - .filter(|def_id| { - if let Some(assoc) = self.associated_value(*def_id, item_name) { - // Check for both mode is the same so we avoid suggesting - // incorrect associated item. - match (mode, assoc.fn_has_self_parameter, source) { - (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { - // We check that the suggest type is actually - // different from the received one - // So we avoid suggestion method with Box - // for instance - self.tcx.at(span).type_of(*def_id) != rcvr_ty - && self.tcx.at(span).type_of(*def_id) != rcvr_ty - } - (Mode::Path, false, _) => true, - _ => false, - } - } else { - false + // Find all the requirements that come from a local `impl` block. + let mut skip_list: FxHashSet<_> = Default::default(); + let mut spanned_predicates: FxHashMap = Default::default(); + for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates + .iter() + .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) + .filter_map(|(p, parent, c)| match c.code() { + ObligationCauseCode::ImplDerivedObligation(data) => { + Some((&data.derived, p, parent, data.impl_def_id, data)) + } + _ => None, + }) + { + let parent_trait_ref = data.parent_trait_pred; + let path = parent_trait_ref.print_modifiers_and_trait_path(); + let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); + let unsatisfied_msg = "unsatisfied trait bound introduced here"; + let derive_msg = "unsatisfied trait bound introduced in this `derive` macro"; + match self.tcx.hir().get_if_local(impl_def_id) { + // Unmet obligation comes from a `derive` macro, point at it once to + // avoid multiple span labels pointing at the same place. + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }), + .. + })) if matches!( + self_ty.span.ctxt().outer_expn_data().kind, + ExpnKind::Macro(MacroKind::Derive, _) + ) || matches!( + of_trait.as_ref().map(|t| t.path.span.ctxt().outer_expn_data().kind), + Some(ExpnKind::Macro(MacroKind::Derive, _)) + ) => + { + let span = self_ty.span.ctxt().outer_expn_data().call_site; + let mut spans: MultiSpan = span.into(); + spans.push_span_label(span, derive_msg); + let entry = spanned_predicates.entry(spans); + entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + } + + // Unmet obligation coming from an `impl`. + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, generics, .. }), + span: item_span, + .. + })) => { + let sized_pred = + unsatisfied_predicates.iter().any(|(pred, _, _)| { + match pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { + Some(pred.def_id()) == self.tcx.lang_items().sized_trait() + && pred.polarity == ty::ImplPolarity::Positive } - }) - .collect::>(); - if !inherent_impls_candidate.is_empty() { - inherent_impls_candidate.sort(); - inherent_impls_candidate.dedup(); - - // number of type to shows at most. - let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; - let type_candidates = inherent_impls_candidate - .iter() - .take(limit) - .map(|impl_item| { - format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) - }) - .collect::>() - .join("\n"); - let additional_types = if inherent_impls_candidate.len() > limit { - format!( - "\nand {} more types", - inherent_impls_candidate.len() - limit - ) - } else { - "".to_string() + _ => false, + } + }); + for param in generics.params { + if param.span == cause.span && sized_pred { + let (sp, sugg) = match param.colon_span { + Some(sp) => (sp.shrink_to_hi(), " ?Sized +"), + None => (param.span.shrink_to_hi(), ": ?Sized"), }; - err.note(&format!( - "the {item_kind} was found for\n{}{}", - type_candidates, additional_types - )); + err.span_suggestion_verbose( + sp, + "consider relaxing the type parameter's implicit \ + `Sized` bound", + sugg, + Applicability::MachineApplicable, + ); } } - } else { - let ty_str = if ty_str.len() > 50 { - String::new() + if let Some(pred) = parent_p { + // Done to add the "doesn't satisfy" `span_label`. + let _ = format_pred(*pred); + } + skip_list.insert(p); + let mut spans = if cause.span != *item_span { + let mut spans: MultiSpan = cause.span.into(); + spans.push_span_label(cause.span, unsatisfied_msg); + spans } else { - format!("on `{ty_str}` ") + let mut spans = Vec::with_capacity(2); + if let Some(trait_ref) = of_trait { + spans.push(trait_ref.path.span); + } + spans.push(self_ty.span); + spans.into() }; - err.span_label(span, format!( - "{item_kind} cannot be called {ty_str}due to unsatisfied trait bounds" - )); - } - }; + if let Some(trait_ref) = of_trait { + spans.push_span_label(trait_ref.path.span, ""); + } + spans.push_span_label(self_ty.span, ""); - // If the method name is the name of a field with a function or closure type, - // give a helping note that it has to be called as `(x.f)(...)`. - if let SelfSource::MethodCall(expr) = source { - if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err) - && lev_candidate.is_none() - && !custom_span_label - { - label_span_not_found(&mut err); + let entry = spanned_predicates.entry(spans); + entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } - } else if !custom_span_label { - label_span_not_found(&mut err); - } - - // Don't suggest (for example) `expr.field.clone()` if `expr.clone()` - // can't be called due to `typeof(expr): Clone` not holding. - if unsatisfied_predicates.is_empty() { - self.suggest_calling_method_on_field( - &mut err, source, span, rcvr_ty, item_name, - ); + Some(_) => unreachable!(), + None => (), } + } + let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); + spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span()); + for (span, (_path, _self_ty, preds)) in spanned_predicates { + let mut preds: Vec<_> = preds + .into_iter() + .filter_map(|pred| format_pred(*pred)) + .map(|(p, _)| format!("`{}`", p)) + .collect(); + preds.sort(); + preds.dedup(); + let msg = if let [pred] = &preds[..] { + format!("trait bound {} was not satisfied", pred) + } else { + format!("the following trait bounds were not satisfied:\n{}", preds.join("\n"),) + }; + err.span_note(span, &msg); + unsatisfied_bounds = true; + } - self.check_for_inner_self(&mut err, source, rcvr_ty, item_name); - - bound_spans.sort(); - bound_spans.dedup(); - for (span, msg) in bound_spans.into_iter() { - err.span_label(span, &msg); - } + // The requirements that didn't have an `impl` span to show. + let mut bound_list = unsatisfied_predicates + .iter() + .filter_map(|(pred, parent_pred, _cause)| { + format_pred(*pred).map(|(p, self_ty)| { + collect_type_param_suggestions(self_ty, *pred, &p); + ( + match parent_pred { + None => format!("`{}`", &p), + Some(parent_pred) => match format_pred(*parent_pred) { + None => format!("`{}`", &p), + Some((parent_p, _)) => { + collect_type_param_suggestions(self_ty, *parent_pred, &p); + format!("`{}`\nwhich is required by `{}`", p, parent_p) + } + }, + }, + *pred, + ) + }) + }) + .filter(|(_, pred)| !skip_list.contains(&pred)) + .map(|(t, _)| t) + .enumerate() + .collect::>(); + + for ((span, add_where_or_comma), obligations) in type_params.into_iter() { + restrict_type_params = true; + // #74886: Sort here so that the output is always the same. + let mut obligations = obligations.into_iter().collect::>(); + obligations.sort(); + err.span_suggestion_verbose( + span, + &format!( + "consider restricting the type parameter{s} to satisfy the \ + trait bound{s}", + s = pluralize!(obligations.len()) + ), + format!("{} {}", add_where_or_comma, obligations.join(", ")), + Applicability::MaybeIncorrect, + ); + } - if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params { + bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically. + bound_list.dedup_by(|(_, a), (_, b)| a == b); // #35677 + bound_list.sort_by_key(|(pos, _)| *pos); // Keep the original predicate order. + + if !bound_list.is_empty() || !skip_list.is_empty() { + let bound_list = + bound_list.into_iter().map(|(_, path)| path).collect::>().join("\n"); + let actual_prefix = rcvr_ty.prefix_string(self.tcx); + info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); + let (primary_message, label) = if unimplemented_traits.len() == 1 + && unimplemented_traits_only + { + unimplemented_traits + .into_iter() + .next() + .map(|(_, (trait_ref, obligation))| { + if trait_ref.self_ty().references_error() || rcvr_ty.references_error() + { + // Avoid crashing. + return (None, None); + } + let OnUnimplementedNote { message, label, .. } = + self.err_ctxt().on_unimplemented_note(trait_ref, &obligation); + (message, label) + }) + .unwrap() } else { - self.suggest_traits_to_import( - &mut err, - span, - rcvr_ty, - item_name, - args.map(|(_, args)| args.len() + 1), - source, - out_of_scope_traits, - &unsatisfied_predicates, - &static_candidates, - unsatisfied_bounds, - ); + (None, None) + }; + let primary_message = primary_message.unwrap_or_else(|| format!( + "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied" + )); + err.set_primary_message(&primary_message); + if let Some(label) = label { + custom_span_label = true; + err.span_label(span, label); } - - // Don't emit a suggestion if we found an actual method - // that had unsatisfied trait bounds - if unsatisfied_predicates.is_empty() && rcvr_ty.is_enum() { - let adt_def = rcvr_ty.ty_adt_def().expect("enum is not an ADT"); - if let Some(suggestion) = lev_distance::find_best_match_for_name( - &adt_def.variants().iter().map(|s| s.name).collect::>(), - item_name.name, - None, - ) { - err.span_suggestion( - span, - "there is a variant with a similar name", - suggestion, - Applicability::MaybeIncorrect, - ); - } + if !bound_list.is_empty() { + err.note(&format!( + "the following trait bounds were not satisfied:\n{bound_list}" + )); } + self.suggest_derive(&mut err, &unsatisfied_predicates); - if item_name.name == sym::as_str && rcvr_ty.peel_refs().is_str() { - let msg = "remove this method call"; - let mut fallback_span = true; - if let SelfSource::MethodCall(expr) = source { - let call_expr = - self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); - if let Some(span) = call_expr.span.trim_start(expr.span) { - err.span_suggestion(span, msg, "", Applicability::MachineApplicable); - fallback_span = false; - } - } - if fallback_span { - err.span_label(span, msg); + unsatisfied_bounds = true; + } + } + + let label_span_not_found = |err: &mut Diagnostic| { + if unsatisfied_predicates.is_empty() { + err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); + let is_string_or_ref_str = match rcvr_ty.kind() { + ty::Ref(_, ty, _) => { + ty.is_str() + || matches!( + ty.kind(), + ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string() + ) } - } else if let Some(lev_candidate) = lev_candidate { - // Don't emit a suggestion if we found an actual method - // that had unsatisfied trait bounds - if unsatisfied_predicates.is_empty() { - let def_kind = lev_candidate.kind.as_def_kind(); - // Methods are defined within the context of a struct and their first parameter is always self, - // which represents the instance of the struct the method is being called on - // Associated functions don’t take self as a parameter and - // they are not methods because they don’t have an instance of the struct to work with. - if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter { - err.span_suggestion( - span, - "there is a method with a similar name", - lev_candidate.name, - Applicability::MaybeIncorrect, - ); + ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(), + _ => false, + }; + if is_string_or_ref_str && item_name.name == sym::iter { + err.span_suggestion_verbose( + item_name.span, + "because of the in-memory representation of `&str`, to obtain \ + an `Iterator` over each of its codepoint use method `chars`", + "chars", + Applicability::MachineApplicable, + ); + } + if let ty::Adt(adt, _) = rcvr_ty.kind() { + let mut inherent_impls_candidate = self + .tcx + .inherent_impls(adt.did()) + .iter() + .copied() + .filter(|def_id| { + if let Some(assoc) = self.associated_value(*def_id, item_name) { + // Check for both mode is the same so we avoid suggesting + // incorrect associated item. + match (mode, assoc.fn_has_self_parameter, source) { + (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != rcvr_ty + && self.tcx.at(span).type_of(*def_id) != rcvr_ty + } + (Mode::Path, false, _) => true, + _ => false, + } + } else { + false + } + }) + .collect::>(); + if !inherent_impls_candidate.is_empty() { + inherent_impls_candidate.sort(); + inherent_impls_candidate.dedup(); + + // number of type to shows at most. + let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; + let type_candidates = inherent_impls_candidate + .iter() + .take(limit) + .map(|impl_item| { + format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) + }) + .collect::>() + .join("\n"); + let additional_types = if inherent_impls_candidate.len() > limit { + format!("\nand {} more types", inherent_impls_candidate.len() - limit) } else { - err.span_suggestion( - span, - &format!( - "there is {} {} with a similar name", - def_kind.article(), - def_kind.descr(lev_candidate.def_id), - ), - lev_candidate.name, - Applicability::MaybeIncorrect, - ); - } + "".to_string() + }; + err.note(&format!( + "the {item_kind} was found for\n{}{}", + type_candidates, additional_types + )); } } + } else { + err.span_label( + span, + format!( + "{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds" + ), + ); + } + }; - self.check_for_deref_method(&mut err, source, rcvr_ty, item_name); - - return Some(err); + // If the method name is the name of a field with a function or closure type, + // give a helping note that it has to be called as `(x.f)(...)`. + if let SelfSource::MethodCall(expr) = source { + if !self.suggest_calling_field_as_fn(span, rcvr_ty, expr, item_name, &mut err) + && lev_candidate.is_none() + && !custom_span_label + { + label_span_not_found(&mut err); } + } else if !custom_span_label { + label_span_not_found(&mut err); + } - MethodError::Ambiguity(mut sources) => { - let mut err = struct_span_err!( - self.sess(), - item_name.span, - E0034, - "multiple applicable items in scope" - ); - err.span_label(item_name.span, format!("multiple `{}` found", item_name)); + // Don't suggest (for example) `expr.field.clone()` if `expr.clone()` + // can't be called due to `typeof(expr): Clone` not holding. + if unsatisfied_predicates.is_empty() { + self.suggest_calling_method_on_field(&mut err, source, span, rcvr_ty, item_name); + } - report_candidates(span, &mut err, &mut sources, Some(sugg_span)); - err.emit(); - } + self.check_for_inner_self(&mut err, source, rcvr_ty, item_name); - MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { - let kind = kind.descr(def_id); - let mut err = struct_span_err!( - self.tcx.sess, - item_name.span, - E0624, - "{} `{}` is private", - kind, - item_name + bound_spans.sort(); + bound_spans.dedup(); + for (span, msg) in bound_spans.into_iter() { + err.span_label(span, &msg); + } + + if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params { + } else { + self.suggest_traits_to_import( + &mut err, + span, + rcvr_ty, + item_name, + args.map(|(_, args)| args.len() + 1), + source, + no_match_data.out_of_scope_traits.clone(), + &unsatisfied_predicates, + &static_candidates, + unsatisfied_bounds, + ); + } + + // Don't emit a suggestion if we found an actual method + // that had unsatisfied trait bounds + if unsatisfied_predicates.is_empty() && rcvr_ty.is_enum() { + let adt_def = rcvr_ty.ty_adt_def().expect("enum is not an ADT"); + if let Some(suggestion) = lev_distance::find_best_match_for_name( + &adt_def.variants().iter().map(|s| s.name).collect::>(), + item_name.name, + None, + ) { + err.span_suggestion( + span, + "there is a variant with a similar name", + suggestion, + Applicability::MaybeIncorrect, ); - err.span_label(item_name.span, &format!("private {}", kind)); - let sp = self - .tcx - .hir() - .span_if_local(def_id) - .unwrap_or_else(|| self.tcx.def_span(def_id)); - err.span_label(sp, &format!("private {} defined here", kind)); - self.suggest_valid_traits(&mut err, out_of_scope_traits); - err.emit(); } + } - MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => { - let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); - let mut err = self.sess().struct_span_err(span, &msg); - err.span_label(bound_span, "this has a `Sized` requirement"); - if !candidates.is_empty() { - let help = format!( - "{an}other candidate{s} {were} found in the following trait{s}, perhaps \ - add a `use` for {one_of_them}:", - an = if candidates.len() == 1 { "an" } else { "" }, - s = pluralize!(candidates.len()), - were = pluralize!("was", candidates.len()), - one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" }, + if item_name.name == sym::as_str && rcvr_ty.peel_refs().is_str() { + let msg = "remove this method call"; + let mut fallback_span = true; + if let SelfSource::MethodCall(expr) = source { + let call_expr = + self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); + if let Some(span) = call_expr.span.trim_start(expr.span) { + err.span_suggestion(span, msg, "", Applicability::MachineApplicable); + fallback_span = false; + } + } + if fallback_span { + err.span_label(span, msg); + } + } else if let Some(lev_candidate) = lev_candidate { + // Don't emit a suggestion if we found an actual method + // that had unsatisfied trait bounds + if unsatisfied_predicates.is_empty() { + let def_kind = lev_candidate.kind.as_def_kind(); + // Methods are defined within the context of a struct and their first parameter is always self, + // which represents the instance of the struct the method is being called on + // Associated functions don’t take self as a parameter and + // they are not methods because they don’t have an instance of the struct to work with. + if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter { + err.span_suggestion( + span, + &format!("there is a method with a similar name",), + lev_candidate.name, + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion( + span, + &format!( + "there is {} {} with a similar name", + def_kind.article(), + def_kind.descr(lev_candidate.def_id), + ), + lev_candidate.name, + Applicability::MaybeIncorrect, ); - self.suggest_use_candidates(&mut err, help, candidates); } - if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() { - if needs_mut { - let trait_type = self.tcx.mk_ref( - *region, - ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() }, + } + } + + self.check_for_deref_method(&mut err, source, rcvr_ty, item_name); + return Some(err); + } + + fn note_candidates_on_method_error( + &self, + rcvr_ty: Ty<'tcx>, + item_name: Ident, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + span: Span, + err: &mut Diagnostic, + sources: &mut Vec, + sugg_span: Option, + ) { + sources.sort(); + sources.dedup(); + // Dynamic limit to avoid hiding just one candidate, which is silly. + let limit = if sources.len() == 5 { 5 } else { 4 }; + + for (idx, source) in sources.iter().take(limit).enumerate() { + match *source { + CandidateSource::Impl(impl_did) => { + // Provide the best span we can. Use the item, if local to crate, else + // the impl, if local to crate (item may be defaulted), else nothing. + let Some(item) = self.associated_value(impl_did, item_name).or_else(|| { + let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; + self.associated_value(impl_trait_ref.def_id, item_name) + }) else { + continue; + }; + + let note_span = if item.def_id.is_local() { + Some(self.tcx.def_span(item.def_id)) + } else if impl_did.is_local() { + Some(self.tcx.def_span(impl_did)) + } else { + None + }; + + let impl_ty = self.tcx.at(span).type_of(impl_did); + + let insertion = match self.tcx.impl_trait_ref(impl_did) { + None => String::new(), + Some(trait_ref) => { + format!(" of the trait `{}`", self.tcx.def_path_str(trait_ref.def_id)) + } + }; + + let (note_str, idx) = if sources.len() > 1 { + ( + format!( + "candidate #{} is defined in an impl{} for the type `{}`", + idx + 1, + insertion, + impl_ty, + ), + Some(idx + 1), + ) + } else { + ( + format!( + "the candidate is defined in an impl{} for the type `{}`", + insertion, impl_ty, + ), + None, + ) + }; + if let Some(note_span) = note_span { + // We have a span pointing to the method. Show note with snippet. + err.span_note(note_span, ¬e_str); + } else { + err.note(¬e_str); + } + if let Some(sugg_span) = sugg_span + && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { + let path = self.tcx.def_path_str(trait_ref.def_id); + + let ty = match item.kind { + ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, + ty::AssocKind::Fn => self + .tcx + .fn_sig(item.def_id) + .inputs() + .skip_binder() + .get(0) + .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr()) + .copied() + .unwrap_or(rcvr_ty), + }; + print_disambiguation_help( + item_name, + args, + err, + path, + ty, + item.kind, + item.def_id, + sugg_span, + idx, + self.tcx.sess.source_map(), + item.fn_has_self_parameter, + ); + } + } + CandidateSource::Trait(trait_did) => { + let Some(item) = self.associated_value(trait_did, item_name) else { continue }; + let item_span = self.tcx.def_span(item.def_id); + let idx = if sources.len() > 1 { + let msg = &format!( + "candidate #{} is defined in the trait `{}`", + idx + 1, + self.tcx.def_path_str(trait_did) + ); + err.span_note(item_span, msg); + Some(idx + 1) + } else { + let msg = &format!( + "the candidate is defined in the trait `{}`", + self.tcx.def_path_str(trait_did) + ); + err.span_note(item_span, msg); + None + }; + if let Some(sugg_span) = sugg_span { + let path = self.tcx.def_path_str(trait_did); + print_disambiguation_help( + item_name, + args, + err, + path, + rcvr_ty, + item.kind, + item.def_id, + sugg_span, + idx, + self.tcx.sess.source_map(), + item.fn_has_self_parameter, ); - err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty)); } } - err.emit(); } - - MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), } - None + if sources.len() > limit { + err.note(&format!("and {} others", sources.len() - limit)); + } } /// Suggest calling `Ty::method` if `.method()` isn't found because the method -- cgit 1.4.1-3-g733a5 From 93e62a4bf629c0904c047e02b79905c70b9abf79 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 27 Dec 2022 19:11:13 +0800 Subject: resolve merge conflict --- compiler/rustc_hir_typeck/src/method/suggest.rs | 104 ++++++++++++++---------- 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index d391e318207..71c3803e64f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -221,7 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); - let ty_str = self.ty_to_string(rcvr_ty); + let ty_str = with_forced_trimmed_paths!(self.ty_to_string(rcvr_ty)); let is_method = mode == Mode::MethodCall; let unsatisfied_predicates = &no_match_data.unsatisfied_predicates; let lev_candidate = no_match_data.lev_candidate; @@ -523,7 +523,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let term = pred.skip_binder().term; let obligation = format!("{} = {}", projection_ty, term); - let quiet = format!("{} = {}", quiet_projection_ty, term); + let quiet = with_forced_trimmed_paths!(format!( + "{} = {}", + quiet_projection_ty, term + )); bound_span_label(projection_ty.self_ty(), &obligation, &quiet); Some((obligation, projection_ty.self_ty())) @@ -533,7 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let self_ty = p.self_ty(); let path = p.print_only_trait_path(); let obligation = format!("{}: {}", self_ty, path); - let quiet = format!("_: {}", path); + let quiet = with_forced_trimmed_paths!(format!("_: {}", path)); bound_span_label(self_ty, &obligation, &quiet); Some((obligation, self_ty)) } @@ -636,6 +639,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..), + span: item_span, + .. + })) => { + tcx.sess.delay_span_bug( + *item_span, + "auto trait is invoked with no method error, but no error reported?", + ); + } Some(_) => unreachable!(), None => (), } @@ -731,9 +744,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { (None, None) }; - let primary_message = primary_message.unwrap_or_else(|| format!( - "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied" - )); + let primary_message = primary_message.unwrap_or_else(|| { + format!( + "the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, \ + but its trait bounds were not satisfied" + ) + }); err.set_primary_message(&primary_message); if let Some(label) = label { custom_span_label = true; @@ -826,11 +842,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } else { + let ty_str = + if ty_str.len() > 50 { String::new() } else { format!("on `{ty_str}` ") }; err.span_label( span, - format!( - "{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds" - ), + format!("{item_kind} cannot be called {ty_str}due to unsatisfied trait bounds"), ); } }; @@ -922,7 +938,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if def_kind == DefKind::AssocFn && lev_candidate.fn_has_self_parameter { err.span_suggestion( span, - &format!("there is a method with a similar name",), + "there is a method with a similar name", lev_candidate.name, Applicability::MaybeIncorrect, ); @@ -966,11 +982,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Provide the best span we can. Use the item, if local to crate, else // the impl, if local to crate (item may be defaulted), else nothing. let Some(item) = self.associated_value(impl_did, item_name).or_else(|| { - let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; - self.associated_value(impl_trait_ref.def_id, item_name) - }) else { - continue; - }; + let impl_trait_ref = self.tcx.impl_trait_ref(impl_did)?; + self.associated_value(impl_trait_ref.def_id, item_name) + }) else { + continue; + }; let note_span = if item.def_id.is_local() { Some(self.tcx.def_span(item.def_id)) @@ -1015,35 +1031,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(¬e_str); } if let Some(sugg_span) = sugg_span - && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { - let path = self.tcx.def_path_str(trait_ref.def_id); - - let ty = match item.kind { - ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, - ty::AssocKind::Fn => self - .tcx - .fn_sig(item.def_id) - .inputs() - .skip_binder() - .get(0) - .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr()) - .copied() - .unwrap_or(rcvr_ty), - }; - print_disambiguation_help( - item_name, - args, - err, - path, - ty, - item.kind, - item.def_id, - sugg_span, - idx, - self.tcx.sess.source_map(), - item.fn_has_self_parameter, - ); - } + && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { + let path = self.tcx.def_path_str(trait_ref.def_id); + + let ty = match item.kind { + ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty, + ty::AssocKind::Fn => self + .tcx + .fn_sig(item.def_id) + .inputs() + .skip_binder() + .get(0) + .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr()) + .copied() + .unwrap_or(rcvr_ty), + }; + print_disambiguation_help( + item_name, + args, + err, + path, + ty, + item.kind, + item.def_id, + sugg_span, + idx, + self.tcx.sess.source_map(), + item.fn_has_self_parameter, + ); + } } CandidateSource::Trait(trait_did) => { let Some(item) = self.associated_value(trait_did, item_name) else { continue }; -- cgit 1.4.1-3-g733a5 From 1f1dd5f3cc522de86eb0ef5b8df53af0e347f73b Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 16:14:21 +1300 Subject: pattern destructure `has_test` Co-authored-by: Bruno Kolenbrander <59372212+mejrs@users.noreply.github.com> --- src/tools/tidy/src/error_codes.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index ac87e4797c5..42d94311d22 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -173,9 +173,7 @@ fn check_error_codes_docs( return; } - // `has_test.0` checks whether the error code has any (potentially untested) code example. - // `has_test.1` checks whether the error code has a proper (definitely tested) doctest. - let has_test = check_explanation_has_doctest(&contents, &err_code); + let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) = check_explanation_has_doctest(&contents, &err_code); if has_test.2 { verbose_print!( verbose, -- cgit 1.4.1-3-g733a5 From b7341db5d82e93c4257763b33fec853817197078 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Mon, 2 Jan 2023 16:22:18 +1300 Subject: fix CI --- src/tools/tidy/src/error_codes.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 42d94311d22..938e194abdf 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -173,22 +173,23 @@ fn check_error_codes_docs( return; } - let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) = check_explanation_has_doctest(&contents, &err_code); - if has_test.2 { + let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) = + check_explanation_has_doctest(&contents, &err_code); + if emit_ignore_warning { verbose_print!( verbose, "warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \ `IGNORE_DOCTEST_CHECK` constant instead." ); } - if has_test.3 { + if emit_no_longer_warning { no_longer_emitted_codes.push(err_code.to_owned()); verbose_print!( verbose, "warning: Error code `{err_code}` is no longer emitted and should be removed entirely." ); } - if !has_test.0 { + if !found_code_example { verbose_print!( verbose, "warning: Error code `{err_code}` doesn't have a code example, all error codes are expected to have one \ @@ -196,15 +197,15 @@ fn check_error_codes_docs( ); } - let test_ignored = IGNORE_DOCTEST_CHECK.contains(&err_code); + let test_ignored = IGNORE_DOCTEST_CHECK.contains(&&err_code); // Check that the explanation has a doctest, and if it shouldn't, that it doesn't - if !has_test.1 && !test_ignored { + if !found_proper_doctest && !test_ignored { errors.push(format!( "`{}` doesn't use its own error code in compile_fail example", path.display(), )); - } else if has_test.1 && test_ignored { + } else if found_proper_doctest && test_ignored { errors.push(format!( "`{}` has a compile_fail doctest with its own error code, it shouldn't \ be listed in `IGNORE_DOCTEST_CHECK`", -- cgit 1.4.1-3-g733a5 From cafdd2f7bb1be0fa888e0aecafa3adde1a4b5476 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 2 Jan 2023 03:52:29 +0000 Subject: Note maximum integer literal for `IntLiteralTooLarge` --- compiler/rustc_error_messages/locales/en-US/session.ftl | 1 + compiler/rustc_session/src/errors.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index ab9e8b6baae..5b4e6fcf927 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -85,6 +85,7 @@ session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float lite .help = valid suffixes are `f32` and `f64` session_int_literal_too_large = integer literal is too large + .note = value exceeds limit of 340282366920938463463374607431768211455 session_invalid_int_literal_width = invalid width `{$width}` for integer literal .help = valid widths are 8, 16, 32, 64 and 128 diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index e72b76cfee9..effb561688c 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -260,6 +260,7 @@ pub(crate) struct InvalidFloatLiteralSuffix { #[derive(Diagnostic)] #[diag(session_int_literal_too_large)] +#[note] pub(crate) struct IntLiteralTooLarge { #[primary_span] pub span: Span, -- cgit 1.4.1-3-g733a5 From 32ab2d95f1538d50434cb833348fc7c19527bcba Mon Sep 17 00:00:00 2001 From: Gimbles <93856041+gimbles@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:51:54 +0530 Subject: Update format.rs --- compiler/rustc_builtin_macros/src/format.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 63bc0d552c1..b2b7b9d75bd 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -638,7 +638,7 @@ fn report_missing_placeholders( if show_doc_note { diag.note(concat!( stringify!($kind), - " formatting not supported; see the documentation for `std::fmt`", + " formatting is not supported; see the documentation for `std::fmt`", )); } if suggestions.len() > 0 { -- cgit 1.4.1-3-g733a5 From f8755ab864a271a7cc2c4e6cdd8ad0f7cf8e64e1 Mon Sep 17 00:00:00 2001 From: gimbles Date: Mon, 2 Jan 2023 16:53:43 +0530 Subject: maybe --- src/test/ui/fmt/ifmt-bad-arg.stderr | 2 +- src/test/ui/fmt/issue-89173.rs | 2 +- src/test/ui/fmt/issue-89173.stderr | 2 +- src/test/ui/macros/format-foreign.stderr | 10 +++++----- src/test/ui/macros/format-unused-lables.stderr | 2 +- src/test/ui/macros/issue-92267.stderr | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr index a8a2a47fe46..c2619d6df58 100644 --- a/src/test/ui/fmt/ifmt-bad-arg.stderr +++ b/src/test/ui/fmt/ifmt-bad-arg.stderr @@ -170,7 +170,7 @@ LL | format!("foo %s baz", "bar"); | | | help: format specifiers use curly braces: `{}` | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: invalid format string: expected `'}'`, found `'t'` --> $DIR/ifmt-bad-arg.rs:75:1 diff --git a/src/test/ui/fmt/issue-89173.rs b/src/test/ui/fmt/issue-89173.rs index 96277d4d0d9..fc99af40859 100644 --- a/src/test/ui/fmt/issue-89173.rs +++ b/src/test/ui/fmt/issue-89173.rs @@ -10,5 +10,5 @@ fn main() { //~| NOTE: argument never used //~| NOTE: argument never used //~| NOTE: format specifiers use curly braces, and you have to use a positional or named parameter for the width - //~| NOTE: printf formatting not supported + //~| NOTE: printf formatting is not supported } diff --git a/src/test/ui/fmt/issue-89173.stderr b/src/test/ui/fmt/issue-89173.stderr index 7b21e0a4fc8..ddeb769eadc 100644 --- a/src/test/ui/fmt/issue-89173.stderr +++ b/src/test/ui/fmt/issue-89173.stderr @@ -12,7 +12,7 @@ note: format specifiers use curly braces, and you have to use a positional or na | LL | print!("%0*x", width, num); | ^^^^ - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: aborting due to previous error diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index ff5236dc949..7971c2ab2b9 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -8,7 +8,7 @@ LL | println!("%.*3$s %s!\n", "Hello,", "World", 4); | | argument never used | multiple missing formatting specifiers | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL | println!("{:.2$} {}!\n", "Hello,", "World", 4); @@ -22,7 +22,7 @@ LL | println!("%1$*2$.*3$f", 123.456); | | | help: format specifiers use curly braces: `{0:1$.2$}` | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: multiple unused formatting arguments --> $DIR/format-foreign.rs:6:7 @@ -37,7 +37,7 @@ LL | | "###, "Hello,", "World", 4); | |____| argument never used | multiple missing formatting specifiers | - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL ~ println!(r###"{:.2$} @@ -60,7 +60,7 @@ LL | println!("Hi there, $NAME.", NAME="Tim"); | | | help: format specifiers use curly braces: `{NAME}` | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` error: multiple unused formatting arguments --> $DIR/format-foreign.rs:15:32 @@ -72,7 +72,7 @@ LL | println!("$1 $0 $$ $NAME", 1, 2, NAME=3); | | argument never used | multiple missing formatting specifiers | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` help: format specifiers use curly braces | LL | println!("{1} {0} $$ {NAME}", 1, 2, NAME=3); diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index 7423c7b7c8b..fad87fa2aee 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -44,7 +44,7 @@ LL | "things" LL | , UNUSED="args"); | ^^^^^^ named argument never used | - = note: shell formatting not supported; see the documentation for `std::fmt` + = note: shell formatting is not supported; see the documentation for `std::fmt` error: aborting due to 4 previous errors diff --git a/src/test/ui/macros/issue-92267.stderr b/src/test/ui/macros/issue-92267.stderr index d2d66c81198..5359f68cd55 100644 --- a/src/test/ui/macros/issue-92267.stderr +++ b/src/test/ui/macros/issue-92267.stderr @@ -10,7 +10,7 @@ note: format specifiers use curly braces, and the conversion specifier ` | LL | pub fn main() { println!("🦀%%%", 0) } | ^^ - = note: printf formatting not supported; see the documentation for `std::fmt` + = note: printf formatting is not supported; see the documentation for `std::fmt` error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 537c7f4fa95f4c5b0a6259ee7badae5ad57d0940 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 2 Jan 2023 05:07:02 +0000 Subject: Print correct base for too-large literals Also update tests --- compiler/rustc_ast/src/util/literal.rs | 4 +- .../rustc_error_messages/locales/en-US/session.ftl | 2 +- compiler/rustc_session/src/errors.rs | 12 +++- src/test/ui/lexer/error-stage.stderr | 2 + src/test/ui/lexer/lex-bad-numeric-literals.rs | 8 +++ src/test/ui/lexer/lex-bad-numeric-literals.stderr | 76 +++++++++++++++------- ...ssue-104769-concat_bytes-invalid-literal.stderr | 2 + .../ui/parser/int-literal-too-large-span.stderr | 2 + src/test/ui/parser/issues/issue-5544-a.stderr | 2 + src/test/ui/parser/issues/issue-5544-b.stderr | 2 + 10 files changed, 83 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 0daeecb53a8..69a9a583048 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -34,7 +34,7 @@ pub enum LitError { InvalidIntSuffix, InvalidFloatSuffix, NonDecimalFloat(u32), - IntTooLarge, + IntTooLarge(u32), } impl LitKind { @@ -333,6 +333,6 @@ fn integer_lit(symbol: Symbol, suffix: Option) -> Result= base)); - if from_lexer { LitError::LexerError } else { LitError::IntTooLarge } + if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) } }) } diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index 5b4e6fcf927..bc37d91a7c6 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -85,7 +85,7 @@ session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float lite .help = valid suffixes are `f32` and `f64` session_int_literal_too_large = integer literal is too large - .note = value exceeds limit of 340282366920938463463374607431768211455 + .note = value exceeds limit of `{$limit}` session_invalid_int_literal_width = invalid width `{$width}` for integer literal .help = valid widths are 8, 16, 32, 64 and 128 diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index effb561688c..f5a72573d58 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -264,6 +264,7 @@ pub(crate) struct InvalidFloatLiteralSuffix { pub(crate) struct IntLiteralTooLarge { #[primary_span] pub span: Span, + pub limit: String, } #[derive(Diagnostic)] @@ -362,8 +363,15 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: _ => unreachable!(), }; } - LitError::IntTooLarge => { - sess.emit_err(IntLiteralTooLarge { span }); + LitError::IntTooLarge(base) => { + let max = u128::MAX; + let limit = match base { + 2 => format!("{max:#b}"), + 8 => format!("{max:#o}"), + 16 => format!("{max:#x}"), + _ => format!("{max}"), + }; + sess.emit_err(IntLiteralTooLarge { span, limit }); } } } diff --git a/src/test/ui/lexer/error-stage.stderr b/src/test/ui/lexer/error-stage.stderr index 697a7c28da1..ecbdb14dc86 100644 --- a/src/test/ui/lexer/error-stage.stderr +++ b/src/test/ui/lexer/error-stage.stderr @@ -49,6 +49,8 @@ error: integer literal is too large | LL | 999340282366920938463463374607431768211455999; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` error: aborting due to 8 previous errors diff --git a/src/test/ui/lexer/lex-bad-numeric-literals.rs b/src/test/ui/lexer/lex-bad-numeric-literals.rs index cf8440ca488..56bdc50e40d 100644 --- a/src/test/ui/lexer/lex-bad-numeric-literals.rs +++ b/src/test/ui/lexer/lex-bad-numeric-literals.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + fn main() { 0o1.0; //~ ERROR: octal float literal is not supported 0o2f32; //~ ERROR: octal float literal is not supported @@ -15,6 +17,12 @@ fn main() { //~^ ERROR: integer literal is too large 9900000000000000000000000000999999999999999999999999999999; //~^ ERROR: integer literal is too large + 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110; + //~^ ERROR: integer literal is too large + 0o37777777777777777777777777777777777777777770; + //~^ ERROR: integer literal is too large + 0xffffffffffffffffffffffffffffffff0; + //~^ ERROR: integer literal is too large 0x; //~ ERROR: no valid digits 0xu32; //~ ERROR: no valid digits 0ou32; //~ ERROR: no valid digits diff --git a/src/test/ui/lexer/lex-bad-numeric-literals.stderr b/src/test/ui/lexer/lex-bad-numeric-literals.stderr index f05d6160302..1457541970a 100644 --- a/src/test/ui/lexer/lex-bad-numeric-literals.stderr +++ b/src/test/ui/lexer/lex-bad-numeric-literals.stderr @@ -1,141 +1,169 @@ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:2:5 + --> $DIR/lex-bad-numeric-literals.rs:4:5 | LL | 0o1.0; | ^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:4:5 + --> $DIR/lex-bad-numeric-literals.rs:6:5 | LL | 0o3.0f32; | ^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:5:5 + --> $DIR/lex-bad-numeric-literals.rs:7:5 | LL | 0o4e4; | ^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:6:5 + --> $DIR/lex-bad-numeric-literals.rs:8:5 | LL | 0o5.0e5; | ^^^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:7:5 + --> $DIR/lex-bad-numeric-literals.rs:9:5 | LL | 0o6e6f32; | ^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:8:5 + --> $DIR/lex-bad-numeric-literals.rs:10:5 | LL | 0o7.0e7f64; | ^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:9:5 + --> $DIR/lex-bad-numeric-literals.rs:11:5 | LL | 0x8.0e+9; | ^^^^^^^^ error: hexadecimal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:10:5 + --> $DIR/lex-bad-numeric-literals.rs:12:5 | LL | 0x9.0e-9; | ^^^^^^^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:11:5 + --> $DIR/lex-bad-numeric-literals.rs:13:5 | LL | 0o; | ^^ error: expected at least one digit in exponent - --> $DIR/lex-bad-numeric-literals.rs:12:5 + --> $DIR/lex-bad-numeric-literals.rs:14:5 | LL | 1e+; | ^^^ error: hexadecimal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:13:5 + --> $DIR/lex-bad-numeric-literals.rs:15:5 | LL | 0x539.0; | ^^^^^^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:18:5 + --> $DIR/lex-bad-numeric-literals.rs:26:5 | LL | 0x; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:19:5 + --> $DIR/lex-bad-numeric-literals.rs:27:5 | LL | 0xu32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:20:5 + --> $DIR/lex-bad-numeric-literals.rs:28:5 | LL | 0ou32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:21:5 + --> $DIR/lex-bad-numeric-literals.rs:29:5 | LL | 0bu32; | ^^ error[E0768]: no valid digits found for number - --> $DIR/lex-bad-numeric-literals.rs:22:5 + --> $DIR/lex-bad-numeric-literals.rs:30:5 | LL | 0b; | ^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:24:5 + --> $DIR/lex-bad-numeric-literals.rs:32:5 | LL | 0o123.456; | ^^^^^^^^^ error: binary float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:26:5 + --> $DIR/lex-bad-numeric-literals.rs:34:5 | LL | 0b111.101; | ^^^^^^^^^ error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:3:5 + --> $DIR/lex-bad-numeric-literals.rs:5:5 | LL | 0o2f32; | ^^^^^^ not supported error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:14:5 + --> $DIR/lex-bad-numeric-literals.rs:16:5 | LL | 9900000000000000000000000000999999999999999999999999999999; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` error: integer literal is too large - --> $DIR/lex-bad-numeric-literals.rs:16:5 + --> $DIR/lex-bad-numeric-literals.rs:18:5 | LL | 9900000000000000000000000000999999999999999999999999999999; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` + +error: integer literal is too large + --> $DIR/lex-bad-numeric-literals.rs:20:5 + | +LL | 0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111` + +error: integer literal is too large + --> $DIR/lex-bad-numeric-literals.rs:22:5 + | +LL | 0o37777777777777777777777777777777777777777770; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `0o3777777777777777777777777777777777777777777` + +error: integer literal is too large + --> $DIR/lex-bad-numeric-literals.rs:24:5 + | +LL | 0xffffffffffffffffffffffffffffffff0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `0xffffffffffffffffffffffffffffffff` error: octal float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:23:5 + --> $DIR/lex-bad-numeric-literals.rs:31:5 | LL | 0o123f64; | ^^^^^^^^ not supported error: binary float literal is not supported - --> $DIR/lex-bad-numeric-literals.rs:25:5 + --> $DIR/lex-bad-numeric-literals.rs:33:5 | LL | 0b101f64; | ^^^^^^^^ not supported -error: aborting due to 23 previous errors +error: aborting due to 26 previous errors For more information about this error, try `rustc --explain E0768`. diff --git a/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr index 8d70faa494d..8807279c27f 100644 --- a/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr +++ b/src/test/ui/macros/issue-104769-concat_bytes-invalid-literal.stderr @@ -11,6 +11,8 @@ error: integer literal is too large | LL | concat_bytes!(888888888888888888888888888888888888888); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/int-literal-too-large-span.stderr b/src/test/ui/parser/int-literal-too-large-span.stderr index 7cae85fc9fe..49d6aa5eff8 100644 --- a/src/test/ui/parser/int-literal-too-large-span.stderr +++ b/src/test/ui/parser/int-literal-too-large-span.stderr @@ -3,6 +3,8 @@ error: integer literal is too large | LL | 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-5544-a.stderr b/src/test/ui/parser/issues/issue-5544-a.stderr index de579c3c134..6e68c75850a 100644 --- a/src/test/ui/parser/issues/issue-5544-a.stderr +++ b/src/test/ui/parser/issues/issue-5544-a.stderr @@ -3,6 +3,8 @@ error: integer literal is too large | LL | let __isize = 340282366920938463463374607431768211456; // 2^128 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `340282366920938463463374607431768211455` error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-5544-b.stderr b/src/test/ui/parser/issues/issue-5544-b.stderr index 7df212dedfe..5d0e76d5d94 100644 --- a/src/test/ui/parser/issues/issue-5544-b.stderr +++ b/src/test/ui/parser/issues/issue-5544-b.stderr @@ -3,6 +3,8 @@ error: integer literal is too large | LL | let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: value exceeds limit of `0xffffffffffffffffffffffffffffffff` error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 5974f6f0a53614e82df9430b95bcb6e9473265fa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 22 Dec 2022 16:32:08 +0100 Subject: default OOM handler: use non-unwinding panic (unless -Zoom=panic is set), to match std handler --- library/alloc/src/alloc.rs | 15 ++++++++++++++- library/alloc/src/lib.rs | 1 + library/core/src/panicking.rs | 23 +++++++++++++++++------ library/std/src/alloc.rs | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index e5fbfc55761..e1c612c5b3f 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -402,7 +402,20 @@ pub mod __alloc_error_handler { // `#[alloc_error_handler]`. #[rustc_std_internal_symbol] pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { - panic!("memory allocation of {size} bytes failed") + extern "Rust" { + // This symbol is emitted by rustc next to __rust_alloc_error_handler. + // Its value depends on the -Zoom={panic,abort} compiler option. + static __rust_alloc_error_handler_should_panic: u8; + } + + #[allow(unused_unsafe)] + if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + panic!("memory allocation of {size} bytes failed") + } else { + core::panicking::panic_nounwind_fmt(format_args!( + "memory allocation of {size} bytes failed" + )) + } } #[cfg(bootstrap)] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 96960d43f58..2a7edc2add1 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -110,6 +110,7 @@ #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_refs_to_cell)] #![feature(core_intrinsics)] +#![feature(core_panic)] #![feature(const_eval_select)] #![feature(const_pin)] #![feature(const_waker)] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 9fce78d076b..36b43ec2181 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -64,13 +64,17 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { unsafe { panic_impl(&pi) } } -/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize. -/// (No `fmt` variant as a `fmt::Arguments` needs more space to be passed.) +/// Like `panic_fmt`, but for non-unwinding panics. +/// +/// Has to be a separate function so that it can carry the `rustc_nounwind` attribute. #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(not(bootstrap), lang = "panic_nounwind")] // needed by codegen for non-unwinding panics +#[track_caller] +// This attribute has the key side-effect that if the panic handler ignores `can_unwind` +// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, +// which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -pub fn panic_nounwind(msg: &'static str) -> ! { +pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -83,8 +87,6 @@ pub fn panic_nounwind(msg: &'static str) -> ! { } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pieces = [msg]; - let fmt = fmt::Arguments::new_v1(&pieces, &[]); let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. @@ -112,6 +114,15 @@ pub const fn panic(expr: &'static str) -> ! { panic_fmt(fmt::Arguments::new_v1(&[expr], &[])); } +/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize. +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[cfg_attr(not(bootstrap), lang = "panic_nounwind")] // needed by codegen for non-unwinding panics +#[rustc_nounwind] +pub fn panic_nounwind(expr: &'static str) -> ! { + panic_nounwind_fmt(fmt::Arguments::new_v1(&[expr], &[])); +} + #[inline] #[track_caller] #[rustc_diagnostic_item = "panic_str"] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 61c1ff578b2..c5a5991cc81 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -338,7 +338,7 @@ fn default_alloc_error_hook(layout: Layout) { #[allow(unused_unsafe)] if unsafe { __rust_alloc_error_handler_should_panic != 0 } { - panic!("memory allocation of {} bytes failed\n", layout.size()); + panic!("memory allocation of {} bytes failed", layout.size()); } else { rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); } -- cgit 1.4.1-3-g733a5 From c00ab4b2de2b5a321476244a9316d4dd3d8f8242 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Tue, 3 Jan 2023 08:44:57 +1300 Subject: print highest error code --- src/tools/tidy/src/error_codes.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 938e194abdf..fdc9d789905 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -51,6 +51,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut // Stage 1: create list let error_codes = extract_error_codes(root_path, &mut errors, verbose); println!("Found {} error codes", error_codes.len()); + println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); // Stage 2: check list has docs let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose); -- cgit 1.4.1-3-g733a5 From 817cc3344677d4dcab7798cb1f191d9b3a760d15 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 2 Jan 2023 13:12:45 -0700 Subject: rustdoc: remove legacy box-sizing CSS According to [caniuse], these vendor prefixes aren't needed in any supported web browsers as defined in [RFC 1985] * The last version of Chrome that required a vendor prefix was version 9. The current version is 108. * Firefox 28 is the last version that required a vendor prefix. The [current Firefox ESR] is version 102. * The last version of Safari that required a vendor prefix was version 5. The current version is 16. * The last version of Safari/iOS that required a vendor prefix was version 4. The current version is 16. * Edge never required vendor prefixes. * UCAndroid never required vendor prefixes. [caniuse]: https://caniuse.com/?search=box-sizing [RFC 1985]: https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html [current Firefox ESR]: https://wiki.mozilla.org/Releases --- src/librustdoc/html/static/css/rustdoc.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bc0458bcd28..6f8a306d665 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -76,8 +76,6 @@ } * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; box-sizing: border-box; } -- cgit 1.4.1-3-g733a5 From 357c3cf72cfa7f4455ae71ad62816dfcc843746b Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Mon, 2 Jan 2023 00:00:00 +0000 Subject: Fix handling of dead unwinds in backward analyses Dead unwinds set contains a head of an unreachable unwind edge. --- compiler/rustc_mir_dataflow/src/framework/direction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 5ff6b9e7e69..077a21fc8af 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -287,7 +287,7 @@ impl Direction for Backward { | mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. } if unwind == bb => { - if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { + if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) { propagate(pred, exit_state); } } -- cgit 1.4.1-3-g733a5 From eb53eea60920e28d3c3e053b170d015be7493a74 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 29 Dec 2022 21:08:09 +0000 Subject: Add json output to `-Zdump-mono-stats` This allows analyzing the output programatically; for example, finding the item with the highest `total_estimate`. I also took the liberty of adding `untracked` tests to `rustc_session` and documentation to the unstable book for `dump-mono-items`. --- Cargo.lock | 2 + compiler/rustc_interface/src/tests.rs | 12 +++--- compiler/rustc_monomorphize/Cargo.toml | 2 + .../rustc_monomorphize/src/partitioning/mod.rs | 48 ++++++++++++++-------- compiler/rustc_session/src/config.rs | 18 ++++++++ compiler/rustc_session/src/options.rs | 20 ++++++++- .../src/compiler-flags/dump-mono-stats-format.md | 6 +++ .../src/compiler-flags/dump-mono-stats.md | 14 +++++++ src/test/run-make/dump-mono-stats/Makefile | 5 +++ src/test/run-make/dump-mono-stats/foo.rs | 1 + src/test/rustdoc-ui/z-help.stdout | 3 +- 11 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md create mode 100644 src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md create mode 100644 src/test/run-make/dump-mono-stats/Makefile create mode 100644 src/test/run-make/dump-mono-stats/foo.rs diff --git a/Cargo.lock b/Cargo.lock index 9581099c210..9037feec79e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4226,6 +4226,8 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "serde", + "serde_json", "smallvec", "tracing", ] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ff2196d5857..947d8e80cb0 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -3,17 +3,16 @@ use crate::interface::parse_cfgspecs; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; -use rustc_session::config::InstrumentCoverage; -use rustc_session::config::Strip; +use rustc_session::config::rustc_optgroups; use rustc_session::config::{build_configuration, build_session_options, to_crate_config}; -use rustc_session::config::{ - rustc_optgroups, ErrorOutputType, ExternLocation, LocationDetail, Options, Passes, -}; use rustc_session::config::{ BranchProtection, Externs, OomStrategy, OutputType, OutputTypes, PAuthKey, PacRet, ProcMacroExecutionStrategy, SymbolManglingVersion, WasiExecModel, }; use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath}; +use rustc_session::config::{DumpMonoStatsFormat, MirSpanview}; +use rustc_session::config::{ErrorOutputType, ExternLocation, LocationDetail, Options, Strip}; +use rustc_session::config::{InstrumentCoverage, Passes}; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; @@ -647,6 +646,9 @@ fn test_unstable_options_tracking_hash() { untracked!(dump_mir_dir, String::from("abc")); untracked!(dump_mir_exclude_pass_number, true); untracked!(dump_mir_graphviz, true); + untracked!(dump_mir_spanview, Some(MirSpanview::Statement)); + untracked!(dump_mono_stats, SwitchWithOptPath::Enabled(Some("mono-items-dir/".into()))); + untracked!(dump_mono_stats_format, DumpMonoStatsFormat::Json); untracked!(dylib_lto, true); untracked!(emit_stack_sizes, true); untracked!(future_incompat_test, true); diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 6ee5330b63f..c8af10576b4 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" [lib] [dependencies] +serde = "1" +serde_json = "1" smallvec = { version = "1.8.1", features = [ "union", "may_dangle" ] } tracing = "0.1" rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 4f25fc71314..f0417b06a04 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -109,7 +109,7 @@ use rustc_middle::mir::mono::{CodegenUnit, Linkage}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_session::config::SwitchWithOptPath; +use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; use rustc_span::symbol::Symbol; use crate::collector::InliningMap; @@ -492,9 +492,11 @@ fn dump_mono_items_stats<'tcx>( Path::new(".") }; - let filename = format!("{}.mono_items.md", crate_name.unwrap_or("unknown-crate")); + let format = tcx.sess.opts.unstable_opts.dump_mono_stats_format; + let ext = format.extension(); + let filename = format!("{}.mono_items.{ext}", crate_name.unwrap_or("unknown-crate")); let output_path = output_directory.join(&filename); - let file = File::create(output_path)?; + let file = File::create(&output_path)?; let mut file = BufWriter::new(file); // Gather instantiated mono items grouped by def_id @@ -508,30 +510,44 @@ fn dump_mono_items_stats<'tcx>( } } + #[derive(serde::Serialize)] + struct MonoItem { + name: String, + instantiation_count: usize, + size_estimate: usize, + total_estimate: usize, + } + // Output stats sorted by total instantiated size, from heaviest to lightest let mut stats: Vec<_> = items_per_def_id .into_iter() .map(|(def_id, items)| { + let name = with_no_trimmed_paths!(tcx.def_path_str(def_id)); let instantiation_count = items.len(); let size_estimate = items[0].size_estimate(tcx); let total_estimate = instantiation_count * size_estimate; - (def_id, instantiation_count, size_estimate, total_estimate) + MonoItem { name, instantiation_count, size_estimate, total_estimate } }) .collect(); - stats.sort_unstable_by_key(|(_, _, _, total_estimate)| cmp::Reverse(*total_estimate)); + stats.sort_unstable_by_key(|item| cmp::Reverse(item.total_estimate)); if !stats.is_empty() { - writeln!( - file, - "| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |" - )?; - writeln!(file, "| --- | ---: | ---: | ---: |")?; - for (def_id, instantiation_count, size_estimate, total_estimate) in stats { - let item = with_no_trimmed_paths!(tcx.def_path_str(def_id)); - writeln!( - file, - "| {item} | {instantiation_count} | {size_estimate} | {total_estimate} |" - )?; + match format { + DumpMonoStatsFormat::Json => serde_json::to_writer(file, &stats)?, + DumpMonoStatsFormat::Markdown => { + writeln!( + file, + "| Item | Instantiation count | Estimated Cost Per Instantiation | Total Estimated Cost |" + )?; + writeln!(file, "| --- | ---: | ---: | ---: |")?; + + for MonoItem { name, instantiation_count, size_estimate, total_estimate } in stats { + writeln!( + file, + "| `{name}` | {instantiation_count} | {size_estimate} | {total_estimate} |" + )?; + } + } } } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3bafd3730bd..f3758cd7d27 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2975,3 +2975,21 @@ pub enum ProcMacroExecutionStrategy { /// Run the proc-macro code on a different thread. CrossThread, } + +/// Which format to use for `-Z dump-mono-stats` +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum DumpMonoStatsFormat { + /// Pretty-print a markdown table + Markdown, + /// Emit structured JSON + Json, +} + +impl DumpMonoStatsFormat { + pub fn extension(self) -> &'static str { + match self { + Self::Markdown => "md", + Self::Json => "json", + } + } +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ae01efebacc..7ff667ecb2c 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -377,6 +377,7 @@ mod desc { pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`"; + pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`"; pub const parse_instrument_coverage: &str = "`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`"; pub const parse_unpretty: &str = "`string` or `string=string`"; @@ -820,6 +821,21 @@ mod parse { true } + pub(crate) fn parse_dump_mono_stats(slot: &mut DumpMonoStatsFormat, v: Option<&str>) -> bool { + match v { + None => true, + Some("json") => { + *slot = DumpMonoStatsFormat::Json; + true + } + Some("markdown") => { + *slot = DumpMonoStatsFormat::Markdown; + true + } + Some(_) => false, + } + } + pub(crate) fn parse_instrument_coverage( slot: &mut Option, v: Option<&str>, @@ -1295,7 +1311,9 @@ options! { an additional `.html` file showing the computed coverage spans."), dump_mono_stats: SwitchWithOptPath = (SwitchWithOptPath::Disabled, parse_switch_with_opt_path, [UNTRACKED], - "output statistics about monomorphization collection (format: markdown)"), + "output statistics about monomorphization collection"), + dump_mono_stats_format: DumpMonoStatsFormat = (DumpMonoStatsFormat::Markdown, parse_dump_mono_stats, [UNTRACKED], + "the format to use for -Z dump-mono-stats (`markdown` (default) or `json`)"), dwarf_version: Option = (None, parse_opt_number, [TRACKED], "version of DWARF debug information to emit (default: 2 or 4, depending on platform)"), dylib_lto: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md new file mode 100644 index 00000000000..a497a75261f --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats-format.md @@ -0,0 +1,6 @@ +# `dump-mono-stats-format` + +-------------------- + +The `-Z dump-mono-stats-format` compiler flag controls what file format to use for `-Z dump-mono-stats`. +The default is markdown; currently JSON is also supported. JSON can be useful for programatically manipulating the results (e.g. to find the item that took the longest to compile). diff --git a/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md new file mode 100644 index 00000000000..4c8bc8b4578 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/dump-mono-stats.md @@ -0,0 +1,14 @@ +# `dump-mono-stats` + +-------------------- + +The `-Z dump-mono-stats` compiler flag generates a file with a list of the monomorphized items in the current crate. +It is useful for investigating compile times. + +It accepts an optional directory where the file will be located. If no directory is specified, the file will be placed in the current directory. + +See also `-Z dump-mono-stats-format` and `-Z print-mono-items`. Unlike `print-mono-items`, +`dump-mono-stats` aggregates monomorphized items by definition and includes a size estimate of how +large the item is when codegened. + +See for an overview of monomorphized items. diff --git a/src/test/run-make/dump-mono-stats/Makefile b/src/test/run-make/dump-mono-stats/Makefile new file mode 100644 index 00000000000..fe1112fb0a4 --- /dev/null +++ b/src/test/run-make/dump-mono-stats/Makefile @@ -0,0 +1,5 @@ +include ../../run-make-fulldeps/tools.mk + +all: + $(RUSTC) --crate-type lib foo.rs -Z dump-mono-stats=$(TMPDIR) -Zdump-mono-stats-format=json + cat $(TMPDIR)/foo.mono_items.json | $(CGREP) '"name":"bar"' diff --git a/src/test/run-make/dump-mono-stats/foo.rs b/src/test/run-make/dump-mono-stats/foo.rs new file mode 100644 index 00000000000..c5c0bc606cd --- /dev/null +++ b/src/test/run-make/dump-mono-stats/foo.rs @@ -0,0 +1 @@ +pub fn bar() {} diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 53677b18377..9bd6c5fedf5 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -35,7 +35,8 @@ -Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no) -Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no) -Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans. - -Z dump-mono-stats=val -- output statistics about monomorphization collection (format: markdown) + -Z dump-mono-stats=val -- output statistics about monomorphization collection + -Z dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`) -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) -Z dylib-lto=val -- enables LTO for dylib crate type -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) -- cgit 1.4.1-3-g733a5 From 5c79624bfaf28540b739f33ffe9d2d1f132555d2 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 29 Dec 2022 21:53:13 +0000 Subject: Fix `unknown_crate` when `--crate-name` isn't passed on the CLI --- compiler/rustc_monomorphize/src/partitioning/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index f0417b06a04..97fbb458e79 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -102,7 +102,7 @@ use std::path::{Path, PathBuf}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync; -use rustc_hir::def_id::DefIdSet; +use rustc_hir::def_id::{DefIdSet, LOCAL_CRATE}; use rustc_middle::mir; use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{CodegenUnit, Linkage}; @@ -417,7 +417,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co // Output monomorphization stats per def_id if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats { if let Err(err) = - dump_mono_items_stats(tcx, &codegen_units, path, tcx.sess.opts.crate_name.as_deref()) + dump_mono_items_stats(tcx, &codegen_units, path, tcx.crate_name(LOCAL_CRATE)) { tcx.sess.emit_fatal(CouldntDumpMonoStats { error: err.to_string() }); } @@ -483,7 +483,7 @@ fn dump_mono_items_stats<'tcx>( tcx: TyCtxt<'tcx>, codegen_units: &[CodegenUnit<'tcx>], output_directory: &Option, - crate_name: Option<&str>, + crate_name: Symbol, ) -> Result<(), Box> { let output_directory = if let Some(ref directory) = output_directory { fs::create_dir_all(directory)?; @@ -494,7 +494,7 @@ fn dump_mono_items_stats<'tcx>( let format = tcx.sess.opts.unstable_opts.dump_mono_stats_format; let ext = format.extension(); - let filename = format!("{}.mono_items.{ext}", crate_name.unwrap_or("unknown-crate")); + let filename = format!("{crate_name}.mono_items.{ext}"); let output_path = output_directory.join(&filename); let file = File::create(&output_path)?; let mut file = BufWriter::new(file); -- cgit 1.4.1-3-g733a5 From 2a7d5599706f127c1ebe6e5f992f9245d7f09b8a Mon Sep 17 00:00:00 2001 From: Léo Lanteri Thauvin Date: Mon, 26 Dec 2022 18:49:19 +0100 Subject: Don't trim path for `unsafe_op_in_unsafe_fn` lints --- compiler/rustc_mir_build/src/check_unsafety.rs | 23 +++++++++++++---------- src/test/ui/unsafe/auxiliary/issue-106126.rs | 9 +++++++++ src/test/ui/unsafe/issue-106126-good-path-bug.rs | 12 ++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/unsafe/auxiliary/issue-106126.rs create mode 100644 src/test/ui/unsafe/issue-106126-good-path-bug.rs diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 3c311729a52..03a7f2d70fa 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -5,6 +5,7 @@ use rustc_middle::thir::visit::{self, Visitor}; use rustc_hir as hir; use rustc_middle::mir::BorrowKind; use rustc_middle::thir::*; +use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; @@ -524,17 +525,19 @@ impl UnsafeOpKind { hir_id: hir::HirId, span: Span, ) { + // FIXME: ideally we would want to trim the def paths, but this is not + // feasible with the current lint emission API (see issue #106126). match self { - CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint( + CallToUnsafeFunction(Some(did)) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { span, - function: &tcx.def_path_str(did.unwrap()), + function: &with_no_trimmed_paths!(tcx.def_path_str(*did)), }, ), - CallToUnsafeFunction(..) => tcx.emit_spanned_lint( + CallToUnsafeFunction(None) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, @@ -594,7 +597,7 @@ impl UnsafeOpKind { span, UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { span, - function: &tcx.def_path_str(*did), + function: &with_no_trimmed_paths!(tcx.def_path_str(*did)), }, ), } @@ -607,24 +610,24 @@ impl UnsafeOpKind { unsafe_op_in_unsafe_fn_allowed: bool, ) { match self { - CallToUnsafeFunction(did) if did.is_some() && unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(Some(did)) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(did) if did.is_some() => { + CallToUnsafeFunction(Some(did)) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(..) if unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span }, ); } - CallToUnsafeFunction(..) => { + CallToUnsafeFunction(None) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span }); } UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => { diff --git a/src/test/ui/unsafe/auxiliary/issue-106126.rs b/src/test/ui/unsafe/auxiliary/issue-106126.rs new file mode 100644 index 00000000000..091a3edb756 --- /dev/null +++ b/src/test/ui/unsafe/auxiliary/issue-106126.rs @@ -0,0 +1,9 @@ +#[macro_export] +macro_rules! foo { + () => { + unsafe fn __unsf() {} + unsafe fn __foo() { + __unsf(); + } + }; +} diff --git a/src/test/ui/unsafe/issue-106126-good-path-bug.rs b/src/test/ui/unsafe/issue-106126-good-path-bug.rs new file mode 100644 index 00000000000..93f478ee358 --- /dev/null +++ b/src/test/ui/unsafe/issue-106126-good-path-bug.rs @@ -0,0 +1,12 @@ +// Regression test for #106126. +// check-pass +// aux-build:issue-106126.rs + +#![deny(unsafe_op_in_unsafe_fn)] + +#[macro_use] +extern crate issue_106126; + +foo!(); + +fn main() {} -- cgit 1.4.1-3-g733a5 From 7770b06b06efc4abda75e608e67044a0a344771e Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Tue, 13 Sep 2022 11:17:13 +0200 Subject: only specify --target by default for -Zgcc-ld=lld on wasm On macOS, it's not yet clear which cases of clang/OS/target/SDK version impact how to find ld/lld/rust-lld. The --target is not needed on our current targets with a vanilla config, but may be in some cases. Specifying it all the time breaks the 10.7+ targets on x64 macOS. We try to only specify it on macOS if the linker flavors are different, for possible cases of cross-compilation with `-Zgcc-ld=lld` but the expectation is that it should be passed manually when needed in these situations. --- compiler/rustc_codegen_ssa/src/back/link.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index edde1537b81..36f7e5954bf 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2822,11 +2822,30 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // Implement the "linker flavor" part of -Zgcc-ld // by asking cc to use some kind of lld. cmd.arg("-fuse-ld=lld"); + if !flavor.is_gnu() { // Tell clang to use a non-default LLD flavor. // Gcc doesn't understand the target option, but we currently assume // that gcc is not used for Apple and Wasm targets (#97402). - cmd.arg(format!("--target={}", sess.target.llvm_target)); + // + // Note that we don't want to do that by default on macOS: e.g. passing a + // 10.7 target to LLVM works, but not to recent versions of clang/macOS, as + // shown in issue #101653 and the discussion in PR #101792. + // + // It could be required in some cases of cross-compiling with + // `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know + // which specific versions of clang, macOS SDK, host and target OS + // combinations impact us here. + // + // So we do a simple first-approximation until we know more of what the + // Apple targets require (and which would be handled prior to hitting this + // `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then + // this should be manually passed if needed. We specify the target when + // targeting a different linker flavor on macOS, and that's also always + // the case when targeting WASM. + if sess.target.linker_flavor != sess.host.linker_flavor { + cmd.arg(format!("--target={}", sess.target.llvm_target)); + } } } } -- cgit 1.4.1-3-g733a5 From e9ca6636e108cb4380d38a45c5ebb1d485079210 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 2 Jan 2023 16:36:29 -0700 Subject: get latest x version from parsing cargo command --- Cargo.lock | 17 ++++++++------- src/tools/tidy/Cargo.toml | 1 + src/tools/tidy/src/x_version.rs | 48 ++++++++++++++++++++++++++++++++--------- 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cafdc83d4f..784aca237f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4814,9 +4814,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] @@ -4833,9 +4833,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -4853,9 +4853,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "indexmap", "itoa", @@ -5133,9 +5133,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.102" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -5310,6 +5310,7 @@ dependencies = [ "miropt-test-tools", "regex", "semver", + "serde_json", "termcolor", "walkdir", ] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 5f5ae3a65ef..a13ecbe955a 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -12,6 +12,7 @@ lazy_static = "1" walkdir = "2" ignore = "0.4.18" semver = "1.0.14" +serde_json = "1.0.91" termcolor = "1.1.3" [[bin]] diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 868b3d925d3..6cadc18fd3e 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -1,4 +1,5 @@ -use semver::{BuildMetadata, Prerelease, Version}; +use semver::Version; +use serde_json::Value; use std::io::ErrorKind; use std::process::{Command, Stdio}; @@ -33,20 +34,47 @@ pub fn check(bad: &mut bool) { if output.status.success() { let version = String::from_utf8_lossy(&output.stdout); let version = Version::parse(version.trim_end()).unwrap(); - let expected = Version { - major: 0, - minor: 1, - patch: 0, - pre: Prerelease::new("").unwrap(), - build: BuildMetadata::EMPTY, - }; - if version < expected { + + if let Some(expected) = get_x_wrapper_version() { + if version < expected { + return tidy_error!( + bad, + "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" + ); + } + } else { return tidy_error!( bad, - "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" + "Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`" ); } } else { return tidy_error!(bad, "failed to check version of `x`: {}", output.status); } } + +// Parse latest version out of `x` Cargo.toml +fn get_x_wrapper_version() -> Option { + let cmd = Command::new("cargo") + .arg("metadata") + .args(["--no-deps", "--format-version", "1", "--manifest-path", "src/tools/x/Cargo.toml"]) + .stdout(Stdio::piped()) + .spawn(); + + let child = match cmd { + Ok(child) => child, + Err(e) => { + println!("failed to get version of `x`: {}", e); + return None; + } + }; + + let cargo_output = child.wait_with_output().unwrap(); + let cargo_output_str = + String::from_utf8(cargo_output.stdout).expect("Unable to parse `src/tools/x/Cargo.toml`"); + + let v: Value = serde_json::from_str(&cargo_output_str).unwrap(); + let vesrion_str = &v["packages"][0]["version"].as_str()?; + + Some(Version::parse(vesrion_str).unwrap()) +} -- cgit 1.4.1-3-g733a5 From 3eabea9e2c16803ff5864a78be8ecaf1531005d4 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Tue, 3 Jan 2023 00:00:00 +0000 Subject: Remove duplicated elaborate box derefs pass The pass runs earlier as a part of `run_runtime_lowering_passes`. --- compiler/rustc_mir_transform/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index ae79c2290f6..806758f71dc 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -524,11 +524,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Returns the sequence of passes that do the initial cleanup of runtime MIR. fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let passes: &[&dyn MirPass<'tcx>] = &[ - &elaborate_box_derefs::ElaborateBoxDerefs, - &lower_intrinsics::LowerIntrinsics, - &simplify::SimplifyCfg::new("elaborate-drops"), - ]; + let passes: &[&dyn MirPass<'tcx>] = + &[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops")]; pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup))); } -- cgit 1.4.1-3-g733a5 From b2317a642d36e26e6cdf0624c38d461384f7b94e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 3 Jan 2023 01:09:08 +0000 Subject: has_overflow only if value is *not* within limit --- compiler/rustc_trait_selection/src/solve/overflow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/solve/overflow.rs b/compiler/rustc_trait_selection/src/solve/overflow.rs index 8d73a83aec9..fdd6adb681b 100644 --- a/compiler/rustc_trait_selection/src/solve/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/overflow.rs @@ -36,7 +36,7 @@ impl OverflowData { #[inline] pub(super) fn has_overflow(&self, depth: usize) -> bool { - self.current_limit.value_within_limit(depth + self.additional_depth) + !self.current_limit.value_within_limit(depth + self.additional_depth) } /// Updating the current limit when hitting overflow. -- cgit 1.4.1-3-g733a5 From 6c254ed6dca48ebbd83209493df0ffc1d2584f38 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Mon, 2 Jan 2023 17:26:16 -0800 Subject: rustdoc: allow popover child links to work No need to prevent default click behavior on a
, it will also disable all child click behavior. --- src/librustdoc/html/static/js/main.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 60e4e749224..92baa68b5be 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1040,9 +1040,6 @@ function loadCss(cssUrl) { help_button.appendChild(container); container.onblur = helpBlurHandler; - container.onclick = event => { - event.preventDefault(); - }; help_button.onblur = helpBlurHandler; help_button.children[0].onblur = helpBlurHandler; } -- cgit 1.4.1-3-g733a5 From 376dd8a9b36eb4d0c192f3767562ca0bdab60ff9 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Mon, 2 Jan 2023 19:31:18 -0700 Subject: use cargo_metadata to get x version --- Cargo.lock | 1 - src/tools/tidy/Cargo.toml | 1 - src/tools/tidy/src/main.rs | 2 +- src/tools/tidy/src/x_version.rs | 36 ++++++++++-------------------------- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 784aca237f0..4cb64882cb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5310,7 +5310,6 @@ dependencies = [ "miropt-test-tools", "regex", "semver", - "serde_json", "termcolor", "walkdir", ] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index a13ecbe955a..5f5ae3a65ef 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -12,7 +12,6 @@ lazy_static = "1" walkdir = "2" ignore = "0.4.18" semver = "1.0.14" -serde_json = "1.0.91" termcolor = "1.1.3" [[bin]] diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 56fcc561a3f..7bb8ddc6949 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -107,7 +107,7 @@ fn main() { check!(alphabetical, &compiler_path); check!(alphabetical, &library_path); - check!(x_version); + check!(x_version, &root_path, &cargo); let collected = { drain_handles(&mut handles); diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 6cadc18fd3e..070a751b051 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -1,9 +1,9 @@ use semver::Version; -use serde_json::Value; use std::io::ErrorKind; +use std::path::Path; use std::process::{Command, Stdio}; -pub fn check(bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); // This runs the command inside a temporary directory. // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. @@ -35,7 +35,7 @@ pub fn check(bad: &mut bool) { let version = String::from_utf8_lossy(&output.stdout); let version = Version::parse(version.trim_end()).unwrap(); - if let Some(expected) = get_x_wrapper_version() { + if let Some(expected) = get_x_wrapper_version(root, cargo) { if version < expected { return tidy_error!( bad, @@ -54,27 +54,11 @@ pub fn check(bad: &mut bool) { } // Parse latest version out of `x` Cargo.toml -fn get_x_wrapper_version() -> Option { - let cmd = Command::new("cargo") - .arg("metadata") - .args(["--no-deps", "--format-version", "1", "--manifest-path", "src/tools/x/Cargo.toml"]) - .stdout(Stdio::piped()) - .spawn(); - - let child = match cmd { - Ok(child) => child, - Err(e) => { - println!("failed to get version of `x`: {}", e); - return None; - } - }; - - let cargo_output = child.wait_with_output().unwrap(); - let cargo_output_str = - String::from_utf8(cargo_output.stdout).expect("Unable to parse `src/tools/x/Cargo.toml`"); - - let v: Value = serde_json::from_str(&cargo_output_str).unwrap(); - let vesrion_str = &v["packages"][0]["version"].as_str()?; - - Some(Version::parse(vesrion_str).unwrap()) +fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option { + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("src/tools/x/Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures); + let mut metadata = t!(cmd.exec()); + metadata.packages.pop().map(|x| x.version) } -- cgit 1.4.1-3-g733a5 From 6f1d9ba581dbf1282825e87424021d8c4cb7ba54 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 3 Jan 2023 03:39:41 +0000 Subject: Allow passing a specific date to `bump-stage0` This allows regenerating `src/stage0.json` on changes to the tool, without needing to hard-code the date in the source. --- src/bootstrap/run.rs | 1 + src/tools/bump-stage0/src/main.rs | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 05de51f8cc5..e0280854541 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -105,6 +105,7 @@ impl Step for BumpStage0 { fn run(self, builder: &Builder<'_>) -> Self::Output { let mut cmd = builder.tool_cmd(Tool::BumpStage0); + cmd.args(builder.config.cmd.args()); builder.run(&mut cmd); } } diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index aa346daf7e5..530a80b1ed3 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -1,4 +1,4 @@ -use anyhow::Error; +use anyhow::{Context, Error}; use curl::easy::Easy; use indexmap::IndexMap; use std::collections::HashMap; @@ -13,12 +13,13 @@ struct Tool { comments: Vec, channel: Channel, + date: Option, version: [u16; 3], checksums: IndexMap, } impl Tool { - fn new() -> Result { + fn new(date: Option) -> Result { let channel = match std::fs::read_to_string("src/ci/channel")?.trim() { "stable" => Channel::Stable, "beta" => Channel::Beta, @@ -40,6 +41,7 @@ impl Tool { Ok(Self { channel, version, + date, config: existing.config, comments: existing.comments, checksums: IndexMap::new(), @@ -84,7 +86,7 @@ impl Tool { Channel::Nightly => "beta".to_string(), }; - let manifest = fetch_manifest(&self.config, &channel)?; + let manifest = fetch_manifest(&self.config, &channel, self.date.as_deref())?; self.collect_checksums(&manifest, COMPILER_COMPONENTS)?; Ok(Stage0Toolchain { date: manifest.date, @@ -110,7 +112,7 @@ impl Tool { return Ok(None); } - let manifest = fetch_manifest(&self.config, "nightly")?; + let manifest = fetch_manifest(&self.config, "nightly", self.date.as_deref())?; self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?; Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() })) } @@ -141,16 +143,19 @@ impl Tool { } fn main() -> Result<(), Error> { - let tool = Tool::new()?; + let tool = Tool::new(std::env::args().nth(1))?; tool.update_json()?; Ok(()) } -fn fetch_manifest(config: &Config, channel: &str) -> Result { - Ok(toml::from_slice(&http_get(&format!( - "{}/dist/channel-rust-{}.toml", - config.dist_server, channel - ))?)?) +fn fetch_manifest(config: &Config, channel: &str, date: Option<&str>) -> Result { + let url = if let Some(date) = date { + format!("{}/dist/{}/channel-rust-{}.toml", config.dist_server, date, channel) + } else { + format!("{}/dist/channel-rust-{}.toml", config.dist_server, channel) + }; + + Ok(toml::from_slice(&http_get(&url)?)?) } fn http_get(url: &str) -> Result, Error> { @@ -164,7 +169,7 @@ fn http_get(url: &str) -> Result, Error> { data.extend_from_slice(new_data); Ok(new_data.len()) })?; - transfer.perform()?; + transfer.perform().context(format!("failed to fetch {url}"))?; } Ok(data) } -- cgit 1.4.1-3-g733a5 From 85f649fd27754cf54dff48131b87800a02edb948 Mon Sep 17 00:00:00 2001 From: J Haigh Date: Mon, 2 Jan 2023 20:49:18 -0700 Subject: no_deps Co-authored-by: Joshua Nelson --- src/tools/tidy/src/x_version.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 070a751b051..5dc6a0588c3 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -58,6 +58,7 @@ fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option { let mut cmd = cargo_metadata::MetadataCommand::new(); cmd.cargo_path(cargo) .manifest_path(root.join("src/tools/x/Cargo.toml")) + .no_deps() .features(cargo_metadata::CargoOpt::AllFeatures); let mut metadata = t!(cmd.exec()); metadata.packages.pop().map(|x| x.version) -- cgit 1.4.1-3-g733a5 From e808a69911c31609b67c1e94a940b398af324f34 Mon Sep 17 00:00:00 2001 From: Rageking8 Date: Tue, 3 Jan 2023 15:48:16 +0800 Subject: fix dupe word typos --- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_lint/src/late.rs | 2 +- src/librustdoc/visit_ast.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index cdb901b7f86..10d8db5393d 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1392,7 +1392,7 @@ declare_lint! { /// /// The attribute must be used in conjunction with the /// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]` - /// annotation will function as as no-op. + /// annotation will function as a no-op. /// /// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-track-caller.html UNGATED_ASYNC_FN_TRACK_CALLER, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 5f84d5c8b94..c18abaef8e2 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -29,7 +29,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); }) } -/// Implements the AST traversal for early lint passes. `T` provides the the +/// Implements the AST traversal for early lint passes. `T` provides the /// `check_*` methods. pub struct EarlyContextAndPass<'a, T: EarlyLintPass> { context: EarlyContext<'a>, diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index e2876938d70..b2a2656746e 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -40,7 +40,7 @@ macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({ $cx.pass.$f(&$cx.context, $($args),*); }) } -/// Implements the AST traversal for late lint passes. `T` provides the the +/// Implements the AST traversal for late lint passes. `T` provides the /// `check_*` methods. pub struct LateContextAndPass<'tcx, T: LateLintPass<'tcx>> { context: LateContext<'tcx>, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 310a01194ea..7db47035967 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -410,7 +410,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { /// This method will create a new module and push it onto the "modules stack" then call /// `visit_mod_contents`. Once done, it'll remove it from the "modules stack" and instead - /// add into into the list of modules of the current module. + /// add into the list of modules of the current module. fn enter_mod(&mut self, id: hir::HirId, m: &'tcx hir::Mod<'tcx>, name: Symbol) { self.modules.push(Module::new(name, id, m.spans.inner_span)); -- cgit 1.4.1-3-g733a5 From 7680b164b00af55e7af64bdc8027b6deb4fb8233 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Mon, 2 Jan 2023 19:30:39 +0000 Subject: jsondoclint: Parse args with clap. --- Cargo.lock | 18 +++++++++++++++++- src/tools/jsondoclint/Cargo.toml | 1 + src/tools/jsondoclint/src/main.rs | 14 ++++++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f99e58e59b8..0483d50fc2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -597,7 +597,7 @@ checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" dependencies = [ "atty", "bitflags", - "clap_derive", + "clap_derive 3.2.18", "clap_lex 0.2.2", "indexmap", "once_cell", @@ -614,7 +614,9 @@ checksum = "6bf8832993da70a4c6d13c581f4463c2bdda27b9bf1c5498dc4365543abe6d6f" dependencies = [ "atty", "bitflags", + "clap_derive 4.0.13", "clap_lex 0.3.0", + "once_cell", "strsim", "termcolor", ] @@ -641,6 +643,19 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_derive" +version = "4.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "clap_lex" version = "0.2.2" @@ -2097,6 +2112,7 @@ name = "jsondoclint" version = "0.1.0" dependencies = [ "anyhow", + "clap 4.0.15", "fs-err", "rustdoc-json-types", "serde_json", diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml index 84a6c7f96c4..0dda3935ed8 100644 --- a/src/tools/jsondoclint/Cargo.toml +++ b/src/tools/jsondoclint/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.62" +clap = { version = "4.0.15", features = ["derive"] } fs-err = "2.8.1" rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" } serde_json = "1.0.85" diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs index fc54c421b4b..91a7aeb063f 100644 --- a/src/tools/jsondoclint/src/main.rs +++ b/src/tools/jsondoclint/src/main.rs @@ -1,6 +1,5 @@ -use std::env; - -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, Result}; +use clap::Parser; use fs_err as fs; use rustdoc_json_types::{Crate, Id, FORMAT_VERSION}; use serde_json::Value; @@ -21,8 +20,15 @@ enum ErrorKind { Custom(String), } +#[derive(Parser)] +struct Cli { + /// The path to the json file to be linted + path: String, +} + fn main() -> Result<()> { - let path = env::args().nth(1).ok_or_else(|| anyhow!("no path given"))?; + let Cli { path } = Cli::parse(); + let contents = fs::read_to_string(&path)?; let krate: Crate = serde_json::from_str(&contents)?; assert_eq!(krate.format_version, FORMAT_VERSION); -- cgit 1.4.1-3-g733a5 From 855b7e8cf3963b9f187249f1f38b6bb2baa9c353 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Mon, 2 Jan 2023 19:40:00 +0000 Subject: jsondoclint: Add `--verbose` flag. Without verbose: 0:61941:36627 not in index or paths, but refered to at '$.index["0:62007"].inner.for.inner.id' and 12 more With verbose: 0:10808:27206 not in index or paths, but refered to at '$.index["0:10813"].inner.for.inner.id', '$.index["0:52495"].inner.for.inner.id', '$.index["a:0:2666:215-0:10808:27206"].inner.for.inner.id', '$.index["a:0:2680:223-0:10808:27206"].inner.for.inner.id', '$.index["a:0:2730:7845-0:10808:27206"].inner.for.inner.id', '$.index["a:0:7731:21706-0:10808:27206"].inner.for.inner.id', '$.index["a:0:7732:21705-0:10808:27206"].inner.for.inner.id' --- src/tools/jsondoclint/src/main.rs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs index 91a7aeb063f..89965dc2403 100644 --- a/src/tools/jsondoclint/src/main.rs +++ b/src/tools/jsondoclint/src/main.rs @@ -24,10 +24,14 @@ enum ErrorKind { struct Cli { /// The path to the json file to be linted path: String, + + /// Show verbose output + #[arg(long)] + verbose: bool, } fn main() -> Result<()> { - let Cli { path } = Cli::parse(); + let Cli { path, verbose } = Cli::parse(); let contents = fs::read_to_string(&path)?; let krate: Crate = serde_json::from_str(&contents)?; @@ -53,11 +57,27 @@ fn main() -> Result<()> { err.id.0, json_find::to_jsonpath(&sel) ), - [sel, ..] => eprintln!( - "{} not in index or paths, but refered to at '{}' and more", - err.id.0, - json_find::to_jsonpath(&sel) - ), + [sel, ..] => { + if verbose { + let sels = sels + .iter() + .map(json_find::to_jsonpath) + .map(|i| format!("'{i}'")) + .collect::>() + .join(", "); + eprintln!( + "{} not in index or paths, but refered to at {sels}", + err.id.0 + ); + } else { + eprintln!( + "{} not in index or paths, but refered to at '{}' and {} more", + err.id.0, + json_find::to_jsonpath(&sel), + sels.len() - 1, + ) + } + } } } ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg), -- cgit 1.4.1-3-g733a5 From 95329080d317f01f22ddce1dec8be693ef4b29f4 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Mon, 2 Jan 2023 19:54:08 +0000 Subject: jsondoclint: Find selector for missing ID when error is created, not reported. This is needed for json output, but even without that, it increases performance massivly. On my machine, in reduces the time to check core.json from 40.190s to 11.333s. --- src/tools/jsondoclint/src/main.rs | 73 ++++++++++++++-------------- src/tools/jsondoclint/src/validator.rs | 13 +++-- src/tools/jsondoclint/src/validator/tests.rs | 20 +++++++- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs index 89965dc2403..266900ea3a2 100644 --- a/src/tools/jsondoclint/src/main.rs +++ b/src/tools/jsondoclint/src/main.rs @@ -16,7 +16,7 @@ struct Error { #[derive(Debug, PartialEq, Eq)] enum ErrorKind { - NotFound, + NotFound(Vec), Custom(String), } @@ -37,49 +37,48 @@ fn main() -> Result<()> { let krate: Crate = serde_json::from_str(&contents)?; assert_eq!(krate.format_version, FORMAT_VERSION); - let mut validator = validator::Validator::new(&krate); + let krate_json: Value = serde_json::from_str(&contents)?; + + let mut validator = validator::Validator::new(&krate, krate_json); validator.check_crate(); if !validator.errs.is_empty() { for err in validator.errs { match err.kind { - ErrorKind::NotFound => { - let krate_json: Value = serde_json::from_str(&contents)?; - - let sels = - json_find::find_selector(&krate_json, &Value::String(err.id.0.clone())); - match &sels[..] { - [] => unreachable!( - "id must be in crate, or it wouldn't be reported as not found" - ), - [sel] => eprintln!( - "{} not in index or paths, but refered to at '{}'", - err.id.0, - json_find::to_jsonpath(&sel) - ), - [sel, ..] => { - if verbose { - let sels = sels - .iter() - .map(json_find::to_jsonpath) - .map(|i| format!("'{i}'")) - .collect::>() - .join(", "); - eprintln!( - "{} not in index or paths, but refered to at {sels}", - err.id.0 - ); - } else { - eprintln!( - "{} not in index or paths, but refered to at '{}' and {} more", - err.id.0, - json_find::to_jsonpath(&sel), - sels.len() - 1, - ) - } + ErrorKind::NotFound(sels) => match &sels[..] { + [] => { + unreachable!( + "id {:?} must be in crate, or it wouldn't be reported as not found", + err.id + ) + } + [sel] => eprintln!( + "{} not in index or paths, but refered to at '{}'", + err.id.0, + json_find::to_jsonpath(&sel) + ), + [sel, ..] => { + if verbose { + let sels = sels + .iter() + .map(json_find::to_jsonpath) + .map(|i| format!("'{i}'")) + .collect::>() + .join(", "); + eprintln!( + "{} not in index or paths, but refered to at {sels}", + err.id.0 + ); + } else { + eprintln!( + "{} not in index or paths, but refered to at '{}' and {} more", + err.id.0, + json_find::to_jsonpath(&sel), + sels.len() - 1, + ) } } - } + }, ErrorKind::Custom(msg) => eprintln!("{}: {}", err.id.0, msg), } } diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 291d02d67bd..f1b9c1acbae 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -7,8 +7,9 @@ use rustdoc_json_types::{ Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding, TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate, }; +use serde_json::Value; -use crate::{item_kind::Kind, Error, ErrorKind}; +use crate::{item_kind::Kind, json_find, Error, ErrorKind}; /// The Validator walks over the JSON tree, and ensures it is well formed. /// It is made of several parts. @@ -22,6 +23,7 @@ use crate::{item_kind::Kind, Error, ErrorKind}; pub struct Validator<'a> { pub(crate) errs: Vec, krate: &'a Crate, + krate_json: Value, /// Worklist of Ids to check. todo: HashSet<&'a Id>, /// Ids that have already been visited, so don't need to be checked again. @@ -39,9 +41,10 @@ enum PathKind { } impl<'a> Validator<'a> { - pub fn new(krate: &'a Crate) -> Self { + pub fn new(krate: &'a Crate, krate_json: Value) -> Self { Self { krate, + krate_json, errs: Vec::new(), seen_ids: HashSet::new(), todo: HashSet::new(), @@ -373,7 +376,11 @@ impl<'a> Validator<'a> { } else { if !self.missing_ids.contains(id) { self.missing_ids.insert(id); - self.fail(id, ErrorKind::NotFound) + + let sels = json_find::find_selector(&self.krate_json, &Value::String(id.0.clone())); + assert_ne!(sels.len(), 0); + + self.fail(id, ErrorKind::NotFound(sels)) } } } diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs index c4aeee9c53b..37b826153ef 100644 --- a/src/tools/jsondoclint/src/validator/tests.rs +++ b/src/tools/jsondoclint/src/validator/tests.rs @@ -2,11 +2,16 @@ use std::collections::HashMap; use rustdoc_json_types::{Crate, Item, Visibility}; +use crate::json_find::SelectorPart; + use super::*; #[track_caller] fn check(krate: &Crate, errs: &[Error]) { - let mut validator = Validator::new(krate); + let krate_string = serde_json::to_string(krate).unwrap(); + let krate_json = serde_json::from_str(&krate_string).unwrap(); + + let mut validator = Validator::new(krate, krate_json); validator.check_crate(); assert_eq!(errs, &validator.errs[..]); @@ -46,5 +51,16 @@ fn errors_on_missing_links() { format_version: rustdoc_json_types::FORMAT_VERSION, }; - check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]); + check( + &k, + &[Error { + kind: ErrorKind::NotFound(vec![vec![ + SelectorPart::Field("index".to_owned()), + SelectorPart::Field("0".to_owned()), + SelectorPart::Field("links".to_owned()), + SelectorPart::Field("Not Found".to_owned()), + ]]), + id: id("1"), + }], + ); } -- cgit 1.4.1-3-g733a5 From 226ab7fd759d94e81d6831f869e41502a7f183c7 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Mon, 2 Jan 2023 20:15:45 +0000 Subject: jsondoclint: Add option to dump errors as json. The output looks like: { "errors": [ { "id": "2:2017:1833", "kind": { "NotFound": [ [ {"Field": "index"}, {"Field": "0:0:1571"}, {"Field": "links"}, {"Field": "pointer::read"} ] ] } } ], "path": "/home/nixon/dev/rust/rust/build/x86_64-unknown-linux-gnu/test/rustdoc-json/intra-doc-links/pointer_method/pointer_method.json" } --- Cargo.lock | 1 + src/tools/jsondoclint/Cargo.toml | 1 + src/tools/jsondoclint/src/json_find.rs | 3 ++- src/tools/jsondoclint/src/main.rs | 25 ++++++++++++++++++++++--- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0483d50fc2a..bb438f288f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2115,6 +2115,7 @@ dependencies = [ "clap 4.0.15", "fs-err", "rustdoc-json-types", + "serde", "serde_json", ] diff --git a/src/tools/jsondoclint/Cargo.toml b/src/tools/jsondoclint/Cargo.toml index 0dda3935ed8..8990310a4f4 100644 --- a/src/tools/jsondoclint/Cargo.toml +++ b/src/tools/jsondoclint/Cargo.toml @@ -10,4 +10,5 @@ anyhow = "1.0.62" clap = { version = "4.0.15", features = ["derive"] } fs-err = "2.8.1" rustdoc-json-types = { version = "0.1.0", path = "../../rustdoc-json-types" } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" diff --git a/src/tools/jsondoclint/src/json_find.rs b/src/tools/jsondoclint/src/json_find.rs index 70e7440f730..a183c4068ce 100644 --- a/src/tools/jsondoclint/src/json_find.rs +++ b/src/tools/jsondoclint/src/json_find.rs @@ -1,8 +1,9 @@ use std::fmt::Write; +use serde::Serialize; use serde_json::Value; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub enum SelectorPart { Field(String), Index(usize), diff --git a/src/tools/jsondoclint/src/main.rs b/src/tools/jsondoclint/src/main.rs index 266900ea3a2..05e938f4f7d 100644 --- a/src/tools/jsondoclint/src/main.rs +++ b/src/tools/jsondoclint/src/main.rs @@ -1,25 +1,34 @@ +use std::io::{BufWriter, Write}; + use anyhow::{bail, Result}; use clap::Parser; use fs_err as fs; use rustdoc_json_types::{Crate, Id, FORMAT_VERSION}; +use serde::Serialize; use serde_json::Value; pub(crate) mod item_kind; mod json_find; mod validator; -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Serialize, Clone)] struct Error { kind: ErrorKind, id: Id, } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Serialize, Clone)] enum ErrorKind { NotFound(Vec), Custom(String), } +#[derive(Debug, Serialize)] +struct JsonOutput { + path: String, + errors: Vec, +} + #[derive(Parser)] struct Cli { /// The path to the json file to be linted @@ -28,10 +37,13 @@ struct Cli { /// Show verbose output #[arg(long)] verbose: bool, + + #[arg(long)] + json_output: Option, } fn main() -> Result<()> { - let Cli { path, verbose } = Cli::parse(); + let Cli { path, verbose, json_output } = Cli::parse(); let contents = fs::read_to_string(&path)?; let krate: Crate = serde_json::from_str(&contents)?; @@ -42,6 +54,13 @@ fn main() -> Result<()> { let mut validator = validator::Validator::new(&krate, krate_json); validator.check_crate(); + if let Some(json_output) = json_output { + let output = JsonOutput { path: path.clone(), errors: validator.errs.clone() }; + let mut f = BufWriter::new(fs::File::create(json_output)?); + serde_json::to_writer(&mut f, &output)?; + f.flush()?; + } + if !validator.errs.is_empty() { for err in validator.errs { match err.kind { -- cgit 1.4.1-3-g733a5 From f1f99c611a77b2ca4f9bde02c1ad77a57c12fcc7 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Sun, 1 Jan 2023 20:07:45 +0000 Subject: clean: Remove `ctor_kind` from `VariantStruct`. It's always `None`. --- src/librustdoc/clean/mod.rs | 2 -- src/librustdoc/clean/types.rs | 1 - src/librustdoc/html/render/print_item.rs | 11 +---------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 07a9c48365f..025a4379f45 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1960,7 +1960,6 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), ), None => VariantKind::Struct(VariantStruct { - ctor_kind: None, fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; @@ -1985,7 +1984,6 @@ fn clean_variant_data<'tcx>( let kind = match variant { hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct { - ctor_kind: None, fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(), }), hir::VariantData::Tuple(..) => { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 77ec0242621..6d55a6794f5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2111,7 +2111,6 @@ impl Union { /// only as a variant in an enum. #[derive(Clone, Debug)] pub(crate) struct VariantStruct { - pub(crate) ctor_kind: Option, pub(crate) fields: Vec, } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 40dfb069750..c16d6477fc3 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1229,16 +1229,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(")"); } clean::VariantKind::Struct(ref s) => { - render_struct( - w, - v, - None, - s.ctor_kind, - &s.fields, - " ", - false, - cx, - ); + render_struct(w, v, None, None, &s.fields, " ", false, cx); } }, _ => unreachable!(), -- cgit 1.4.1-3-g733a5 From 25c153149ead5aebf7626a1ff42a6e0a3c35108e Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:11:33 +0100 Subject: Add `build_helper` crate to share code between tidy and bootstrap --- Cargo.lock | 5 +++++ Cargo.toml | 1 + src/bootstrap/Cargo.lock | 5 +++++ src/bootstrap/Cargo.toml | 1 + src/bootstrap/format.rs | 30 +---------------------------- src/bootstrap/lib.rs | 3 ++- src/bootstrap/native.rs | 4 +++- src/bootstrap/util.rs | 29 ---------------------------- src/tools/build_helper/Cargo.toml | 8 ++++++++ src/tools/build_helper/src/ci.rs | 40 +++++++++++++++++++++++++++++++++++++++ src/tools/build_helper/src/git.rs | 30 +++++++++++++++++++++++++++++ src/tools/build_helper/src/lib.rs | 2 ++ 12 files changed, 98 insertions(+), 60 deletions(-) create mode 100644 src/tools/build_helper/Cargo.toml create mode 100644 src/tools/build_helper/src/ci.rs create mode 100644 src/tools/build_helper/src/git.rs create mode 100644 src/tools/build_helper/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f99e58e59b8..7a86a1012a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,10 @@ dependencies = [ "toml", ] +[[package]] +name = "build_helper" +version = "0.1.0" + [[package]] name = "bump-stage0" version = "0.1.0" @@ -5304,6 +5308,7 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ + "build_helper", "cargo_metadata 0.14.0", "ignore", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index 1cec4a84480..ce08d4edb56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "library/std", "library/test", "src/rustdoc-json-types", + "src/tools/build_helper", "src/tools/cargotest", "src/tools/clippy", "src/tools/clippy/clippy_dev", diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index efe8ae3169f..4a0ba592577 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -36,6 +36,7 @@ dependencies = [ name = "bootstrap" version = "0.0.0" dependencies = [ + "build_helper", "cc", "cmake", "fd-lock", @@ -70,6 +71,10 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "build_helper" +version = "0.1.0" + [[package]] name = "cc" version = "1.0.73" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index fafe82a9c12..22ceeca941e 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -30,6 +30,7 @@ path = "bin/sccache-plus-cl.rs" test = false [dependencies] +build_helper = { path = "../tools/build_helper" } cmake = "0.1.38" fd-lock = "3.0.8" filetime = "0.2" diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 84e46118959..cca45f4a634 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -2,6 +2,7 @@ use crate::builder::Builder; use crate::util::{output, program_out_of_date, t}; +use build_helper::git::get_rust_lang_rust_remote; use ignore::WalkBuilder; use std::collections::VecDeque; use std::path::{Path, PathBuf}; @@ -95,35 +96,6 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Option> { ) } -/// Finds the remote for rust-lang/rust. -/// For example for these remotes it will return `upstream`. -/// ```text -/// origin https://github.com/Nilstrieb/rust.git (fetch) -/// origin https://github.com/Nilstrieb/rust.git (push) -/// upstream https://github.com/rust-lang/rust (fetch) -/// upstream https://github.com/rust-lang/rust (push) -/// ``` -fn get_rust_lang_rust_remote() -> Result { - let mut git = Command::new("git"); - git.args(["config", "--local", "--get-regex", "remote\\..*\\.url"]); - - let output = git.output().map_err(|err| format!("{err:?}"))?; - if !output.status.success() { - return Err("failed to execute git config command".to_owned()); - } - - let stdout = String::from_utf8(output.stdout).map_err(|err| format!("{err:?}"))?; - - let rust_lang_remote = stdout - .lines() - .find(|remote| remote.contains("rust-lang")) - .ok_or_else(|| "rust-lang/rust remote not found".to_owned())?; - - let remote_name = - rust_lang_remote.split('.').nth(1).ok_or_else(|| "remote name not found".to_owned())?; - Ok(remote_name.into()) -} - #[derive(serde::Deserialize)] struct RustfmtConfig { ignore: Vec, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 5ea41d10bc8..d44b96cfb99 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -113,6 +113,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; +use build_helper::ci::CiEnv; use channel::GitInfo; use config::{DryRun, Target}; use filetime::FileTime; @@ -121,7 +122,7 @@ use once_cell::sync::OnceCell; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{ - exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, CiEnv, + exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, }; mod bolt; diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 4e503dfe864..bdc81b07b8d 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -24,6 +24,8 @@ use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo}; +use build_helper::ci::CiEnv; + #[derive(Clone)] pub struct LlvmResult { /// Path to llvm-config binary. @@ -217,7 +219,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { return false; } - if crate::util::CiEnv::is_ci() { + if CiEnv::is_ci() { // We assume we have access to git, so it's okay to unconditionally pass // `true` here. let llvm_sha = detect_llvm_sha(config, true); diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 58220783228..8ce9a9ce38c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -255,35 +255,6 @@ pub enum CiEnv { GitHubActions, } -impl CiEnv { - /// Obtains the current CI environment. - pub fn current() -> CiEnv { - if env::var("TF_BUILD").map_or(false, |e| e == "True") { - CiEnv::AzurePipelines - } else if env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") { - CiEnv::GitHubActions - } else { - CiEnv::None - } - } - - pub fn is_ci() -> bool { - Self::current() != CiEnv::None - } - - /// If in a CI environment, forces the command to run with colors. - pub fn force_coloring_in_ci(self, cmd: &mut Command) { - if self != CiEnv::None { - // Due to use of stamp/docker, the output stream of rustbuild is not - // a TTY in CI, so coloring is by-default turned off. - // The explicit `TERM=xterm` environment is needed for - // `--color always` to actually work. This env var was lost when - // compiling through the Makefile. Very strange. - cmd.env("TERM", "xterm").args(&["--color", "always"]); - } - } -} - pub fn forcing_clang_based_tests() -> bool { if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { match &var.to_string_lossy().to_lowercase()[..] { diff --git a/src/tools/build_helper/Cargo.toml b/src/tools/build_helper/Cargo.toml new file mode 100644 index 00000000000..99f6fea2ecf --- /dev/null +++ b/src/tools/build_helper/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "build_helper" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs new file mode 100644 index 00000000000..9f113c72b93 --- /dev/null +++ b/src/tools/build_helper/src/ci.rs @@ -0,0 +1,40 @@ +use std::process::Command; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum CiEnv { + /// Not a CI environment. + None, + /// The Azure Pipelines environment, for Linux (including Docker), Windows, and macOS builds. + AzurePipelines, + /// The GitHub Actions environment, for Linux (including Docker), Windows and macOS builds. + GitHubActions, +} + +impl CiEnv { + /// Obtains the current CI environment. + pub fn current() -> CiEnv { + if std::env::var("TF_BUILD").map_or(false, |e| e == "True") { + CiEnv::AzurePipelines + } else if std::env::var("GITHUB_ACTIONS").map_or(false, |e| e == "true") { + CiEnv::GitHubActions + } else { + CiEnv::None + } + } + + pub fn is_ci() -> bool { + Self::current() != CiEnv::None + } + + /// If in a CI environment, forces the command to run with colors. + pub fn force_coloring_in_ci(self, cmd: &mut Command) { + if self != CiEnv::None { + // Due to use of stamp/docker, the output stream of rustbuild is not + // a TTY in CI, so coloring is by-default turned off. + // The explicit `TERM=xterm` environment is needed for + // `--color always` to actually work. This env var was lost when + // compiling through the Makefile. Very strange. + cmd.env("TERM", "xterm").args(&["--color", "always"]); + } + } +} diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs new file mode 100644 index 00000000000..e9638206e67 --- /dev/null +++ b/src/tools/build_helper/src/git.rs @@ -0,0 +1,30 @@ +use std::process::Command; + +/// Finds the remote for rust-lang/rust. +/// For example for these remotes it will return `upstream`. +/// ```text +/// origin https://github.com/Nilstrieb/rust.git (fetch) +/// origin https://github.com/Nilstrieb/rust.git (push) +/// upstream https://github.com/rust-lang/rust (fetch) +/// upstream https://github.com/rust-lang/rust (push) +/// ``` +pub fn get_rust_lang_rust_remote() -> Result { + let mut git = Command::new("git"); + git.args(["config", "--local", "--get-regex", "remote\\..*\\.url"]); + + let output = git.output().map_err(|err| format!("{err:?}"))?; + if !output.status.success() { + return Err("failed to execute git config command".to_owned()); + } + + let stdout = String::from_utf8(output.stdout).map_err(|err| format!("{err:?}"))?; + + let rust_lang_remote = stdout + .lines() + .find(|remote| remote.contains("rust-lang")) + .ok_or_else(|| "rust-lang/rust remote not found".to_owned())?; + + let remote_name = + rust_lang_remote.split('.').nth(1).ok_or_else(|| "remote name not found".to_owned())?; + Ok(remote_name.into()) +} diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs new file mode 100644 index 00000000000..d3d2323db85 --- /dev/null +++ b/src/tools/build_helper/src/lib.rs @@ -0,0 +1,2 @@ +pub mod ci; +pub mod git; -- cgit 1.4.1-3-g733a5 From 4fe2bd567536719e556d7fc9a4b571042b7807f9 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 3 Jan 2023 10:23:55 -0700 Subject: rustdoc: remove legacy font-feature-settings CSS According to [caniuse], these vendor prefixes aren't needed in any supported web browsers as defined in [RFC 1985]. * The last version of Chrome that required a vendor prefix was version 47. The current version is 108. * Firefox 33 is the last version that required a vendor prefix. The [current Firefox ESR] is version 102. * The last version of Safari that required a vendor prefix was version 9.1. The current version is 16. * The last version of Safari/iOS that required a vendor prefix was version 9.3. The current version is 16. * Edge never required vendor prefixes. * UCAndroid never required vendor prefixes. [caniuse]: https://caniuse.com/?search=font-feature-settings [RFC 1985]: https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html [current Firefox ESR]: https://wiki.mozilla.org/Releases --- src/librustdoc/html/static/css/rustdoc.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index bc0458bcd28..f4c9cea5935 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -110,11 +110,7 @@ body { /* Then override it with `anywhere`, which is required to make non-Safari browsers break more aggressively when we want them to. */ overflow-wrap: anywhere; - - -webkit-font-feature-settings: "kern", "liga"; - -moz-font-feature-settings: "kern", "liga"; font-feature-settings: "kern", "liga"; - background-color: var(--main-background-color); color: var(--main-color); } -- cgit 1.4.1-3-g733a5 From 59eee74ce8b2b056c44f8743fd1661e4858cc12b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Jan 2023 18:10:32 +0100 Subject: Fix link generation for local primitive types in rustdoc JSON output --- src/librustdoc/json/conversions.rs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index d7184053c87..4a81a9d2d61 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -8,8 +8,9 @@ use std::convert::From; use std::fmt; use rustc_ast::ast; -use rustc_hir::{def::CtorKind, def_id::DefId}; +use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId}; use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::symbol::sym; use rustc_span::{Pos, Symbol}; use rustc_target::spec::abi::Abi as RustcAbi; @@ -217,13 +218,27 @@ pub(crate) fn from_item_id_with_name(item_id: ItemId, tcx: TyCtxt<'_>, name: Opt impl<'a> fmt::Display for DisplayDefId<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let name = match self.2 { + let DisplayDefId(def_id, tcx, name) = self; + let name = match name { Some(name) => format!(":{}", name.as_u32()), - None => self - .1 - .opt_item_name(self.0) - .map(|n| format!(":{}", n.as_u32())) - .unwrap_or_default(), + None => { + // We need this workaround because primitive types' DefId actually refers to + // their parent module, which isn't present in the output JSON items. So + // instead, we directly get the primitive symbol and convert it to u32 to + // generate the ID. + if matches!(tcx.def_kind(def_id), DefKind::Mod) && + let Some(prim) = tcx.get_attrs(*def_id, sym::doc) + .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) + .filter(|attr| attr.has_name(sym::primitive)) + .find_map(|attr| attr.value_str()) { + format!(":{}", prim.as_u32()) + } else { + tcx + .opt_item_name(*def_id) + .map(|n| format!(":{}", n.as_u32())) + .unwrap_or_default() + } + } }; write!(f, "{}:{}{}", self.0.krate.as_u32(), u32::from(self.0.index), name) } -- cgit 1.4.1-3-g733a5 From f69fee4fea59fb84582a021d929fd6ecee37db8a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Jan 2023 18:29:40 +0100 Subject: Add regression test for #104064 --- src/test/rustdoc-json/primitives/local_primitive.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/rustdoc-json/primitives/local_primitive.rs diff --git a/src/test/rustdoc-json/primitives/local_primitive.rs b/src/test/rustdoc-json/primitives/local_primitive.rs new file mode 100644 index 00000000000..f27e6a2adec --- /dev/null +++ b/src/test/rustdoc-json/primitives/local_primitive.rs @@ -0,0 +1,21 @@ +// Regression test for . + +#![feature(no_core)] +#![feature(rustc_attrs)] +#![feature(rustdoc_internals)] +#![no_core] +#![rustc_coherence_is_core] + +//! Link to [i32][prim@i32] [i64][prim@i64] + +#[doc(primitive = "i32")] +mod prim_i32 {} + +// @set local_i32 = "$.index[*][?(@.name=='i32')].id" + +// @has "$.index[*][?(@.name=='local_primitive')]" +// @ismany "$.index[*][?(@.name=='local_primitive')].inner.items[*]" $local_i32 +// @is "$.index[*][?(@.name=='local_primitive')].links['prim@i32']" $local_i32 + +// Let's ensure the `prim_i32` module isn't present in the output JSON: +// @!has "$.index[*][?(@.name=='prim_i32')]" -- cgit 1.4.1-3-g733a5 From 9914a8924e651bd013d86ae6254a2283b7afc583 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 3 Jan 2023 09:47:03 -0800 Subject: Add cuviper to the review rotation for libs --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 0da9fcddad8..58108dac496 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -479,6 +479,7 @@ compiler = [ "compiler-team-contributors", ] libs = [ + "@cuviper", "@joshtriplett", "@Mark-Simulacrum", "@m-ou-se", -- cgit 1.4.1-3-g733a5 From 3534e0a393b447791fffaa84a97114dd3c761890 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 3 Jan 2023 04:13:19 +0000 Subject: Fix a few clippy lints in libtest - Remove unnecessary references and dereferences - Use `.contains` instead of `a <= x && x <= b` - Use `mem::take` instead of `mem::replace` where possible --- library/test/src/console.rs | 6 +++--- library/test/src/formatters/json.rs | 18 +++++++++--------- library/test/src/formatters/junit.rs | 16 ++++++++-------- library/test/src/formatters/pretty.rs | 16 ++++++++-------- library/test/src/formatters/terse.rs | 20 ++++++++++---------- library/test/src/lib.rs | 2 +- library/test/src/term/terminfo/mod.rs | 6 +++--- library/test/src/term/terminfo/parm.rs | 8 ++++---- library/test/src/term/terminfo/searcher.rs | 4 ++-- library/test/src/test_result.rs | 4 ++-- library/test/src/types.rs | 2 +- 11 files changed, 51 insertions(+), 51 deletions(-) diff --git a/library/test/src/console.rs b/library/test/src/console.rs index a3c39f71f08..24cbe035f2f 100644 --- a/library/test/src/console.rs +++ b/library/test/src/console.rs @@ -147,7 +147,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res let mut ntest = 0; let mut nbench = 0; - for test in filter_tests(&opts, tests).into_iter() { + for test in filter_tests(opts, tests).into_iter() { use crate::TestFn::*; let TestDescAndFn { desc: TestDesc { name, .. }, testfn } = test; @@ -244,7 +244,7 @@ fn on_test_event( let stdout = &completed_test.stdout; st.write_log_result(test, result, exec_time.as_ref())?; - out.write_result(test, result, exec_time.as_ref(), &*stdout, st)?; + out.write_result(test, result, exec_time.as_ref(), stdout, st)?; handle_test_result(st, completed_test); } } @@ -262,7 +262,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu let max_name_len = tests .iter() - .max_by_key(|t| len_if_padded(*t)) + .max_by_key(|t| len_if_padded(t)) .map(|t| t.desc.name.as_slice().len()) .unwrap_or(0); diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 5526aadb67f..95d2faf2506 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -40,20 +40,20 @@ impl JsonFormatter { extra: Option<&str>, ) -> io::Result<()> { // A doc test's name includes a filename which must be escaped for correct json. - self.write_message(&*format!( + self.write_message(&format!( r#"{{ "type": "{}", "name": "{}", "event": "{}""#, ty, EscapedString(name), evt ))?; if let Some(exec_time) = exec_time { - self.write_message(&*format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()))?; + self.write_message(&format!(r#", "exec_time": {}"#, exec_time.0.as_secs_f64()))?; } if let Some(stdout) = stdout { - self.write_message(&*format!(r#", "stdout": "{}""#, EscapedString(stdout)))?; + self.write_message(&format!(r#", "stdout": "{}""#, EscapedString(stdout)))?; } if let Some(extra) = extra { - self.write_message(&*format!(r#", {extra}"#))?; + self.write_message(&format!(r#", {extra}"#))?; } self.writeln_message(" }") } @@ -66,13 +66,13 @@ impl OutputFormatter for JsonFormatter { } else { String::new() }; - self.writeln_message(&*format!( + self.writeln_message(&format!( r#"{{ "type": "suite", "event": "started", "test_count": {test_count}{shuffle_seed_json} }}"# )) } fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> { - self.writeln_message(&*format!( + self.writeln_message(&format!( r#"{{ "type": "test", "event": "started", "name": "{}" }}"#, EscapedString(desc.name.as_slice()) )) @@ -151,20 +151,20 @@ impl OutputFormatter for JsonFormatter { mbps ); - self.writeln_message(&*line) + self.writeln_message(&line) } } } fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { - self.writeln_message(&*format!( + self.writeln_message(&format!( r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#, EscapedString(desc.name.as_slice()) )) } fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result { - self.write_message(&*format!( + self.write_message(&format!( "{{ \"type\": \"suite\", \ \"event\": \"{}\", \ \"passed\": {}, \ diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index e6fb4f5707b..7a40ce33cb7 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -64,7 +64,7 @@ impl OutputFormatter for JunitFormatter { fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result { self.write_message("")?; - self.write_message(&*format!( + self.write_message(&format!( " OutputFormatter for JunitFormatter { >", state.failed, state.total, state.ignored ))?; - for (desc, result, duration) in std::mem::replace(&mut self.results, Vec::new()) { + for (desc, result, duration) in std::mem::take(&mut self.results) { let (class_name, test_name) = parse_class_name(&desc); match result { TestResult::TrIgnored => { /* no-op */ } TestResult::TrFailed => { - self.write_message(&*format!( + self.write_message(&format!( "", class_name, @@ -90,19 +90,19 @@ impl OutputFormatter for JunitFormatter { } TestResult::TrFailedMsg(ref m) => { - self.write_message(&*format!( + self.write_message(&format!( "", class_name, test_name, duration.as_secs_f64() ))?; - self.write_message(&*format!(""))?; + self.write_message(&format!(""))?; self.write_message("")?; } TestResult::TrTimedFail => { - self.write_message(&*format!( + self.write_message(&format!( "", class_name, @@ -114,7 +114,7 @@ impl OutputFormatter for JunitFormatter { } TestResult::TrBench(ref b) => { - self.write_message(&*format!( + self.write_message(&format!( "", class_name, test_name, b.ns_iter_summ.sum @@ -122,7 +122,7 @@ impl OutputFormatter for JunitFormatter { } TestResult::TrOk => { - self.write_message(&*format!( + self.write_message(&format!( "", class_name, diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs index 0299c8b5433..247778e515f 100644 --- a/library/test/src/formatters/pretty.rs +++ b/library/test/src/formatters/pretty.rs @@ -134,7 +134,7 @@ impl PrettyFormatter { let mut results = Vec::new(); let mut stdouts = String::new(); - for &(ref f, ref stdout) in inputs { + for (f, stdout) in inputs { results.push(f.name.to_string()); if !stdout.is_empty() { stdouts.push_str(&format!("---- {} stdout ----\n", f.name)); @@ -171,9 +171,9 @@ impl PrettyFormatter { fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> { let name = desc.padded_name(self.max_name_len, desc.name.padding()); if let Some(test_mode) = desc.test_mode() { - self.write_plain(&format!("test {name} - {test_mode} ... "))?; + self.write_plain(format!("test {name} - {test_mode} ... "))?; } else { - self.write_plain(&format!("test {name} ... "))?; + self.write_plain(format!("test {name} ... "))?; } Ok(()) @@ -188,7 +188,7 @@ impl OutputFormatter for PrettyFormatter { } else { String::new() }; - self.write_plain(&format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n")) + self.write_plain(format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n")) } fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> { @@ -221,7 +221,7 @@ impl OutputFormatter for PrettyFormatter { TestResult::TrIgnored => self.write_ignored(desc.ignore_message)?, TestResult::TrBench(ref bs) => { self.write_bench()?; - self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?; + self.write_plain(format!(": {}", fmt_bench_samples(bs)))?; } TestResult::TrTimedFail => self.write_time_failed()?, } @@ -231,7 +231,7 @@ impl OutputFormatter for PrettyFormatter { } fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { - self.write_plain(&format!( + self.write_plain(format!( "test {} has been running for over {} seconds\n", desc.name, time::TEST_WARN_TIMEOUT_S @@ -267,11 +267,11 @@ impl OutputFormatter for PrettyFormatter { state.passed, state.failed, state.ignored, state.measured, state.filtered_out ); - self.write_plain(&s)?; + self.write_plain(s)?; if let Some(ref exec_time) = state.exec_time { let time_str = format!("; finished in {exec_time}"); - self.write_plain(&time_str)?; + self.write_plain(time_str)?; } self.write_plain("\n\n")?; diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs index 5dace8baef7..0837ab16905 100644 --- a/library/test/src/formatters/terse.rs +++ b/library/test/src/formatters/terse.rs @@ -70,7 +70,7 @@ impl TerseFormatter { // screen when dealing with line-buffered output (e.g., piping to // `stamp` in the rust CI). let out = format!(" {}/{}\n", self.test_count + 1, self.total_test_count); - self.write_plain(&out)?; + self.write_plain(out)?; } self.test_count += 1; @@ -106,7 +106,7 @@ impl TerseFormatter { self.write_plain("\nsuccesses:\n")?; let mut successes = Vec::new(); let mut stdouts = String::new(); - for &(ref f, ref stdout) in &state.not_failures { + for (f, stdout) in &state.not_failures { successes.push(f.name.to_string()); if !stdout.is_empty() { stdouts.push_str(&format!("---- {} stdout ----\n", f.name)); @@ -132,7 +132,7 @@ impl TerseFormatter { self.write_plain("\nfailures:\n")?; let mut failures = Vec::new(); let mut fail_out = String::new(); - for &(ref f, ref stdout) in &state.failures { + for (f, stdout) in &state.failures { failures.push(f.name.to_string()); if !stdout.is_empty() { fail_out.push_str(&format!("---- {} stdout ----\n", f.name)); @@ -157,9 +157,9 @@ impl TerseFormatter { fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> { let name = desc.padded_name(self.max_name_len, desc.name.padding()); if let Some(test_mode) = desc.test_mode() { - self.write_plain(&format!("test {name} - {test_mode} ... "))?; + self.write_plain(format!("test {name} - {test_mode} ... "))?; } else { - self.write_plain(&format!("test {name} ... "))?; + self.write_plain(format!("test {name} ... "))?; } Ok(()) @@ -175,7 +175,7 @@ impl OutputFormatter for TerseFormatter { } else { String::new() }; - self.write_plain(&format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n")) + self.write_plain(format!("\nrunning {test_count} {noun}{shuffle_seed_msg}\n")) } fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> { @@ -209,13 +209,13 @@ impl OutputFormatter for TerseFormatter { self.write_test_name(desc)?; } self.write_bench()?; - self.write_plain(&format!(": {}\n", fmt_bench_samples(bs))) + self.write_plain(format!(": {}\n", fmt_bench_samples(bs))) } } } fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { - self.write_plain(&format!( + self.write_plain(format!( "test {} has been running for over {} seconds\n", desc.name, time::TEST_WARN_TIMEOUT_S @@ -245,11 +245,11 @@ impl OutputFormatter for TerseFormatter { state.passed, state.failed, state.ignored, state.measured, state.filtered_out ); - self.write_plain(&s)?; + self.write_plain(s)?; if let Some(ref exec_time) = state.exec_time { let time_str = format!("; finished in {exec_time}"); - self.write_plain(&time_str)?; + self.write_plain(time_str)?; } self.write_plain("\n\n")?; diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index f6a41bbb88c..30dc4ff8553 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -789,7 +789,7 @@ fn run_test_in_spawned_subprocess( } }); let record_result2 = record_result.clone(); - panic::set_hook(Box::new(move |info| record_result2(Some(&info)))); + panic::set_hook(Box::new(move |info| record_result2(Some(info)))); if let Err(message) = testfn() { panic!("{}", message); } diff --git a/library/test/src/term/terminfo/mod.rs b/library/test/src/term/terminfo/mod.rs index 35585901971..67ba89410cd 100644 --- a/library/test/src/term/terminfo/mod.rs +++ b/library/test/src/term/terminfo/mod.rs @@ -149,7 +149,7 @@ impl Terminal for TerminfoTerminal { // are there any terminals that have color/attrs and not sgr0? // Try falling back to sgr, then op let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) { - Some(op) => match expand(&op, &[], &mut Variables::new()) { + Some(op) => match expand(op, &[], &mut Variables::new()) { Ok(cmd) => cmd, Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)), }, @@ -180,12 +180,12 @@ impl TerminfoTerminal { } fn dim_if_necessary(&self, color: color::Color) -> color::Color { - if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color } + if color >= self.num_colors && (8..16).contains(&color) { color - 8 } else { color } } fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result { match self.ti.strings.get(cmd) { - Some(cmd) => match expand(&cmd, params, &mut Variables::new()) { + Some(cmd) => match expand(cmd, params, &mut Variables::new()) { Ok(s) => self.out.write_all(&s).and(Ok(true)), Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)), }, diff --git a/library/test/src/term/terminfo/parm.rs b/library/test/src/term/terminfo/parm.rs index 0756c8374aa..2815f6cfc77 100644 --- a/library/test/src/term/terminfo/parm.rs +++ b/library/test/src/term/terminfo/parm.rs @@ -282,14 +282,14 @@ pub(crate) fn expand( ); } SetVar => { - if cur >= 'A' && cur <= 'Z' { + if cur.is_ascii_uppercase() { if let Some(arg) = stack.pop() { let idx = (cur as u8) - b'A'; vars.sta_va[idx as usize] = arg; } else { return Err("stack is empty".to_string()); } - } else if cur >= 'a' && cur <= 'z' { + } else if cur.is_ascii_lowercase() { if let Some(arg) = stack.pop() { let idx = (cur as u8) - b'a'; vars.dyn_va[idx as usize] = arg; @@ -301,10 +301,10 @@ pub(crate) fn expand( } } GetVar => { - if cur >= 'A' && cur <= 'Z' { + if cur.is_ascii_uppercase() { let idx = (cur as u8) - b'A'; stack.push(vars.sta_va[idx as usize].clone()); - } else if cur >= 'a' && cur <= 'z' { + } else if cur.is_ascii_lowercase() { let idx = (cur as u8) - b'a'; stack.push(vars.dyn_va[idx as usize].clone()); } else { diff --git a/library/test/src/term/terminfo/searcher.rs b/library/test/src/term/terminfo/searcher.rs index 68e181a6895..87b91f34498 100644 --- a/library/test/src/term/terminfo/searcher.rs +++ b/library/test/src/term/terminfo/searcher.rs @@ -22,7 +22,7 @@ pub(crate) fn get_dbpath_for_term(term: &str) -> Option { if let Ok(dirs) = env::var("TERMINFO_DIRS") { for i in dirs.split(':') { - if i == "" { + if i.is_empty() { dirs_to_search.push(PathBuf::from("/usr/share/terminfo")); } else { dirs_to_search.push(PathBuf::from(i)); @@ -49,7 +49,7 @@ pub(crate) fn get_dbpath_for_term(term: &str) -> Option { for mut p in dirs_to_search { if fs::metadata(&p).is_ok() { p.push(&first_char.to_string()); - p.push(&term); + p.push(term); if fs::metadata(&p).is_ok() { return Some(p); } diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index 7c5b0d6c0f7..1da238e3e8c 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -33,7 +33,7 @@ pub fn calc_result<'a>( ) -> TestResult { let result = match (&desc.should_panic, task_result) { (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk, - (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { + (&ShouldPanic::YesWithMessage(msg), Err(err)) => { let maybe_panic_str = err .downcast_ref::() .map(|e| &**e) @@ -52,7 +52,7 @@ pub fn calc_result<'a>( r#"expected panic with string value, found non-string value: `{:?}` expected substring: `{:?}`"#, - (**err).type_id(), + (*err).type_id(), msg )) } diff --git a/library/test/src/types.rs b/library/test/src/types.rs index 888afff7921..6f2e033095a 100644 --- a/library/test/src/types.rs +++ b/library/test/src/types.rs @@ -47,7 +47,7 @@ impl TestName { match *self { StaticTestName(s) => s, DynTestName(ref s) => s, - AlignedTestName(ref s, _) => &*s, + AlignedTestName(ref s, _) => s, } } -- cgit 1.4.1-3-g733a5 From 6eb205d591863f03e661f79ea3cb993f69eff844 Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Wed, 23 Nov 2022 18:20:57 +0000 Subject: bootstrap dist: ensure LLD's step --- src/bootstrap/dist.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 340aa78ebf9..479bfeb8e85 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2067,6 +2067,12 @@ impl Step for RustDev { builder.ensure(crate::native::Llvm { target }); + // If the config has LLD enabled, ensure its step. We'll we want to package it, and use it + // in download-ci-llvm. + if builder.config.lld_enabled { + builder.ensure(crate::native::Lld { target }); + } + let src_bindir = builder.llvm_out(target).join("bin"); // If updating this list, you likely want to change // src/bootstrap/download-ci-llvm-stamp as well, otherwise local users -- cgit 1.4.1-3-g733a5 From 835b58d61971890c3134f1d7a6a23d32f3ae7479 Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Wed, 23 Nov 2022 18:08:15 +0000 Subject: make the `native::LLD` step able to use an already built lld Makes the lld step avoid building it from source when possible: when dist has packaged it along the other LLVM binaries for the rust-dev component. --- src/bootstrap/native.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 4e503dfe864..0f92c81e4d9 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -826,6 +826,20 @@ impl Step for Lld { let LlvmResult { llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target: self.target }); + // The `dist` step packages LLD next to LLVM's binaries for download-ci-llvm. The root path + // we usually expect here is `./build/$triple/ci-llvm/`, with the binaries in its `bin` + // subfolder. We check if that's the case, and if LLD's binary already exists there next to + // `llvm-config`: if so, we can use it instead of building LLVM/LLD from source. + let ci_llvm_bin = llvm_config.parent().unwrap(); + if ci_llvm_bin.is_dir() && ci_llvm_bin.file_name().unwrap() == "bin" { + let lld_path = ci_llvm_bin.join(exe("lld", target)); + if lld_path.exists() { + // The following steps copying `lld` as `rust-lld` to the sysroot, expect it in the + // `bin` subfolder of this step's out dir. + return ci_llvm_bin.parent().unwrap().to_path_buf(); + } + } + let out_dir = builder.lld_out(target); let done_stamp = out_dir.join("lld-finished-building"); if done_stamp.exists() { -- cgit 1.4.1-3-g733a5 From 4e4658f0aafbf559a2c3e8674f10a06cadbfc737 Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Wed, 23 Nov 2022 18:12:58 +0000 Subject: slight cleanup --- src/bootstrap/native.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 0f92c81e4d9..48158d51e00 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -823,8 +823,7 @@ impl Step for Lld { } let target = self.target; - let LlvmResult { llvm_config, llvm_cmake_dir } = - builder.ensure(Llvm { target: self.target }); + let LlvmResult { llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target }); // The `dist` step packages LLD next to LLVM's binaries for download-ci-llvm. The root path // we usually expect here is `./build/$triple/ci-llvm/`, with the binaries in its `bin` -- cgit 1.4.1-3-g733a5 From f635f9d4e4448bbccca28a93e42ca52043edeb41 Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Wed, 23 Nov 2022 18:16:37 +0000 Subject: turn a comment into an actual doc comment --- src/bootstrap/native.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 48158d51e00..781a738a811 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -63,13 +63,13 @@ impl LdFlags { } } -// This returns whether we've already previously built LLVM. -// -// It's used to avoid busting caches during x.py check -- if we've already built -// LLVM, it's fine for us to not try to avoid doing so. -// -// This will return the llvm-config if it can get it (but it will not build it -// if not). +/// This returns whether we've already previously built LLVM. +/// +/// It's used to avoid busting caches during x.py check -- if we've already built +/// LLVM, it's fine for us to not try to avoid doing so. +/// +/// This will return the llvm-config if it can get it (but it will not build it +/// if not). pub fn prebuilt_llvm_config( builder: &Builder<'_>, target: TargetSelection, -- cgit 1.4.1-3-g733a5 From c73a46c6bff445230a922e6b5e3018f87443bcbe Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Tue, 22 Nov 2022 22:38:53 +0000 Subject: bump download-ci-llvm-stamp --- src/bootstrap/download-ci-llvm-stamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index d19a1ae95cf..94630e40f3c 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/102790 +Last change is for: https://github.com/rust-lang/rust/pull/104748 -- cgit 1.4.1-3-g733a5 From e0f5c6da1df52a64b80753bf33bae3176729ae52 Mon Sep 17 00:00:00 2001 From: Rémy Rakic Date: Tue, 3 Jan 2023 20:21:49 +0000 Subject: ensure lld's step unconditionally for RustDev component --- src/bootstrap/dist.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 479bfeb8e85..68215790bed 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2067,11 +2067,8 @@ impl Step for RustDev { builder.ensure(crate::native::Llvm { target }); - // If the config has LLD enabled, ensure its step. We'll we want to package it, and use it - // in download-ci-llvm. - if builder.config.lld_enabled { - builder.ensure(crate::native::Lld { target }); - } + // We want to package `lld` to use it with `download-ci-llvm`. + builder.ensure(crate::native::Lld { target }); let src_bindir = builder.llvm_out(target).join("bin"); // If updating this list, you likely want to change -- cgit 1.4.1-3-g733a5 From 077fae94a175408d8d7624af8a9fb96ce71bf3c3 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 30 Dec 2022 05:09:09 +0000 Subject: Add note about wrapping in braces Previously it was not clear why this errored or if it was even supported, as there was no diagnostic that suggested wrapping it in braces. Thus, add a simple diagnostic that suggests wrapping enum variants in braces. --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 29 ++++++++++++------- .../ui/const-generics/assoc_const_eq_diagnostic.rs | 18 ++++++++++++ .../assoc_const_eq_diagnostic.stderr | 33 ++++++++++++++++++++++ 3 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/const-generics/assoc_const_eq_diagnostic.rs create mode 100644 src/test/ui/const-generics/assoc_const_eq_diagnostic.stderr diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index d7ab942665b..686db67e36d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1199,17 +1199,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; let expected = def_kind.descr(assoc_item_def_id); - let reported = tcx - .sess - .struct_span_err( + let mut err = tcx.sess.struct_span_err( + binding.span, + &format!("expected {expected} bound, found {got}"), + ); + err.span_note( + tcx.def_span(assoc_item_def_id), + &format!("{expected} defined here"), + ); + + if let hir::def::DefKind::AssocConst = def_kind + && let Some(t) = term.ty() && (t.is_enum() || t.references_error()) + && tcx.features().associated_const_equality { + err.span_suggestion( binding.span, - &format!("expected {expected} bound, found {got}"), - ) - .span_note( - tcx.def_span(assoc_item_def_id), - &format!("{expected} defined here"), - ) - .emit(); + "if equating a const, try wrapping with braces", + format!("{} = {{ const }}", binding.item_name), + Applicability::HasPlaceholders, + ); + } + let reported = err.emit(); term = match def_kind { hir::def::DefKind::AssocTy => { tcx.ty_error_with_guaranteed(reported).into() diff --git a/src/test/ui/const-generics/assoc_const_eq_diagnostic.rs b/src/test/ui/const-generics/assoc_const_eq_diagnostic.rs new file mode 100644 index 00000000000..4d0aaf88e40 --- /dev/null +++ b/src/test/ui/const-generics/assoc_const_eq_diagnostic.rs @@ -0,0 +1,18 @@ +#![feature(associated_const_equality)] + +pub enum Mode { + Cool, +} + +pub trait Parse { + const MODE: Mode; +} + +pub trait CoolStuff: Parse {} +//~^ ERROR expected associated constant bound +//~| ERROR expected type + +fn no_help() -> Mode::Cool {} +//~^ ERROR expected type, found variant + +fn main() {} diff --git a/src/test/ui/const-generics/assoc_const_eq_diagnostic.stderr b/src/test/ui/const-generics/assoc_const_eq_diagnostic.stderr new file mode 100644 index 00000000000..ba727ee0ea3 --- /dev/null +++ b/src/test/ui/const-generics/assoc_const_eq_diagnostic.stderr @@ -0,0 +1,33 @@ +error[E0573]: expected type, found variant `Mode::Cool` + --> $DIR/assoc_const_eq_diagnostic.rs:11:35 + | +LL | pub trait CoolStuff: Parse {} + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Mode` + +error[E0573]: expected type, found variant `Mode::Cool` + --> $DIR/assoc_const_eq_diagnostic.rs:15:17 + | +LL | fn no_help() -> Mode::Cool {} + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Mode` + +error: expected associated constant bound, found type + --> $DIR/assoc_const_eq_diagnostic.rs:11:28 + | +LL | pub trait CoolStuff: Parse {} + | ^^^^^^^^^^^^^^^^^ help: if equating a const, try wrapping with braces: `MODE = { const }` + | +note: associated constant defined here + --> $DIR/assoc_const_eq_diagnostic.rs:8:5 + | +LL | const MODE: Mode; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0573`. -- cgit 1.4.1-3-g733a5 From a0390463fc27b627a86682722aaa11ff567212b8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 27 Dec 2022 23:56:46 +0000 Subject: Suggest more impl Trait on `-> _` --- compiler/rustc_hir_analysis/src/collect.rs | 141 ++++++++++++++++++--------- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/future/future.rs | 1 + src/test/ui/fn/issue-80179.rs | 5 +- src/test/ui/fn/issue-80179.stderr | 8 +- src/test/ui/fn/suggest-return-closure.rs | 31 ++++++ src/test/ui/fn/suggest-return-closure.stderr | 30 ++++++ src/test/ui/fn/suggest-return-future.rs | 23 +++++ src/test/ui/fn/suggest-return-future.stderr | 21 ++++ 9 files changed, 207 insertions(+), 54 deletions(-) create mode 100644 src/test/ui/fn/suggest-return-closure.rs create mode 100644 src/test/ui/fn/suggest-return-closure.stderr create mode 100644 src/test/ui/fn/suggest-return-future.rs create mode 100644 src/test/ui/fn/suggest-return-future.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1ff7429e415..53a58df0916 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -17,6 +17,7 @@ use crate::astconv::AstConv; use crate::check::intrinsic::intrinsic_operation_unsafety; use crate::errors; +use hir::def::DefKind; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey}; @@ -24,8 +25,8 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericParamKind, Node}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter; use rustc_middle::ty::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; @@ -1195,12 +1196,11 @@ fn infer_return_ty_for_fn_sig<'tcx>( ty::ReErased => tcx.lifetimes.re_static, _ => r, }); - let fn_sig = ty::Binder::dummy(fn_sig); let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(ty); let mut diag = bad_placeholder(tcx, visitor.0, "return type"); - let ret_ty = fn_sig.skip_binder().output(); + let ret_ty = fn_sig.output(); if ret_ty.is_suggestable(tcx, false) { diag.span_suggestion( ty.span, @@ -1223,6 +1223,13 @@ fn infer_return_ty_for_fn_sig<'tcx>( Applicability::MachineApplicable, ); } + } else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, hir_id, def_id) { + diag.span_suggestion( + ty.span, + "replace with an appropriate return type", + sugg, + Applicability::MachineApplicable, + ); } else if ret_ty.is_closure() { // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds // to prevent the user from getting a papercut while trying to use the unique closure @@ -1232,17 +1239,10 @@ fn infer_return_ty_for_fn_sig<'tcx>( "for more information on `Fn` traits and closure types, see \ https://doc.rust-lang.org/book/ch13-01-closures.html", ); - } else if let Some(i_ty) = suggest_impl_iterator(tcx, ret_ty, ty.span, hir_id, def_id) { - diag.span_suggestion( - ty.span, - "replace with an appropriate return type", - format!("impl Iterator", i_ty), - Applicability::MachineApplicable, - ); } diag.emit(); - fn_sig + ty::Binder::dummy(fn_sig) } None => >::ty_of_fn( icx, @@ -1256,47 +1256,94 @@ fn infer_return_ty_for_fn_sig<'tcx>( } } -fn suggest_impl_iterator<'tcx>( +fn suggest_impl_trait<'tcx>( tcx: TyCtxt<'tcx>, ret_ty: Ty<'tcx>, span: Span, hir_id: hir::HirId, def_id: LocalDefId, -) -> Option> { - let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) else { return None; }; - let Some(iterator_item) = tcx.get_diagnostic_item(sym::IteratorItem) else { return None; }; - if !tcx - .infer_ctxt() - .build() - .type_implements_trait(iter_trait, [ret_ty], tcx.param_env(def_id)) - .must_apply_modulo_regions() - { - return None; - } - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new_in_snapshot(&infcx); - // Find the type of `Iterator::Item`. - let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; - let ty_var = infcx.next_ty_var(origin); - let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Projection( - ty::ProjectionPredicate { - projection_ty: tcx.mk_alias_ty(iterator_item, tcx.mk_substs([ret_ty.into()].iter())), - term: ty_var.into(), - }, - ))); - // Add `::Item = _` obligation. - ocx.register_obligation(crate::traits::Obligation::misc( - tcx, - span, - hir_id, - tcx.param_env(def_id), - projection, - )); - if ocx.select_where_possible().is_empty() - && let item_ty = infcx.resolve_vars_if_possible(ty_var) - && item_ty.is_suggestable(tcx, false) - { - return Some(item_ty); +) -> Option { + let format_as_assoc: fn(_, _, _, _, _) -> _ = + |tcx: TyCtxt<'tcx>, + _: ty::SubstsRef<'tcx>, + trait_def_id: DefId, + assoc_item_def_id: DefId, + item_ty: Ty<'tcx>| { + let trait_name = tcx.item_name(trait_def_id); + let assoc_name = tcx.item_name(assoc_item_def_id); + Some(format!("impl {trait_name}<{assoc_name} = {item_ty}>")) + }; + let format_as_parenthesized: fn(_, _, _, _, _) -> _ = + |tcx: TyCtxt<'tcx>, + substs: ty::SubstsRef<'tcx>, + trait_def_id: DefId, + _: DefId, + item_ty: Ty<'tcx>| { + let trait_name = tcx.item_name(trait_def_id); + let args_tuple = substs.type_at(1); + let ty::Tuple(types) = *args_tuple.kind() else { return None; }; + if !types.is_suggestable(tcx, false) { + return None; + } + let maybe_ret = + if item_ty.is_unit() { String::new() } else { format!(" -> {item_ty}") }; + Some(format!( + "impl {trait_name}({}){maybe_ret}", + types.iter().map(|ty| ty.to_string()).collect::>().join(", ") + )) + }; + + for (trait_def_id, assoc_item_def_id, formatter) in [ + ( + tcx.get_diagnostic_item(sym::Iterator), + tcx.get_diagnostic_item(sym::IteratorItem), + format_as_assoc, + ), + ( + tcx.lang_items().future_trait(), + tcx.get_diagnostic_item(sym::FutureOutput), + format_as_assoc, + ), + (tcx.lang_items().fn_trait(), tcx.lang_items().fn_once_output(), format_as_parenthesized), + ( + tcx.lang_items().fn_mut_trait(), + tcx.lang_items().fn_once_output(), + format_as_parenthesized, + ), + ( + tcx.lang_items().fn_once_trait(), + tcx.lang_items().fn_once_output(), + format_as_parenthesized, + ), + ] { + let Some(trait_def_id) = trait_def_id else { continue; }; + let Some(assoc_item_def_id) = assoc_item_def_id else { continue; }; + if tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy { + continue; + } + let param_env = tcx.param_env(def_id); + let infcx = tcx.infer_ctxt().build(); + let substs = ty::InternalSubsts::for_item(tcx, trait_def_id, |param, _| { + if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(span, param) } + }); + if !infcx.type_implements_trait(trait_def_id, substs, param_env).must_apply_modulo_regions() + { + continue; + } + let ocx = ObligationCtxt::new_in_snapshot(&infcx); + let item_ty = ocx.normalize( + &ObligationCause::misc(span, hir_id), + param_env, + tcx.mk_projection(assoc_item_def_id, substs), + ); + // FIXME(compiler-errors): We may benefit from resolving regions here. + if ocx.select_where_possible().is_empty() + && let item_ty = infcx.resolve_vars_if_possible(item_ty) + && item_ty.is_suggestable(tcx, false) + && let Some(sugg) = formatter(tcx, infcx.resolve_vars_if_possible(substs), trait_def_id, assoc_item_def_id, item_ty) + { + return Some(sugg); + } } None } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 85510fa2c66..5d5f8d6d654 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -193,6 +193,7 @@ symbols! { FromIterator, FromResidual, Future, + FutureOutput, FxHashMap, FxHashSet, GlobalAlloc, diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index f29d3e1e98b..8c7111cb3ff 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -37,6 +37,7 @@ use crate::task::{Context, Poll}; pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] + #[rustc_diagnostic_item = "FutureOutput"] type Output; /// Attempt to resolve the future to a final value, registering diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs index fcef6f1b60e..bea8deadc89 100644 --- a/src/test/ui/fn/issue-80179.rs +++ b/src/test/ui/fn/issue-80179.rs @@ -18,9 +18,8 @@ fn returns_fn_ptr() -> _ { fn returns_closure() -> _ { //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] //~| NOTE not allowed in type signatures -//~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound -//~| NOTE for more information on `Fn` traits and closure types, see -// https://doc.rust-lang.org/book/ch13-01-closures.html +//~| HELP replace with an appropriate return type +//~| SUGGESTION impl Fn() -> i32 || 0 } diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr index 2ca4ae982d9..dff8252b371 100644 --- a/src/test/ui/fn/issue-80179.stderr +++ b/src/test/ui/fn/issue-80179.stderr @@ -11,10 +11,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/issue-80179.rs:18:25 | LL | fn returns_closure() -> _ { - | ^ not allowed in type signatures - | - = help: consider using an `Fn`, `FnMut`, or `FnOnce` trait bound - = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl Fn() -> i32` error: aborting due to 2 previous errors diff --git a/src/test/ui/fn/suggest-return-closure.rs b/src/test/ui/fn/suggest-return-closure.rs new file mode 100644 index 00000000000..1b9094cea38 --- /dev/null +++ b/src/test/ui/fn/suggest-return-closure.rs @@ -0,0 +1,31 @@ +fn fn_once() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + //~| NOTE not allowed in type signatures + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl FnOnce() + let x = String::new(); + || { + drop(x); + } +} + +fn fn_mut() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + //~| NOTE not allowed in type signatures + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl FnMut(char) + let x = String::new(); + |c| { + x.push(c); + } +} + +fn fun() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + //~| NOTE not allowed in type signatures + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl Fn() -> i32 + || 1i32 +} + +fn main() {} diff --git a/src/test/ui/fn/suggest-return-closure.stderr b/src/test/ui/fn/suggest-return-closure.stderr new file mode 100644 index 00000000000..f4b2c7f5274 --- /dev/null +++ b/src/test/ui/fn/suggest-return-closure.stderr @@ -0,0 +1,30 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-return-closure.rs:1:17 + | +LL | fn fn_once() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl FnOnce()` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-return-closure.rs:12:16 + | +LL | fn fn_mut() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl FnMut(char)` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-return-closure.rs:23:13 + | +LL | fn fun() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl Fn() -> i32` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/fn/suggest-return-future.rs b/src/test/ui/fn/suggest-return-future.rs new file mode 100644 index 00000000000..750740d9426 --- /dev/null +++ b/src/test/ui/fn/suggest-return-future.rs @@ -0,0 +1,23 @@ +// edition: 2021 + +async fn a() -> i32 { + 0 +} + +fn foo() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + //~| NOTE not allowed in type signatures + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl Future + a() +} + +fn bar() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + //~| NOTE not allowed in type signatures + //~| HELP replace with an appropriate return type + //~| SUGGESTION impl Future + async { a().await } +} + +fn main() {} diff --git a/src/test/ui/fn/suggest-return-future.stderr b/src/test/ui/fn/suggest-return-future.stderr new file mode 100644 index 00000000000..a4c8b5d8c4b --- /dev/null +++ b/src/test/ui/fn/suggest-return-future.stderr @@ -0,0 +1,21 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-return-future.rs:7:13 + | +LL | fn foo() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl Future` + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/suggest-return-future.rs:15:13 + | +LL | fn bar() -> _ { + | ^ + | | + | not allowed in type signatures + | help: replace with an appropriate return type: `impl Future` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. -- cgit 1.4.1-3-g733a5 From 89086f7d36e3a692b48cae8a408057734f044567 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 4 Jan 2023 00:26:53 +0000 Subject: Restore Fn trait note --- compiler/rustc_hir_analysis/src/collect.rs | 6 +++--- src/test/ui/fn/issue-80179.rs | 1 + src/test/ui/fn/issue-80179.stderr | 2 ++ src/test/ui/fn/suggest-return-closure.rs | 3 +++ src/test/ui/fn/suggest-return-closure.stderr | 10 ++++++++-- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 53a58df0916..cf847047c90 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1231,10 +1231,10 @@ fn infer_return_ty_for_fn_sig<'tcx>( Applicability::MachineApplicable, ); } else if ret_ty.is_closure() { - // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds - // to prevent the user from getting a papercut while trying to use the unique closure - // syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`). diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound"); + } + // Also note how `Fn` traits work just in case! + if ret_ty.is_closure() { diag.note( "for more information on `Fn` traits and closure types, see \ https://doc.rust-lang.org/book/ch13-01-closures.html", diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs index bea8deadc89..35e39bebb29 100644 --- a/src/test/ui/fn/issue-80179.rs +++ b/src/test/ui/fn/issue-80179.rs @@ -20,6 +20,7 @@ fn returns_closure() -> _ { //~| NOTE not allowed in type signatures //~| HELP replace with an appropriate return type //~| SUGGESTION impl Fn() -> i32 +//~| NOTE for more information on `Fn` traits and closure types || 0 } diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr index dff8252b371..f5d6c44db75 100644 --- a/src/test/ui/fn/issue-80179.stderr +++ b/src/test/ui/fn/issue-80179.stderr @@ -15,6 +15,8 @@ LL | fn returns_closure() -> _ { | | | not allowed in type signatures | help: replace with an appropriate return type: `impl Fn() -> i32` + | + = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error: aborting due to 2 previous errors diff --git a/src/test/ui/fn/suggest-return-closure.rs b/src/test/ui/fn/suggest-return-closure.rs index 1b9094cea38..33daa1ea0b4 100644 --- a/src/test/ui/fn/suggest-return-closure.rs +++ b/src/test/ui/fn/suggest-return-closure.rs @@ -3,6 +3,7 @@ fn fn_once() -> _ { //~| NOTE not allowed in type signatures //~| HELP replace with an appropriate return type //~| SUGGESTION impl FnOnce() + //~| NOTE for more information on `Fn` traits and closure types let x = String::new(); || { drop(x); @@ -14,6 +15,7 @@ fn fn_mut() -> _ { //~| NOTE not allowed in type signatures //~| HELP replace with an appropriate return type //~| SUGGESTION impl FnMut(char) + //~| NOTE for more information on `Fn` traits and closure types let x = String::new(); |c| { x.push(c); @@ -25,6 +27,7 @@ fn fun() -> _ { //~| NOTE not allowed in type signatures //~| HELP replace with an appropriate return type //~| SUGGESTION impl Fn() -> i32 + //~| NOTE for more information on `Fn` traits and closure types || 1i32 } diff --git a/src/test/ui/fn/suggest-return-closure.stderr b/src/test/ui/fn/suggest-return-closure.stderr index f4b2c7f5274..341044469ea 100644 --- a/src/test/ui/fn/suggest-return-closure.stderr +++ b/src/test/ui/fn/suggest-return-closure.stderr @@ -6,24 +6,30 @@ LL | fn fn_once() -> _ { | | | not allowed in type signatures | help: replace with an appropriate return type: `impl FnOnce()` + | + = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/suggest-return-closure.rs:12:16 + --> $DIR/suggest-return-closure.rs:13:16 | LL | fn fn_mut() -> _ { | ^ | | | not allowed in type signatures | help: replace with an appropriate return type: `impl FnMut(char)` + | + = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/suggest-return-closure.rs:23:13 + --> $DIR/suggest-return-closure.rs:25:13 | LL | fn fun() -> _ { | ^ | | | not allowed in type signatures | help: replace with an appropriate return type: `impl Fn() -> i32` + | + = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error: aborting due to 3 previous errors -- cgit 1.4.1-3-g733a5 From a313ef05a78330ac342cddf819214cb6414164e2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 3 Jan 2023 07:31:04 +0000 Subject: rename get_parent_node to parent_id --- .../src/diagnostics/conflict_errors.rs | 2 +- .../src/diagnostics/mutability_errors.rs | 2 +- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 4 ++-- .../rustc_hir_analysis/src/collect/generics_of.rs | 4 ++-- .../rustc_hir_analysis/src/collect/lifetimes.rs | 2 +- .../src/collect/predicates_of.rs | 2 +- compiler/rustc_hir_analysis/src/collect/type_of.rs | 8 +++---- compiler/rustc_hir_typeck/src/_match.rs | 4 ++-- compiler/rustc_hir_typeck/src/callee.rs | 6 ++--- compiler/rustc_hir_typeck/src/coercion.rs | 6 ++--- compiler/rustc_hir_typeck/src/demand.rs | 24 ++++++++++---------- compiler/rustc_hir_typeck/src/expr.rs | 8 +++---- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 4 ++-- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 19 ++++++++-------- compiler/rustc_hir_typeck/src/pat.rs | 4 ++-- .../src/infer/error_reporting/suggest.rs | 6 ++--- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/internal.rs | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 3 +-- compiler/rustc_lint/src/types.rs | 6 ++--- compiler/rustc_middle/src/hir/map/mod.rs | 26 +++++++++++----------- compiler/rustc_middle/src/lint.rs | 2 +- compiler/rustc_middle/src/ty/error.rs | 2 +- .../src/thir/pattern/check_match.rs | 12 +++++----- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_save_analysis/src/lib.rs | 2 +- .../src/traits/error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 20 ++++++++--------- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/tools/clippy/clippy_lints/src/escape.rs | 6 ++--- .../clippy_lints/src/index_refutable_slice.rs | 4 ++-- .../clippy_lints/src/loops/same_item_push.rs | 2 +- .../clippy/clippy_lints/src/manual_rem_euclid.rs | 2 +- .../src/matches/match_single_binding.rs | 6 ++--- .../src/mixed_read_write_in_expression.rs | 2 +- .../clippy_lints/src/needless_pass_by_value.rs | 2 +- .../clippy/clippy_lints/src/non_copy_const.rs | 2 +- .../clippy_lints/src/pass_by_ref_or_value.rs | 2 +- .../clippy/clippy_lints/src/unit_types/unit_arg.rs | 4 ++-- .../clippy/clippy_lints/src/unnecessary_wraps.rs | 2 +- .../src/utils/internal_lints/metadata_collector.rs | 2 +- .../utils/internal_lints/unnecessary_def_path.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 4 ++-- 48 files changed, 119 insertions(+), 121 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3c3cb8c6b9c..6b663ea3147 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -394,7 +394,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } let typeck = self.infcx.tcx.typeck(self.mir_def_id()); - let hir_id = hir.get_parent_node(expr.hir_id); + let hir_id = hir.parent_id(expr.hir_id); if let Some(parent) = hir.find(hir_id) { let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6f6d1b01bd4..c022fb55a16 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1004,7 +1004,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let hir = self.infcx.tcx.hir(); let closure_id = self.mir_hir_id(); let closure_span = self.infcx.tcx.def_span(self.mir_def_id()); - let fn_call_id = hir.get_parent_node(closure_id); + let fn_call_id = hir.parent_id(closure_id); let node = hir.get(fn_call_id); let def_id = hir.enclosing_body_owner(fn_call_id); let mut look_at_return = true; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 034f06bb889..4f74dbe99e3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3460,7 +3460,7 @@ impl<'hir> Node<'hir> { /// ```ignore (illustrative) /// ctor /// .ctor_hir_id() - /// .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id))) + /// .and_then(|ctor_id| tcx.hir().find(tcx.hir().parent_id(ctor_id))) /// .and_then(|parent| parent.ident()) /// ``` pub fn ident(&self) -> Option { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index d7ab942665b..93b91b3c9c6 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2936,7 +2936,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) = hir.get(fn_hir_id) else { return None }; let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) = - hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") }; + hir.get(hir.parent_id(fn_hir_id)) else { bug!("ImplItem should have Impl parent") }; let trait_ref = self.instantiate_mono_trait_ref( i.of_trait.as_ref()?, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1ff7429e415..fb732d7f945 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -212,7 +212,7 @@ pub(crate) fn placeholder_type_error_diag<'tcx>( is_fn = true; // Check if parent is const or static - let parent_id = tcx.hir().get_parent_node(hir_ty.hir_id); + let parent_id = tcx.hir().parent_id(hir_ty.hir_id); let parent_node = tcx.hir().get(parent_id); is_const_or_static = matches!( @@ -1108,7 +1108,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => { // Do not try to infer the return type for a impl method coming from a trait if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = - tcx.hir().get(tcx.hir().get_parent_node(hir_id)) + tcx.hir().get(tcx.hir().parent_id(hir_id)) && i.of_trait.is_some() { >::ty_of_fn( diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index cb4c35c0ce1..8ff96869b55 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -103,7 +103,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // `min_const_generics`. Some(parent_def_id.to_def_id()) } else { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); match parent_node { // HACK(eddyb) this provides the correct generics for repeat // expressions' count (i.e. `N` in `[x; N]`), and explicit @@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // provide junk type parameter defs for const blocks. if let Node::AnonConst(_) = node { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node { params.push(ty::GenericParamDef { index: next_index(), diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index fb519d6731d..0a1188c16a8 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -682,7 +682,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); // Ensure that the parent of the def is an item, not HRTB - let parent_id = self.tcx.hir().get_parent_node(hir_id); + let parent_id = self.tcx.hir().parent_id(hir_id); if !parent_id.is_owner() { struct_span_err!( self.tcx.sess, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 0943350e2d4..8412b7418b3 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -270,7 +270,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP // We create bi-directional Outlives predicates between the original // and the duplicated parameter, to ensure that they do not get out of sync. if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { - let opaque_ty_id = tcx.hir().get_parent_node(hir_id); + let opaque_ty_id = tcx.hir().parent_id(hir_id); let opaque_ty_node = tcx.hir().get(opaque_ty_id); let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { bug!("unexpected {opaque_ty_node:?}") diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 4bd55a54831..1c8acf6590d 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -28,7 +28,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< _ => return None, }; - let parent_node_id = tcx.hir().get_parent_node(hir_id); + let parent_node_id = tcx.hir().parent_id(hir_id); let parent_node = tcx.hir().get(parent_node_id); let (generics, arg_idx) = match parent_node { @@ -402,7 +402,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } Node::AnonConst(_) => { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); match parent_node { Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) @@ -445,7 +445,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .. }, ) if let Node::TraitRef(trait_ref) = - tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + tcx.hir().get(tcx.hir().parent_id(binding_id)) && e.hir_id == hir_id => { let Some(trait_def_id) = trait_ref.trait_def_id() else { @@ -472,7 +472,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::TypeBinding( binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. }, ) if let Node::TraitRef(trait_ref) = - tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + tcx.hir().get(tcx.hir().parent_id(binding_id)) && let Some((idx, _)) = gen_args.args.iter().enumerate().find(|(_, arg)| { if let GenericArg::Const(ct) = arg { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index ab12cae4e2b..7659b2d0a0b 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -289,7 +289,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> { let node = { - let rslt = self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(hir_id)); + let rslt = self.tcx.hir().parent_id(self.tcx.hir().parent_id(hir_id)); self.tcx.hir().get(rslt) }; if let hir::Node::Block(block) = node { @@ -297,7 +297,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let parent = self .tcx .hir() - .get(self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(block.hir_id))); + .get(self.tcx.hir().parent_id(self.tcx.hir().parent_id(block.hir_id))); if let (Some(expr), hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })) = (&block.expr, parent) { diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 829913d278d..2cb976f718c 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -288,7 +288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_span: Span, ) { let hir = self.tcx.hir(); - let parent_hir_id = hir.get_parent_node(hir_id); + let parent_hir_id = hir.parent_id(hir_id); let parent_node = hir.get(parent_hir_id); if let ( hir::Node::Expr(hir::Expr { @@ -303,7 +303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // Actually need to unwrap a few more layers of HIR to get to // the _real_ closure... - let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id)); + let async_closure = hir.parent_id(hir.parent_id(parent_hir_id)); if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }), .. @@ -336,7 +336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr: &'tcx hir::Expr<'tcx>, callee_expr: &'tcx hir::Expr<'tcx>, ) -> bool { - let hir_id = self.tcx.hir().get_parent_node(call_expr.hir_id); + let hir_id = self.tcx.hir().parent_id(call_expr.hir_id); let parent_node = self.tcx.hir().get(hir_id); if let ( hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }), diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 3fb14e31ea1..9e91a3f9076 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1547,7 +1547,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err.span_label(cause.span, "return type is not `()`"); } ObligationCauseCode::BlockTailExpression(blk_id) => { - let parent_id = fcx.tcx.hir().get_parent_node(blk_id); + let parent_id = fcx.tcx.hir().parent_id(blk_id); err = self.report_return_mismatched_types( cause, expected, @@ -1578,7 +1578,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { None, ); if !fcx.tcx.features().unsized_locals { - let id = fcx.tcx.hir().get_parent_node(id); + let id = fcx.tcx.hir().parent_id(id); unsized_return = self.is_return_ty_unsized(fcx, id); } } @@ -1668,7 +1668,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut pointing_at_return_type = false; let mut fn_output = None; - let parent_id = fcx.tcx.hir().get_parent_node(id); + let parent_id = fcx.tcx.hir().parent_id(id); let parent = fcx.tcx.hir().get(parent_id); if let Some(expr) = expression && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 1360383a75a..6f1af904c02 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -211,7 +211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, error: Option>, ) { - let parent = self.tcx.hir().get_parent_node(expr.hir_id); + let parent = self.tcx.hir().parent_id(expr.hir_id); match (self.tcx.hir().find(parent), error) { (Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _) if init.hir_id == expr.hir_id => @@ -258,7 +258,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Path { res: hir::def::Res::Local(hir_id), .. }, )) => { if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) { - let parent = self.tcx.hir().get_parent_node(pat.hir_id); + let parent = self.tcx.hir().parent_id(pat.hir_id); primary_span = pat.span; secondary_span = pat.span; match self.tcx.hir().find(parent) { @@ -326,7 +326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, error: Option>, ) { - let parent = self.tcx.hir().get_parent_node(expr.hir_id); + let parent = self.tcx.hir().parent_id(expr.hir_id); let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {return;}; let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. @@ -510,7 +510,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unroll desugaring, to make sure this works for `for` loops etc. loop { - parent = self.tcx.hir().get_parent_node(id); + parent = self.tcx.hir().parent_id(id); if let Some(parent_span) = self.tcx.hir().opt_span(parent) { if parent_span.find_ancestor_inside(expr.span).is_some() { // The parent node is part of the same span, so is the result of the @@ -790,12 +790,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - let local_parent = self.tcx.hir().get_parent_node(local_id); + let local_parent = self.tcx.hir().parent_id(local_id); let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) = self.tcx.hir().find(local_parent) else { return None; }; - let param_parent = self.tcx.hir().get_parent_node(*param_hir_id); + let param_parent = self.tcx.hir().parent_id(*param_hir_id); let Some(Node::Expr(hir::Expr { hir_id: expr_hir_id, kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }), @@ -804,7 +804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - let expr_parent = self.tcx.hir().get_parent_node(*expr_hir_id); + let expr_parent = self.tcx.hir().parent_id(*expr_hir_id); let hir = self.tcx.hir().find(expr_parent); let closure_params_len = closure_fn_decl.inputs.len(); let ( @@ -857,7 +857,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }?; - match hir.find(hir.get_parent_node(expr.hir_id))? { + match hir.find(hir.parent_id(expr.hir_id))? { Node::ExprField(field) => { if field.ident.name == local.name && field.is_shorthand { return Some(local.name); @@ -883,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Returns whether the given expression is an `else if`. pub(crate) fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool { if let hir::ExprKind::If(..) = expr.kind { - let parent_id = self.tcx.hir().get_parent_node(expr.hir_id); + let parent_id = self.tcx.hir().parent_id(expr.hir_id); if let Some(Node::Expr(hir::Expr { kind: hir::ExprKind::If(_, _, Some(else_expr)), .. @@ -1040,7 +1040,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(..), .. - })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id)) + })) = self.tcx.hir().find(self.tcx.hir().parent_id(expr.hir_id)) { if mutability.is_mut() { // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` @@ -1268,7 +1268,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut sugg = vec![]; if let Some(hir::Node::ExprField(field)) = - self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id)) + self.tcx.hir().find(self.tcx.hir().parent_id(expr.hir_id)) { // `expr` is a literal field for a struct, only suggest if appropriate if field.is_shorthand { @@ -1625,7 +1625,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [start, end], _, ) = expr.kind else { return; }; - let parent = self.tcx.hir().get_parent_node(expr.hir_id); + let parent = self.tcx.hir().parent_id(expr.hir_id); if let Some(hir::Node::ExprField(_)) = self.tcx.hir().find(parent) { // Ignore `Foo { field: a..Default::default() }` return; diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b8b4e873663..ee5578a8de6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -920,7 +920,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { original_expr_id: HirId, then: impl FnOnce(&hir::Expr<'_>), ) { - let mut parent = self.tcx.hir().get_parent_node(original_expr_id); + let mut parent = self.tcx.hir().parent_id(original_expr_id); while let Some(node) = self.tcx.hir().find(parent) { match node { hir::Node::Expr(hir::Expr { @@ -959,7 +959,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | hir::Node::TraitItem(_) | hir::Node::Crate(_) => break, _ => { - parent = self.tcx.hir().get_parent_node(parent); + parent = self.tcx.hir().parent_id(parent); } } } @@ -1083,7 +1083,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Do not suggest `if let x = y` as `==` is way more likely to be the intention. let hir = self.tcx.hir(); if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) = - hir.get(hir.get_parent_node(hir.get_parent_node(expr.hir_id))) + hir.get(hir.parent_id(hir.parent_id(expr.hir_id))) { err.span_suggestion_verbose( expr.span.shrink_to_lo(), @@ -2462,7 +2462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.span, "method, not a field"); let expr_is_call = if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) = - self.tcx.hir().get(self.tcx.hir().get_parent_node(expr.hir_id)) + self.tcx.hir().get(self.tcx.hir().parent_id(expr.hir_id)) { expr.hir_id == callee.hir_id } else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 150e917c739..a452dcc5014 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1436,7 +1436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut contained_in_place = false; while let hir::Node::Expr(parent_expr) = - self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id)) + self.tcx.hir().get(self.tcx.hir().parent_id(expr_id)) { match &parent_expr.kind { hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index d342d96a10f..fbb4da153b8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1803,7 +1803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: call_hir_id, span: call_span, .. - }) = hir.get(hir.get_parent_node(expr.hir_id)) + }) = hir.get(hir.parent_id(expr.hir_id)) && callee.hir_id == expr.hir_id { if self.closure_span_overlaps_error(error, *call_span) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 322e11c978f..066e98c7457 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results .borrow() .liberated_fn_sigs() - .get(self.tcx.hir().get_parent_node(self.body_id)) + .get(self.tcx.hir().parent_id(self.body_id)) .copied() } @@ -642,7 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check if the parent expression is a call to Pin::new. If it // is and we were expecting a Box, ergo Pin>, we // can suggest Box::pin. - let parent = self.tcx.hir().get_parent_node(expr.hir_id); + let parent = self.tcx.hir().parent_id(expr.hir_id); let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = self.tcx.hir().find(parent) else { return false; }; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b06927f9662..26d4e7d1df3 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -224,7 +224,7 @@ fn typeck_with_fallback<'tcx>( _ => None, }) .unwrap_or_else(|| match tcx.hir().get(id) { - Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(id)) { + Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) { Node::Expr(&hir::Expr { kind: hir::ExprKind::ConstBlock(ref anon_const), .. diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 71c3803e64f..ccee9b2554c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let sugg_span = if let SelfSource::MethodCall(expr) = source { // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing. - self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span + self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)).span } else { span }; @@ -334,7 +334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let SelfSource::MethodCall(rcvr_expr) = source { self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| { let call_expr = - self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(rcvr_expr.hir_id)); + self.tcx.hir().expect_expr(self.tcx.hir().parent_id(rcvr_expr.hir_id)); let probe = self.lookup_probe(item_name, output_ty, call_expr, ProbeScope::AllTraits); probe.is_ok() @@ -916,8 +916,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = "remove this method call"; let mut fallback_span = true; if let SelfSource::MethodCall(expr) = source { - let call_expr = - self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); + let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(expr.span) { err.span_suggestion(span, msg, "", Applicability::MachineApplicable); fallback_span = false; @@ -1270,7 +1269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else { - let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id)); + let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(item_name.span) { err.span_suggestion( @@ -1452,7 +1451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let filename = tcx.sess.source_map().span_to_filename(span); let parent_node = - self.tcx.hir().get(self.tcx.hir().get_parent_node(hir_id)); + self.tcx.hir().get(self.tcx.hir().parent_id(hir_id)); let msg = format!( "you must specify a type for this binding, like `{}`", concrete_type, @@ -1525,7 +1524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name }; visitor.visit_body(&body); - let parent = self.tcx.hir().get_parent_node(seg1.hir_id); + let parent = self.tcx.hir().parent_id(seg1.hir_id); if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) && let Some(expr) = visitor.result && let Some(self_ty) = self.node_ty_opt(expr.hir_id) @@ -1563,7 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Some((fields, substs)) = self.get_field_candidates_considering_privacy(span, actual, mod_id) { - let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); + let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)); let lang_items = self.tcx.lang_items(); let never_mention_traits = [ @@ -1633,7 +1632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let tcx = self.tcx; let SelfSource::MethodCall(expr) = source else { return; }; - let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id)); + let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id)); let ty::Adt(kind, substs) = actual.kind() else { return; }; match kind.adt_kind() { @@ -2594,7 +2593,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let parent = self.tcx.hir().get_parent_node(expr.hir_id); + let parent = self.tcx.hir().parent_id(expr.hir_id); if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) && let hir::ExprKind::MethodCall( hir::PathSegment { ident: method_name, .. }, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 28e959b7c6a..ff3b347ee01 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -692,7 +692,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; if let PatKind::Ref(inner, mutbl) = pat.kind && let PatKind::Binding(_, _, binding, ..) = inner.kind { - let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id); + let binding_parent_id = tcx.hir().parent_id(pat.hir_id); let binding_parent = tcx.hir().get(binding_parent_id); debug!(?inner, ?pat, ?binding_parent); @@ -936,7 +936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), ), ); - match self.tcx.hir().get(self.tcx.hir().get_parent_node(pat.hir_id)) { + match self.tcx.hir().get(self.tcx.hir().parent_id(pat.hir_id)) { hir::Node::PatField(..) => { e.span_suggestion_verbose( ident.span.shrink_to_hi(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 30ca9f41d6e..1ebfde16df9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -411,7 +411,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span: Span, ) { let hir = self.tcx.hir(); - let fn_hir_id = hir.get_parent_node(cause.body_id); + let fn_hir_id = hir.parent_id(cause.body_id); if let Some(node) = self.tcx.hir().find(fn_hir_id) && let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_sig, _, body_id), .. @@ -585,9 +585,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; local.pat.walk(&mut find_compatible_candidates); } - match hir.find(hir.get_parent_node(blk.hir_id)) { + match hir.find(hir.parent_id(blk.hir_id)) { Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { - match hir.find(hir.get_parent_node(*hir_id)) { + match hir.find(hir.parent_id(*hir_id)) { Some(hir::Node::Arm(hir::Arm { pat, .. })) => { pat.walk(&mut find_compatible_candidates); } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 10d8db5393d..3c2f2e9417a 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1526,7 +1526,7 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub { fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { let map = cx.tcx.hir(); - if matches!(map.get(map.get_parent_node(field.hir_id)), Node::Variant(_)) { + if matches!(map.get(map.parent_id(field.hir_id)), Node::Variant(_)) { return; } self.perform_lint(cx, "field", field.def_id, field.vis_span, false); diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 4f92661dbd3..96084a50984 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { TyKind::Path(QPath::Resolved(_, path)) => { if lint_ty_kind_usage(cx, &path.res) { let hir = cx.tcx.hir(); - let span = match hir.find(hir.get_parent_node(ty.hir_id)) { + let span = match hir.find(hir.parent_id(ty.hir_id)) { Some(Node::Pat(Pat { kind: PatKind::Path(qpath) diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 91fcd6d690e..a4182c121ed 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -444,8 +444,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) { if let PatKind::Binding(_, hid, ident, _) = p.kind { - if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) - { + if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().parent_id(hid)) { if !field.is_shorthand { // Only check if a new name has been introduced, to avoid warning // on both the struct definition and this pattern. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 8e27bc03c48..9b67ab38f90 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -127,9 +127,9 @@ fn lint_overflowing_range_endpoint<'tcx>( ) -> bool { // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. - let par_id = cx.tcx.hir().get_parent_node(expr.hir_id); + let par_id = cx.tcx.hir().parent_id(expr.hir_id); let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false }; - let field_par_id = cx.tcx.hir().get_parent_node(field.hir_id); + let field_par_id = cx.tcx.hir().parent_id(field.hir_id); let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false }; if !is_range_literal(struct_expr) { return false; @@ -404,7 +404,7 @@ fn lint_uint_literal<'tcx>( _ => bug!(), }; if lit_val < min || lit_val > max { - let parent_id = cx.tcx.hir().get_parent_node(e.hir_id); + let parent_id = cx.tcx.hir().parent_id(e.hir_id); if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) { match par_e.kind { hir::ExprKind::Cast(..) => { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index d799d3a5ad7..e00949d45a2 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -69,7 +69,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { } loop { // There are nodes that do not have entries, so we need to skip them. - let parent_id = self.map.get_parent_node(self.current_id); + let parent_id = self.map.parent_id(self.current_id); if parent_id == self.current_id { self.current_id = CRATE_HIR_ID; @@ -246,7 +246,7 @@ impl<'hir> Map<'hir> { }, Node::Variant(_) => DefKind::Variant, Node::Ctor(variant_data) => { - let ctor_of = match self.find(self.get_parent_node(hir_id)) { + let ctor_of = match self.find(self.parent_id(hir_id)) { Some(Node::Item(..)) => def::CtorOf::Struct, Some(Node::Variant(..)) => def::CtorOf::Variant, _ => unreachable!(), @@ -257,7 +257,7 @@ impl<'hir> Map<'hir> { } } Node::AnonConst(_) => { - let inline = match self.find(self.get_parent_node(hir_id)) { + let inline = match self.find(self.parent_id(hir_id)) { Some(Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })) if anon_const.hir_id == hir_id => true, @@ -312,7 +312,7 @@ impl<'hir> Map<'hir> { } #[track_caller] - pub fn get_parent_node(self, hir_id: HirId) -> HirId { + pub fn parent_id(self, hir_id: HirId) -> HirId { self.find_parent_node(hir_id) .unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id))) } @@ -414,7 +414,7 @@ impl<'hir> Map<'hir> { /// 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.get_parent_node(hir_id); + let parent = self.parent_id(hir_id); assert!(self.find(parent).map_or(false, |n| is_body_owner(n, hir_id)), "{hir_id:?}"); parent } @@ -642,21 +642,21 @@ 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 `get_parent_node`. + /// 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 { ParentHirIterator { current_id, map: self } } /// 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 `get_parent_node`. + /// 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).filter_map(move |id| Some((id, self.find(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 `get_parent_node`. + /// 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 } @@ -664,7 +664,7 @@ impl<'hir> Map<'hir> { /// Checks if the node is left-hand side of an assignment. pub fn is_lhs(self, id: HirId) -> bool { - match self.find(self.get_parent_node(id)) { + match self.find(self.parent_id(id)) { Some(Node::Expr(expr)) => match expr.kind { ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id, _ => false, @@ -892,7 +892,7 @@ impl<'hir> Map<'hir> { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::opt_span`. - Node::Ctor(..) => match self.find(self.get_parent_node(id))? { + Node::Ctor(..) => match self.find(self.parent_id(id))? { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -1021,7 +1021,7 @@ impl<'hir> Map<'hir> { ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()), _ => named_span(item.span, item.ident, None), }, - Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)), + Node::Ctor(_) => return self.opt_span(self.parent_id(hir_id)), Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), span, @@ -1063,7 +1063,7 @@ impl<'hir> Map<'hir> { Node::PatField(field) => field.span, Node::Arm(arm) => arm.span, Node::Block(block) => block.span, - Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)), + Node::Ctor(..) => self.span_with_body(self.parent_id(hir_id)), Node::Lifetime(lifetime) => lifetime.ident.span, Node::GenericParam(param) => param.span, Node::Infer(i) => i.span, @@ -1093,7 +1093,7 @@ impl<'hir> Map<'hir> { /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { - match self.get(self.get_parent_node(anon_const)) { + match self.get(self.parent_id(anon_const)) { Node::GenericParam(GenericParam { def_id: param_id, kind: GenericParamKind::Const { .. }, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 51df42f6d14..eb48b325e84 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -182,7 +182,7 @@ impl TyCtxt<'_> { if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { return id; } - let next = hir.get_parent_node(id); + let next = hir.parent_id(id); if next == id { bug!("lint traversal reached the root of the crate"); } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 14d07608a78..e1aa7fea441 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -457,7 +457,7 @@ impl<'tcx> TyCtxt<'tcx> { .def_id .as_local() .map(|id| hir.local_def_id_to_hir_id(id)) - .and_then(|id| self.hir().find(self.hir().get_parent_node(id))) + .and_then(|id| self.hir().find(self.hir().parent_id(id))) .as_ref() .and_then(|node| node.generics()) { 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 a94d8d6c643..e7ee0d9e908 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -247,14 +247,14 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { fn check_let_chain(&mut self, cx: &mut MatchCheckCtxt<'p, 'tcx>, pat_id: HirId) -> bool { let hir = self.tcx.hir(); - let parent = hir.get_parent_node(pat_id); + let parent = hir.parent_id(pat_id); // First, figure out if the given pattern is part of a let chain, // and if so, obtain the top node of the chain. let mut top = parent; let mut part_of_chain = false; loop { - let new_top = hir.get_parent_node(top); + let new_top = hir.parent_id(top); if let hir::Node::Expr( hir::Expr { kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs), @@ -1054,7 +1054,7 @@ pub enum LetSource { fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource { let hir = tcx.hir(); - let parent = hir.get_parent_node(pat_id); + let parent = hir.parent_id(pat_id); let_source_parent(tcx, parent, Some(pat_id)) } @@ -1073,7 +1073,7 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option) -> L _ => {} } - let parent_parent = hir.get_parent_node(parent); + let parent_parent = hir.parent_id(parent); let parent_parent_node = hir.get(parent_parent); match parent_parent_node { hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => { @@ -1085,8 +1085,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option) -> L _ => {} } - let parent_parent_parent = hir.get_parent_node(parent_parent); - let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent); + let parent_parent_parent = hir.parent_id(parent_parent); + let parent_parent_parent_parent = hir.parent_id(parent_parent_parent); let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent); if let hir::Node::Expr(hir::Expr { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 72d38aeac7a..ef241c5398d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -2141,7 +2141,7 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { if !old_error_set_ancestry.insert(id) { break; } - let parent = tcx.hir().get_parent_node(id); + let parent = tcx.hir().parent_id(id); if parent == id { break; } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 6afd5fe5a7f..a8d82de02b7 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -600,7 +600,7 @@ impl<'tcx> SaveContext<'tcx> { if seg.res != Res::Err { seg.res } else { - let parent_node = self.tcx.hir().get_parent_node(hir_id); + let parent_node = self.tcx.hir().parent_id(hir_id); self.get_path_res(parent_node) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 9bfe527647d..b0a730c8ad1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -117,7 +117,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Some(if movability.is_some() { "an async closure" } else { "a closure" }) }), hir::Node::Expr(hir::Expr { .. }) => { - let parent_hid = hir.get_parent_node(hir_id); + let parent_hid = hir.parent_id(hir_id); if parent_hid != hir_id { self.describe_enclosure(parent_hid) } else { None } } _ => None, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7c21a1047bc..bf5e06268e9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -838,7 +838,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let hir = self.tcx.hir(); let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?); - let parent_node = hir.get_parent_node(hir_id); + let parent_node = hir.parent_id(hir_id); match hir.find(parent_node) { Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => { get_name(err, &local.pat.kind) @@ -1421,7 +1421,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { let hir = self.tcx.hir(); - let parent_node = hir.get_parent_node(obligation.cause.body_id); + let parent_node = hir.parent_id(obligation.cause.body_id); let node = hir.find(parent_node); if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node && let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind @@ -1458,7 +1458,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option { let hir = self.tcx.hir(); - let parent_node = hir.get_parent_node(obligation.cause.body_id); + let parent_node = hir.parent_id(obligation.cause.body_id); let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find(parent_node) else { return None; }; @@ -1483,7 +1483,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } let hir = self.tcx.hir(); - let fn_hir_id = hir.get_parent_node(obligation.cause.body_id); + let fn_hir_id = hir.parent_id(obligation.cause.body_id); let node = hir.find(fn_hir_id); let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), @@ -1695,7 +1695,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } let hir = self.tcx.hir(); - let parent_node = hir.get_parent_node(obligation.cause.body_id); + let parent_node = hir.parent_id(obligation.cause.body_id); let node = hir.find(parent_node); if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) = node @@ -2291,7 +2291,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let expr = hir.expect_expr(expr_id); debug!("target_ty evaluated from {:?}", expr); - let parent = hir.get_parent_node(expr_id); + let parent = hir.parent_id(expr_id); if let Some(hir::Node::Expr(e)) = hir.find(parent) { let parent_span = hir.span(parent); let parent_did = parent.owner.to_def_id(); @@ -2512,7 +2512,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::VariableType(hir_id) => { - let parent_node = self.tcx.hir().get_parent_node(hir_id); + let parent_node = self.tcx.hir().parent_id(hir_id); match self.tcx.hir().find(parent_node) { Some(Node::Local(hir::Local { ty: Some(ty), .. })) => { err.span_suggestion_verbose( @@ -2992,7 +2992,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { span: Span, ) { let body_hir_id = obligation.cause.body_id; - let item_id = self.tcx.hir().get_parent_node(body_hir_id); + let item_id = self.tcx.hir().parent_id(body_hir_id); if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(self.tcx.hir().local_def_id(item_id)) @@ -3219,7 +3219,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) - && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id) + && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id) && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id) && let Some(binding_expr) = local.init { @@ -3287,7 +3287,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) - && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id) + && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id) && let Some(parent) = self.tcx.hir().find(parent_hir_id) { // We've reached the root of the method call chain... diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index e2d10f550c3..e17b8346c0e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -161,7 +161,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..), .. }) => { - let parent_hir_id = tcx.hir().get_parent_node(hir_id); + let parent_hir_id = tcx.hir().parent_id(hir_id); match tcx.hir().get(parent_hir_id) { hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 1d09adec12f..58b7b9829a1 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -131,7 +131,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { _ => return false, } - matches!(map.find(map.get_parent_node(id)), Some(Node::Param(_))) + matches!(map.find(map.parent_id(id)), Some(Node::Param(_))) } impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { @@ -156,8 +156,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { let map = &self.cx.tcx.hir(); if is_argument(*map, cmt.hir_id) { // Skip closure arguments - let parent_id = map.get_parent_node(cmt.hir_id); - if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) { + let parent_id = map.parent_id(cmt.hir_id); + if let Some(Node::Expr(..)) = map.find(map.parent_id(parent_id)) { return; } diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index cf35b1f175c..bdeddf44df7 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -251,7 +251,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { let map = cx.tcx.hir(); // Checking for slice indexing - let parent_id = map.get_parent_node(expr.hir_id); + let parent_id = map.parent_id(expr.hir_id); if let Some(hir::Node::Expr(parent_expr)) = map.find(parent_id); if let hir::ExprKind::Index(_, index_expr) = parent_expr.kind; if let Some((Constant::Int(index_value), _)) = constant(cx, cx.typeck_results(), index_expr); @@ -259,7 +259,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> { if index_value < max_suggested_slice; // Make sure that this slice index is read only - let maybe_addrof_id = map.get_parent_node(parent_id); + let maybe_addrof_id = map.parent_id(parent_id); if let Some(hir::Node::Expr(maybe_addrof_expr)) = map.find(maybe_addrof_id); if let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs index 07edee46fa6..540656a2cd9 100644 --- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs +++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs @@ -63,7 +63,7 @@ pub(super) fn check<'tcx>( if let Node::Pat(pat) = node; if let PatKind::Binding(bind_ann, ..) = pat.kind; if !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut)); - let parent_node = cx.tcx.hir().get_parent_node(hir_id); + let parent_node = cx.tcx.hir().parent_id(hir_id); if let Some(Node::Local(parent_let_expr)) = cx.tcx.hir().find(parent_node); if let Some(init) = parent_let_expr.init; then { diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs index 8d447c37150..494fde395e9 100644 --- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs +++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { && let Some(hir_id) = path_to_local(expr3) && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) { // Apply only to params or locals with annotated types - match cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { + match cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { Some(Node::Param(..)) => (), Some(Node::Local(local)) => { let Some(ty) = local.ty else { return }; diff --git a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs index c94a1f76330..abe9d231f4a 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs @@ -140,8 +140,8 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option { let map = &cx.tcx.hir(); - if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id)) { - return match map.find(map.get_parent_node(parent_arm_expr.hir_id)) { + if let Some(Node::Expr(parent_arm_expr)) = map.find(map.parent_id(ex.hir_id)) { + return match map.find(map.parent_id(parent_arm_expr.hir_id)) { Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local { span: parent_let_expr.span, pat_span: parent_let_expr.pat.span(), @@ -183,7 +183,7 @@ fn sugg_with_curlies<'a>( // If the parent is already an arm, and the body is another match statement, // we need curly braces around suggestion - let parent_node_id = cx.tcx.hir().get_parent_node(match_expr.hir_id); + let parent_node_id = cx.tcx.hir().parent_id(match_expr.hir_id); if let Node::Arm(arm) = &cx.tcx.hir().get(parent_node_id) { if let ExprKind::Match(..) = arm.body.kind { cbrace_end = format!("\n{indent}}}"); diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs index 321fa4b7f99..f0be7771bb1 100644 --- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs +++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs @@ -186,7 +186,7 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) { let map = &vis.cx.tcx.hir(); let mut cur_id = vis.write_expr.hir_id; loop { - let parent_id = map.get_parent_node(cur_id); + let parent_id = map.parent_id(cur_id); if parent_id == cur_id { break; } diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 2f0b7ce16e5..58c54280a23 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) 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 2a3bd4ee6ce..07fd321d69f 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -366,7 +366,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { let mut dereferenced_expr = expr; let mut needs_check_adjustment = true; loop { - let parent_id = cx.tcx.hir().get_parent_node(cur_expr.hir_id); + let parent_id = cx.tcx.hir().parent_id(cur_expr.hir_id); if parent_id == cur_expr.hir_id { break; } diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index 75add4ee4aa..f96a19b2723 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -299,7 +299,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs index ef9f740f704..ac4f8789a43 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs @@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { return; } let map = &cx.tcx.hir(); - let opt_parent_node = map.find(map.get_parent_node(expr.hir_id)); + let opt_parent_node = map.find(map.parent_id(expr.hir_id)); if_chain! { if let Some(hir::Node::Expr(parent_expr)) = opt_parent_node; if is_questionmark_desugar_marked_call(parent_expr); @@ -192,7 +192,7 @@ fn fmt_stmts_and_call( let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent))); // expr is not in a block statement or result expression position, wrap in a block - let parent_node = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(call_expr.hir_id)); + let parent_node = cx.tcx.hir().find(cx.tcx.hir().parent_id(call_expr.hir_id)); if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) { let block_indent = call_expr_indent + 4; stmts_and_call_snippet = diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs index 60b46854b4f..63f4f01b087 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs @@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { } // Abort if the method is implementing a trait or of it a trait method. - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs index 929544cd69d..a177ae507bb 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -1058,7 +1058,7 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) - fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> { let map = cx.tcx.hir(); - match map.find(map.get_parent_node(hir_id)) { + match map.find(map.parent_id(hir_id)) { Some(hir::Node::Local(local)) => Some(local), Some(hir::Node::Pat(pattern)) => get_parent_local_hir_id(cx, pattern.hir_id), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 393988dbad3..7144363637a 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -219,7 +219,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option match cx.qpath_res(qpath, expr.hir_id) { Res::Local(hir_id) => { - let parent_id = cx.tcx.hir().get_parent_node(hir_id); + let parent_id = cx.tcx.hir().parent_id(hir_id); if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir().find(parent_id) { path_to_matched_type(cx, init) } else { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index d863609b6a7..63d0938169a 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -174,7 +174,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option< if_chain! { if let Some(Node::Pat(pat)) = hir.find(hir_id); if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..)); - let parent = hir.get_parent_node(hir_id); + let parent = hir.parent_id(hir_id); if let Some(Node::Local(local)) = hir.find(parent); then { return local.init; @@ -2075,7 +2075,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { /// } /// ``` pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { false -- cgit 1.4.1-3-g733a5 From 6af339dbfac612c13ae3811b70a066f6babc5e02 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 3 Jan 2023 07:31:33 +0000 Subject: rename find_parent_node to opt_parent_id --- compiler/rustc_const_eval/src/transform/check_consts/mod.rs | 2 +- .../src/structured_errors/wrong_number_of_generic_args.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../src/generator_interior/drop_ranges/record_consumed_borrow.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 4 ++-- compiler/rustc_middle/src/mir/mod.rs | 2 +- src/librustdoc/passes/check_doc_test_visibility.rs | 2 +- src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 655ec345ed3..0a90572d39e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -115,7 +115,7 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let local_def_id = def_id.expect_local(); let hir_id = tcx.local_def_id_to_hir_id(local_def_id); - let Some(parent) = tcx.hir().find_parent_node(hir_id) else { return false }; + let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false }; let parent_def = tcx.hir().get(parent); if !matches!( diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 4451db19f5c..3df8f776ede 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -716,7 +716,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { num = num_trait_generics_except_self, ); - if let Some(parent_node) = self.tcx.hir().find_parent_node(self.path_segment.hir_id) + if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id) && let Some(parent_node) = self.tcx.hir().find(parent_node) && let hir::Node::Expr(expr) = parent_node { match expr.kind { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index ee5578a8de6..7b66422cce6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -943,7 +943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) => { // Check if our original expression is a child of the condition of a while loop let expr_is_ancestor = std::iter::successors(Some(original_expr_id), |id| { - self.tcx.hir().find_parent_node(*id) + self.tcx.hir().opt_parent_id(*id) }) .take_while(|id| *id != parent) .any(|id| id == expr.hir_id); diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs index bfe95852aa7..472205be7b5 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -140,7 +140,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { diag_expr_id: HirId, ) { let hir = self.tcx.hir(); - let parent = match hir.find_parent_node(place_with_id.hir_id) { + let parent = match hir.opt_parent_id(place_with_id.hir_id) { Some(parent) => parent, None => place_with_id.hir_id, }; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e00949d45a2..65a49a5fe85 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -298,7 +298,7 @@ impl<'hir> Map<'hir> { /// Finds the id of the parent node to this one. /// /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`]. - pub fn find_parent_node(self, id: HirId) -> Option { + pub fn opt_parent_id(self, id: HirId) -> Option { if id.local_id == ItemLocalId::from_u32(0) { Some(self.tcx.hir_owner_parent(id.owner)) } else { @@ -313,7 +313,7 @@ impl<'hir> Map<'hir> { #[track_caller] pub fn parent_id(self, hir_id: HirId) -> HirId { - self.find_parent_node(hir_id) + self.opt_parent_id(hir_id) .unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id))) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a89e6566d56..14bdff4568f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2506,7 +2506,7 @@ impl<'tcx> ConstantKind<'tcx> { } let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let parent_substs = if let Some(parent_hir_id) = tcx.hir().find_parent_node(hir_id) { + let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) { if let Some(parent_did) = tcx.hir().opt_local_def_id(parent_hir_id) { InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) } else { diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 057d2fdd9d5..6aa2dda980c 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -82,7 +82,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) - let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.item_id.expect_def_id().expect_local()); // check if parent is trait impl - if let Some(parent_hir_id) = cx.tcx.hir().find_parent_node(hir_id) { + if let Some(parent_hir_id) = cx.tcx.hir().opt_parent_id(hir_id) { if let Some(parent_node) = cx.tcx.hir().find(parent_hir_id) { if matches!( parent_node, diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs index c8e54d7b8e0..27cc5a1c3f0 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs @@ -68,7 +68,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { let map = cx.tcx.hir(); if_chain! { - if let Some(parent_id) = map.find_parent_node(expr.hir_id); + if let Some(parent_id) = map.opt_parent_id(expr.hir_id); if let Some(parent) = map.find(parent_id); then { let expr = match parent { -- cgit 1.4.1-3-g733a5 From b1b19bd8519ec2645578ecfcc55a438324ee5908 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 3 Jan 2023 17:30:35 +0000 Subject: get_parent and find_parent --- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 2 +- .../rustc_hir_analysis/src/collect/generics_of.rs | 4 +- compiler/rustc_hir_analysis/src/collect/type_of.rs | 6 +- compiler/rustc_hir_typeck/src/_match.rs | 5 +- compiler/rustc_hir_typeck/src/demand.rs | 11 ++-- compiler/rustc_hir_typeck/src/expr.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- .../src/infer/error_reporting/suggest.rs | 69 +++++++++++----------- compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/internal.rs | 2 +- compiler/rustc_lint/src/nonstandard_style.rs | 2 +- compiler/rustc_lint/src/types.rs | 3 +- compiler/rustc_middle/src/hir/map/mod.rs | 18 ++++-- compiler/rustc_middle/src/ty/error.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 6 +- src/tools/clippy/clippy_lints/src/escape.rs | 4 +- .../clippy/clippy_lints/src/manual_rem_euclid.rs | 2 +- .../src/matches/match_single_binding.rs | 7 +-- .../clippy_lints/src/needless_pass_by_value.rs | 2 +- .../clippy_lints/src/pass_by_ref_or_value.rs | 2 +- .../clippy/clippy_lints/src/unit_types/unit_arg.rs | 4 +- .../clippy/clippy_lints/src/unnecessary_wraps.rs | 2 +- .../src/utils/internal_lints/metadata_collector.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 4 +- 29 files changed, 86 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4f74dbe99e3..bc897ed8112 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3460,7 +3460,7 @@ impl<'hir> Node<'hir> { /// ```ignore (illustrative) /// ctor /// .ctor_hir_id() - /// .and_then(|ctor_id| tcx.hir().find(tcx.hir().parent_id(ctor_id))) + /// .and_then(|ctor_id| tcx.hir().find_parent(ctor_id)) /// .and_then(|parent| parent.ident()) /// ``` pub fn ident(&self) -> Option { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 93b91b3c9c6..1b334f65b9e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2936,7 +2936,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) = hir.get(fn_hir_id) else { return None }; let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) = - hir.get(hir.parent_id(fn_hir_id)) else { bug!("ImplItem should have Impl parent") }; + hir.get_parent(fn_hir_id) else { bug!("ImplItem should have Impl parent") }; let trait_ref = self.instantiate_mono_trait_ref( i.of_trait.as_ref()?, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index fb732d7f945..86ee18c04ec 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1108,7 +1108,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => { // Do not try to infer the return type for a impl method coming from a trait if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = - tcx.hir().get(tcx.hir().parent_id(hir_id)) + tcx.hir().get_parent(hir_id) && i.of_trait.is_some() { >::ty_of_fn( diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 8ff96869b55..96221c3e3d8 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -103,7 +103,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // `min_const_generics`. Some(parent_def_id.to_def_id()) } else { - let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); + let parent_node = tcx.hir().get_parent(hir_id); match parent_node { // HACK(eddyb) this provides the correct generics for repeat // expressions' count (i.e. `N` in `[x; N]`), and explicit @@ -320,7 +320,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // provide junk type parameter defs for const blocks. if let Node::AnonConst(_) = node { - let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); + let parent_node = tcx.hir().get_parent(hir_id); if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node { params.push(ty::GenericParamDef { index: next_index(), diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 1c8acf6590d..1f9a9f80302 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -402,7 +402,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } Node::AnonConst(_) => { - let parent_node = tcx.hir().get(tcx.hir().parent_id(hir_id)); + let parent_node = tcx.hir().get_parent(hir_id); match parent_node { Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) @@ -445,7 +445,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .. }, ) if let Node::TraitRef(trait_ref) = - tcx.hir().get(tcx.hir().parent_id(binding_id)) + tcx.hir().get_parent(binding_id) && e.hir_id == hir_id => { let Some(trait_def_id) = trait_ref.trait_def_id() else { @@ -472,7 +472,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::TypeBinding( binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. }, ) if let Node::TraitRef(trait_ref) = - tcx.hir().get(tcx.hir().parent_id(binding_id)) + tcx.hir().get_parent(binding_id) && let Some((idx, _)) = gen_args.args.iter().enumerate().find(|(_, arg)| { if let GenericArg::Const(ct) = arg { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 7659b2d0a0b..71a469784cd 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -294,10 +294,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let hir::Node::Block(block) = node { // check that the body's parent is an fn - let parent = self - .tcx - .hir() - .get(self.tcx.hir().parent_id(self.tcx.hir().parent_id(block.hir_id))); + let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id)); if let (Some(expr), hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })) = (&block.expr, parent) { diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 6f1af904c02..9c6c53abf07 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -258,10 +258,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::Path { res: hir::def::Res::Local(hir_id), .. }, )) => { if let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(*hir_id) { - let parent = self.tcx.hir().parent_id(pat.hir_id); primary_span = pat.span; secondary_span = pat.span; - match self.tcx.hir().find(parent) { + match self.tcx.hir().find_parent(pat.hir_id) { Some(hir::Node::Local(hir::Local { ty: Some(ty), .. })) => { primary_span = ty.span; post_message = " type"; @@ -857,7 +856,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }?; - match hir.find(hir.parent_id(expr.hir_id))? { + match hir.find_parent(expr.hir_id)? { Node::ExprField(field) => { if field.ident.name == local.name && field.is_shorthand { return Some(local.name); @@ -1040,7 +1039,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(..), .. - })) = self.tcx.hir().find(self.tcx.hir().parent_id(expr.hir_id)) + })) = self.tcx.hir().find_parent(expr.hir_id) { if mutability.is_mut() { // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` @@ -1267,9 +1266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut sugg = vec![]; - if let Some(hir::Node::ExprField(field)) = - self.tcx.hir().find(self.tcx.hir().parent_id(expr.hir_id)) - { + if let Some(hir::Node::ExprField(field)) = self.tcx.hir().find_parent(expr.hir_id) { // `expr` is a literal field for a struct, only suggest if appropriate if field.is_shorthand { // This is a field literal diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7b66422cce6..631749fcc0f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1083,7 +1083,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Do not suggest `if let x = y` as `==` is way more likely to be the intention. let hir = self.tcx.hir(); if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) = - hir.get(hir.parent_id(hir.parent_id(expr.hir_id))) + hir.get_parent(hir.parent_id(expr.hir_id)) { err.span_suggestion_verbose( expr.span.shrink_to_lo(), @@ -2462,7 +2462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field.span, "method, not a field"); let expr_is_call = if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) = - self.tcx.hir().get(self.tcx.hir().parent_id(expr.hir_id)) + self.tcx.hir().get_parent(expr.hir_id) { expr.hir_id == callee.hir_id } else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index a452dcc5014..634688de01a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1435,9 +1435,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool { let mut contained_in_place = false; - while let hir::Node::Expr(parent_expr) = - self.tcx.hir().get(self.tcx.hir().parent_id(expr_id)) - { + while let hir::Node::Expr(parent_expr) = self.tcx.hir().get_parent(expr_id) { match &parent_expr.kind { hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => { if lhs.hir_id == expr_id { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index fbb4da153b8..3de0f7c6f65 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1803,7 +1803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: call_hir_id, span: call_span, .. - }) = hir.get(hir.parent_id(expr.hir_id)) + }) = hir.get_parent(expr.hir_id) && callee.hir_id == expr.hir_id { if self.closure_span_overlaps_error(error, *call_span) { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index ccee9b2554c..dd9ea59eefc 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1451,7 +1451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let filename = tcx.sess.source_map().span_to_filename(span); let parent_node = - self.tcx.hir().get(self.tcx.hir().parent_id(hir_id)); + self.tcx.hir().get_parent(hir_id); let msg = format!( "you must specify a type for this binding, like `{}`", concrete_type, diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ff3b347ee01..0143901f2d7 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -936,7 +936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), ), ); - match self.tcx.hir().get(self.tcx.hir().parent_id(pat.hir_id)) { + match self.tcx.hir().get_parent(pat.hir_id) { hir::Node::PatField(..) => { e.span_suggestion_verbose( ident.span.shrink_to_hi(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 1ebfde16df9..5b02956a106 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -585,45 +585,42 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; local.pat.walk(&mut find_compatible_candidates); } - match hir.find(hir.parent_id(blk.hir_id)) { - Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => { - match hir.find(hir.parent_id(*hir_id)) { - Some(hir::Node::Arm(hir::Arm { pat, .. })) => { - pat.walk(&mut find_compatible_candidates); - } - Some( - hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Fn(_, body), - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), - .. - }) - | hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(hir::Closure { body, .. }), - .. - }), - ) => { - for param in hir.body(*body).params { - param.pat.walk(&mut find_compatible_candidates); - } - } - Some(hir::Node::Expr(hir::Expr { - kind: - hir::ExprKind::If( - hir::Expr { kind: hir::ExprKind::Let(let_), .. }, - then_block, - _, - ), + match hir.find_parent(blk.hir_id) { + Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => match hir.find_parent(*hir_id) { + Some(hir::Node::Arm(hir::Arm { pat, .. })) => { + pat.walk(&mut find_compatible_candidates); + } + Some( + hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Fn(_, body), .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)), + .. + }) + | hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), .. - })) if then_block.hir_id == *hir_id => { - let_.pat.walk(&mut find_compatible_candidates); + }), + ) => { + for param in hir.body(*body).params { + param.pat.walk(&mut find_compatible_candidates); } - _ => {} } - } + Some(hir::Node::Expr(hir::Expr { + kind: + hir::ExprKind::If( + hir::Expr { kind: hir::ExprKind::Let(let_), .. }, + then_block, + _, + ), + .. + })) if then_block.hir_id == *hir_id => { + let_.pat.walk(&mut find_compatible_candidates); + } + _ => {} + }, _ => {} } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3c2f2e9417a..d58168ff377 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1526,7 +1526,7 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub { fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { let map = cx.tcx.hir(); - if matches!(map.get(map.parent_id(field.hir_id)), Node::Variant(_)) { + if matches!(map.get_parent(field.hir_id), Node::Variant(_)) { return; } self.perform_lint(cx, "field", field.def_id, field.vis_span, false); diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 96084a50984..48902cd0569 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { TyKind::Path(QPath::Resolved(_, path)) => { if lint_ty_kind_usage(cx, &path.res) { let hir = cx.tcx.hir(); - let span = match hir.find(hir.parent_id(ty.hir_id)) { + let span = match hir.find_parent(ty.hir_id) { Some(Node::Pat(Pat { kind: PatKind::Path(qpath) diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index a4182c121ed..f37d6e9a63d 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -444,7 +444,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase { fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) { if let PatKind::Binding(_, hid, ident, _) = p.kind { - if let hir::Node::PatField(field) = cx.tcx.hir().get(cx.tcx.hir().parent_id(hid)) { + if let hir::Node::PatField(field) = cx.tcx.hir().get_parent(hid) { if !field.is_shorthand { // Only check if a new name has been introduced, to avoid warning // on both the struct definition and this pattern. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 9b67ab38f90..fa415243ba0 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -129,8 +129,7 @@ fn lint_overflowing_range_endpoint<'tcx>( // which are represented as `ExprKind::Struct`. let par_id = cx.tcx.hir().parent_id(expr.hir_id); let Node::ExprField(field) = cx.tcx.hir().get(par_id) else { return false }; - let field_par_id = cx.tcx.hir().parent_id(field.hir_id); - let Node::Expr(struct_expr) = cx.tcx.hir().get(field_par_id) else { return false }; + let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false }; if !is_range_literal(struct_expr) { return false; }; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 65a49a5fe85..883554f959c 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -246,7 +246,7 @@ impl<'hir> Map<'hir> { }, Node::Variant(_) => DefKind::Variant, Node::Ctor(variant_data) => { - let ctor_of = match self.find(self.parent_id(hir_id)) { + let ctor_of = match self.find_parent(hir_id) { Some(Node::Item(..)) => def::CtorOf::Struct, Some(Node::Variant(..)) => def::CtorOf::Variant, _ => unreachable!(), @@ -257,7 +257,7 @@ impl<'hir> Map<'hir> { } } Node::AnonConst(_) => { - let inline = match self.find(self.parent_id(hir_id)) { + let inline = match self.find_parent(hir_id) { Some(Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })) if anon_const.hir_id == hir_id => true, @@ -317,6 +317,14 @@ impl<'hir> Map<'hir> { .unwrap_or_else(|| bug!("No parent for node {:?}", self.node_to_string(hir_id))) } + pub fn get_parent(self, hir_id: HirId) -> Node<'hir> { + self.get(self.parent_id(hir_id)) + } + + pub fn find_parent(self, hir_id: HirId) -> Option> { + self.find(self.opt_parent_id(hir_id)?) + } + /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. pub fn find(self, id: HirId) -> Option> { if id.local_id == ItemLocalId::from_u32(0) { @@ -664,7 +672,7 @@ impl<'hir> Map<'hir> { /// Checks if the node is left-hand side of an assignment. pub fn is_lhs(self, id: HirId) -> bool { - match self.find(self.parent_id(id)) { + match self.find_parent(id) { Some(Node::Expr(expr)) => match expr.kind { ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id, _ => false, @@ -892,7 +900,7 @@ impl<'hir> Map<'hir> { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::opt_span`. - Node::Ctor(..) => match self.find(self.parent_id(id))? { + Node::Ctor(..) => match self.find_parent(id)? { Node::Item(item) => Some(item.ident), Node::Variant(variant) => Some(variant.ident), _ => unreachable!(), @@ -1093,7 +1101,7 @@ impl<'hir> Map<'hir> { /// Returns the HirId of `N` in `struct Foo` when /// called with the HirId for the `{ ... }` anon const pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option { - match self.get(self.parent_id(anon_const)) { + match self.get_parent(anon_const) { Node::GenericParam(GenericParam { def_id: param_id, kind: GenericParamKind::Const { .. }, diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index e1aa7fea441..50554cf9a82 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -457,7 +457,7 @@ impl<'tcx> TyCtxt<'tcx> { .def_id .as_local() .map(|id| hir.local_def_id_to_hir_id(id)) - .and_then(|id| self.hir().find(self.hir().parent_id(id))) + .and_then(|id| self.hir().find_parent(id)) .as_ref() .and_then(|node| node.generics()) { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index bf5e06268e9..8c2c1828774 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -838,8 +838,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let hir = self.tcx.hir(); let hir_id = hir.local_def_id_to_hir_id(def_id.as_local()?); - let parent_node = hir.parent_id(hir_id); - match hir.find(parent_node) { + match hir.find_parent(hir_id) { Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => { get_name(err, &local.pat.kind) } @@ -3287,8 +3286,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id) - && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id) - && let Some(parent) = self.tcx.hir().find(parent_hir_id) + && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id) { // We've reached the root of the method call chain... if let hir::Node::Local(local) = parent diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 58b7b9829a1..dfb43893326 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -131,7 +131,7 @@ fn is_argument(map: rustc_middle::hir::map::Map<'_>, id: HirId) -> bool { _ => return false, } - matches!(map.find(map.parent_id(id)), Some(Node::Param(_))) + matches!(map.find_parent(id), Some(Node::Param(_))) } impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { @@ -157,7 +157,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { if is_argument(*map, cmt.hir_id) { // Skip closure arguments let parent_id = map.parent_id(cmt.hir_id); - if let Some(Node::Expr(..)) = map.find(map.parent_id(parent_id)) { + if let Some(Node::Expr(..)) = map.find_parent(parent_id) { return; } diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs index 494fde395e9..38f41d077c1 100644 --- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs +++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { && let Some(hir_id) = path_to_local(expr3) && let Some(Node::Pat(_)) = cx.tcx.hir().find(hir_id) { // Apply only to params or locals with annotated types - match cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { + match cx.tcx.hir().find_parent(hir_id) { Some(Node::Param(..)) => (), Some(Node::Local(local)) => { let Some(ty) = local.ty else { return }; diff --git a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs index abe9d231f4a..065a5c72621 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs @@ -140,8 +140,8 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option { let map = &cx.tcx.hir(); - if let Some(Node::Expr(parent_arm_expr)) = map.find(map.parent_id(ex.hir_id)) { - return match map.find(map.parent_id(parent_arm_expr.hir_id)) { + if let Some(Node::Expr(parent_arm_expr)) = map.find_parent(ex.hir_id) { + return match map.find_parent(parent_arm_expr.hir_id) { Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local { span: parent_let_expr.span, pat_span: parent_let_expr.pat.span(), @@ -183,8 +183,7 @@ fn sugg_with_curlies<'a>( // If the parent is already an arm, and the body is another match statement, // we need curly braces around suggestion - let parent_node_id = cx.tcx.hir().parent_id(match_expr.hir_id); - if let Node::Arm(arm) = &cx.tcx.hir().get(parent_node_id) { + if let Node::Arm(arm) = &cx.tcx.hir().get_parent(match_expr.hir_id) { if let ExprKind::Match(..) = arm.body.kind { cbrace_end = format!("\n{indent}}}"); // Fix body indent due to the match diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 58c54280a23..1249db5dc47 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index f96a19b2723..870a1c7d88d 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -299,7 +299,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } // Exclude non-inherent impls - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs index ac4f8789a43..dd120599c04 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs @@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { return; } let map = &cx.tcx.hir(); - let opt_parent_node = map.find(map.parent_id(expr.hir_id)); + let opt_parent_node = map.find_parent(expr.hir_id); if_chain! { if let Some(hir::Node::Expr(parent_expr)) = opt_parent_node; if is_questionmark_desugar_marked_call(parent_expr); @@ -192,7 +192,7 @@ fn fmt_stmts_and_call( let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent))); // expr is not in a block statement or result expression position, wrap in a block - let parent_node = cx.tcx.hir().find(cx.tcx.hir().parent_id(call_expr.hir_id)); + let parent_node = cx.tcx.hir().find_parent(call_expr.hir_id); if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) { let block_indent = call_expr_indent + 4; stmts_and_call_snippet = diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs index 63f4f01b087..84ec0d0fb1c 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs @@ -91,7 +91,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps { } // Abort if the method is implementing a trait or of it a trait method. - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { if matches!( item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..) diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs index a177ae507bb..c86f24cbd37 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -1058,7 +1058,7 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) - fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> { let map = cx.tcx.hir(); - match map.find(map.parent_id(hir_id)) { + match map.find_parent((hir_id)) { Some(hir::Node::Local(local)) => Some(local), Some(hir::Node::Pat(pattern)) => get_parent_local_hir_id(cx, pattern.hir_id), _ => None, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 63d0938169a..8290fe9ecb4 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1287,7 +1287,7 @@ pub fn contains_return(expr: &hir::Expr<'_>) -> bool { /// Gets the parent node, if any. pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option> { - tcx.hir().parent_iter(id).next().map(|(_, node)| node) + tcx.hir().find_parent(id) } /// Gets the parent expression, if any –- this is useful to constrain a lint. @@ -2075,7 +2075,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { /// } /// ``` pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool { - if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().parent_id(hir_id)) { + if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) { matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })) } else { false -- cgit 1.4.1-3-g733a5 From 7690fe3bc66cae219301368650317936f0d4e3a9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 10 Dec 2022 20:31:01 +0000 Subject: Simplify some iterator combinators --- .../src/diagnostics/conflict_errors.rs | 23 +++--- .../src/diagnostics/region_errors.rs | 50 ++++++------ compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_hir_typeck/src/lib.rs | 9 +-- .../rustc_hir_typeck/src/method/prelude2021.rs | 3 +- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +- compiler/rustc_hir_typeck/src/method/suggest.rs | 4 +- .../nice_region_error/static_impl_trait.rs | 91 +++++++++------------- compiler/rustc_lint/src/unused.rs | 27 +++---- compiler/rustc_macros/src/symbols/tests.rs | 3 +- compiler/rustc_resolve/src/ident.rs | 9 +-- 12 files changed, 91 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3c3cb8c6b9c..6d6ad199be3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -527,26 +527,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // that are *partially* initialized by assigning to a field of an uninitialized // binding. We differentiate between them for more accurate wording here. "isn't fully initialized" - } else if spans - .iter() - .filter(|i| { - // We filter these to avoid misleading wording in cases like the following, - // where `x` has an `init`, but it is in the same place we're looking at: - // ``` - // let x; - // x += 1; - // ``` - !i.contains(span) + } else if !spans.iter().any(|i| { + // We filter these to avoid misleading wording in cases like the following, + // where `x` has an `init`, but it is in the same place we're looking at: + // ``` + // let x; + // x += 1; + // ``` + !i.contains(span) // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` && !visitor .errors .iter() .map(|(sp, _)| *sp) .any(|sp| span < sp && !sp.contains(span)) - }) - .count() - == 0 - { + }) { show_assign_sugg = true; "isn't initialized" } else { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index bcc8afbfd95..631e147ce8c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -316,35 +316,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // obligation comes from the `impl`. Find that `impl` so that we can point // at it in the suggestion. let trait_did = trait_did.to_def_id(); - match tcx - .hir() - .trait_impls(trait_did) - .iter() - .filter_map(|&impl_did| { - match tcx.hir().get_if_local(impl_did.to_def_id()) { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) if trait_objects.iter().all(|did| { - // FIXME: we should check `self_ty` against the receiver - // type in the `UnifyReceiver` context, 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`. - // In that case, only the first one will get suggestions. - let mut traits = vec![]; - let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); - hir_v.visit_ty(self_ty); - !traits.is_empty() - }) => - { - Some(self_ty) - } - _ => None, + match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { + match tcx.hir().get_if_local(impl_did.to_def_id()) { + Some(Node::Item(Item { + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), + .. + })) if trait_objects.iter().all(|did| { + // FIXME: we should check `self_ty` against the receiver + // type in the `UnifyReceiver` context, 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`. + // In that case, only the first one will get suggestions. + let mut traits = vec![]; + let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); + hir_v.visit_ty(self_ty); + !traits.is_empty() + }) => + { + Some(self_ty) } - }) - .next() - { + _ => None, + } + }) { Some(self_ty) => Some((trait_item.ident, self_ty)), _ => None, } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index effb2de4827..a92242b2615 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1244,7 +1244,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { ) -> RValue<'gcc> { // FIXME(antoyo): remove when having a proper API. let gcc_func = unsafe { std::mem::transmute(func) }; - let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { + let call = if self.functions.borrow().values().any(|value| *value == gcc_func) { self.function_call(func, args, funclet) } else { diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 837708aeb0e..4424b31c054 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -253,7 +253,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> { let function: Function<'gcc> = unsafe { std::mem::transmute(value) }; - debug_assert!(self.functions.borrow().values().find(|value| **value == function).is_some(), + debug_assert!(self.functions.borrow().values().any(|value| *value == function), "{:?} ({:?}) is not a function", value, value.get_type()); function } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index b06927f9662..cecf3d3f1e0 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -240,10 +240,8 @@ fn typeck_with_fallback<'tcx>( }), Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. }) | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => { - let operand_ty = asm - .operands - .iter() - .filter_map(|(op, _op_sp)| match op { + let operand_ty = + asm.operands.iter().find_map(|(op, _op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => { @@ -259,8 +257,7 @@ fn typeck_with_fallback<'tcx>( })) } _ => None, - }) - .next(); + }); operand_ty.unwrap_or_else(fallback) } _ => fallback(), diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index dea14dd93d6..3d6c2119bea 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -341,8 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find an identifier with which this trait was imported (note that `_` doesn't count). let any_id = import_items .iter() - .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None }) - .next(); + .find_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None }); if let Some(any_id) = any_id { if any_id.name == Empty { // Glob import, so just use its name. diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 1afaae0e020..2daf1979ee5 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1111,7 +1111,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // a raw pointer !step.self_ty.references_error() && !step.from_unsafe_deref }) - .flat_map(|step| { + .find_map(|step| { let InferOk { value: self_ty, obligations: _ } = self .fcx .probe_instantiate_query_response( @@ -1147,7 +1147,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }) }) }) - .next() } /// For each type `T` in the step list, this attempts to find a method where diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 71c3803e64f..b04ef55a994 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -257,9 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx .inherent_impls(adt_def.did()) .iter() - .filter_map(|def_id| self.associated_value(*def_id, item_name)) - .count() - >= 1 + .any(|def_id| self.associated_value(*def_id, item_name).is_some()) } else { false } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9bd2202d260..58be91bc276 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -309,19 +309,12 @@ pub fn suggest_new_region_bound( let did = item_id.owner_id.to_def_id(); let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did)); - if let Some(span) = opaque - .bounds - .iter() - .filter_map(|arg| match arg { - GenericBound::Outlives(Lifetime { - res: LifetimeName::Static, - ident, - .. - }) => Some(ident.span), - _ => None, - }) - .next() - { + if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg { + GenericBound::Outlives(Lifetime { + res: LifetimeName::Static, ident, .. + }) => Some(ident.span), + _ => None, + }) { if let Some(explicit_static) = &explicit_static { err.span_suggestion_verbose( span, @@ -338,20 +331,14 @@ pub fn suggest_new_region_bound( Applicability::MaybeIncorrect, ); } - } else if opaque - .bounds - .iter() - .filter_map(|arg| match arg { - GenericBound::Outlives(Lifetime { ident, .. }) - if ident.name.to_string() == lifetime_name => - { - Some(ident.span) - } - _ => None, - }) - .next() - .is_some() - { + } else if opaque.bounds.iter().any(|arg| match arg { + GenericBound::Outlives(Lifetime { ident, .. }) + if ident.name.to_string() == lifetime_name => + { + true + } + _ => false, + }) { } else { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), @@ -428,35 +415,29 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // obligation comes from the `impl`. Find that `impl` so that we can point // at it in the suggestion. let trait_did = trait_did.to_def_id(); - match tcx - .hir() - .trait_impls(trait_did) - .iter() - .filter_map(|&impl_did| { - match tcx.hir().get_if_local(impl_did.to_def_id()) { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) if trait_objects.iter().all(|did| { - // FIXME: we should check `self_ty` against the receiver - // type in the `UnifyReceiver` context, 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`. - // In that case, only the first one will get suggestions. - let mut traits = vec![]; - let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); - hir_v.visit_ty(self_ty); - !traits.is_empty() - }) => - { - Some(self_ty) - } - _ => None, + match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { + match tcx.hir().get_if_local(impl_did.to_def_id()) { + Some(Node::Item(Item { + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), + .. + })) if trait_objects.iter().all(|did| { + // FIXME: we should check `self_ty` against the receiver + // type in the `UnifyReceiver` context, 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`. + // In that case, only the first one will get suggestions. + let mut traits = vec![]; + let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); + hir_v.visit_ty(self_ty); + !traits.is_empty() + }) => + { + Some(self_ty) } - }) - .next() - { + _ => None, + } + }) { Some(self_ty) => Some((trait_item.ident, self_ty)), _ => None, } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index a7a5234049f..bf1f150fc3b 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -256,7 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { cx.tcx, cx.tcx.explicit_item_bounds(def).iter().cloned(), ) - .filter_map(|obligation| { + .find_map(|obligation| { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait( ref poly_trait_predicate, @@ -270,22 +270,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } }) .map(|inner| MustUsePath::Opaque(Box::new(inner))) - .next() } - ty::Dynamic(binders, _, _) => binders - .iter() - .filter_map(|predicate| { - if let ty::ExistentialPredicate::Trait(ref trait_ref) = - predicate.skip_binder() - { - let def_id = trait_ref.def_id; - is_def_must_use(cx, def_id, span) - } else { - None - } - .map(|inner| MustUsePath::TraitObject(Box::new(inner))) - }) - .next(), + ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() + { + let def_id = trait_ref.def_id; + is_def_must_use(cx, def_id, span) + } else { + None + } + .map(|inner| MustUsePath::TraitObject(Box::new(inner))) + }), ty::Tuple(tys) => { let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind { debug_assert_eq!(elem_exprs.len(), tys.len()); diff --git a/compiler/rustc_macros/src/symbols/tests.rs b/compiler/rustc_macros/src/symbols/tests.rs index 842d2a97718..bd0c08a53c4 100644 --- a/compiler/rustc_macros/src/symbols/tests.rs +++ b/compiler/rustc_macros/src/symbols/tests.rs @@ -16,14 +16,13 @@ fn test_symbols() { let m: &syn::ItemMacro = file .items .iter() - .filter_map(|i| { + .find_map(|i| { if let syn::Item::Macro(m) = i { if m.mac.path == symbols_path { Some(m) } else { None } } else { None } }) - .next() .expect("did not find `symbols!` macro invocation."); let body_tokens = m.mac.tokens.clone(); diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 0c4b35b8833..e41fe325b81 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -820,13 +820,12 @@ impl<'a> Resolver<'a> { // binding if it exists. What we really want here is having two separate scopes in // a module - one for non-globs and one for globs, but until that's done use this // hack to avoid inconsistent resolution ICEs during import validation. - let binding = [resolution.binding, resolution.shadowed_glob] - .into_iter() - .filter_map(|binding| match (binding, ignore_binding) { + let binding = [resolution.binding, resolution.shadowed_glob].into_iter().find_map( + |binding| match (binding, ignore_binding) { (Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None, _ => binding, - }) - .next(); + }, + ); let Some(binding) = binding else { return Err((Determined, Weak::No)); }; -- cgit 1.4.1-3-g733a5 From 2baee88bdb6ebbfda067818f5f4194083c2a77c1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 27 Dec 2022 17:53:29 +0000 Subject: Address comments --- .../src/diagnostics/conflict_errors.rs | 12 +-- .../src/diagnostics/region_errors.rs | 63 +-------------- .../nice_region_error/static_impl_trait.rs | 92 ++++++++++------------ compiler/rustc_lint/src/unused.rs | 2 +- 4 files changed, 52 insertions(+), 117 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 6d6ad199be3..50cd13a2ccc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -535,12 +535,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // x += 1; // ``` !i.contains(span) - // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` - && !visitor - .errors - .iter() - .map(|(sp, _)| *sp) - .any(|sp| span < sp && !sp.contains(span)) + // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` + && !visitor + .errors + .iter() + .map(|(sp, _)| *sp) + .any(|sp| span < sp && !sp.contains(span)) }) { show_assign_sugg = true; "isn't initialized" diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 631e147ce8c..567a9814fcc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -4,9 +4,9 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, Item, ItemKind, Node}; use rustc_infer::infer::{ error_reporting::nice_region_error::{ self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params, @@ -291,65 +291,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { outlives_suggestion.add_suggestion(self); } - fn get_impl_ident_and_self_ty_from_trait( - &self, - def_id: DefId, - trait_objects: &FxIndexSet, - ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { - let tcx = self.infcx.tcx; - match tcx.hir().get_if_local(def_id) { - Some(Node::ImplItem(impl_item)) => { - match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id) - { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) => Some((impl_item.ident, self_ty)), - _ => None, - } - } - Some(Node::TraitItem(trait_item)) => { - let trait_did = tcx.hir().get_parent_item(trait_item.hir_id()); - match tcx.hir().find_by_def_id(trait_did.def_id) { - Some(Node::Item(Item { kind: ItemKind::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_did.to_def_id(); - match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { - match tcx.hir().get_if_local(impl_did.to_def_id()) { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) if trait_objects.iter().all(|did| { - // FIXME: we should check `self_ty` against the receiver - // type in the `UnifyReceiver` context, 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`. - // In that case, only the first one will get suggestions. - let mut traits = vec![]; - let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); - hir_v.visit_ty(self_ty); - !traits.is_empty() - }) => - { - Some(self_ty) - } - _ => None, - } - }) { - Some(self_ty) => Some((trait_item.ident, self_ty)), - _ => None, - } - } - _ => None, - } - } - _ => None, - } - } - /// Report an error because the universal region `fr` was required to outlive /// `outlived_fr` but it is not known to do so. For example: /// @@ -844,7 +785,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { visitor.visit_ty(param.param_ty); let Some((ident, self_ty)) = - self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &visitor.0) else {return}; + NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &visitor.0) else { return; }; self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 58be91bc276..d9cdfa9dd4f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -239,7 +239,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let mut v = TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(param.param_ty); if let Some((ident, self_ty)) = - self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0) + 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); @@ -390,60 +390,54 @@ pub fn suggest_new_region_bound( } impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { - fn get_impl_ident_and_self_ty_from_trait( - &self, + pub fn get_impl_ident_and_self_ty_from_trait( + tcx: TyCtxt<'tcx>, def_id: DefId, trait_objects: &FxIndexSet, ) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> { - let tcx = self.tcx(); - match tcx.hir().get_if_local(def_id) { - Some(Node::ImplItem(impl_item)) => { - match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id) + match tcx.hir().get_if_local(def_id)? { + Node::ImplItem(impl_item) => { + 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, .. }), + .. + }) = tcx.hir().owner(impl_did) { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) => Some((impl_item.ident, self_ty)), - _ => None, + Some((impl_item.ident, self_ty)) + } else { + None } } - Some(Node::TraitItem(trait_item)) => { - let trait_did = tcx.hir().get_parent_item(trait_item.hir_id()); - match tcx.hir().find_by_def_id(trait_did.def_id) { - Some(Node::Item(Item { kind: ItemKind::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_did.to_def_id(); - match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { - match tcx.hir().get_if_local(impl_did.to_def_id()) { - Some(Node::Item(Item { - kind: ItemKind::Impl(hir::Impl { self_ty, .. }), - .. - })) if trait_objects.iter().all(|did| { - // FIXME: we should check `self_ty` against the receiver - // type in the `UnifyReceiver` context, 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`. - // In that case, only the first one will get suggestions. - let mut traits = vec![]; - let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); - hir_v.visit_ty(self_ty); - !traits.is_empty() - }) => - { - Some(self_ty) - } - _ => None, - } - }) { - Some(self_ty) => Some((trait_item.ident, self_ty)), - _ => None, - } + Node::TraitItem(trait_item) => { + 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| { + if let Node::Item(Item { + kind: ItemKind::Impl(hir::Impl { self_ty, .. }), + .. + }) = tcx.hir().find_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 + // 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`. + // In that case, only the first one will get suggestions. + let mut traits = vec![]; + let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); + hir_v.visit_ty(self_ty); + !traits.is_empty() + }) + { + Some((trait_item.ident, *self_ty)) + } else { + None } - _ => None, - } + }) } _ => None, } @@ -474,7 +468,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // 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)) = self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) else { + let Some((ident, self_ty)) = NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) else { return false; }; diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index bf1f150fc3b..525079681ca 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -276,10 +276,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { { let def_id = trait_ref.def_id; is_def_must_use(cx, def_id, span) + .map(|inner| MustUsePath::TraitObject(Box::new(inner))) } else { None } - .map(|inner| MustUsePath::TraitObject(Box::new(inner))) }), ty::Tuple(tys) => { let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind { -- cgit 1.4.1-3-g733a5 From b25da9ce6dd28d13c85911e0630d019403b7f5f3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 12 Nov 2022 23:54:39 +0000 Subject: layout_of: `T: Thin` implies `sizeof(&T) == sizeof(usize)` --- compiler/rustc_ty_utils/src/layout.rs | 36 ++++++++++++++++++------ src/test/ui/layout/thin-meta-implies-thin-ptr.rs | 11 ++++++++ 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/layout/thin-meta-implies-thin-ptr.rs diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index c8c6acaa453..6aa016133ca 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -155,17 +155,37 @@ fn layout_of_uncached<'tcx>( } let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); - let metadata = match unsized_part.kind() { - ty::Foreign(..) => { + + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata_ty = tcx.normalize_erasing_regions( + param_env, + tcx.mk_projection(metadata_def_id, [pointee]), + ); + let metadata_layout = cx.layout_of(metadata_ty)?; + // If the metadata is a 1-zst, then the pointer is thin. + if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 { return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); } - ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), - ty::Dynamic(..) => { - let mut vtable = scalar_unit(Pointer); - vtable.valid_range_mut().start = 1; - vtable + + let Abi::Scalar(metadata) = metadata_layout.abi else { + return Err(LayoutError::Unknown(unsized_part)); + }; + metadata + } else { + match unsized_part.kind() { + ty::Foreign(..) => { + return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + } + ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), + ty::Dynamic(..) => { + let mut vtable = scalar_unit(Pointer); + vtable.valid_range_mut().start = 1; + vtable + } + _ => { + return Err(LayoutError::Unknown(unsized_part)); + } } - _ => return Err(LayoutError::Unknown(unsized_part)), }; // Effectively a (ptr, meta) tuple. diff --git a/src/test/ui/layout/thin-meta-implies-thin-ptr.rs b/src/test/ui/layout/thin-meta-implies-thin-ptr.rs new file mode 100644 index 00000000000..972579ea8be --- /dev/null +++ b/src/test/ui/layout/thin-meta-implies-thin-ptr.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(ptr_metadata)] + +use std::ptr::Thin; + +fn main() {} + +fn foo(t: *const T) -> *const () { + unsafe { std::mem::transmute(t) } +} -- cgit 1.4.1-3-g733a5 From 2011316e596c19a8b5ae8cc00102667c2cdb1ef7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Nov 2022 21:49:54 +0000 Subject: Mirror metadata changes in layout sanity check --- compiler/rustc_middle/src/ty/layout.rs | 52 +++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 9e0ca44d098..112f15c6f9e 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -670,13 +670,24 @@ where }); } - match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { - ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize), - ty::Dynamic(_, _, ty::Dyn) => { - TyMaybeWithLayout::Ty(tcx.mk_imm_ref( + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { + let metadata = tcx.normalize_erasing_regions( + cx.param_env(), + tcx.mk_projection(metadata_def_id, [pointee]), + ); + + // Map `Metadata = DynMetadata` back to a vtable, since it + // offers better information than `std::ptr::metadata::VTable`, + // and we rely on this layout information to trigger a panic in + // `std::mem::uninitialized::<&dyn Trait>()`, for example. + if let ty::Adt(def, substs) = metadata.kind() + && Some(def.did()) == tcx.lang_items().dyn_metadata() + && substs.type_at(0).is_trait() + { + tcx.mk_imm_ref( tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3), - )) + ) /* FIXME: use actual fn pointers Warning: naively computing the number of entries in the vtable by counting the methods on the trait + methods on @@ -690,9 +701,36 @@ where tcx.mk_array(Option), ]) */ + } else { + metadata } - _ => bug!("TyAndLayout::field({:?}): not applicable", this), - } + } else { + match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { + ty::Slice(_) | ty::Str => tcx.types.usize, + ty::Dynamic(_, _, ty::Dyn) => { + tcx.mk_imm_ref( + tcx.lifetimes.re_static, + tcx.mk_array(tcx.types.usize, 3), + ) + /* FIXME: use actual fn pointers + Warning: naively computing the number of entries in the + vtable by counting the methods on the trait + methods on + all parent traits does not work, because some methods can + be not object safe and thus excluded from the vtable. + Increase this counter if you tried to implement this but + failed to do it without duplicating a lot of code from + other places in the compiler: 2 + tcx.mk_tup(&[ + tcx.mk_array(tcx.types.usize, 3), + tcx.mk_array(Option), + ]) + */ + } + _ => bug!("TyAndLayout::field({:?}): not applicable", this), + } + }; + + TyMaybeWithLayout::Ty(metadata) } // Arrays and slices. -- cgit 1.4.1-3-g733a5 From a5d39cf290d9762d982b6930f10fb4dd34119c3f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 4 Jan 2023 01:02:52 +0000 Subject: review comment: Deduplicate dyn ty_and_layout_field code --- compiler/rustc_middle/src/ty/layout.rs | 55 ++++++++++++---------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 112f15c6f9e..00f53afd663 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -670,6 +670,23 @@ where }); } + let mk_dyn_vtable = || { + tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.usize, 3)) + /* FIXME: use actual fn pointers + Warning: naively computing the number of entries in the + vtable by counting the methods on the trait + methods on + all parent traits does not work, because some methods can + be not object safe and thus excluded from the vtable. + Increase this counter if you tried to implement this but + failed to do it without duplicating a lot of code from + other places in the compiler: 2 + tcx.mk_tup(&[ + tcx.mk_array(tcx.types.usize, 3), + tcx.mk_array(Option), + ]) + */ + }; + let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { let metadata = tcx.normalize_erasing_regions( cx.param_env(), @@ -684,48 +701,14 @@ where && Some(def.did()) == tcx.lang_items().dyn_metadata() && substs.type_at(0).is_trait() { - tcx.mk_imm_ref( - tcx.lifetimes.re_static, - tcx.mk_array(tcx.types.usize, 3), - ) - /* FIXME: use actual fn pointers - Warning: naively computing the number of entries in the - vtable by counting the methods on the trait + methods on - all parent traits does not work, because some methods can - be not object safe and thus excluded from the vtable. - Increase this counter if you tried to implement this but - failed to do it without duplicating a lot of code from - other places in the compiler: 2 - tcx.mk_tup(&[ - tcx.mk_array(tcx.types.usize, 3), - tcx.mk_array(Option), - ]) - */ + mk_dyn_vtable() } else { metadata } } else { match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { ty::Slice(_) | ty::Str => tcx.types.usize, - ty::Dynamic(_, _, ty::Dyn) => { - tcx.mk_imm_ref( - tcx.lifetimes.re_static, - tcx.mk_array(tcx.types.usize, 3), - ) - /* FIXME: use actual fn pointers - Warning: naively computing the number of entries in the - vtable by counting the methods on the trait + methods on - all parent traits does not work, because some methods can - be not object safe and thus excluded from the vtable. - Increase this counter if you tried to implement this but - failed to do it without duplicating a lot of code from - other places in the compiler: 2 - tcx.mk_tup(&[ - tcx.mk_array(tcx.types.usize, 3), - tcx.mk_array(Option), - ]) - */ - } + ty::Dynamic(_, _, ty::Dyn) => mk_dyn_vtable(), _ => bug!("TyAndLayout::field({:?}): not applicable", this), } }; -- cgit 1.4.1-3-g733a5 From f98adb32f543d710e6af1941e5373d397b476d6b Mon Sep 17 00:00:00 2001 From: CarsonV Date: Tue, 3 Jan 2023 20:12:09 -0600 Subject: Enable query_impl doctests --- compiler/rustc_query_impl/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index b2111a1262a..46e77626479 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" edition = "2021" [lib] -doctest = false + [dependencies] measureme = "10.0.0" -- cgit 1.4.1-3-g733a5 From 49111eced698e7df62756af364f799609cae3aa7 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 3 Jan 2023 19:46:40 -0700 Subject: rustdoc: fix buggy JS check for absolute URL The old code did the wrong thing when faced with a crate named "http". --- src/librustdoc/html/static/js/main.js | 2 +- src/test/rustdoc-gui/implementors.goml | 6 ++++++ src/test/rustdoc-gui/search-filter.goml | 2 ++ src/test/rustdoc-gui/sidebar-source-code.goml | 2 +- src/test/rustdoc-gui/source-code-page.goml | 2 +- src/test/rustdoc-gui/src/lib2/Cargo.lock | 8 ++++++++ src/test/rustdoc-gui/src/lib2/Cargo.toml | 1 + src/test/rustdoc-gui/src/lib2/http/Cargo.toml | 7 +++++++ src/test/rustdoc-gui/src/lib2/http/lib.rs | 1 + src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml | 3 +++ src/test/rustdoc-gui/src/lib2/implementors/lib.rs | 2 ++ 11 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 src/test/rustdoc-gui/src/lib2/http/Cargo.toml create mode 100644 src/test/rustdoc-gui/src/lib2/http/lib.rs diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 60e4e749224..d47b0953179 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -563,7 +563,7 @@ function loadCss(cssUrl) { onEachLazy(code.getElementsByTagName("a"), elem => { const href = elem.getAttribute("href"); - if (href && href.indexOf("http") !== 0) { + if (href && !/^(?:[a-z+]+:)?\/\//.test(href)) { elem.setAttribute("href", window.rootPath + href); } }); diff --git a/src/test/rustdoc-gui/implementors.goml b/src/test/rustdoc-gui/implementors.goml index 4999283dc8b..997c0ed8f01 100644 --- a/src/test/rustdoc-gui/implementors.goml +++ b/src/test/rustdoc-gui/implementors.goml @@ -33,3 +33,9 @@ goto: "file://" + |DOC_PATH| + "/lib2/trait.TraitToReexport.html" assert-count: ("#implementors-list .impl", 1) goto: "file://" + |DOC_PATH| + "/implementors/trait.TraitToReexport.html" assert-count: ("#implementors-list .impl", 1) + +// Now check that the link is properly rewritten for a crate called `http`. +// An older version of rustdoc had a buggy check for absolute links. +goto: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html" +assert-count: ("#implementors-list .impl", 1) +assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"}) diff --git a/src/test/rustdoc-gui/search-filter.goml b/src/test/rustdoc-gui/search-filter.goml index e556da0c54e..5bc6e87d6d2 100644 --- a/src/test/rustdoc-gui/search-filter.goml +++ b/src/test/rustdoc-gui/search-filter.goml @@ -15,6 +15,7 @@ click: "#crate-search" press-key: "ArrowDown" press-key: "ArrowDown" press-key: "ArrowDown" +press-key: "ArrowDown" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#search-tabs" @@ -39,6 +40,7 @@ click: "#crate-search" press-key: "ArrowUp" press-key: "ArrowUp" press-key: "ArrowUp" +press-key: "ArrowUp" press-key: "Enter" // Waiting for the search results to appear... wait-for: "#search-tabs" diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index d5f57ed6102..6bc07fbae04 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -73,7 +73,7 @@ assert: "//*[@class='dir-entry' and @open]/*[text()='sub_mod']" // Only "another_folder" should be "open" in "lib2". assert: "//*[@class='dir-entry' and not(@open)]/*[text()='another_mod']" // All other trees should be collapsed. -assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 7) +assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@open)]", 8) // We now switch to mobile mode. size: (600, 600) diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index aa792196960..e0397890519 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -102,7 +102,7 @@ assert: ".source-sidebar-expanded" // We check that the first entry of the sidebar is collapsed assert-property: ("#source-sidebar details:first-of-type", {"open": "false"}) -assert-text: ("#source-sidebar details:first-of-type > summary", "huge_logo") +assert-text: ("#source-sidebar details:first-of-type > summary", "http") // We now click on it. click: "#source-sidebar details:first-of-type > summary" assert-property: ("#source-sidebar details:first-of-type", {"open": "true"}) diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.lock b/src/test/rustdoc-gui/src/lib2/Cargo.lock index a5873ceb325..425a3ae7e5c 100644 --- a/src/test/rustdoc-gui/src/lib2/Cargo.lock +++ b/src/test/rustdoc-gui/src/lib2/Cargo.lock @@ -2,13 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "http" +version = "0.1.0" + [[package]] name = "implementors" version = "0.1.0" +dependencies = [ + "http", +] [[package]] name = "lib2" version = "0.1.0" dependencies = [ + "http", "implementors", ] diff --git a/src/test/rustdoc-gui/src/lib2/Cargo.toml b/src/test/rustdoc-gui/src/lib2/Cargo.toml index 2e37f3f667a..8bca77ff834 100644 --- a/src/test/rustdoc-gui/src/lib2/Cargo.toml +++ b/src/test/rustdoc-gui/src/lib2/Cargo.toml @@ -8,3 +8,4 @@ path = "lib.rs" [dependencies] implementors = { path = "./implementors" } +http = { path = "./http" } diff --git a/src/test/rustdoc-gui/src/lib2/http/Cargo.toml b/src/test/rustdoc-gui/src/lib2/http/Cargo.toml new file mode 100644 index 00000000000..fa719efa526 --- /dev/null +++ b/src/test/rustdoc-gui/src/lib2/http/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "http" +version = "0.1.0" +edition = "2018" + +[lib] +path = "lib.rs" diff --git a/src/test/rustdoc-gui/src/lib2/http/lib.rs b/src/test/rustdoc-gui/src/lib2/http/lib.rs new file mode 100644 index 00000000000..204e0749427 --- /dev/null +++ b/src/test/rustdoc-gui/src/lib2/http/lib.rs @@ -0,0 +1 @@ +pub trait HttpTrait {} diff --git a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml index 7ef1052c49f..9dafc43df5f 100644 --- a/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml +++ b/src/test/rustdoc-gui/src/lib2/implementors/Cargo.toml @@ -5,3 +5,6 @@ edition = "2018" [lib] path = "lib.rs" + +[dependencies] +http = { path = "../http/" } diff --git a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs index 1620e842291..2842ac50dc1 100644 --- a/src/test/rustdoc-gui/src/lib2/implementors/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/implementors/lib.rs @@ -10,6 +10,8 @@ impl Whatever for Struct { type Foo = u8; } +impl http::HttpTrait for Struct {} + mod traits { pub trait TraitToReexport { fn method() {} -- cgit 1.4.1-3-g733a5 From 2399df288ef5af538a331a974b037b889be5cfd2 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Tue, 3 Jan 2023 20:38:07 -0800 Subject: Add test case to click popover child link --- src/test/rustdoc-gui/help-page.goml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/rustdoc-gui/help-page.goml b/src/test/rustdoc-gui/help-page.goml index 80203901ed3..050cf325bb8 100644 --- a/src/test/rustdoc-gui/help-page.goml +++ b/src/test/rustdoc-gui/help-page.goml @@ -61,3 +61,11 @@ click: "#help-button > a" assert-css: ("#help", {"display": "none"}) compare-elements-property-false: (".sub", "#help", ["offsetWidth"]) compare-elements-position-false: (".sub", "#help", ("x")) + +// This test ensures that the "the rustdoc book" anchor link within the help popover works. +goto: "file://" + |DOC_PATH| + "/test_docs/index.html" +size: (1000, 1000) // Popover only appears when the screen width is >700px. +assert-false: "#help" +click: "#help-button > a" +click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']" +assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"} -- cgit 1.4.1-3-g733a5 From 9792c9affb55e44bd93957c166a971007c66b5a2 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Tue, 3 Jan 2023 23:44:35 -0800 Subject: Add hardcoded wait time for external navigation to load --- src/test/rustdoc-gui/help-page.goml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/rustdoc-gui/help-page.goml b/src/test/rustdoc-gui/help-page.goml index 050cf325bb8..83f2556fd8f 100644 --- a/src/test/rustdoc-gui/help-page.goml +++ b/src/test/rustdoc-gui/help-page.goml @@ -68,4 +68,5 @@ size: (1000, 1000) // Popover only appears when the screen width is >700px. assert-false: "#help" click: "#help-button > a" click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']" +wait-for: 2000 assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"} -- cgit 1.4.1-3-g733a5 From 77051167083b58c4cd59c658197bcfe6476a7fa5 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 4 Jan 2023 13:37:38 +0000 Subject: Fix each_linked_rlib when the current crate has 0 crate types --- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 71589e9993b..e7df9cc695a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -230,6 +230,9 @@ pub fn each_linked_rlib( }); } } + if info.dependency_formats.is_empty() { + return Err(errors::LinkRlibError::MissingFormat); + } &info.dependency_formats[0].1 } else { let fmts = info -- cgit 1.4.1-3-g733a5 From ac4426c093b5e7a457e0e32cc6ea2d3fb99c3148 Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Sat, 31 Dec 2022 13:45:22 +0100 Subject: Merge borrowck permission checks Merge `check_access_permission` and `check_if_reassignment_to_immutable_state`. The goal of this commit is twofold: First, we simplify the codebase by removing duplicate logic. Second, we avoid duplicate reporting of illegal reassignment errors by reusing the exiting de-duplicating logic of access_place. --- compiler/rustc_borrowck/src/lib.rs | 48 +++++++++----------------------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ae1bea008b6..278ffed0747 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -863,7 +863,6 @@ enum WriteKind { /// local place can be mutated. // // FIXME: @nikomatsakis suggested that this flag could be removed with the following modifications: -// - Merge `check_access_permissions()` and `check_if_reassignment_to_immutable_state()`. // - Split `is_mutable()` into `is_assignable()` (can be directly assigned) and // `is_declared_mutable()`. // - Take flow state into consideration in `is_assignable()` for local variables. @@ -1132,20 +1131,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Write of P[i] or *P requires P init'd. self.check_if_assigned_path_is_moved(location, place_span, flow_state); - // Special case: you can assign an immutable local variable - // (e.g., `x = ...`) so long as it has never been initialized - // before (at this point in the flow). - if let Some(local) = place_span.0.as_local() { - if let Mutability::Not = self.body.local_decls[local].mutability { - // check for reassignments to immutable local variables - self.check_if_reassignment_to_immutable_state( - location, local, place_span, flow_state, - ); - return; - } - } - - // Otherwise, use the normal access permission rules. self.access_place( location, place_span, @@ -1554,24 +1539,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn check_if_reassignment_to_immutable_state( - &mut self, - location: Location, - local: Local, - place_span: (Place<'tcx>, Span), - flow_state: &Flows<'cx, 'tcx>, - ) { - debug!("check_if_reassignment_to_immutable_state({:?})", local); - - // Check if any of the initializations of `local` have happened yet: - if let Some(init_index) = self.is_local_ever_initialized(local, flow_state) { - // And, if so, report an error. - let init = &self.move_data.inits[init_index]; - let span = init.span(&self.body); - self.report_illegal_reassignment(location, place_span, span, place_span.0); - } - } - fn check_if_full_path_is_moved( &mut self, location: Location, @@ -2037,12 +2004,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // partial initialization, do not complain about mutability // errors except for actual mutation (as opposed to an attempt // to do a partial initialization). - let previously_initialized = - self.is_local_ever_initialized(place.local, flow_state).is_some(); + let previously_initialized = self.is_local_ever_initialized(place.local, flow_state); // at this point, we have set up the error reporting state. - if previously_initialized { - self.report_mutability_error(place, span, the_place_err, error_access, location); + if let Some(init_index) = previously_initialized { + if let (AccessKind::Mutate, Some(_)) = (error_access, place.as_local()) { + // If this is a mutate access to an immutable local variable with no projections + // report the error as an illegal reassignment + let init = &self.move_data.inits[init_index]; + let assigned_span = init.span(&self.body); + self.report_illegal_reassignment(location, (place, span), assigned_span, place); + } else { + self.report_mutability_error(place, span, the_place_err, error_access, location) + } true } else { false -- cgit 1.4.1-3-g733a5 From 0c43b42b0cd1823388418504e84f3c4fec6f33b9 Mon Sep 17 00:00:00 2001 From: Gijs Burghoorn Date: Wed, 4 Jan 2023 16:07:33 +0100 Subject: Improve include macro documentation --- library/core/src/macros/mod.rs | 64 +++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index cfc1cabe229..b20e60ad96d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1312,28 +1312,52 @@ pub(crate) mod builtin { /* compiler built-in */ }; } - + /// Parses a file as an expression or an item according to the context. /// - /// The file is located relative to the current file (similarly to how - /// modules are found). The provided path is interpreted in a platform-specific - /// way at compile time. So, for instance, an invocation with a Windows path - /// containing backslashes `\` would not compile correctly on Unix. - /// - /// Using this macro is often a bad idea, because if the file is - /// parsed as an expression, it is going to be placed in the - /// surrounding code unhygienically. This could result in variables - /// or functions being different from what the file expected if - /// there are variables or functions that have the same name in - /// the current file. + ///
+ ///
+    ///
+    /// **Warning**: For multi-file Rust projects, the `include!` macro is probably not what you
+    /// are looking for. Usually, multi-file Rust projects use
+    /// [modules](https://doc.rust-lang.org/reference/items/modules.html). Multi-file projects and
+    /// modules are explained in the Rust-by-Example book
+    /// [here](https://doc.rust-lang.org/rust-by-example/mod/split.html) and the module system is
+    /// explained in the Rust Book
+    /// [here](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html).
+    ///
+    /// 
+ ///
+ /// + /// If the included file is parsed as an expression, it is placed in the surrounding code + /// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). This + /// could result in variables or functions being different from what the file expected if there + /// are variables or functions that have the same name in the current file. + /// + /// The included file is located relative to the current file (similarly to how modules are + /// found). The provided path is interpreted in a platform-specific way at compile time. So, + /// for instance, an invocation with a Windows path containing backslashes `\` would not + /// compile correctly on Unix. /// + /// # Uses + /// + /// The `include!` macro is primarily used for two purposes. It is used to include + /// documentation that is written in a separate file and it is used to include [build artifacts + /// usually as a result from the `build.rs` + /// script](https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script). + /// + /// When using the `include` macro to include stretches of documentation, remember that the + /// included file still needs to be a valid rust syntax. It is also possible to + /// use the [`include_str`] macro as `#![doc = include_str!("...")]` (at the module level) or + /// `#[doc = include_str!("...")]` (at the item level) to include documentation from a plain + /// text or markdown file. + /// /// # Examples - /// - /// Assume there are two files in the same directory with the following - /// contents: - /// + /// + /// Assume there are two files in the same directory with the following contents: + /// /// File 'monkeys.in': - /// + /// /// ```ignore (only-for-syntax-highlight) /// ['🙈', '🙊', '🙉'] /// .iter() @@ -1341,9 +1365,9 @@ pub(crate) mod builtin { /// .take(6) /// .collect::() /// ``` - /// + /// /// File 'main.rs': - /// + /// /// ```ignore (cannot-doctest-external-file-dependency) /// fn main() { /// let my_string = include!("monkeys.in"); @@ -1351,7 +1375,7 @@ pub(crate) mod builtin { /// println!("{my_string}"); /// } /// ``` - /// + /// /// Compiling 'main.rs' and running the resulting binary will print /// "🙈🙊🙉🙈🙊🙉". #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From eb2980c7f1df7d4c461837daeca4c14eeea80429 Mon Sep 17 00:00:00 2001 From: Gijs Burghoorn Date: Wed, 4 Jan 2023 16:18:34 +0100 Subject: Tidy up whitespace --- library/core/src/macros/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index b20e60ad96d..ff80d1160f6 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1312,7 +1312,7 @@ pub(crate) mod builtin { /* compiler built-in */ }; } - + /// Parses a file as an expression or an item according to the context. /// ///
@@ -1328,19 +1328,19 @@ pub(crate) mod builtin { /// /// ///
- /// + /// /// If the included file is parsed as an expression, it is placed in the surrounding code /// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). This /// could result in variables or functions being different from what the file expected if there /// are variables or functions that have the same name in the current file. - /// + /// /// The included file is located relative to the current file (similarly to how modules are /// found). The provided path is interpreted in a platform-specific way at compile time. So, /// for instance, an invocation with a Windows path containing backslashes `\` would not /// compile correctly on Unix. /// /// # Uses - /// + /// /// The `include!` macro is primarily used for two purposes. It is used to include /// documentation that is written in a separate file and it is used to include [build artifacts /// usually as a result from the `build.rs` @@ -1351,13 +1351,13 @@ pub(crate) mod builtin { /// use the [`include_str`] macro as `#![doc = include_str!("...")]` (at the module level) or /// `#[doc = include_str!("...")]` (at the item level) to include documentation from a plain /// text or markdown file. - /// + /// /// # Examples - /// + /// /// Assume there are two files in the same directory with the following contents: - /// + /// /// File 'monkeys.in': - /// + /// /// ```ignore (only-for-syntax-highlight) /// ['🙈', '🙊', '🙉'] /// .iter() @@ -1365,9 +1365,9 @@ pub(crate) mod builtin { /// .take(6) /// .collect::() /// ``` - /// + /// /// File 'main.rs': - /// + /// /// ```ignore (cannot-doctest-external-file-dependency) /// fn main() { /// let my_string = include!("monkeys.in"); @@ -1375,7 +1375,7 @@ pub(crate) mod builtin { /// println!("{my_string}"); /// } /// ``` - /// + /// /// Compiling 'main.rs' and running the resulting binary will print /// "🙈🙊🙉🙈🙊🙉". #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From f902200de4a722908919da701c05244fed3dabc5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 4 Jan 2023 12:27:05 +0100 Subject: Add retry mechanism for rustdoc GUI tests to reduce flakyness --- src/tools/rustdoc-gui/tester.js | 122 +++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 46 deletions(-) diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index d40d9a3cb54..900ca389436 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -9,6 +9,9 @@ const path = require("path"); const os = require('os'); const {Options, runTest} = require('browser-ui-test'); +// If a test fails or errors, we will retry it two more times in case it was a flaky failure. +const NB_RETRY = 3; + function showHelp() { console.log("rustdoc-js options:"); console.log(" --doc-folder [PATH] : location of the generated doc folder"); @@ -129,11 +132,59 @@ function char_printer(n_tests) { }; } -/// Sort array by .file_name property +// Sort array by .file_name property function by_filename(a, b) { return a.file_name - b.file_name; } +async function runTests(opts, framework_options, files, results, status_bar, showTestFailures) { + const tests_queue = []; + + for (const testPath of files) { + const callback = runTest(testPath, framework_options) + .then(out => { + const [output, nb_failures] = out; + results[nb_failures === 0 ? "successful" : "failed"].push({ + file_name: testPath, + output: output, + }); + if (nb_failures === 0) { + status_bar.successful(); + } else if (showTestFailures) { + status_bar.erroneous(); + } + }) + .catch(err => { + results.errored.push({ + file_name: testPath, + output: err, + }); + if (showTestFailures) { + status_bar.erroneous(); + } + }) + .finally(() => { + // We now remove the promise from the tests_queue. + tests_queue.splice(tests_queue.indexOf(callback), 1); + }); + tests_queue.push(callback); + if (opts["jobs"] > 0 && tests_queue.length >= opts["jobs"]) { + await Promise.race(tests_queue); + } + } + if (tests_queue.length > 0) { + await Promise.all(tests_queue); + } +} + +function createEmptyResults() { + return { + successful: [], + failed: [], + errored: [], + }; +} + async function main(argv) { let opts = parseOptions(argv.slice(2)); if (opts === null) { @@ -144,7 +195,7 @@ async function main(argv) { let debug = false; // Run tests in sequentially let headless = true; - const options = new Options(); + const framework_options = new Options(); try { // This is more convenient that setting fields one by one. let args = [ @@ -169,13 +220,12 @@ async function main(argv) { args.push("--executable-path"); args.push(opts["executable_path"]); } - options.parseArguments(args); + framework_options.parseArguments(args); } catch (error) { console.error(`invalid argument: ${error}`); process.exit(1); } - let failed = false; let files; if (opts["files"].length === 0) { files = fs.readdirSync(opts["tests_folder"]); @@ -187,6 +237,9 @@ async function main(argv) { console.error("rustdoc-gui: No test selected"); process.exit(2); } + files.forEach((file_name, index) => { + files[index] = path.join(opts["tests_folder"], file_name); + }); files.sort(); if (!headless) { @@ -215,52 +268,29 @@ async function main(argv) { }; process.on('exit', exitHandling); - const tests_queue = []; - let results = { - successful: [], - failed: [], - errored: [], - }; + const originalFilesLen = files.length; + let results = createEmptyResults(); const status_bar = char_printer(files.length); - for (let i = 0; i < files.length; ++i) { - const file_name = files[i]; - const testPath = path.join(opts["tests_folder"], file_name); - const callback = runTest(testPath, options) - .then(out => { - const [output, nb_failures] = out; - results[nb_failures === 0 ? "successful" : "failed"].push({ - file_name: testPath, - output: output, - }); - if (nb_failures > 0) { - status_bar.erroneous(); - failed = true; - } else { - status_bar.successful(); - } - }) - .catch(err => { - results.errored.push({ - file_name: testPath + file_name, - output: err, - }); - status_bar.erroneous(); - failed = true; - }) - .finally(() => { - // We now remove the promise from the tests_queue. - tests_queue.splice(tests_queue.indexOf(callback), 1); - }); - tests_queue.push(callback); - if (opts["jobs"] > 0 && tests_queue.length >= opts["jobs"]) { - await Promise.race(tests_queue); + + let new_results; + for (let it = 0; it < NB_RETRY && files.length > 0; ++it) { + new_results = createEmptyResults(); + await runTests(opts, framework_options, files, new_results, status_bar, it + 1 >= NB_RETRY); + Array.prototype.push.apply(results.successful, new_results.successful); + // We generate the new list of files with the previously failing tests. + files = Array.prototype.concat(new_results.failed, new_results.errored); + if (files.length > originalFilesLen / 2) { + // If we have too many failing tests, it's very likely not flaky failures anymore so + // no need to retry. + break; } } - if (tests_queue.length > 0) { - await Promise.all(tests_queue); - } + status_bar.finish(); + Array.prototype.push.apply(results.failed, new_results.failed); + Array.prototype.push.apply(results.errored, new_results.errored); + // We don't need this listener anymore. process.removeListener("exit", exitHandling); @@ -287,7 +317,7 @@ async function main(argv) { }); } - if (failed) { + if (results.failed.length > 0 || results.errored.length > 0) { process.exit(1); } } -- cgit 1.4.1-3-g733a5 From 6306fd3be407fa526785d2222f4cb00ed1f01abf Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 4 Jan 2023 15:33:59 +0000 Subject: Update cargo 8 commits in 2381cbdb4e9b07090f552d34a44a529b6e620e44..8c460b2237a6359a7e3335890db8da049bdd62fc 2022-12-23 12:19:27 +0000 to 2023-01-04 14:30:01 +0000 - test: revive nightly plugin tests to work (rust-lang/cargo#11534) - Add note to release notes about rejecting multiple registries. (rust-lang/cargo#11531) - Fix a typo `fresheness` -> `freshness` (rust-lang/cargo#11529) - Reasons for rebuilding (rust-lang/cargo#11407) - Asymmetric tokens (rust-lang/cargo#10771) - Use proper git URL for GitHub repos (rust-lang/cargo#11517) - Add `registry.default` example (rust-lang/cargo#11516) - Support vendoring with different revs from same git repo (rust-lang/cargo#10690) Also update license exceptions and permitted dependencies for new cargo dependency "pasetors". A new dependency `getrandom` is added into `rustc-workspace-hacks`, since it requires feature `js`. --- Cargo.lock | 392 ++++++++++++++++++++++++++++-- src/tools/cargo | 2 +- src/tools/rustc-workspace-hack/Cargo.toml | 2 + src/tools/tidy/src/deps.rs | 12 + 4 files changed, 391 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46b0a01a18e..d7381b6c938 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,6 +197,18 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64ct" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" + [[package]] name = "bitflags" version = "1.3.2" @@ -271,6 +283,12 @@ dependencies = [ "toml", ] +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + [[package]] name = "bytecount" version = "0.6.2" @@ -341,6 +359,7 @@ dependencies = [ "opener", "openssl", "os_info", + "pasetors", "pathdiff", "percent-encoding", "pretty_env_logger", @@ -358,6 +377,7 @@ dependencies = [ "tar", "tempfile", "termcolor", + "time 0.3.17", "toml_edit", "unicode-width", "unicode-xid", @@ -443,10 +463,13 @@ dependencies = [ "glob", "itertools", "lazy_static", + "pasetors", + "serde", "serde_json", "snapbox", "tar", "termcolor", + "time 0.3.17", "toml_edit", "url", "winapi", @@ -585,7 +608,7 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time", + "time 0.1.43", "winapi", ] @@ -899,6 +922,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" +[[package]] +name = "const-oid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" + [[package]] name = "content_inspector" version = "0.2.4" @@ -953,7 +982,7 @@ dependencies = [ [[package]] name = "crates-io" -version = "0.35.0" +version = "0.35.1" dependencies = [ "anyhow", "curl", @@ -1015,13 +1044,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "typenum", ] [[package]] @@ -1046,6 +1088,12 @@ dependencies = [ "quote", ] +[[package]] +name = "ct-codecs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" + [[package]] name = "ctor" version = "0.1.26" @@ -1102,6 +1150,17 @@ dependencies = [ "syn", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "derive-new" version = "0.5.8" @@ -1140,12 +1199,13 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] name = "digest" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", + "subtle", ] [[package]] @@ -1232,6 +1292,27 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519-compact" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" +dependencies = [ + "getrandom 0.2.8", +] + [[package]] name = "either" version = "1.6.0" @@ -1250,6 +1331,28 @@ dependencies = [ "serde_json", ] +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "ena" version = "0.14.0" @@ -1369,6 +1472,22 @@ dependencies = [ "instant", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" + [[package]] name = "filetime" version = "0.2.14" @@ -1644,8 +1763,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1708,6 +1829,17 @@ dependencies = [ "regex", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "gsgdt" version = "0.1.2" @@ -1797,6 +1929,24 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "home" version = "0.5.3" @@ -1961,7 +2111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" dependencies = [ "bitmaps", - "rand_core 0.6.2", + "rand_core 0.6.4", "rand_xoshiro", "sized-chunks", "typenum", @@ -2094,6 +2244,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "jsondocck" version = "0.1.0" @@ -2664,6 +2823,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "orion" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2baf7fd2e326e3895c681176788dd227fcd8369350e53c570592d8563fecbb6" +dependencies = [ + "fiat-crypto", + "subtle", + "zeroize", +] + [[package]] name = "os_info" version = "3.5.0" @@ -2696,6 +2866,17 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "p384" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2", +] + [[package]] name = "packed_simd_2" version = "0.3.8" @@ -2777,12 +2958,42 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "pasetors" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed20c4c21d893414f42e0cbfebe8a8036b5ae9b0264611fb6504e395eda6ceec" +dependencies = [ + "ct-codecs", + "ed25519-compact", + "getrandom 0.2.8", + "orion", + "p384", + "rand_core 0.6.4", + "regex", + "serde", + "serde_json", + "sha2", + "subtle", + "time 0.3.17", + "zeroize", +] + [[package]] name = "pathdiff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -2902,6 +3113,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.25" @@ -3094,7 +3315,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.0", - "rand_core 0.6.2", + "rand_core 0.6.4", ] [[package]] @@ -3114,7 +3335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.4", ] [[package]] @@ -3128,9 +3349,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom 0.2.8", ] @@ -3159,7 +3380,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" dependencies = [ - "rand_core 0.6.2", + "rand_core 0.6.4", ] [[package]] @@ -3265,6 +3486,17 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + [[package]] name = "rls" version = "2.0.0" @@ -3404,6 +3636,7 @@ version = "1.0.0" dependencies = [ "bstr 0.2.17", "clap 3.2.20", + "getrandom 0.2.8", "libc", "libz-sys", "rand 0.8.5", @@ -4793,6 +5026,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "2.0.0" @@ -4895,9 +5142,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.1" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", @@ -4925,6 +5172,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "similar" version = "2.1.0" @@ -5028,6 +5285,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -5150,6 +5417,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "1.0.107" @@ -5347,6 +5620,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "tinystr" version = "0.7.0" @@ -5530,9 +5830,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.12.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-parse" @@ -5856,6 +6156,60 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + [[package]] name = "winapi" version = "0.3.9" @@ -6048,6 +6402,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" + [[package]] name = "zerovec" version = "0.9.0" diff --git a/src/tools/cargo b/src/tools/cargo index 2381cbdb4e9..8c460b2237a 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 2381cbdb4e9b07090f552d34a44a529b6e620e44 +Subproject commit 8c460b2237a6359a7e3335890db8da049bdd62fc diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index a5f0c0f320a..84b16a37a33 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -77,6 +77,8 @@ clap = { version = "3.1.1", features = ["derive", "clap_derive"]} curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } # Ensure `extra_traits` of libc, which is used transitively by Cargo. libc = { version = "0.2", features = ["extra_traits"] } +# Ensure `js` of getrandom, which is (unfortunately) used transitively by Cargo. +getrandom = { version = "0.2", features = ["js"] } # Ensure default features of libz-sys, which are disabled in some scenarios. libz-sys = { version = "1.1.2" } # Ensure default features of regex, which are disabled in some scenarios. diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 75454cbdc5f..f649e391b79 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -40,6 +40,8 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("im-rc", "MPL-2.0+"), // cargo ("sized-chunks", "MPL-2.0+"), // cargo via im-rc ("bitmaps", "MPL-2.0+"), // cargo via im-rc + ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), // cargo via pasetors + ("subtle", "BSD-3-Clause"), // cargo via pasetors ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot ("snap", "BSD-3-Clause"), // rustc ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) @@ -96,6 +98,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "autocfg", "bitflags", "block-buffer", + "bumpalo", // Included in Cargo's dep graph but only activated on wasm32-*-unknown. "cc", "cfg-if", "chalk-derive", @@ -153,6 +156,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "itertools", "itoa", "jobserver", + "js-sys", // Included in Cargo's dep graph but only activated on wasm32-*-unknown. "lazy_static", "libc", "libloading", @@ -222,6 +226,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "stable_deref_trait", "stacker", "static_assertions", + "subtle", // dependency of cargo (via pasetors) "syn", "synstructure", "tempfile", @@ -264,6 +269,13 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "valuable", "version_check", "wasi", + // vvv Included in Cargo's dep graph but only activated on wasm32-*-unknown. + "wasm-bindgen", + "wasm-bindgen-backend", + "wasm-bindgen-macro", + "wasm-bindgen-macro-support", + "wasm-bindgen-shared", + // ^^^ Included in Cargo's dep graph but only activated on wasm32-*-unknown. "winapi", "winapi-i686-pc-windows-gnu", "winapi-util", -- cgit 1.4.1-3-g733a5 From 8f80a23c252d08d83083b79036ee7199d3164eb9 Mon Sep 17 00:00:00 2001 From: KaDiWa Date: Wed, 4 Jan 2023 18:15:43 +0100 Subject: adjust comments about pre-push.sh hook --- src/bootstrap/setup.rs | 4 ++-- src/etc/pre-push.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index cd360cbef96..ca4feac6fac 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -351,7 +351,7 @@ pub fn interactive_path() -> io::Result { Ok(template) } -// install a git hook to automatically run tidy --bless, if they want +// install a git hook to automatically run tidy, if they want fn install_git_hook_maybe(config: &Config) -> io::Result<()> { let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| { assert!(output.status.success(), "failed to run `git`"); @@ -367,7 +367,7 @@ fn install_git_hook_maybe(config: &Config) -> io::Result<()> { println!(); println!( "Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality. -If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before +If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before pushing your code to ensure your code is up to par. If you decide later that this behavior is undesirable, simply delete the `pre-push` file from .git/hooks." ); diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index 2a3086338b4..7a846d44ad6 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Call `tidy --bless` before git push +# Call `tidy` before git push # Copy this script to .git/hooks to activate, # and remove it from .git/hooks to deactivate. # -- cgit 1.4.1-3-g733a5 From a4974fa9c7b5a0a74af5912f560c83f6d2ac78f6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 2 Jan 2023 23:12:47 +0000 Subject: Split `-Zchalk` flag into `-Ztrait-solver=(stock|chalk|next)` flag --- compiler/rustc_interface/src/tests.rs | 3 ++- compiler/rustc_session/src/config.rs | 13 ++++++++++++- compiler/rustc_session/src/options.rs | 16 ++++++++++++++-- compiler/rustc_trait_selection/src/traits/engine.rs | 18 ++++++++++-------- .../src/traits/error_reporting/mod.rs | 3 ++- .../src/traits/select/confirmation.rs | 4 ++-- compiler/rustc_ty_utils/src/ty.rs | 3 ++- 7 files changed, 44 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9ec71c6b87e..316e2e29cd8 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,6 +4,7 @@ use crate::interface::parse_cfgspecs; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::rustc_optgroups; +use rustc_session::config::TraitSolver; use rustc_session::config::{build_configuration, build_session_options, to_crate_config}; use rustc_session::config::{ BranchProtection, Externs, OomStrategy, OutputType, OutputTypes, PAuthKey, PacRet, @@ -722,7 +723,6 @@ fn test_unstable_options_tracking_hash() { pac_ret: Some(PacRet { leaf: true, key: PAuthKey::B }) }) ); - tracked!(chalk, true); tracked!(codegen_backend, Some("abc".to_string())); tracked!(crate_attr, vec!["abc".to_string()]); tracked!(debug_info_for_profiling, true); @@ -792,6 +792,7 @@ fn test_unstable_options_tracking_hash() { tracked!(thinlto, Some(true)); tracked!(thir_unsafeck, true); tracked!(tls_model, Some(TlsModel::GeneralDynamic)); + tracked!(trait_solver, TraitSolver::Chalk); tracked!(translate_remapped_path_to_local_path, false); tracked!(trap_unreachable, Some(false)); tracked!(treat_err_as_bug, NonZeroUsize::new(1)); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5f78f6d079d..4f1175856dc 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -554,6 +554,16 @@ pub enum PrintRequest { SplitDebuginfo, } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum TraitSolver { + /// Stock trait solver in `rustc_trait_selection::traits::select` + Stock, + /// Chalk trait solver + Chalk, + /// Experimental trait solver in `rustc_trait_selection::solve` + Next, +} + pub enum Input { /// Load source code from a file. File(PathBuf), @@ -2761,7 +2771,7 @@ pub(crate) mod dep_tracking { BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OomStrategy, OptLevel, OutputType, OutputTypes, Passes, SourceFileHashAlgorithm, SplitDwarfKind, - SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths, + SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -2861,6 +2871,7 @@ pub(crate) mod dep_tracking { BranchProtection, OomStrategy, LanguageIdentifier, + TraitSolver, ); impl DepTrackingHash for (T1, T2) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b379aef80fb..9ce50246b08 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -382,6 +382,8 @@ mod desc { "`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`"; pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; + pub const parse_trait_solver: &str = + "one of the supported solver modes (`stock`, `chalk`, or `next`)"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -880,6 +882,16 @@ mod parse { } } + pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool { + match v { + Some("stock") => *slot = TraitSolver::Stock, + Some("chalk") => *slot = TraitSolver::Chalk, + Some("next") => *slot = TraitSolver::Next, + _ => return false, + } + true + } + pub(crate) fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool { if v.is_some() { let mut bool_arg = None; @@ -1249,8 +1261,6 @@ options! { "instrument control-flow architecture protection"), cgu_partitioning_strategy: Option = (None, parse_opt_string, [TRACKED], "the codegen unit partitioning strategy to use"), - chalk: bool = (false, parse_bool, [TRACKED], - "enable the experimental Chalk-based trait solving engine"), codegen_backend: Option = (None, parse_opt_string, [TRACKED], "the backend to use"), combine_cgu: bool = (false, parse_bool, [TRACKED], @@ -1609,6 +1619,8 @@ options! { "for every macro invocation, print its name and arguments (default: no)"), track_diagnostics: bool = (false, parse_bool, [UNTRACKED], "tracks where in rustc a diagnostic was emitted"), + trait_solver: TraitSolver = (TraitSolver::Stock, parse_trait_solver, [TRACKED], + "specify the trait solver mode used by rustc (default: stock)"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index c028e89e4ea..bd56d058a49 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use super::TraitEngine; use super::{ChalkFulfillmentContext, FulfillmentContext}; +use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::traits::NormalizeExt; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -20,6 +21,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_session::config::TraitSolver; use rustc_span::Span; pub trait TraitEngineExt<'tcx> { @@ -29,18 +31,18 @@ pub trait TraitEngineExt<'tcx> { impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> Box { - if tcx.sess.opts.unstable_opts.chalk { - Box::new(ChalkFulfillmentContext::new()) - } else { - Box::new(FulfillmentContext::new()) + match tcx.sess.opts.unstable_opts.trait_solver { + TraitSolver::Stock => Box::new(FulfillmentContext::new()), + TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new()), + TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()), } } fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box { - if tcx.sess.opts.unstable_opts.chalk { - Box::new(ChalkFulfillmentContext::new_in_snapshot()) - } else { - Box::new(FulfillmentContext::new_in_snapshot()) + match tcx.sess.opts.unstable_opts.trait_solver { + TraitSolver::Stock => Box::new(FulfillmentContext::new_in_snapshot()), + TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new_in_snapshot()), + TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()), } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 8a08c7533aa..ac52316d9c9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -40,6 +40,7 @@ use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, }; +use rustc_session::config::TraitSolver; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::symbol::sym; @@ -1167,7 +1168,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::WellFormed(ty) => { - if !self.tcx.sess.opts.unstable_opts.chalk { + if self.tcx.sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk { // WF predicates cannot themselves make // errors. They can only block due to // ambiguity; otherwise, they always diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 466641ea6df..15526b34ed2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -15,6 +15,7 @@ use rustc_middle::ty::{ self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, }; +use rustc_session::config::TraitSolver; use rustc_span::def_id::DefId; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; @@ -767,8 +768,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations"); // FIXME: Chalk - - if !self.tcx().sess.opts.unstable_opts.chalk { + if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk { nested.push(obligation.with( self.tcx(), ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)), diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index e2d10f550c3..86afac113d7 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; +use rustc_session::config::TraitSolver; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -121,7 +122,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // are any errors at that point, so outside of type inference you can be // sure that this will succeed without errors anyway. - if tcx.sess.opts.unstable_opts.chalk { + if tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Chalk { let environment = well_formed_types_in_env(tcx, def_id); predicates.extend(environment); } -- cgit 1.4.1-3-g733a5 From 1e81f9a47fb801fab1c06ba40b06347ffebbd066 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 2 Jan 2023 23:18:00 +0000 Subject: Update tests, etc --- src/test/rustdoc-ui/z-help.stdout | 2 +- src/test/ui/chalkify/arithmetic.rs | 2 +- src/test/ui/chalkify/assert.rs | 2 +- src/test/ui/chalkify/basic.rs | 2 +- src/test/ui/chalkify/bugs/async.rs | 2 +- src/test/ui/chalkify/builtin-copy-clone.rs | 2 +- src/test/ui/chalkify/chalk_initial_program.rs | 2 +- src/test/ui/chalkify/closure.rs | 2 +- src/test/ui/chalkify/generic_impls.rs | 2 +- src/test/ui/chalkify/impl_wf.rs | 2 +- src/test/ui/chalkify/impl_wf_2.rs | 2 +- src/test/ui/chalkify/inherent_impl.rs | 2 +- src/test/ui/chalkify/inherent_impl_min.rs | 2 +- src/test/ui/chalkify/lower_env1.rs | 2 +- src/test/ui/chalkify/lower_env2.rs | 2 +- src/test/ui/chalkify/lower_env3.rs | 2 +- src/test/ui/chalkify/lower_impl.rs | 2 +- src/test/ui/chalkify/lower_struct.rs | 2 +- src/test/ui/chalkify/lower_trait.rs | 2 +- src/test/ui/chalkify/lower_trait_higher_rank.rs | 2 +- src/test/ui/chalkify/lower_trait_where_clause.rs | 2 +- src/test/ui/chalkify/println.rs | 2 +- src/test/ui/chalkify/projection.rs | 2 +- src/test/ui/chalkify/recursive_where_clause_on_type.rs | 2 +- src/test/ui/chalkify/super_trait.rs | 2 +- src/test/ui/chalkify/trait-objects.rs | 2 +- src/test/ui/chalkify/trait_implied_bound.rs | 2 +- src/test/ui/chalkify/type_implied_bound.rs | 2 +- src/test/ui/chalkify/type_inference.rs | 2 +- src/test/ui/chalkify/type_wf.rs | 2 +- src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs | 2 +- src/tools/compiletest/src/runtest.rs | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 9bd6c5fedf5..0464613dc6e 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -8,7 +8,6 @@ -Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64 -Z cf-protection=val -- instrument control-flow architecture protection -Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use - -Z chalk=val -- enable the experimental Chalk-based trait solving engine -Z codegen-backend=val -- the backend to use -Z combine-cgu=val -- combine CGUs into a single one -Z crate-attr=val -- inject the given attribute in the crate @@ -175,6 +174,7 @@ -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted + -Z trait-solver=val -- specify the trait solver mode used by rustc (default: stock) -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output diff --git a/src/test/ui/chalkify/arithmetic.rs b/src/test/ui/chalkify/arithmetic.rs index a20acce4c76..6c78a71b0fc 100644 --- a/src/test/ui/chalkify/arithmetic.rs +++ b/src/test/ui/chalkify/arithmetic.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk fn main() { 1 + 2; diff --git a/src/test/ui/chalkify/assert.rs b/src/test/ui/chalkify/assert.rs index f4ebf91924c..834c8935e76 100644 --- a/src/test/ui/chalkify/assert.rs +++ b/src/test/ui/chalkify/assert.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk fn main() { assert_eq!(1, 1); diff --git a/src/test/ui/chalkify/basic.rs b/src/test/ui/chalkify/basic.rs index dbd60fc8bb1..4a7cd939669 100644 --- a/src/test/ui/chalkify/basic.rs +++ b/src/test/ui/chalkify/basic.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo {} diff --git a/src/test/ui/chalkify/bugs/async.rs b/src/test/ui/chalkify/bugs/async.rs index ae5224dbd6f..ed0f5dc9bd3 100644 --- a/src/test/ui/chalkify/bugs/async.rs +++ b/src/test/ui/chalkify/bugs/async.rs @@ -1,6 +1,6 @@ // check-fail // known-bug: unknown -// compile-flags: -Z chalk --edition=2021 +// compile-flags: -Z trait-solver=chalk --edition=2021 fn main() -> () {} diff --git a/src/test/ui/chalkify/builtin-copy-clone.rs b/src/test/ui/chalkify/builtin-copy-clone.rs index 7712e946542..a478c006ef1 100644 --- a/src/test/ui/chalkify/builtin-copy-clone.rs +++ b/src/test/ui/chalkify/builtin-copy-clone.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk // Test that `Clone` is correctly implemented for builtin types. diff --git a/src/test/ui/chalkify/chalk_initial_program.rs b/src/test/ui/chalkify/chalk_initial_program.rs index df25bad622b..21de72b6fcc 100644 --- a/src/test/ui/chalkify/chalk_initial_program.rs +++ b/src/test/ui/chalkify/chalk_initial_program.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/closure.rs b/src/test/ui/chalkify/closure.rs index 568e2e30c41..a908a1e97ec 100644 --- a/src/test/ui/chalkify/closure.rs +++ b/src/test/ui/chalkify/closure.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk fn main() -> () { let t = || {}; diff --git a/src/test/ui/chalkify/generic_impls.rs b/src/test/ui/chalkify/generic_impls.rs index d70c6f8055d..7d33e12d8be 100644 --- a/src/test/ui/chalkify/generic_impls.rs +++ b/src/test/ui/chalkify/generic_impls.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/impl_wf.rs b/src/test/ui/chalkify/impl_wf.rs index 66f57c2d110..c8dfd4c3a5b 100644 --- a/src/test/ui/chalkify/impl_wf.rs +++ b/src/test/ui/chalkify/impl_wf.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo: Sized { } diff --git a/src/test/ui/chalkify/impl_wf_2.rs b/src/test/ui/chalkify/impl_wf_2.rs index 758a7185e39..325044ad634 100644 --- a/src/test/ui/chalkify/impl_wf_2.rs +++ b/src/test/ui/chalkify/impl_wf_2.rs @@ -1,6 +1,6 @@ // Split out of impl_wf.rs to work around rust aborting compilation early -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo: Sized { } diff --git a/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs index a2730219fbe..f0f24d485cd 100644 --- a/src/test/ui/chalkify/inherent_impl.rs +++ b/src/test/ui/chalkify/inherent_impl.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/inherent_impl_min.rs b/src/test/ui/chalkify/inherent_impl_min.rs index 774c46e401c..3eda7102dec 100644 --- a/src/test/ui/chalkify/inherent_impl_min.rs +++ b/src/test/ui/chalkify/inherent_impl_min.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/lower_env1.rs b/src/test/ui/chalkify/lower_env1.rs index e3c75695921..c8762001e6a 100644 --- a/src/test/ui/chalkify/lower_env1.rs +++ b/src/test/ui/chalkify/lower_env1.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk #![allow(dead_code)] diff --git a/src/test/ui/chalkify/lower_env2.rs b/src/test/ui/chalkify/lower_env2.rs index b5432ce0e30..7d4f81f12ea 100644 --- a/src/test/ui/chalkify/lower_env2.rs +++ b/src/test/ui/chalkify/lower_env2.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk #![allow(dead_code)] diff --git a/src/test/ui/chalkify/lower_env3.rs b/src/test/ui/chalkify/lower_env3.rs index 673f08d78ab..5b70c4abbb5 100644 --- a/src/test/ui/chalkify/lower_env3.rs +++ b/src/test/ui/chalkify/lower_env3.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk #![allow(dead_code)] diff --git a/src/test/ui/chalkify/lower_impl.rs b/src/test/ui/chalkify/lower_impl.rs index f586cf08391..6f79b3ba386 100644 --- a/src/test/ui/chalkify/lower_impl.rs +++ b/src/test/ui/chalkify/lower_impl.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/lower_struct.rs b/src/test/ui/chalkify/lower_struct.rs index 94a0716d383..6be0d4dd5bd 100644 --- a/src/test/ui/chalkify/lower_struct.rs +++ b/src/test/ui/chalkify/lower_struct.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk struct Foo<'a, T> where Box: Clone { _x: std::marker::PhantomData<&'a T>, diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs index d8f6180ceb3..8f5b358220b 100644 --- a/src/test/ui/chalkify/lower_trait.rs +++ b/src/test/ui/chalkify/lower_trait.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Bar { } diff --git a/src/test/ui/chalkify/lower_trait_higher_rank.rs b/src/test/ui/chalkify/lower_trait_higher_rank.rs index a48979491a1..f04a1deea87 100644 --- a/src/test/ui/chalkify/lower_trait_higher_rank.rs +++ b/src/test/ui/chalkify/lower_trait_higher_rank.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8 { diff --git a/src/test/ui/chalkify/lower_trait_where_clause.rs b/src/test/ui/chalkify/lower_trait_where_clause.rs index 19cff8db7cb..a21d2f31963 100644 --- a/src/test/ui/chalkify/lower_trait_where_clause.rs +++ b/src/test/ui/chalkify/lower_trait_where_clause.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk use std::borrow::Borrow; diff --git a/src/test/ui/chalkify/println.rs b/src/test/ui/chalkify/println.rs index 0f0df29019e..edddc382152 100644 --- a/src/test/ui/chalkify/println.rs +++ b/src/test/ui/chalkify/println.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk fn main() { println!("hello"); diff --git a/src/test/ui/chalkify/projection.rs b/src/test/ui/chalkify/projection.rs index d6a8dd7a4a2..19bb2ae1497 100644 --- a/src/test/ui/chalkify/projection.rs +++ b/src/test/ui/chalkify/projection.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.rs b/src/test/ui/chalkify/recursive_where_clause_on_type.rs index 87324a5f79b..5855f000c7b 100644 --- a/src/test/ui/chalkify/recursive_where_clause_on_type.rs +++ b/src/test/ui/chalkify/recursive_where_clause_on_type.rs @@ -1,6 +1,6 @@ // FIXME(chalk): should fail, see comments // check-fail -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk #![feature(trivial_bounds)] diff --git a/src/test/ui/chalkify/super_trait.rs b/src/test/ui/chalkify/super_trait.rs index eeff9fd9b80..540ae51e57f 100644 --- a/src/test/ui/chalkify/super_trait.rs +++ b/src/test/ui/chalkify/super_trait.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } trait Bar: Foo { } diff --git a/src/test/ui/chalkify/trait-objects.rs b/src/test/ui/chalkify/trait-objects.rs index d56abc42bf5..144d9788b82 100644 --- a/src/test/ui/chalkify/trait-objects.rs +++ b/src/test/ui/chalkify/trait-objects.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk use std::fmt::Display; diff --git a/src/test/ui/chalkify/trait_implied_bound.rs b/src/test/ui/chalkify/trait_implied_bound.rs index 8a2e1cf5990..f97dbf6b7e7 100644 --- a/src/test/ui/chalkify/trait_implied_bound.rs +++ b/src/test/ui/chalkify/trait_implied_bound.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } trait Bar where U: Foo { } diff --git a/src/test/ui/chalkify/type_implied_bound.rs b/src/test/ui/chalkify/type_implied_bound.rs index 8673f5319bd..70f1b4265e4 100644 --- a/src/test/ui/chalkify/type_implied_bound.rs +++ b/src/test/ui/chalkify/type_implied_bound.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Eq { } trait Hash: Eq { } diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs index 369777a7904..d7167d0dc57 100644 --- a/src/test/ui/chalkify/type_inference.rs +++ b/src/test/ui/chalkify/type_inference.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } impl Foo for i32 { } diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs index eeeefcfb7dd..37d2f5ca832 100644 --- a/src/test/ui/chalkify/type_wf.rs +++ b/src/test/ui/chalkify/type_wf.rs @@ -1,5 +1,5 @@ // check-fail -// compile-flags: -Z chalk +// compile-flags: -Z trait-solver=chalk trait Foo { } diff --git a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs index 79844dcbdac..c177655c5ac 100644 --- a/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs +++ b/src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs @@ -1,5 +1,5 @@ // A test exploiting the bug behind #25860 except with -// implied trait bounds which currently don't exist without `-Zchalk`. +// implied trait bounds which currently don't exist without `-Ztrait-solver=chalk`. use std::marker::PhantomData; struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) where diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7a3c0d28fc3..7e48dd20660 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2011,7 +2011,7 @@ impl<'test> TestCx<'test> { rustc.args(&["-Zpolonius"]); } Some(CompareMode::Chalk) => { - rustc.args(&["-Zchalk"]); + rustc.args(&["-Ztrait-solver=chalk"]); } Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => { rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]); -- cgit 1.4.1-3-g733a5 From 8b0f43b19dcd97cc6b31c2d02b5526a48dd93c06 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 4 Jan 2023 16:49:38 +0000 Subject: Rename stock solver to classic --- compiler/rustc_session/src/config.rs | 4 ++-- compiler/rustc_session/src/options.rs | 10 ++++++---- compiler/rustc_trait_selection/src/traits/engine.rs | 4 ++-- src/test/rustdoc-ui/z-help.stdout | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 4f1175856dc..a87e820386e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -556,8 +556,8 @@ pub enum PrintRequest { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum TraitSolver { - /// Stock trait solver in `rustc_trait_selection::traits::select` - Stock, + /// Classic trait solver in `rustc_trait_selection::traits::select` + Classic, /// Chalk trait solver Chalk, /// Experimental trait solver in `rustc_trait_selection::solve` diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9ce50246b08..043a60a1c53 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -383,7 +383,7 @@ mod desc { pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; pub const parse_trait_solver: &str = - "one of the supported solver modes (`stock`, `chalk`, or `next`)"; + "one of the supported solver modes (`classic`, `chalk`, or `next`)"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -884,9 +884,11 @@ mod parse { pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool { match v { - Some("stock") => *slot = TraitSolver::Stock, + Some("classic") => *slot = TraitSolver::Classic, Some("chalk") => *slot = TraitSolver::Chalk, Some("next") => *slot = TraitSolver::Next, + // default trait solver is subject to change.. + Some("default") => *slot = TraitSolver::Classic, _ => return false, } true @@ -1619,8 +1621,8 @@ options! { "for every macro invocation, print its name and arguments (default: no)"), track_diagnostics: bool = (false, parse_bool, [UNTRACKED], "tracks where in rustc a diagnostic was emitted"), - trait_solver: TraitSolver = (TraitSolver::Stock, parse_trait_solver, [TRACKED], - "specify the trait solver mode used by rustc (default: stock)"), + trait_solver: TraitSolver = (TraitSolver::Classic, parse_trait_solver, [TRACKED], + "specify the trait solver mode used by rustc (default: classic)"), // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved // alongside query results and changes to translation options can affect diagnostics - so // translation options should be tracked. diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index bd56d058a49..bc6d9d4b922 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -32,7 +32,7 @@ pub trait TraitEngineExt<'tcx> { impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> Box { match tcx.sess.opts.unstable_opts.trait_solver { - TraitSolver::Stock => Box::new(FulfillmentContext::new()), + TraitSolver::Classic => Box::new(FulfillmentContext::new()), TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new()), TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()), } @@ -40,7 +40,7 @@ impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { fn new_in_snapshot(tcx: TyCtxt<'tcx>) -> Box { match tcx.sess.opts.unstable_opts.trait_solver { - TraitSolver::Stock => Box::new(FulfillmentContext::new_in_snapshot()), + TraitSolver::Classic => Box::new(FulfillmentContext::new_in_snapshot()), TraitSolver::Chalk => Box::new(ChalkFulfillmentContext::new_in_snapshot()), TraitSolver::Next => Box::new(NextFulfillmentCtxt::new()), } diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 0464613dc6e..537dc92be19 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -174,7 +174,7 @@ -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted - -Z trait-solver=val -- specify the trait solver mode used by rustc (default: stock) + -Z trait-solver=val -- specify the trait solver mode used by rustc (default: classic) -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics -Z translate-lang=val -- language identifier for diagnostic output -- cgit 1.4.1-3-g733a5 From 7ffcedf6659d30c4a076d89b2586b385ad2f2d16 Mon Sep 17 00:00:00 2001 From: Caio Date: Wed, 4 Jan 2023 16:44:30 -0300 Subject: Move tests --- src/test/ui/associated-consts/issue-105330.rs | 21 ++++ src/test/ui/associated-consts/issue-105330.stderr | 113 +++++++++++++++++++++ src/test/ui/associated-types/issue-25700-1.rs | 13 +++ src/test/ui/associated-types/issue-25700-2.rs | 23 +++++ src/test/ui/associated-types/issue-25700.rs | 14 +++ src/test/ui/associated-types/issue-25700.stderr | 13 +++ .../ui/codegen/issue-82859-slice-miscompile.rs | 19 ++++ src/test/ui/command/issue-10626.rs | 26 +++++ src/test/ui/drop/issue-2734.rs | 22 ++++ src/test/ui/dropck/issue-34053.rs | 30 ++++++ src/test/ui/enum-discriminant/issue-72554.rs | 22 ++++ src/test/ui/enum-discriminant/issue-72554.stderr | 17 ++++ src/test/ui/extern/issue-13655.rs | 32 ++++++ src/test/ui/issues/issue-105330.rs | 21 ---- src/test/ui/issues/issue-105330.stderr | 113 --------------------- src/test/ui/issues/issue-10536.rs | 19 ---- src/test/ui/issues/issue-10536.stderr | 14 --- src/test/ui/issues/issue-10626.rs | 26 ----- src/test/ui/issues/issue-13655.rs | 32 ------ src/test/ui/issues/issue-18937-1.rs | 21 ---- src/test/ui/issues/issue-18937.rs | 40 -------- src/test/ui/issues/issue-18937.stderr | 14 --- src/test/ui/issues/issue-25700-1.rs | 13 --- src/test/ui/issues/issue-25700-2.rs | 23 ----- src/test/ui/issues/issue-25700.rs | 14 --- src/test/ui/issues/issue-25700.stderr | 13 --- src/test/ui/issues/issue-2734.rs | 22 ---- src/test/ui/issues/issue-31173.rs | 15 --- src/test/ui/issues/issue-31173.stderr | 45 -------- src/test/ui/issues/issue-34053.rs | 30 ------ src/test/ui/issues/issue-54189.rs | 6 -- src/test/ui/issues/issue-54189.stderr | 9 -- src/test/ui/issues/issue-72554.rs | 22 ---- src/test/ui/issues/issue-72554.stderr | 17 ---- src/test/ui/issues/issue-82859-slice-miscompile.rs | 19 ---- src/test/ui/issues/issue-99875.rs | 16 --- src/test/ui/issues/issue-99875.stderr | 33 ------ src/test/ui/macros/issue-10536.rs | 19 ++++ src/test/ui/macros/issue-10536.stderr | 14 +++ src/test/ui/nll/issue-54189.rs | 6 ++ src/test/ui/nll/issue-54189.stderr | 9 ++ src/test/ui/traits/issue-99875.rs | 16 +++ src/test/ui/traits/issue-99875.stderr | 33 ++++++ src/test/ui/typeck/issue-18937-1.rs | 21 ++++ src/test/ui/typeck/issue-18937.rs | 40 ++++++++ src/test/ui/typeck/issue-18937.stderr | 14 +++ src/test/ui/typeck/issue-31173.rs | 15 +++ src/test/ui/typeck/issue-31173.stderr | 45 ++++++++ src/tools/tidy/src/ui_tests.rs | 2 +- 49 files changed, 598 insertions(+), 598 deletions(-) create mode 100644 src/test/ui/associated-consts/issue-105330.rs create mode 100644 src/test/ui/associated-consts/issue-105330.stderr create mode 100644 src/test/ui/associated-types/issue-25700-1.rs create mode 100644 src/test/ui/associated-types/issue-25700-2.rs create mode 100644 src/test/ui/associated-types/issue-25700.rs create mode 100644 src/test/ui/associated-types/issue-25700.stderr create mode 100644 src/test/ui/codegen/issue-82859-slice-miscompile.rs create mode 100644 src/test/ui/command/issue-10626.rs create mode 100644 src/test/ui/drop/issue-2734.rs create mode 100644 src/test/ui/dropck/issue-34053.rs create mode 100644 src/test/ui/enum-discriminant/issue-72554.rs create mode 100644 src/test/ui/enum-discriminant/issue-72554.stderr create mode 100644 src/test/ui/extern/issue-13655.rs delete mode 100644 src/test/ui/issues/issue-105330.rs delete mode 100644 src/test/ui/issues/issue-105330.stderr delete mode 100644 src/test/ui/issues/issue-10536.rs delete mode 100644 src/test/ui/issues/issue-10536.stderr delete mode 100644 src/test/ui/issues/issue-10626.rs delete mode 100644 src/test/ui/issues/issue-13655.rs delete mode 100644 src/test/ui/issues/issue-18937-1.rs delete mode 100644 src/test/ui/issues/issue-18937.rs delete mode 100644 src/test/ui/issues/issue-18937.stderr delete mode 100644 src/test/ui/issues/issue-25700-1.rs delete mode 100644 src/test/ui/issues/issue-25700-2.rs delete mode 100644 src/test/ui/issues/issue-25700.rs delete mode 100644 src/test/ui/issues/issue-25700.stderr delete mode 100644 src/test/ui/issues/issue-2734.rs delete mode 100644 src/test/ui/issues/issue-31173.rs delete mode 100644 src/test/ui/issues/issue-31173.stderr delete mode 100644 src/test/ui/issues/issue-34053.rs delete mode 100644 src/test/ui/issues/issue-54189.rs delete mode 100644 src/test/ui/issues/issue-54189.stderr delete mode 100644 src/test/ui/issues/issue-72554.rs delete mode 100644 src/test/ui/issues/issue-72554.stderr delete mode 100644 src/test/ui/issues/issue-82859-slice-miscompile.rs delete mode 100644 src/test/ui/issues/issue-99875.rs delete mode 100644 src/test/ui/issues/issue-99875.stderr create mode 100644 src/test/ui/macros/issue-10536.rs create mode 100644 src/test/ui/macros/issue-10536.stderr create mode 100644 src/test/ui/nll/issue-54189.rs create mode 100644 src/test/ui/nll/issue-54189.stderr create mode 100644 src/test/ui/traits/issue-99875.rs create mode 100644 src/test/ui/traits/issue-99875.stderr create mode 100644 src/test/ui/typeck/issue-18937-1.rs create mode 100644 src/test/ui/typeck/issue-18937.rs create mode 100644 src/test/ui/typeck/issue-18937.stderr create mode 100644 src/test/ui/typeck/issue-31173.rs create mode 100644 src/test/ui/typeck/issue-31173.stderr diff --git a/src/test/ui/associated-consts/issue-105330.rs b/src/test/ui/associated-consts/issue-105330.rs new file mode 100644 index 00000000000..86e45f10b0e --- /dev/null +++ b/src/test/ui/associated-consts/issue-105330.rs @@ -0,0 +1,21 @@ +pub trait TraitWAssocConst { + const A: usize; +} +pub struct Demo {} + +impl TraitWAssocConst for impl Demo { //~ ERROR E0404 + //~^ ERROR E0562 + pubconst A: str = 32; //~ ERROR expected one of +} + +fn foo>() { //~ ERROR E0658 + foo::()(); //~ ERROR E0271 + //~^ ERROR E0618 + //~| ERROR E0277 +} + +fn main>() { //~ ERROR E0131 + //~^ ERROR E0658 + foo::(); //~ ERROR E0277 + //~^ ERROR E0271 +} diff --git a/src/test/ui/associated-consts/issue-105330.stderr b/src/test/ui/associated-consts/issue-105330.stderr new file mode 100644 index 00000000000..30c380152a5 --- /dev/null +++ b/src/test/ui/associated-consts/issue-105330.stderr @@ -0,0 +1,113 @@ +error: expected one of `!` or `::`, found `A` + --> $DIR/issue-105330.rs:8:14 + | +LL | impl TraitWAssocConst for impl Demo { + | - while parsing this item list starting here +LL | +LL | pubconst A: str = 32; + | ^ expected one of `!` or `::` +LL | } + | - the item list ends here + +error[E0404]: expected trait, found struct `Demo` + --> $DIR/issue-105330.rs:6:32 + | +LL | impl TraitWAssocConst for impl Demo { + | ^^^^ not a trait + +error[E0658]: associated const equality is incomplete + --> $DIR/issue-105330.rs:11:28 + | +LL | fn foo>() { + | ^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error[E0658]: associated const equality is incomplete + --> $DIR/issue-105330.rs:17:29 + | +LL | fn main>() { + | ^^^^ + | + = note: see issue #92827 for more information + = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type + --> $DIR/issue-105330.rs:6:27 + | +LL | impl TraitWAssocConst for impl Demo { + | ^^^^^^^^^ + +error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied + --> $DIR/issue-105330.rs:12:11 + | +LL | foo::()(); + | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` + | +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:11 + | +LL | fn foo>() { + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` + +error[E0271]: type mismatch resolving `::A == 32` + --> $DIR/issue-105330.rs:12:11 + | +LL | foo::()(); + | ^^^^ expected `32`, found `::A` + | + = note: expected constant `32` + found constant `::A` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:28 + | +LL | fn foo>() { + | ^^^^ required by this bound in `foo` + +error[E0618]: expected function, found `()` + --> $DIR/issue-105330.rs:12:5 + | +LL | fn foo>() { + | ----------------------------------- `foo::` defined here returns `()` +LL | foo::()(); + | ^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied + --> $DIR/issue-105330.rs:19:11 + | +LL | foo::(); + | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` + | +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:11 + | +LL | fn foo>() { + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` + +error[E0271]: type mismatch resolving `::A == 32` + --> $DIR/issue-105330.rs:19:11 + | +LL | foo::(); + | ^^^^ expected `32`, found `::A` + | + = note: expected constant `32` + found constant `::A` +note: required by a bound in `foo` + --> $DIR/issue-105330.rs:11:28 + | +LL | fn foo>() { + | ^^^^ required by this bound in `foo` + +error[E0131]: `main` function is not allowed to have generic parameters + --> $DIR/issue-105330.rs:17:8 + | +LL | fn main>() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. +For more information about an error, try `rustc --explain E0131`. diff --git a/src/test/ui/associated-types/issue-25700-1.rs b/src/test/ui/associated-types/issue-25700-1.rs new file mode 100644 index 00000000000..5e71a52ba4e --- /dev/null +++ b/src/test/ui/associated-types/issue-25700-1.rs @@ -0,0 +1,13 @@ +// run-pass +struct S(#[allow(unused_tuple_struct_fields)] Option<&'static T>); + +trait Tr { type Out; } +impl Tr for T { type Out = T; } + +impl Copy for S where S: Tr {} +impl Clone for S where S: Tr { + fn clone(&self) -> Self { *self } +} +fn main() { + S::<()>(None); +} diff --git a/src/test/ui/associated-types/issue-25700-2.rs b/src/test/ui/associated-types/issue-25700-2.rs new file mode 100644 index 00000000000..89b1db496f9 --- /dev/null +++ b/src/test/ui/associated-types/issue-25700-2.rs @@ -0,0 +1,23 @@ +// run-pass +pub trait Parser { + type Input; +} + +pub struct Iter(#[allow(unused_tuple_struct_fields)] P, P::Input); + +#[allow(unused_tuple_struct_fields)] +pub struct Map(P, F); +impl Parser for Map where F: FnMut(P) { + type Input = u8; +} + +trait AstId { type Untyped; } +impl AstId for u32 { type Untyped = u32; } + +fn record_type(i: Id::Untyped) -> u8 { + Iter(Map(i, |_: Id::Untyped| {}), 42).1 +} + +pub fn main() { + assert_eq!(record_type::(3), 42); +} diff --git a/src/test/ui/associated-types/issue-25700.rs b/src/test/ui/associated-types/issue-25700.rs new file mode 100644 index 00000000000..e5b9a97523d --- /dev/null +++ b/src/test/ui/associated-types/issue-25700.rs @@ -0,0 +1,14 @@ +struct S(#[allow(unused_tuple_struct_fields)] Option<&'static T>); + +trait Tr { type Out; } +impl Tr for T { type Out = T; } + +impl Copy for S where S: Tr {} +impl Clone for S where S: Tr { + fn clone(&self) -> Self { *self } +} +fn main() { + let t = S::<()>(None); + drop(t); + drop(t); //~ ERROR use of moved value +} diff --git a/src/test/ui/associated-types/issue-25700.stderr b/src/test/ui/associated-types/issue-25700.stderr new file mode 100644 index 00000000000..fa309a55c3c --- /dev/null +++ b/src/test/ui/associated-types/issue-25700.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `t` + --> $DIR/issue-25700.rs:13:10 + | +LL | let t = S::<()>(None); + | - move occurs because `t` has type `S<()>`, which does not implement the `Copy` trait +LL | drop(t); + | - value moved here +LL | drop(t); + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/codegen/issue-82859-slice-miscompile.rs b/src/test/ui/codegen/issue-82859-slice-miscompile.rs new file mode 100644 index 00000000000..b64eb499071 --- /dev/null +++ b/src/test/ui/codegen/issue-82859-slice-miscompile.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -Copt-level=0 -Cdebuginfo=2 + +// Make sure LLVM does not miscompile this. + +fn indirect_get_slice() -> &'static [usize] { + &[] +} + +#[inline(always)] +fn get_slice() -> &'static [usize] { + let ret = indirect_get_slice(); + ret +} + +fn main() { + let output = get_slice().len(); + assert_eq!(output, 0); +} diff --git a/src/test/ui/command/issue-10626.rs b/src/test/ui/command/issue-10626.rs new file mode 100644 index 00000000000..696a2dd1657 --- /dev/null +++ b/src/test/ui/command/issue-10626.rs @@ -0,0 +1,26 @@ +// run-pass +// ignore-emscripten no processes +// ignore-sgx no processes + +// Make sure that if a process doesn't have its stdio/stderr descriptors set up +// that we don't die in a large ball of fire + +use std::env; +use std::process::{Command, Stdio}; + +pub fn main () { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + for _ in 0..1000 { + println!("hello?"); + } + for _ in 0..1000 { + println!("hello?"); + } + return; + } + + let mut p = Command::new(&args[0]); + p.arg("child").stdout(Stdio::null()).stderr(Stdio::null()); + println!("{:?}", p.spawn().unwrap().wait()); +} diff --git a/src/test/ui/drop/issue-2734.rs b/src/test/ui/drop/issue-2734.rs new file mode 100644 index 00000000000..df4f394dc37 --- /dev/null +++ b/src/test/ui/drop/issue-2734.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +trait hax { + fn dummy(&self) { } +} +impl hax for A { } + +fn perform_hax(x: Box) -> Box { + Box::new(x) as Box +} + +fn deadcode() { + perform_hax(Box::new("deadcode".to_string())); +} + +pub fn main() { + let _ = perform_hax(Box::new(42)); +} diff --git a/src/test/ui/dropck/issue-34053.rs b/src/test/ui/dropck/issue-34053.rs new file mode 100644 index 00000000000..fa23ae8f95b --- /dev/null +++ b/src/test/ui/dropck/issue-34053.rs @@ -0,0 +1,30 @@ +// run-pass +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); + +struct A(i32); + +impl Drop for A { + fn drop(&mut self) { + // update global drop count + DROP_COUNTER.fetch_add(1, Ordering::SeqCst); + } +} + +static FOO: A = A(123); +const BAR: A = A(456); + +impl A { + const BAZ: A = A(789); +} + +fn main() { + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); + assert_eq!(&FOO.0, &123); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); + assert_eq!(BAR.0, 456); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1); + assert_eq!(A::BAZ.0, 789); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2); +} diff --git a/src/test/ui/enum-discriminant/issue-72554.rs b/src/test/ui/enum-discriminant/issue-72554.rs new file mode 100644 index 00000000000..54f7e9ac592 --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-72554.rs @@ -0,0 +1,22 @@ +use std::collections::BTreeSet; + +#[derive(Hash)] +pub enum ElemDerived { + //~^ ERROR recursive type `ElemDerived` has infinite size + A(ElemDerived) +} + + +pub enum Elem { + Derived(ElemDerived) +} + +pub struct Set(BTreeSet); + +impl Set { + pub fn into_iter(self) -> impl Iterator { + self.0.into_iter() + } +} + +fn main() {} diff --git a/src/test/ui/enum-discriminant/issue-72554.stderr b/src/test/ui/enum-discriminant/issue-72554.stderr new file mode 100644 index 00000000000..d12be539f7c --- /dev/null +++ b/src/test/ui/enum-discriminant/issue-72554.stderr @@ -0,0 +1,17 @@ +error[E0072]: recursive type `ElemDerived` has infinite size + --> $DIR/issue-72554.rs:4:1 + | +LL | pub enum ElemDerived { + | ^^^^^^^^^^^^^^^^^^^^ +LL | +LL | A(ElemDerived) + | ----------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | A(Box) + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/extern/issue-13655.rs b/src/test/ui/extern/issue-13655.rs new file mode 100644 index 00000000000..6dd1847995f --- /dev/null +++ b/src/test/ui/extern/issue-13655.rs @@ -0,0 +1,32 @@ +// run-pass +#![feature(fn_traits, unboxed_closures)] +use std::ops::Fn; + +struct Foo(T); + +impl Fn<()> for Foo { + extern "rust-call" fn call(&self, _: ()) -> T { + match *self { + Foo(t) => t + } + } +} + +impl FnMut<()> for Foo { + extern "rust-call" fn call_mut(&mut self, _: ()) -> T { + self.call(()) + } +} + +impl FnOnce<()> for Foo { + type Output = T; + + extern "rust-call" fn call_once(self, _: ()) -> T { + self.call(()) + } +} + +fn main() { + let t: u8 = 1; + println!("{}", Foo(t)()); +} diff --git a/src/test/ui/issues/issue-105330.rs b/src/test/ui/issues/issue-105330.rs deleted file mode 100644 index 86e45f10b0e..00000000000 --- a/src/test/ui/issues/issue-105330.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub trait TraitWAssocConst { - const A: usize; -} -pub struct Demo {} - -impl TraitWAssocConst for impl Demo { //~ ERROR E0404 - //~^ ERROR E0562 - pubconst A: str = 32; //~ ERROR expected one of -} - -fn foo>() { //~ ERROR E0658 - foo::()(); //~ ERROR E0271 - //~^ ERROR E0618 - //~| ERROR E0277 -} - -fn main>() { //~ ERROR E0131 - //~^ ERROR E0658 - foo::(); //~ ERROR E0277 - //~^ ERROR E0271 -} diff --git a/src/test/ui/issues/issue-105330.stderr b/src/test/ui/issues/issue-105330.stderr deleted file mode 100644 index 30c380152a5..00000000000 --- a/src/test/ui/issues/issue-105330.stderr +++ /dev/null @@ -1,113 +0,0 @@ -error: expected one of `!` or `::`, found `A` - --> $DIR/issue-105330.rs:8:14 - | -LL | impl TraitWAssocConst for impl Demo { - | - while parsing this item list starting here -LL | -LL | pubconst A: str = 32; - | ^ expected one of `!` or `::` -LL | } - | - the item list ends here - -error[E0404]: expected trait, found struct `Demo` - --> $DIR/issue-105330.rs:6:32 - | -LL | impl TraitWAssocConst for impl Demo { - | ^^^^ not a trait - -error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable - -error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:17:29 - | -LL | fn main>() { - | ^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable - -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type - --> $DIR/issue-105330.rs:6:27 - | -LL | impl TraitWAssocConst for impl Demo { - | ^^^^^^^^^ - -error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` - | -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:11 - | -LL | fn foo>() { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - -error[E0618]: expected function, found `()` - --> $DIR/issue-105330.rs:12:5 - | -LL | fn foo>() { - | ----------------------------------- `foo::` defined here returns `()` -LL | foo::()(); - | ^^^^^^^^^^^^^-- - | | - | call expression requires function - -error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:19:11 - | -LL | foo::(); - | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` - | -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:11 - | -LL | fn foo>() { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:19:11 - | -LL | foo::(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - -error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-105330.rs:17:8 - | -LL | fn main>() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters - -error: aborting due to 11 previous errors - -Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. -For more information about an error, try `rustc --explain E0131`. diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs deleted file mode 100644 index f536d8f940a..00000000000 --- a/src/test/ui/issues/issue-10536.rs +++ /dev/null @@ -1,19 +0,0 @@ -// We only want to assert that this doesn't ICE, we don't particularly care -// about whether it nor it fails to compile. - -macro_rules! foo{ - () => {{ - macro_rules! bar{() => (())} - 1 - }} -} - -pub fn main() { - foo!(); - - assert!({one! two()}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` - - // regardless of whether nested macro_rules works, the following should at - // least throw a conventional error. - assert!({one! two}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` -} diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr deleted file mode 100644 index cc048445871..00000000000 --- a/src/test/ui/issues/issue-10536.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: expected one of `(`, `[`, or `{`, found `two` - --> $DIR/issue-10536.rs:14:19 - | -LL | assert!({one! two()}); - | ^^^ expected one of `(`, `[`, or `{` - -error: expected one of `(`, `[`, or `{`, found `two` - --> $DIR/issue-10536.rs:18:19 - | -LL | assert!({one! two}); - | ^^^ expected one of `(`, `[`, or `{` - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/issues/issue-10626.rs b/src/test/ui/issues/issue-10626.rs deleted file mode 100644 index 696a2dd1657..00000000000 --- a/src/test/ui/issues/issue-10626.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes - -// Make sure that if a process doesn't have its stdio/stderr descriptors set up -// that we don't die in a large ball of fire - -use std::env; -use std::process::{Command, Stdio}; - -pub fn main () { - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - for _ in 0..1000 { - println!("hello?"); - } - for _ in 0..1000 { - println!("hello?"); - } - return; - } - - let mut p = Command::new(&args[0]); - p.arg("child").stdout(Stdio::null()).stderr(Stdio::null()); - println!("{:?}", p.spawn().unwrap().wait()); -} diff --git a/src/test/ui/issues/issue-13655.rs b/src/test/ui/issues/issue-13655.rs deleted file mode 100644 index 6dd1847995f..00000000000 --- a/src/test/ui/issues/issue-13655.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -#![feature(fn_traits, unboxed_closures)] -use std::ops::Fn; - -struct Foo(T); - -impl Fn<()> for Foo { - extern "rust-call" fn call(&self, _: ()) -> T { - match *self { - Foo(t) => t - } - } -} - -impl FnMut<()> for Foo { - extern "rust-call" fn call_mut(&mut self, _: ()) -> T { - self.call(()) - } -} - -impl FnOnce<()> for Foo { - type Output = T; - - extern "rust-call" fn call_once(self, _: ()) -> T { - self.call(()) - } -} - -fn main() { - let t: u8 = 1; - println!("{}", Foo(t)()); -} diff --git a/src/test/ui/issues/issue-18937-1.rs b/src/test/ui/issues/issue-18937-1.rs deleted file mode 100644 index 57e56d832c6..00000000000 --- a/src/test/ui/issues/issue-18937-1.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-pass -// Test that we are able to type-check this example. In particular, -// knowing that `T: 'a` allows us to deduce that `[U]: 'a` (because -// when `T=[U]` it implies that `U: 'a`). -// -// Regr. test for live code we found in the wild when fixing #18937. - -pub trait Leak { - fn leak<'a>(self) -> &'a T where T: 'a; -} - -impl Leak<[U]> for Vec { - fn leak<'a>(mut self) -> &'a [U] where [U]: 'a { - let r: *mut [U] = &mut self[..]; - std::mem::forget(self); - unsafe { &mut *r } - } -} -fn main() { - println!("Hello, world!"); -} diff --git a/src/test/ui/issues/issue-18937.rs b/src/test/ui/issues/issue-18937.rs deleted file mode 100644 index af85e5b2b02..00000000000 --- a/src/test/ui/issues/issue-18937.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Regression test for #18937. - -use std::fmt; - -#[derive(Debug)] -struct MyString<'a>(&'a String); - -struct B { - list: Vec>, -} - -trait A<'a> { - fn foo(&mut self, f: F) - where F: fmt::Debug + 'a, - Self: Sized; -} - -impl<'a> A<'a> for B { - fn foo(&mut self, f: F) - where F: fmt::Debug + 'static, //~ ERROR impl has stricter - { - self.list.push(Box::new(f)); - } -} - -fn main() { - let mut b = B { list: Vec::new() }; - - // Create a borrowed pointer, put it in `b`, then drop what's borrowing it - let a = "hello".to_string(); - b.foo(MyString(&a)); - - // Drop the data which `b` has a reference to - drop(a); - - // Use the data, probably segfaulting - for b in b.list.iter() { - println!("{:?}", b); - } -} diff --git a/src/test/ui/issues/issue-18937.stderr b/src/test/ui/issues/issue-18937.stderr deleted file mode 100644 index 5e2ba0ef4fc..00000000000 --- a/src/test/ui/issues/issue-18937.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0276]: impl has stricter requirements than trait - --> $DIR/issue-18937.rs:20:31 - | -LL | / fn foo(&mut self, f: F) -LL | | where F: fmt::Debug + 'a, -LL | | Self: Sized; - | |__________________________- definition of `foo` from trait -... -LL | where F: fmt::Debug + 'static, - | ^^^^^^^ impl has extra requirement `F: 'static` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/issues/issue-25700-1.rs b/src/test/ui/issues/issue-25700-1.rs deleted file mode 100644 index 5e71a52ba4e..00000000000 --- a/src/test/ui/issues/issue-25700-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -struct S(#[allow(unused_tuple_struct_fields)] Option<&'static T>); - -trait Tr { type Out; } -impl Tr for T { type Out = T; } - -impl Copy for S where S: Tr {} -impl Clone for S where S: Tr { - fn clone(&self) -> Self { *self } -} -fn main() { - S::<()>(None); -} diff --git a/src/test/ui/issues/issue-25700-2.rs b/src/test/ui/issues/issue-25700-2.rs deleted file mode 100644 index 89b1db496f9..00000000000 --- a/src/test/ui/issues/issue-25700-2.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -pub trait Parser { - type Input; -} - -pub struct Iter(#[allow(unused_tuple_struct_fields)] P, P::Input); - -#[allow(unused_tuple_struct_fields)] -pub struct Map(P, F); -impl Parser for Map where F: FnMut(P) { - type Input = u8; -} - -trait AstId { type Untyped; } -impl AstId for u32 { type Untyped = u32; } - -fn record_type(i: Id::Untyped) -> u8 { - Iter(Map(i, |_: Id::Untyped| {}), 42).1 -} - -pub fn main() { - assert_eq!(record_type::(3), 42); -} diff --git a/src/test/ui/issues/issue-25700.rs b/src/test/ui/issues/issue-25700.rs deleted file mode 100644 index e5b9a97523d..00000000000 --- a/src/test/ui/issues/issue-25700.rs +++ /dev/null @@ -1,14 +0,0 @@ -struct S(#[allow(unused_tuple_struct_fields)] Option<&'static T>); - -trait Tr { type Out; } -impl Tr for T { type Out = T; } - -impl Copy for S where S: Tr {} -impl Clone for S where S: Tr { - fn clone(&self) -> Self { *self } -} -fn main() { - let t = S::<()>(None); - drop(t); - drop(t); //~ ERROR use of moved value -} diff --git a/src/test/ui/issues/issue-25700.stderr b/src/test/ui/issues/issue-25700.stderr deleted file mode 100644 index fa309a55c3c..00000000000 --- a/src/test/ui/issues/issue-25700.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0382]: use of moved value: `t` - --> $DIR/issue-25700.rs:13:10 - | -LL | let t = S::<()>(None); - | - move occurs because `t` has type `S<()>`, which does not implement the `Copy` trait -LL | drop(t); - | - value moved here -LL | drop(t); - | ^ value used here after move - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/issues/issue-2734.rs b/src/test/ui/issues/issue-2734.rs deleted file mode 100644 index df4f394dc37..00000000000 --- a/src/test/ui/issues/issue-2734.rs +++ /dev/null @@ -1,22 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -// pretty-expanded FIXME #23616 - -trait hax { - fn dummy(&self) { } -} -impl hax for A { } - -fn perform_hax(x: Box) -> Box { - Box::new(x) as Box -} - -fn deadcode() { - perform_hax(Box::new("deadcode".to_string())); -} - -pub fn main() { - let _ = perform_hax(Box::new(42)); -} diff --git a/src/test/ui/issues/issue-31173.rs b/src/test/ui/issues/issue-31173.rs deleted file mode 100644 index f678df5b42b..00000000000 --- a/src/test/ui/issues/issue-31173.rs +++ /dev/null @@ -1,15 +0,0 @@ -use std::vec::IntoIter; - -pub fn get_tok(it: &mut IntoIter) { - let mut found_e = false; - - let temp: Vec = it - .take_while(|&x| { - found_e = true; - false - }) - .cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8` - .collect(); //~ ERROR the method -} - -fn main() {} diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr deleted file mode 100644 index f3be99f9bcb..00000000000 --- a/src/test/ui/issues/issue-31173.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error[E0271]: expected `TakeWhile<&mut IntoIter, [closure@issue-31173.rs:7:21]>` to be an iterator that yields `&_`, but it yields `u8` - --> $DIR/issue-31173.rs:11:10 - | -LL | .cloned() - | ^^^^^^ expected reference, found `u8` - | - = note: expected reference `&_` - found type `u8` -note: the method call chain might not have had the expected associated types - --> $DIR/issue-31173.rs:3:20 - | -LL | pub fn get_tok(it: &mut IntoIter) { - | ^^^^^^^^^^^^^^^^^ `Iterator::Item` is `u8` here -... -LL | .take_while(|&x| { - | __________- -LL | | found_e = true; -LL | | false -LL | | }) - | |__________- `Iterator::Item` remains `u8` here -note: required by a bound in `cloned` - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - -error[E0599]: the method `collect` exists for struct `Cloned, [closure@issue-31173.rs:7:21]>>`, but its trait bounds were not satisfied - --> $DIR/issue-31173.rs:12:10 - | -LL | .collect(); - | ^^^^^^^ method cannot be called due to unsatisfied trait bounds - --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL - | - = note: doesn't satisfy `<_ as Iterator>::Item = &_` - --> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL - | - = note: doesn't satisfy `_: Iterator` - | - = note: the following trait bounds were not satisfied: - `, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` - which is required by `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0271, E0599. -For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/issues/issue-34053.rs b/src/test/ui/issues/issue-34053.rs deleted file mode 100644 index fa23ae8f95b..00000000000 --- a/src/test/ui/issues/issue-34053.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass -use std::sync::atomic::{AtomicUsize, Ordering}; - -static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); - -struct A(i32); - -impl Drop for A { - fn drop(&mut self) { - // update global drop count - DROP_COUNTER.fetch_add(1, Ordering::SeqCst); - } -} - -static FOO: A = A(123); -const BAR: A = A(456); - -impl A { - const BAZ: A = A(789); -} - -fn main() { - assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); - assert_eq!(&FOO.0, &123); - assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); - assert_eq!(BAR.0, 456); - assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1); - assert_eq!(A::BAZ.0, 789); - assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2); -} diff --git a/src/test/ui/issues/issue-54189.rs b/src/test/ui/issues/issue-54189.rs deleted file mode 100644 index 70aecc384ef..00000000000 --- a/src/test/ui/issues/issue-54189.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } } -//~^ ERROR binding for associated type `Output` references lifetime `'r` - -fn main() { - let f = bug(); -} diff --git a/src/test/ui/issues/issue-54189.stderr b/src/test/ui/issues/issue-54189.stderr deleted file mode 100644 index 4787abd49d1..00000000000 --- a/src/test/ui/issues/issue-54189.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0582]: binding for associated type `Output` references lifetime `'r`, which does not appear in the trait input types - --> $DIR/issue-54189.rs:1:35 - | -LL | fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } } - | ^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0582`. diff --git a/src/test/ui/issues/issue-72554.rs b/src/test/ui/issues/issue-72554.rs deleted file mode 100644 index 54f7e9ac592..00000000000 --- a/src/test/ui/issues/issue-72554.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::collections::BTreeSet; - -#[derive(Hash)] -pub enum ElemDerived { - //~^ ERROR recursive type `ElemDerived` has infinite size - A(ElemDerived) -} - - -pub enum Elem { - Derived(ElemDerived) -} - -pub struct Set(BTreeSet); - -impl Set { - pub fn into_iter(self) -> impl Iterator { - self.0.into_iter() - } -} - -fn main() {} diff --git a/src/test/ui/issues/issue-72554.stderr b/src/test/ui/issues/issue-72554.stderr deleted file mode 100644 index d12be539f7c..00000000000 --- a/src/test/ui/issues/issue-72554.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0072]: recursive type `ElemDerived` has infinite size - --> $DIR/issue-72554.rs:4:1 - | -LL | pub enum ElemDerived { - | ^^^^^^^^^^^^^^^^^^^^ -LL | -LL | A(ElemDerived) - | ----------- recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -LL | A(Box) - | ++++ + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/issues/issue-82859-slice-miscompile.rs b/src/test/ui/issues/issue-82859-slice-miscompile.rs deleted file mode 100644 index b64eb499071..00000000000 --- a/src/test/ui/issues/issue-82859-slice-miscompile.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// compile-flags: -Copt-level=0 -Cdebuginfo=2 - -// Make sure LLVM does not miscompile this. - -fn indirect_get_slice() -> &'static [usize] { - &[] -} - -#[inline(always)] -fn get_slice() -> &'static [usize] { - let ret = indirect_get_slice(); - ret -} - -fn main() { - let output = get_slice().len(); - assert_eq!(output, 0); -} diff --git a/src/test/ui/issues/issue-99875.rs b/src/test/ui/issues/issue-99875.rs deleted file mode 100644 index cf73fd8d31f..00000000000 --- a/src/test/ui/issues/issue-99875.rs +++ /dev/null @@ -1,16 +0,0 @@ -struct Argument; -struct Return; - -fn function(_: Argument) -> Return { todo!() } - -trait Trait {} -impl Trait for fn(Argument) -> Return {} - -fn takes(_: impl Trait) {} - -fn main() { - takes(function); - //~^ ERROR the trait bound - takes(|_: Argument| -> Return { todo!() }); - //~^ ERROR the trait bound -} diff --git a/src/test/ui/issues/issue-99875.stderr b/src/test/ui/issues/issue-99875.stderr deleted file mode 100644 index 3ff8f12f1b8..00000000000 --- a/src/test/ui/issues/issue-99875.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied - --> $DIR/issue-99875.rs:12:11 - | -LL | takes(function); - | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}` - | | - | required by a bound introduced by this call - | - = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` -note: required by a bound in `takes` - --> $DIR/issue-99875.rs:9:18 - | -LL | fn takes(_: impl Trait) {} - | ^^^^^ required by this bound in `takes` - -error[E0277]: the trait bound `[closure@$DIR/issue-99875.rs:14:11: 14:34]: Trait` is not satisfied - --> $DIR/issue-99875.rs:14:11 - | -LL | takes(|_: Argument| -> Return { todo!() }); - | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `[closure@$DIR/issue-99875.rs:14:11: 14:34]` - | | - | required by a bound introduced by this call - | - = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` -note: required by a bound in `takes` - --> $DIR/issue-99875.rs:9:18 - | -LL | fn takes(_: impl Trait) {} - | ^^^^^ required by this bound in `takes` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/macros/issue-10536.rs b/src/test/ui/macros/issue-10536.rs new file mode 100644 index 00000000000..f536d8f940a --- /dev/null +++ b/src/test/ui/macros/issue-10536.rs @@ -0,0 +1,19 @@ +// We only want to assert that this doesn't ICE, we don't particularly care +// about whether it nor it fails to compile. + +macro_rules! foo{ + () => {{ + macro_rules! bar{() => (())} + 1 + }} +} + +pub fn main() { + foo!(); + + assert!({one! two()}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` + + // regardless of whether nested macro_rules works, the following should at + // least throw a conventional error. + assert!({one! two}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` +} diff --git a/src/test/ui/macros/issue-10536.stderr b/src/test/ui/macros/issue-10536.stderr new file mode 100644 index 00000000000..cc048445871 --- /dev/null +++ b/src/test/ui/macros/issue-10536.stderr @@ -0,0 +1,14 @@ +error: expected one of `(`, `[`, or `{`, found `two` + --> $DIR/issue-10536.rs:14:19 + | +LL | assert!({one! two()}); + | ^^^ expected one of `(`, `[`, or `{` + +error: expected one of `(`, `[`, or `{`, found `two` + --> $DIR/issue-10536.rs:18:19 + | +LL | assert!({one! two}); + | ^^^ expected one of `(`, `[`, or `{` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/nll/issue-54189.rs b/src/test/ui/nll/issue-54189.rs new file mode 100644 index 00000000000..70aecc384ef --- /dev/null +++ b/src/test/ui/nll/issue-54189.rs @@ -0,0 +1,6 @@ +fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } } +//~^ ERROR binding for associated type `Output` references lifetime `'r` + +fn main() { + let f = bug(); +} diff --git a/src/test/ui/nll/issue-54189.stderr b/src/test/ui/nll/issue-54189.stderr new file mode 100644 index 00000000000..4787abd49d1 --- /dev/null +++ b/src/test/ui/nll/issue-54189.stderr @@ -0,0 +1,9 @@ +error[E0582]: binding for associated type `Output` references lifetime `'r`, which does not appear in the trait input types + --> $DIR/issue-54189.rs:1:35 + | +LL | fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } } + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0582`. diff --git a/src/test/ui/traits/issue-99875.rs b/src/test/ui/traits/issue-99875.rs new file mode 100644 index 00000000000..cf73fd8d31f --- /dev/null +++ b/src/test/ui/traits/issue-99875.rs @@ -0,0 +1,16 @@ +struct Argument; +struct Return; + +fn function(_: Argument) -> Return { todo!() } + +trait Trait {} +impl Trait for fn(Argument) -> Return {} + +fn takes(_: impl Trait) {} + +fn main() { + takes(function); + //~^ ERROR the trait bound + takes(|_: Argument| -> Return { todo!() }); + //~^ ERROR the trait bound +} diff --git a/src/test/ui/traits/issue-99875.stderr b/src/test/ui/traits/issue-99875.stderr new file mode 100644 index 00000000000..3ff8f12f1b8 --- /dev/null +++ b/src/test/ui/traits/issue-99875.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `fn(Argument) -> Return {function}: Trait` is not satisfied + --> $DIR/issue-99875.rs:12:11 + | +LL | takes(function); + | ----- ^^^^^^^^ the trait `Trait` is not implemented for fn item `fn(Argument) -> Return {function}` + | | + | required by a bound introduced by this call + | + = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` +note: required by a bound in `takes` + --> $DIR/issue-99875.rs:9:18 + | +LL | fn takes(_: impl Trait) {} + | ^^^^^ required by this bound in `takes` + +error[E0277]: the trait bound `[closure@$DIR/issue-99875.rs:14:11: 14:34]: Trait` is not satisfied + --> $DIR/issue-99875.rs:14:11 + | +LL | takes(|_: Argument| -> Return { todo!() }); + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `[closure@$DIR/issue-99875.rs:14:11: 14:34]` + | | + | required by a bound introduced by this call + | + = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` +note: required by a bound in `takes` + --> $DIR/issue-99875.rs:9:18 + | +LL | fn takes(_: impl Trait) {} + | ^^^^^ required by this bound in `takes` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/typeck/issue-18937-1.rs b/src/test/ui/typeck/issue-18937-1.rs new file mode 100644 index 00000000000..57e56d832c6 --- /dev/null +++ b/src/test/ui/typeck/issue-18937-1.rs @@ -0,0 +1,21 @@ +// run-pass +// Test that we are able to type-check this example. In particular, +// knowing that `T: 'a` allows us to deduce that `[U]: 'a` (because +// when `T=[U]` it implies that `U: 'a`). +// +// Regr. test for live code we found in the wild when fixing #18937. + +pub trait Leak { + fn leak<'a>(self) -> &'a T where T: 'a; +} + +impl Leak<[U]> for Vec { + fn leak<'a>(mut self) -> &'a [U] where [U]: 'a { + let r: *mut [U] = &mut self[..]; + std::mem::forget(self); + unsafe { &mut *r } + } +} +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/typeck/issue-18937.rs b/src/test/ui/typeck/issue-18937.rs new file mode 100644 index 00000000000..af85e5b2b02 --- /dev/null +++ b/src/test/ui/typeck/issue-18937.rs @@ -0,0 +1,40 @@ +// Regression test for #18937. + +use std::fmt; + +#[derive(Debug)] +struct MyString<'a>(&'a String); + +struct B { + list: Vec>, +} + +trait A<'a> { + fn foo(&mut self, f: F) + where F: fmt::Debug + 'a, + Self: Sized; +} + +impl<'a> A<'a> for B { + fn foo(&mut self, f: F) + where F: fmt::Debug + 'static, //~ ERROR impl has stricter + { + self.list.push(Box::new(f)); + } +} + +fn main() { + let mut b = B { list: Vec::new() }; + + // Create a borrowed pointer, put it in `b`, then drop what's borrowing it + let a = "hello".to_string(); + b.foo(MyString(&a)); + + // Drop the data which `b` has a reference to + drop(a); + + // Use the data, probably segfaulting + for b in b.list.iter() { + println!("{:?}", b); + } +} diff --git a/src/test/ui/typeck/issue-18937.stderr b/src/test/ui/typeck/issue-18937.stderr new file mode 100644 index 00000000000..5e2ba0ef4fc --- /dev/null +++ b/src/test/ui/typeck/issue-18937.stderr @@ -0,0 +1,14 @@ +error[E0276]: impl has stricter requirements than trait + --> $DIR/issue-18937.rs:20:31 + | +LL | / fn foo(&mut self, f: F) +LL | | where F: fmt::Debug + 'a, +LL | | Self: Sized; + | |__________________________- definition of `foo` from trait +... +LL | where F: fmt::Debug + 'static, + | ^^^^^^^ impl has extra requirement `F: 'static` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/typeck/issue-31173.rs b/src/test/ui/typeck/issue-31173.rs new file mode 100644 index 00000000000..f678df5b42b --- /dev/null +++ b/src/test/ui/typeck/issue-31173.rs @@ -0,0 +1,15 @@ +use std::vec::IntoIter; + +pub fn get_tok(it: &mut IntoIter) { + let mut found_e = false; + + let temp: Vec = it + .take_while(|&x| { + found_e = true; + false + }) + .cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8` + .collect(); //~ ERROR the method +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-31173.stderr b/src/test/ui/typeck/issue-31173.stderr new file mode 100644 index 00000000000..f3be99f9bcb --- /dev/null +++ b/src/test/ui/typeck/issue-31173.stderr @@ -0,0 +1,45 @@ +error[E0271]: expected `TakeWhile<&mut IntoIter, [closure@issue-31173.rs:7:21]>` to be an iterator that yields `&_`, but it yields `u8` + --> $DIR/issue-31173.rs:11:10 + | +LL | .cloned() + | ^^^^^^ expected reference, found `u8` + | + = note: expected reference `&_` + found type `u8` +note: the method call chain might not have had the expected associated types + --> $DIR/issue-31173.rs:3:20 + | +LL | pub fn get_tok(it: &mut IntoIter) { + | ^^^^^^^^^^^^^^^^^ `Iterator::Item` is `u8` here +... +LL | .take_while(|&x| { + | __________- +LL | | found_e = true; +LL | | false +LL | | }) + | |__________- `Iterator::Item` remains `u8` here +note: required by a bound in `cloned` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error[E0599]: the method `collect` exists for struct `Cloned, [closure@issue-31173.rs:7:21]>>`, but its trait bounds were not satisfied + --> $DIR/issue-31173.rs:12:10 + | +LL | .collect(); + | ^^^^^^^ method cannot be called due to unsatisfied trait bounds + --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL + | + = note: doesn't satisfy `<_ as Iterator>::Item = &_` + --> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL + | + = note: doesn't satisfy `_: Iterator` + | + = note: the following trait bounds were not satisfied: + `, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` + which is required by `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` + `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` + which is required by `&mut Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0599. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 070e72437be..166d09fa8b0 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. const ROOT_ENTRY_LIMIT: usize = 939; -const ISSUES_ENTRY_LIMIT: usize = 2050; +const ISSUES_ENTRY_LIMIT: usize = 1998; fn check_entries(path: &Path, bad: &mut bool) { for dir in Walk::new(&path.join("test/ui")) { -- cgit 1.4.1-3-g733a5 From 854082c2189a2b71b661dbe5ac6917c5190bac57 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 4 Jan 2023 12:47:24 -0700 Subject: docs: fix broken link "search bar" --- library/std/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 13dfd41abbf..6575cc71b05 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -14,7 +14,7 @@ //! # How to read this documentation //! //! If you already know the name of what you are looking for, the fastest way to -//! find it is to use the search +//! find it is to use the search //! bar at the top of the page. //! //! Otherwise, you may want to jump to one of these useful sections: -- cgit 1.4.1-3-g733a5 From 01196c5b4cb3d966aa49ad4ed04bd2ea7aa1f6d2 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 4 Jan 2023 13:04:30 -0700 Subject: rustdoc: remove unnecessary wrapper around sidebar and mobile logos This commit changes `.sidebar a:hover:not(.logo-container)` to add the `:not()` pseudo-class, retaining the old appearance of the logo when mousing over it. This didn't used to be necessary because the `a.sidebar-logo` was `display:inline`, and was what got the `background` changed on hover, while the `div.logo-container` inside it was `display:block`. This resulted in the hover rule not having any effect, because the logo-container box was not actually nested inside the sidebar-logo box: https://www.w3.org/TR/CSS2/visuren.html#anonymous-block-level > When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box. --- src/librustdoc/html/static/css/rustdoc.css | 5 +++-- src/librustdoc/html/templates/page.html | 28 ++++++++++++---------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index afc369bc3fd..cdc077e26bf 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -352,6 +352,7 @@ img { .sub-logo-container, .logo-container { /* zero text boxes so that computed line height = image height exactly */ line-height: 0; + display: block; } .sub-logo-container { @@ -495,7 +496,7 @@ ul.block, .block li { color: var(--sidebar-link-color); } .sidebar .current, -.sidebar a:hover { +.sidebar a:hover:not(.logo-container) { background-color: var(--sidebar-current-link-background-color); } @@ -1570,7 +1571,7 @@ in storage.js /* Hide the logo and item name from the sidebar. Those are displayed in the mobile-topbar instead. */ - .sidebar .sidebar-logo, + .sidebar .logo-container, .sidebar .location { display: none; } diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index bcaff957af2..fddda293b9a 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -72,28 +72,24 @@ {%- if page.css_class != "source" -%} {#- -#} {%- endif -%}
/// - /// If the included file is parsed as an expression, it is placed in the surrounding code - /// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). This - /// could result in variables or functions being different from what the file expected if there - /// are variables or functions that have the same name in the current file. + /// The included file is placed in the surrounding code + /// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). If + /// the included file is parsed as an expression and variables or functions share names across + /// both files, it could result in variables or functions being different from what the + /// included file expected. /// /// The included file is located relative to the current file (similarly to how modules are /// found). The provided path is interpreted in a platform-specific way at compile time. So, -- cgit 1.4.1-3-g733a5 From ea43eb3721e9a6567ff402db442fc5c1ad942009 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 2 Jan 2023 16:23:08 -0800 Subject: Point at expressions where inference refines an unexpected type Address #106355. --- compiler/rustc_hir_typeck/src/demand.rs | 162 ++++++++++++++++++++- .../argument-suggestions/two-mismatch-notes.stderr | 2 + .../async-await/dont-suggest-missing-await.stderr | 2 + .../suggest-missing-await-closure.stderr | 2 + .../ui/async-await/suggest-missing-await.stderr | 2 + .../closures/closure-return-type-mismatch.stderr | 2 + src/test/ui/coercion/coerce-to-bang.stderr | 9 ++ .../collections-project-default.stderr | 3 + src/test/ui/issues/issue-15783.stderr | 2 + src/test/ui/let-else/let-else-ref-bindings.stderr | 12 ++ ...o-same-trait-object-with-separate-params.stderr | 15 ++ src/test/ui/mismatched_types/abridged.stderr | 36 +++-- .../ui/parser/struct-literal-variant-in-if.stderr | 2 + ...t-else-does-not-interact-with-let-chains.stderr | 12 ++ src/test/ui/span/coerce-suggestions.stderr | 5 +- src/test/ui/span/issue-33884.stderr | 5 +- src/test/ui/structs/struct-base-wrong-type.stderr | 2 + src/test/ui/suggestions/call-boxed.stderr | 5 +- ...t-suggest-deref-inside-macro-issue-58298.stderr | 5 +- .../issue-86100-tuple-paren-comma.stderr | 2 + src/test/ui/traits/issue-52893.stderr | 2 + src/test/ui/tuple/wrong_argument_ice-3.stderr | 3 + .../ui/type/type-check/assignment-in-if.stderr | 18 +++ .../ui/type/type-mismatch-same-crate-name.stderr | 6 + 24 files changed, 299 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 9c6c53abf07..c9ee5c6cac8 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -4,6 +4,7 @@ use rustc_errors::MultiSpan; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::CtorKind; +use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{is_range_literal, Node}; use rustc_infer::infer::InferOk; @@ -11,8 +12,11 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut}; +use rustc_middle::ty::fold::TypeFolder; +use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::{ + self, Article, AssocItem, Ty, TyCtxt, TypeAndMut, TypeSuperFoldable, TypeVisitable, +}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -53,7 +57,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) || self.suggest_into(err, expr, expr_ty, expected) - || self.suggest_floating_point_literal(err, expr, expected); + || self.suggest_floating_point_literal(err, expr, expected) + || self.point_inference_types(err, expr); } pub fn emit_coerce_suggestions( @@ -205,6 +210,157 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (expected, Some(err)) } + fn point_inference_types(&self, err: &mut Diagnostic, expr: &hir::Expr<'_>) -> bool { + let tcx = self.tcx; + let map = self.tcx.hir(); + + // Hack to make equality checks on types with inference variables and regions useful. + struct TypeEraser<'tcx> { + tcx: TyCtxt<'tcx>, + } + impl<'tcx> TypeFolder<'tcx> for TypeEraser<'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } + fn fold_region(&mut self, _r: ty::Region<'tcx>) -> ty::Region<'tcx> { + self.tcx().lifetimes.re_erased + } + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if !t.needs_infer() && !t.has_erasable_regions() { + return t; + } + match *t.kind() { + ty::Infer(ty::TyVar(_) | ty::FreshTy(_)) => { + self.tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))) + } + ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => { + self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 })) + } + ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => { + self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 })) + } + _ => t.super_fold_with(self), + } + } + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + ct.super_fold_with(self) + } + } + + let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; + let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; }; + let hir::def::Res::Local(hir_id) = p.res else { return false; }; + let Some(node) = map.find(hir_id) else { return false; }; + let hir::Node::Pat(pat) = node else { return false; }; + let parent = map.get_parent_node(pat.hir_id); + let Some(hir::Node::Local(hir::Local { + ty: None, + init: Some(init), + .. + })) = map.find(parent) else { return false; }; + + let ty = self.node_ty(init.hir_id); + if ty.is_closure() || init.span.overlaps(expr.span) { + return false; + } + let mut span_labels = vec![( + init.span, + with_forced_trimmed_paths!(format!( + "here the type of `{ident}` is inferred to be `{ty}`", + )), + )]; + + // Locate all the usages of the relevant binding. + struct FindExprs<'hir> { + hir_id: hir::HirId, + uses: Vec<&'hir hir::Expr<'hir>>, + } + impl<'v> Visitor<'v> for FindExprs<'v> { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = ex.kind + && let hir::def::Res::Local(hir_id) = path.res + && hir_id == self.hir_id + { + self.uses.push(ex); + } + hir::intravisit::walk_expr(self, ex); + } + } + + let mut expr_finder = FindExprs { hir_id, uses: vec![] }; + let id = map.get_parent_item(hir_id); + let hir_id: hir::HirId = id.into(); + + if let Some(node) = map.find(hir_id) && let Some(body_id) = node.body_id() { + let body = map.body(body_id); + expr_finder.visit_expr(body.value); + let mut eraser = TypeEraser { tcx }; + let mut prev = eraser.fold_ty(ty); + + for ex in expr_finder.uses { + if ex.span.overlaps(expr.span) { break; } + let parent = map.get_parent_node(ex.hir_id); + if let Some(hir::Node::Expr(expr)) + | Some(hir::Node::Stmt(hir::Stmt { + kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), + .. + })) = &map.find(parent) + && let hir::ExprKind::MethodCall(s, rcvr, args, span) = expr.kind + && rcvr.hir_id == ex.hir_id + { + let ty = if let Ok(m) = self.lookup_method(ty, s, span, expr, rcvr, args) { + // We get the self type from `lookup_method` because the `rcvr` node + // type will not have had any adjustments from the fn arguments. + let ty = m.sig.inputs_and_output[0]; + match ty.kind() { + // Remove one layer of references to account for `&mut self` and + // `&self`, so that we can compare it against the binding. + ty::Ref(_, ty, _) => *ty, + _ => ty, + } + } else { + self.node_ty(rcvr.hir_id) + }; + let ty = eraser.fold_ty(ty); + if ty.references_error() { + break; + } + if ty != prev { + span_labels.push(( + s.ident.span, + with_forced_trimmed_paths!(format!( + "here the type of `{ident}` is inferred to be `{ty}`", + )), + )); + prev = ty; + } + } else { + let ty = eraser.fold_ty(self.node_ty(ex.hir_id)); + if ty.references_error() { + break; + } + if ty != prev { + span_labels.push(( + ex.span, + with_forced_trimmed_paths!(format!( + "here the type of `{ident}` is inferred to be `{ty}`", + )), + )); + } + prev = ty; + } + if ex.hir_id == expr.hir_id { + // Stop showing spans after the error type was emitted. + break; + } + } + } + for (sp, label) in span_labels { + err.span_label(sp, &label); + } + true + } + fn annotate_expected_due_to_let_ty( &self, err: &mut Diagnostic, diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr index 7873cf964cb..3ccd399863d 100644 --- a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr +++ b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr @@ -1,6 +1,8 @@ error[E0308]: arguments to this function are incorrect --> $DIR/two-mismatch-notes.rs:10:5 | +LL | let w = Wrapper::(1isize); + | ------------------------ here the type of `w` is inferred to be `Wrapper` LL | foo(f, w); | ^^^ | diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 627bf05bba2..6e232dd0064 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | +LL | let x = make_u32(); + | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index a5958baffba..9f51832365b 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | +LL | let x = make_u32(); + | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 1196601ace0..ce4c8edaf74 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | +LL | let x = make_u32(); + | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/closures/closure-return-type-mismatch.stderr b/src/test/ui/closures/closure-return-type-mismatch.stderr index 3a89d30a05d..d33cf383cbc 100644 --- a/src/test/ui/closures/closure-return-type-mismatch.stderr +++ b/src/test/ui/closures/closure-return-type-mismatch.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/closure-return-type-mismatch.rs:7:9 | +LL | let a = true; + | ---- here the type of `a` is inferred to be `bool` LL | a | ^ expected `&str`, found `bool` | diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr index 1207dc7e7a2..d2fd0f78838 100644 --- a/src/test/ui/coercion/coerce-to-bang.stderr +++ b/src/test/ui/coercion/coerce-to-bang.stderr @@ -33,6 +33,9 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:26:12 | +LL | let b = 22; + | -- here the type of `b` is inferred to be `{integer}` +LL | let c = 44; LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. | --- ^ expected `!`, found integer | | @@ -49,6 +52,9 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:36:12 | +LL | let b = 22; + | -- here the type of `b` is inferred to be `{integer}` +LL | let c = 44; LL | foo(a, b, c); | --- ^ expected `!`, found integer | | @@ -65,6 +71,9 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:45:12 | +LL | let b = 22; + | -- here the type of `b` is inferred to be `{integer}` +LL | let c = 44; LL | foo(a, b, c); | --- ^ expected `!`, found integer | | diff --git a/src/test/ui/generic-associated-types/collections-project-default.stderr b/src/test/ui/generic-associated-types/collections-project-default.stderr index 5701017dc34..c11a5acc352 100644 --- a/src/test/ui/generic-associated-types/collections-project-default.stderr +++ b/src/test/ui/generic-associated-types/collections-project-default.stderr @@ -4,6 +4,9 @@ error[E0308]: mismatched types LL | fn floatify_sibling(ints: &C) -> >::Sibling | ------------------------------------ expected `>::Sibling` because of return type ... +LL | let mut res = ::Member::::empty(); + | ------------------------------------------------------- here the type of `res` is inferred to be `<>::Family as CollectionFamily>::Member` +... LL | res | ^^^ expected Collection::Sibling, found CollectionFamily::Member | diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr index 660dfe9ed3d..74a7c5de7ab 100644 --- a/src/test/ui/issues/issue-15783.stderr +++ b/src/test/ui/issues/issue-15783.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/issue-15783.rs:8:19 | +LL | let x = Some(&[name]); + | ------------- here the type of `x` is inferred to be `Option<_>` LL | let msg = foo(x); | --- ^ expected slice `[&str]`, found array `[&str; 1]` | | diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr index 56b9e073330..39b57ceb43d 100644 --- a/src/test/ui/let-else/let-else-ref-bindings.stderr +++ b/src/test/ui/let-else/let-else-ref-bindings.stderr @@ -19,6 +19,12 @@ LL | let Some(ref a): Option<&[u8]> = &some else { return }; error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:24:34 | +LL | let some = Some(bytes); + | ----------- here the type of `some` is inferred to be `Option<_>` +... +LL | let Some(ref a): Option<&[u8]> = some else { return }; + | ---- here the type of `some` is inferred to be `Option>` +... LL | let Some(a): Option<&[u8]> = some else { return }; | ------------- ^^^^ expected `&[u8]`, found struct `Vec` | | @@ -59,6 +65,12 @@ LL | let Some(ref mut a): Option<&mut [u8]> = &mut some else { return }; error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:52:38 | +LL | let mut some = Some(bytes); + | ----------- here the type of `some` is inferred to be `Option<_>` +... +LL | let Some(ref mut a): Option<&mut [u8]> = some else { return }; + | ---- here the type of `some` is inferred to be `Option>` +... LL | let Some(a): Option<&mut [u8]> = some else { return }; | ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec` | | diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 82addab9479..1d836f20012 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -10,6 +10,9 @@ LL | #![feature(unsized_locals, unsized_fn_params)] error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24 | +LL | let z = x.foo(); + | ------- here the type of `z` is inferred to be `u32` +... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | @@ -18,6 +21,9 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24 | +LL | let z = x.foo(); + | ------- here the type of `z` is inferred to be `u64` +... LL | let _seetype: () = z; | -- ^ expected `()`, found `u64` | | @@ -60,6 +66,9 @@ LL | let z = FinalFoo::foo(x); error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24 | +LL | let z = x.foo(); + | ------- here the type of `z` is inferred to be `u8` +... LL | let _seetype: () = z; | -- ^ expected `()`, found `u8` | | @@ -68,6 +77,9 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24 | +LL | let z = x.foo(); + | ------- here the type of `z` is inferred to be `u32` +... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | @@ -76,6 +88,9 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24 | +LL | let z = x.foo(); + | ------- here the type of `z` is inferred to be `u32` +... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index ff1a836c9ae..8fd3239e8ee 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -53,11 +53,19 @@ LL | Ok(Foo { bar: 1 }) error[E0308]: mismatched types --> $DIR/abridged.rs:39:5 | -LL | fn d() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -... -LL | x - | ^ expected struct `String`, found integer +LL | fn d() -> X, String> { + | ---------------------------- expected `X, String>` because of return type +LL | let x = X { + | _____________- +LL | | x: X { +LL | | x: "".to_string(), +LL | | y: 2, +LL | | }, +LL | | y: 3, +LL | | }; + | |_____- here the type of `x` is inferred to be `X<_, _>` +LL | x + | ^ expected struct `String`, found integer | = note: expected struct `X, String>` found struct `X, {integer}>` @@ -65,11 +73,19 @@ LL | x error[E0308]: mismatched types --> $DIR/abridged.rs:50:5 | -LL | fn e() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -... -LL | x - | ^ expected struct `String`, found integer +LL | fn e() -> X, String> { + | ---------------------------- expected `X, String>` because of return type +LL | let x = X { + | _____________- +LL | | x: X { +LL | | x: "".to_string(), +LL | | y: 2, +LL | | }, +LL | | y: "".to_string(), +LL | | }; + | |_____- here the type of `x` is inferred to be `X<_, _>` +LL | x + | ^ expected struct `String`, found integer | = note: expected struct `X, _>` found struct `X, _>` diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr index 9f0c0074d67..97cdd130d0b 100644 --- a/src/test/ui/parser/struct-literal-variant-in-if.stderr +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -51,6 +51,8 @@ LL | if x == E::V { field } {} error[E0308]: mismatched types --> $DIR/struct-literal-variant-in-if.rs:10:20 | +LL | let field = true; + | ---- here the type of `field` is inferred to be `bool` LL | if x == E::V { field } {} | ---------------^^^^^-- | | | diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index 498a112fa9b..1785c31cfb9 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -100,6 +100,12 @@ LL | let Some(n) = opt && let another = n else { error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19 | +LL | let opt = Some(1i32); + | ---------- here the type of `opt` is inferred to be `Option<_>` +LL | +LL | let Some(n) = opt else { + | --- here the type of `opt` is inferred to be `Option` +... LL | let Some(n) = opt && n == 1 else { | ^^^ expected `bool`, found enum `Option` | @@ -120,6 +126,12 @@ LL | let Some(n) = opt && n == 1 else { error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19 | +LL | let opt = Some(1i32); + | ---------- here the type of `opt` is inferred to be `Option<_>` +LL | +LL | let Some(n) = opt else { + | --- here the type of `opt` is inferred to be `Option` +... LL | let Some(n) = opt && let another = n else { | ^^^ expected `bool`, found enum `Option` | diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index db784d5fe6c..75d460d7d8c 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -63,7 +63,10 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:21:9 | LL | s = format!("foo"); - | ^^^^^^^^^^^^^^ expected `&mut String`, found struct `String` + | ^^^^^^^^^^^^^^ + | | + | expected `&mut String`, found struct `String` + | here the type of `res` is inferred to be `String` | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index aee15308517..30e248f381c 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -2,7 +2,10 @@ error[E0308]: mismatched types --> $DIR/issue-33884.rs:6:22 | LL | stream.write_fmt(format!("message received")) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Arguments`, found struct `String` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected struct `Arguments`, found struct `String` + | here the type of `res` is inferred to be `String` | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/structs/struct-base-wrong-type.stderr b/src/test/ui/structs/struct-base-wrong-type.stderr index b039ce2cc92..30feb9cdd70 100644 --- a/src/test/ui/structs/struct-base-wrong-type.stderr +++ b/src/test/ui/structs/struct-base-wrong-type.stderr @@ -13,6 +13,8 @@ LL | static foo_i: Foo = Foo { a: 2, ..4 }; error[E0308]: mismatched types --> $DIR/struct-base-wrong-type.rs:12:27 | +LL | let b = Bar { x: 5 }; + | ------------ here the type of `b` is inferred to be `Bar` LL | let f = Foo { a: 2, ..b }; | ^ expected struct `Foo`, found struct `Bar` diff --git a/src/test/ui/suggestions/call-boxed.stderr b/src/test/ui/suggestions/call-boxed.stderr index 9b619ac9a3f..8295e010f40 100644 --- a/src/test/ui/suggestions/call-boxed.stderr +++ b/src/test/ui/suggestions/call-boxed.stderr @@ -4,7 +4,10 @@ error[E0308]: mismatched types LL | let mut x = 1i32; | ---- expected due to this value LL | let y = Box::new(|| 1); - | -- the found closure + | -------------- + | | | + | | the found closure + | here the type of `y` is inferred to be `Box<_>` LL | x = y; | ^ expected `i32`, found struct `Box` | diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 5dc4e64446f..2546f2515d7 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -4,7 +4,10 @@ error[E0308]: mismatched types LL | / intrinsic_match! { LL | | "abc" LL | | }; - | |_____^ expected `&str`, found struct `String` + | | ^ + | | | + | |_____expected `&str`, found struct `String` + | here the type of `res` is inferred to be `String` | = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr index 8c9a41a2027..388d8d8d895 100644 --- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr +++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr @@ -49,6 +49,8 @@ LL | let _s = S { _s: ("abc".to_string(),) }; error[E0308]: mismatched types --> $DIR/issue-86100-tuple-paren-comma.rs:23:22 | +LL | let t = (1, 2); + | ------ here the type of `t` is inferred to be `({integer}, {integer})` LL | let _x: (i32,) = (t); | ------ ^^^ expected a tuple with 1 element, found one with 2 elements | | diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr index 7924d3db06f..f7b5b7fca06 100644 --- a/src/test/ui/traits/issue-52893.stderr +++ b/src/test/ui/traits/issue-52893.stderr @@ -4,6 +4,8 @@ error[E0308]: mismatched types LL | impl AddClass for Class

| - this type parameter ... +LL | let output = builder.to_ref(); + | ---------------- here the type of `output` is inferred to be `Class

` LL | builder.push(output); | ---- ^^^^^^ expected type parameter `F`, found struct `Class` | | diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr index 0a503e1fe58..c83bc28d855 100644 --- a/src/test/ui/tuple/wrong_argument_ice-3.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr @@ -1,6 +1,9 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | +LL | let new_group = vec![String::new()]; + | ------------------- here the type of `new_group` is inferred to be `Vec<_, _>` +... LL | groups.push(new_group, vec![process]); | ^^^^ ------------- argument of type `Vec<&Process>` unexpected | diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index 9f4558adab1..fb11d6160bb 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -67,6 +67,12 @@ LL | x == 5 error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:18 | +LL | let x = 1; + | - here the type of `x` is inferred to be `{integer}` +... +LL | println!("{}", x); + | - here the type of `x` is inferred to be `usize` +... LL | if x == x && x = x && x == x { | ------ ^ expected `bool`, found `usize` | | @@ -75,6 +81,12 @@ LL | if x == x && x = x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:22 | +LL | let x = 1; + | - here the type of `x` is inferred to be `{integer}` +... +LL | println!("{}", x); + | - here the type of `x` is inferred to be `usize` +... LL | if x == x && x = x && x == x { | ^ expected `bool`, found `usize` @@ -92,6 +104,12 @@ LL | if x == x && x == x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:51:28 | +LL | let x = 1; + | - here the type of `x` is inferred to be `{integer}` +... +LL | println!("{}", x); + | - here the type of `x` is inferred to be `usize` +... LL | if x == x && x == x && x = x { | ---------------- ^ expected `bool`, found `usize` | | diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index fcafd315ebf..e99d30d3396 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:16:20 | +LL | let foo2 = {extern crate crate_a2 as a; a::Foo}; + | ------------------------------------ here the type of `foo2` is inferred to be `_` +... LL | a::try_foo(foo2); | ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo` | | @@ -27,6 +30,9 @@ LL | pub fn try_foo(x: Foo){} error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:20:20 | +LL | let bar2 = {extern crate crate_a2 as a; a::bar()}; + | -------------------------------------- here the type of `bar2` is inferred to be `_` +... LL | a::try_bar(bar2); | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` | | -- cgit 1.4.1-3-g733a5 From 05c30b0ca5450b2beec0a6e4e034953e216f6bbe Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 2 Jan 2023 21:56:19 -0800 Subject: Skip macros to avoid talking about bindings the user can't see --- compiler/rustc_hir_typeck/src/demand.rs | 2 +- src/test/ui/span/coerce-suggestions.stderr | 5 +---- src/test/ui/span/issue-33884.stderr | 5 +---- .../suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr | 5 +---- 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index c9ee5c6cac8..5ba0d41ab9d 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -260,7 +260,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { })) = map.find(parent) else { return false; }; let ty = self.node_ty(init.hir_id); - if ty.is_closure() || init.span.overlaps(expr.span) { + if ty.is_closure() || init.span.overlaps(expr.span) || pat.span.from_expansion() { return false; } let mut span_labels = vec![( diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 75d460d7d8c..db784d5fe6c 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -63,10 +63,7 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:21:9 | LL | s = format!("foo"); - | ^^^^^^^^^^^^^^ - | | - | expected `&mut String`, found struct `String` - | here the type of `res` is inferred to be `String` + | ^^^^^^^^^^^^^^ expected `&mut String`, found struct `String` | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index 30e248f381c..aee15308517 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -2,10 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-33884.rs:6:22 | LL | stream.write_fmt(format!("message received")) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected struct `Arguments`, found struct `String` - | here the type of `res` is inferred to be `String` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Arguments`, found struct `String` | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 2546f2515d7..5dc4e64446f 100644 --- a/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/src/test/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | / intrinsic_match! { LL | | "abc" LL | | }; - | | ^ - | | | - | |_____expected `&str`, found struct `String` - | here the type of `res` is inferred to be `String` + | |_____^ expected `&str`, found struct `String` | = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info) -- cgit 1.4.1-3-g733a5 From 48094a4a6f53ee3be636b4166a7841505bb7cabc Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 2 Jan 2023 22:25:50 -0800 Subject: More eagerly resolve expr `ty`s before writing them This allows the expressions to have more accurate types when showing inference steps. --- compiler/rustc_hir_typeck/src/expr.rs | 1 + src/test/ui/issues/issue-15783.stderr | 2 +- src/test/ui/let-else/let-else-ref-bindings.stderr | 10 ++-------- src/test/ui/mismatched_types/abridged.stderr | 4 ++-- ...sure-that-let-else-does-not-interact-with-let-chains.stderr | 10 ++-------- src/test/ui/suggestions/call-boxed.stderr | 2 +- src/test/ui/tuple/wrong_argument_ice-3.stderr | 2 +- src/test/ui/type/type-mismatch-same-crate-name.stderr | 4 ++-- 8 files changed, 12 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 631749fcc0f..6ed1bc051a5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -234,6 +234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) => self.check_expr_path(qpath, expr, args), _ => self.check_expr_kind(expr, expected), }); + let ty = self.resolve_vars_if_possible(ty); // Warn for non-block expressions with diverging children. match expr.kind { diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr index 74a7c5de7ab..e7fecfebdc8 100644 --- a/src/test/ui/issues/issue-15783.stderr +++ b/src/test/ui/issues/issue-15783.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/issue-15783.rs:8:19 | LL | let x = Some(&[name]); - | ------------- here the type of `x` is inferred to be `Option<_>` + | ------------- here the type of `x` is inferred to be `Option<&[&str; 1]>` LL | let msg = foo(x); | --- ^ expected slice `[&str]`, found array `[&str; 1]` | | diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr index 39b57ceb43d..4c58b2db575 100644 --- a/src/test/ui/let-else/let-else-ref-bindings.stderr +++ b/src/test/ui/let-else/let-else-ref-bindings.stderr @@ -20,10 +20,7 @@ error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:24:34 | LL | let some = Some(bytes); - | ----------- here the type of `some` is inferred to be `Option<_>` -... -LL | let Some(ref a): Option<&[u8]> = some else { return }; - | ---- here the type of `some` is inferred to be `Option>` + | ----------- here the type of `some` is inferred to be `Option>` ... LL | let Some(a): Option<&[u8]> = some else { return }; | ------------- ^^^^ expected `&[u8]`, found struct `Vec` @@ -66,10 +63,7 @@ error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:52:38 | LL | let mut some = Some(bytes); - | ----------- here the type of `some` is inferred to be `Option<_>` -... -LL | let Some(ref mut a): Option<&mut [u8]> = some else { return }; - | ---- here the type of `some` is inferred to be `Option>` + | ----------- here the type of `some` is inferred to be `Option>` ... LL | let Some(a): Option<&mut [u8]> = some else { return }; | ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec` diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 8fd3239e8ee..9b5f0134f12 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -63,7 +63,7 @@ LL | | y: 2, LL | | }, LL | | y: 3, LL | | }; - | |_____- here the type of `x` is inferred to be `X<_, _>` + | |_____- here the type of `x` is inferred to be `X, {integer}>` LL | x | ^ expected struct `String`, found integer | @@ -83,7 +83,7 @@ LL | | y: 2, LL | | }, LL | | y: "".to_string(), LL | | }; - | |_____- here the type of `x` is inferred to be `X<_, _>` + | |_____- here the type of `x` is inferred to be `X, String>` LL | x | ^ expected struct `String`, found integer | diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index 1785c31cfb9..8c30f015c5d 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -101,10 +101,7 @@ error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19 | LL | let opt = Some(1i32); - | ---------- here the type of `opt` is inferred to be `Option<_>` -LL | -LL | let Some(n) = opt else { - | --- here the type of `opt` is inferred to be `Option` + | ---------- here the type of `opt` is inferred to be `Option` ... LL | let Some(n) = opt && n == 1 else { | ^^^ expected `bool`, found enum `Option` @@ -127,10 +124,7 @@ error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19 | LL | let opt = Some(1i32); - | ---------- here the type of `opt` is inferred to be `Option<_>` -LL | -LL | let Some(n) = opt else { - | --- here the type of `opt` is inferred to be `Option` + | ---------- here the type of `opt` is inferred to be `Option` ... LL | let Some(n) = opt && let another = n else { | ^^^ expected `bool`, found enum `Option` diff --git a/src/test/ui/suggestions/call-boxed.stderr b/src/test/ui/suggestions/call-boxed.stderr index 8295e010f40..1609c2a3094 100644 --- a/src/test/ui/suggestions/call-boxed.stderr +++ b/src/test/ui/suggestions/call-boxed.stderr @@ -7,7 +7,7 @@ LL | let y = Box::new(|| 1); | -------------- | | | | | the found closure - | here the type of `y` is inferred to be `Box<_>` + | here the type of `y` is inferred to be `Box<[closure@call-boxed.rs:3:22]>` LL | x = y; | ^ expected `i32`, found struct `Box` | diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr index c83bc28d855..1ad1d692121 100644 --- a/src/test/ui/tuple/wrong_argument_ice-3.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr @@ -2,7 +2,7 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | LL | let new_group = vec![String::new()]; - | ------------------- here the type of `new_group` is inferred to be `Vec<_, _>` + | ------------------- here the type of `new_group` is inferred to be `Vec` ... LL | groups.push(new_group, vec![process]); | ^^^^ ------------- argument of type `Vec<&Process>` unexpected diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index e99d30d3396..0d754459f4a 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:16:20 | LL | let foo2 = {extern crate crate_a2 as a; a::Foo}; - | ------------------------------------ here the type of `foo2` is inferred to be `_` + | ------------------------------------ here the type of `foo2` is inferred to be `Foo` ... LL | a::try_foo(foo2); | ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo` @@ -31,7 +31,7 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:20:20 | LL | let bar2 = {extern crate crate_a2 as a; a::bar()}; - | -------------------------------------- here the type of `bar2` is inferred to be `_` + | -------------------------------------- here the type of `bar2` is inferred to be `Box` ... LL | a::try_bar(bar2); | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` -- cgit 1.4.1-3-g733a5 From 6b0cce4b5018bcd1c7aed1f84cb0b86e3cc03f9f Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 2 Jan 2023 23:34:26 -0800 Subject: review comments: do not always point at init expr --- compiler/rustc_hir_typeck/src/demand.rs | 3 ++ .../argument-suggestions/two-mismatch-notes.stderr | 2 -- .../async-await/dont-suggest-missing-await.stderr | 2 -- .../suggest-missing-await-closure.stderr | 2 -- .../ui/async-await/suggest-missing-await.stderr | 2 -- .../closures/closure-return-type-mismatch.stderr | 2 -- src/test/ui/coercion/coerce-to-bang.stderr | 9 ------ .../collections-project-default.stderr | 3 -- src/test/ui/issues/issue-15783.stderr | 2 -- src/test/ui/let-else/let-else-ref-bindings.stderr | 6 ---- ...o-same-trait-object-with-separate-params.stderr | 15 --------- src/test/ui/mismatched_types/abridged.stderr | 36 ++++++---------------- .../ui/parser/struct-literal-variant-in-if.stderr | 2 -- ...t-else-does-not-interact-with-let-chains.stderr | 6 ---- src/test/ui/structs/struct-base-wrong-type.stderr | 2 -- src/test/ui/suggestions/call-boxed.stderr | 5 +-- .../issue-86100-tuple-paren-comma.stderr | 2 -- src/test/ui/traits/issue-52893.stderr | 2 -- src/test/ui/tuple/wrong_argument_ice-3.stderr | 3 -- .../ui/type/type-mismatch-same-crate-name.stderr | 6 ---- 20 files changed, 14 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5ba0d41ab9d..c50d03b944f 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -355,6 +355,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + if span_labels.len() < 2 { + return false; + } for (sp, label) in span_labels { err.span_label(sp, &label); } diff --git a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr index 3ccd399863d..7873cf964cb 100644 --- a/src/test/ui/argument-suggestions/two-mismatch-notes.stderr +++ b/src/test/ui/argument-suggestions/two-mismatch-notes.stderr @@ -1,8 +1,6 @@ error[E0308]: arguments to this function are incorrect --> $DIR/two-mismatch-notes.rs:10:5 | -LL | let w = Wrapper::(1isize); - | ------------------------ here the type of `w` is inferred to be `Wrapper` LL | foo(f, w); | ^^^ | diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index 6e232dd0064..627bf05bba2 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/dont-suggest-missing-await.rs:14:18 | -LL | let x = make_u32(); - | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr index 9f51832365b..a5958baffba 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.stderr +++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await-closure.rs:16:18 | -LL | let x = make_u32(); - | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index ce4c8edaf74..1196601ace0 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/suggest-missing-await.rs:12:14 | -LL | let x = make_u32(); - | ---------- here the type of `x` is inferred to be `impl Future` LL | take_u32(x) | -------- ^ expected `u32`, found opaque type | | diff --git a/src/test/ui/closures/closure-return-type-mismatch.stderr b/src/test/ui/closures/closure-return-type-mismatch.stderr index d33cf383cbc..3a89d30a05d 100644 --- a/src/test/ui/closures/closure-return-type-mismatch.stderr +++ b/src/test/ui/closures/closure-return-type-mismatch.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/closure-return-type-mismatch.rs:7:9 | -LL | let a = true; - | ---- here the type of `a` is inferred to be `bool` LL | a | ^ expected `&str`, found `bool` | diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr index d2fd0f78838..1207dc7e7a2 100644 --- a/src/test/ui/coercion/coerce-to-bang.stderr +++ b/src/test/ui/coercion/coerce-to-bang.stderr @@ -33,9 +33,6 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:26:12 | -LL | let b = 22; - | -- here the type of `b` is inferred to be `{integer}` -LL | let c = 44; LL | foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. | --- ^ expected `!`, found integer | | @@ -52,9 +49,6 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:36:12 | -LL | let b = 22; - | -- here the type of `b` is inferred to be `{integer}` -LL | let c = 44; LL | foo(a, b, c); | --- ^ expected `!`, found integer | | @@ -71,9 +65,6 @@ LL | fn foo(x: usize, y: !, z: usize) { } error[E0308]: mismatched types --> $DIR/coerce-to-bang.rs:45:12 | -LL | let b = 22; - | -- here the type of `b` is inferred to be `{integer}` -LL | let c = 44; LL | foo(a, b, c); | --- ^ expected `!`, found integer | | diff --git a/src/test/ui/generic-associated-types/collections-project-default.stderr b/src/test/ui/generic-associated-types/collections-project-default.stderr index c11a5acc352..5701017dc34 100644 --- a/src/test/ui/generic-associated-types/collections-project-default.stderr +++ b/src/test/ui/generic-associated-types/collections-project-default.stderr @@ -4,9 +4,6 @@ error[E0308]: mismatched types LL | fn floatify_sibling(ints: &C) -> >::Sibling | ------------------------------------ expected `>::Sibling` because of return type ... -LL | let mut res = ::Member::::empty(); - | ------------------------------------------------------- here the type of `res` is inferred to be `<>::Family as CollectionFamily>::Member` -... LL | res | ^^^ expected Collection::Sibling, found CollectionFamily::Member | diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr index e7fecfebdc8..660dfe9ed3d 100644 --- a/src/test/ui/issues/issue-15783.stderr +++ b/src/test/ui/issues/issue-15783.stderr @@ -1,8 +1,6 @@ error[E0308]: mismatched types --> $DIR/issue-15783.rs:8:19 | -LL | let x = Some(&[name]); - | ------------- here the type of `x` is inferred to be `Option<&[&str; 1]>` LL | let msg = foo(x); | --- ^ expected slice `[&str]`, found array `[&str; 1]` | | diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr index 4c58b2db575..56b9e073330 100644 --- a/src/test/ui/let-else/let-else-ref-bindings.stderr +++ b/src/test/ui/let-else/let-else-ref-bindings.stderr @@ -19,9 +19,6 @@ LL | let Some(ref a): Option<&[u8]> = &some else { return }; error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:24:34 | -LL | let some = Some(bytes); - | ----------- here the type of `some` is inferred to be `Option>` -... LL | let Some(a): Option<&[u8]> = some else { return }; | ------------- ^^^^ expected `&[u8]`, found struct `Vec` | | @@ -62,9 +59,6 @@ LL | let Some(ref mut a): Option<&mut [u8]> = &mut some else { return }; error[E0308]: mismatched types --> $DIR/let-else-ref-bindings.rs:52:38 | -LL | let mut some = Some(bytes); - | ----------- here the type of `some` is inferred to be `Option>` -... LL | let Some(a): Option<&mut [u8]> = some else { return }; | ----------------- ^^^^ expected `&mut [u8]`, found struct `Vec` | | diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 1d836f20012..82addab9479 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -10,9 +10,6 @@ LL | #![feature(unsized_locals, unsized_fn_params)] error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24 | -LL | let z = x.foo(); - | ------- here the type of `z` is inferred to be `u32` -... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | @@ -21,9 +18,6 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:104:24 | -LL | let z = x.foo(); - | ------- here the type of `z` is inferred to be `u64` -... LL | let _seetype: () = z; | -- ^ expected `()`, found `u64` | | @@ -66,9 +60,6 @@ LL | let z = FinalFoo::foo(x); error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24 | -LL | let z = x.foo(); - | ------- here the type of `z` is inferred to be `u8` -... LL | let _seetype: () = z; | -- ^ expected `()`, found `u8` | | @@ -77,9 +68,6 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:157:24 | -LL | let z = x.foo(); - | ------- here the type of `z` is inferred to be `u32` -... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | @@ -88,9 +76,6 @@ LL | let _seetype: () = z; error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:174:24 | -LL | let z = x.foo(); - | ------- here the type of `z` is inferred to be `u32` -... LL | let _seetype: () = z; | -- ^ expected `()`, found `u32` | | diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 9b5f0134f12..ff1a836c9ae 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -53,19 +53,11 @@ LL | Ok(Foo { bar: 1 }) error[E0308]: mismatched types --> $DIR/abridged.rs:39:5 | -LL | fn d() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -LL | let x = X { - | _____________- -LL | | x: X { -LL | | x: "".to_string(), -LL | | y: 2, -LL | | }, -LL | | y: 3, -LL | | }; - | |_____- here the type of `x` is inferred to be `X, {integer}>` -LL | x - | ^ expected struct `String`, found integer +LL | fn d() -> X, String> { + | ---------------------------- expected `X, String>` because of return type +... +LL | x + | ^ expected struct `String`, found integer | = note: expected struct `X, String>` found struct `X, {integer}>` @@ -73,19 +65,11 @@ LL | x error[E0308]: mismatched types --> $DIR/abridged.rs:50:5 | -LL | fn e() -> X, String> { - | ---------------------------- expected `X, String>` because of return type -LL | let x = X { - | _____________- -LL | | x: X { -LL | | x: "".to_string(), -LL | | y: 2, -LL | | }, -LL | | y: "".to_string(), -LL | | }; - | |_____- here the type of `x` is inferred to be `X, String>` -LL | x - | ^ expected struct `String`, found integer +LL | fn e() -> X, String> { + | ---------------------------- expected `X, String>` because of return type +... +LL | x + | ^ expected struct `String`, found integer | = note: expected struct `X, _>` found struct `X, _>` diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr index 97cdd130d0b..9f0c0074d67 100644 --- a/src/test/ui/parser/struct-literal-variant-in-if.stderr +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -51,8 +51,6 @@ LL | if x == E::V { field } {} error[E0308]: mismatched types --> $DIR/struct-literal-variant-in-if.rs:10:20 | -LL | let field = true; - | ---- here the type of `field` is inferred to be `bool` LL | if x == E::V { field } {} | ---------------^^^^^-- | | | diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index 8c30f015c5d..498a112fa9b 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -100,9 +100,6 @@ LL | let Some(n) = opt && let another = n else { error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:9:19 | -LL | let opt = Some(1i32); - | ---------- here the type of `opt` is inferred to be `Option` -... LL | let Some(n) = opt && n == 1 else { | ^^^ expected `bool`, found enum `Option` | @@ -123,9 +120,6 @@ LL | let Some(n) = opt && n == 1 else { error[E0308]: mismatched types --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19 | -LL | let opt = Some(1i32); - | ---------- here the type of `opt` is inferred to be `Option` -... LL | let Some(n) = opt && let another = n else { | ^^^ expected `bool`, found enum `Option` | diff --git a/src/test/ui/structs/struct-base-wrong-type.stderr b/src/test/ui/structs/struct-base-wrong-type.stderr index 30feb9cdd70..b039ce2cc92 100644 --- a/src/test/ui/structs/struct-base-wrong-type.stderr +++ b/src/test/ui/structs/struct-base-wrong-type.stderr @@ -13,8 +13,6 @@ LL | static foo_i: Foo = Foo { a: 2, ..4 }; error[E0308]: mismatched types --> $DIR/struct-base-wrong-type.rs:12:27 | -LL | let b = Bar { x: 5 }; - | ------------ here the type of `b` is inferred to be `Bar` LL | let f = Foo { a: 2, ..b }; | ^ expected struct `Foo`, found struct `Bar` diff --git a/src/test/ui/suggestions/call-boxed.stderr b/src/test/ui/suggestions/call-boxed.stderr index 1609c2a3094..9b619ac9a3f 100644 --- a/src/test/ui/suggestions/call-boxed.stderr +++ b/src/test/ui/suggestions/call-boxed.stderr @@ -4,10 +4,7 @@ error[E0308]: mismatched types LL | let mut x = 1i32; | ---- expected due to this value LL | let y = Box::new(|| 1); - | -------------- - | | | - | | the found closure - | here the type of `y` is inferred to be `Box<[closure@call-boxed.rs:3:22]>` + | -- the found closure LL | x = y; | ^ expected `i32`, found struct `Box` | diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr index 388d8d8d895..8c9a41a2027 100644 --- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr +++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr @@ -49,8 +49,6 @@ LL | let _s = S { _s: ("abc".to_string(),) }; error[E0308]: mismatched types --> $DIR/issue-86100-tuple-paren-comma.rs:23:22 | -LL | let t = (1, 2); - | ------ here the type of `t` is inferred to be `({integer}, {integer})` LL | let _x: (i32,) = (t); | ------ ^^^ expected a tuple with 1 element, found one with 2 elements | | diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr index f7b5b7fca06..7924d3db06f 100644 --- a/src/test/ui/traits/issue-52893.stderr +++ b/src/test/ui/traits/issue-52893.stderr @@ -4,8 +4,6 @@ error[E0308]: mismatched types LL | impl AddClass for Class

| - this type parameter ... -LL | let output = builder.to_ref(); - | ---------------- here the type of `output` is inferred to be `Class

` LL | builder.push(output); | ---- ^^^^^^ expected type parameter `F`, found struct `Class` | | diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr index 1ad1d692121..0a503e1fe58 100644 --- a/src/test/ui/tuple/wrong_argument_ice-3.stderr +++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr @@ -1,9 +1,6 @@ error[E0061]: this method takes 1 argument but 2 arguments were supplied --> $DIR/wrong_argument_ice-3.rs:9:16 | -LL | let new_group = vec![String::new()]; - | ------------------- here the type of `new_group` is inferred to be `Vec` -... LL | groups.push(new_group, vec![process]); | ^^^^ ------------- argument of type `Vec<&Process>` unexpected | diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr index 0d754459f4a..fcafd315ebf 100644 --- a/src/test/ui/type/type-mismatch-same-crate-name.stderr +++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr @@ -1,9 +1,6 @@ error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:16:20 | -LL | let foo2 = {extern crate crate_a2 as a; a::Foo}; - | ------------------------------------ here the type of `foo2` is inferred to be `Foo` -... LL | a::try_foo(foo2); | ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo` | | @@ -30,9 +27,6 @@ LL | pub fn try_foo(x: Foo){} error[E0308]: mismatched types --> $DIR/type-mismatch-same-crate-name.rs:20:20 | -LL | let bar2 = {extern crate crate_a2 as a; a::bar()}; - | -------------------------------------- here the type of `bar2` is inferred to be `Box` -... LL | a::try_bar(bar2); | ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar` | | -- cgit 1.4.1-3-g733a5 From 9cc8d8619062278046e678bbc08401b733a17236 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 3 Jan 2023 20:20:31 -0800 Subject: Tweak output - Only point at a the single expression where the found type was first inferred. - Find method call argument that might have caused the found type to be inferred. - Provide structured suggestion. - Apply some review comments. - Tweak wording. --- compiler/rustc_hir_typeck/src/demand.rs | 165 +++++++++++++++------ .../ui/type/type-check/assignment-in-if.stderr | 15 +- .../ui/type/type-check/point-at-inference-2.rs | 13 ++ .../ui/type/type-check/point-at-inference-2.stderr | 56 +++++++ .../ui/type/type-check/point-at-inference.fixed | 13 ++ src/test/ui/type/type-check/point-at-inference.rs | 13 ++ .../ui/type/type-check/point-at-inference.stderr | 26 ++++ 7 files changed, 242 insertions(+), 59 deletions(-) create mode 100644 src/test/ui/type/type-check/point-at-inference-2.rs create mode 100644 src/test/ui/type/type-check/point-at-inference-2.stderr create mode 100644 src/test/ui/type/type-check/point-at-inference.fixed create mode 100644 src/test/ui/type/type-check/point-at-inference.rs create mode 100644 src/test/ui/type/type-check/point-at-inference.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index c50d03b944f..317e9b5a7a1 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1,5 +1,6 @@ use crate::FnCtxt; use rustc_ast::util::parser::PREC_POSTFIX; +use rustc_data_structures::fx::FxHashMap; use rustc_errors::MultiSpan; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; @@ -14,12 +15,14 @@ use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{ self, Article, AssocItem, Ty, TyCtxt, TypeAndMut, TypeSuperFoldable, TypeVisitable, }; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; +use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches; use rustc_trait_selection::traits::ObligationCause; use super::method::probe; @@ -44,7 +47,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.annotate_alternative_method_deref(err, expr, error); // Use `||` to give these suggestions a precedence - let _ = self.suggest_missing_parentheses(err, expr) + let suggested = self.suggest_missing_parentheses(err, expr) || self.suggest_remove_last_method_call(err, expr, expected) || self.suggest_associated_const(err, expr, expected) || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) @@ -57,8 +60,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) || self.suggest_into(err, expr, expr_ty, expected) - || self.suggest_floating_point_literal(err, expr, expected) - || self.point_inference_types(err, expr); + || self.suggest_floating_point_literal(err, expr, expected); + if !suggested { + self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected); + } } pub fn emit_coerce_suggestions( @@ -210,7 +215,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (expected, Some(err)) } - fn point_inference_types(&self, err: &mut Diagnostic, expr: &hir::Expr<'_>) -> bool { + fn point_at_expr_source_of_inferred_type( + &self, + err: &mut Diagnostic, + expr: &hir::Expr<'_>, + found: Ty<'tcx>, + expected: Ty<'tcx>, + ) -> bool { let tcx = self.tcx; let map = self.tcx.hir(); @@ -250,25 +261,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; }; let hir::def::Res::Local(hir_id) = p.res else { return false; }; - let Some(node) = map.find(hir_id) else { return false; }; - let hir::Node::Pat(pat) = node else { return false; }; + let Some(hir::Node::Pat(pat)) = map.find(hir_id) else { return false; }; let parent = map.get_parent_node(pat.hir_id); let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) = map.find(parent) else { return false; }; - - let ty = self.node_ty(init.hir_id); + let Some(ty) = self.node_ty_opt(init.hir_id) else { return false; }; if ty.is_closure() || init.span.overlaps(expr.span) || pat.span.from_expansion() { return false; } - let mut span_labels = vec![( - init.span, - with_forced_trimmed_paths!(format!( - "here the type of `{ident}` is inferred to be `{ty}`", - )), - )]; // Locate all the usages of the relevant binding. struct FindExprs<'hir> { @@ -296,71 +299,139 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_finder.visit_expr(body.value); let mut eraser = TypeEraser { tcx }; let mut prev = eraser.fold_ty(ty); + let mut prev_span = None; - for ex in expr_finder.uses { - if ex.span.overlaps(expr.span) { break; } - let parent = map.get_parent_node(ex.hir_id); + for binding in expr_finder.uses { + // In every expression where the binding is referenced, we will look at that + // expression's type and see if it is where the incorrect found type was fully + // "materialized" and point at it. We will also try to provide a suggestion there. + let parent = map.get_parent_node(binding.hir_id); if let Some(hir::Node::Expr(expr)) | Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), .. })) = &map.find(parent) - && let hir::ExprKind::MethodCall(s, rcvr, args, span) = expr.kind - && rcvr.hir_id == ex.hir_id + && let hir::ExprKind::MethodCall(s, rcvr, args, _span) = expr.kind + && rcvr.hir_id == binding.hir_id + && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id) { - let ty = if let Ok(m) = self.lookup_method(ty, s, span, expr, rcvr, args) { - // We get the self type from `lookup_method` because the `rcvr` node - // type will not have had any adjustments from the fn arguments. - let ty = m.sig.inputs_and_output[0]; - match ty.kind() { - // Remove one layer of references to account for `&mut self` and - // `&self`, so that we can compare it against the binding. - ty::Ref(_, ty, _) => *ty, - _ => ty, + // We special case methods, because they can influence inference through the + // call's arguments and we can provide a more explicit span. + let sig = self.tcx.fn_sig(def_id); + let def_self_ty = sig.input(0).skip_binder(); + let rcvr_ty = self.node_ty(rcvr.hir_id); + // Get the evaluated type *after* calling the method call, so that the influence + // of the arguments can be reflected in the receiver type. The receiver + // expression has the type *before* theis analysis is done. + let ty = match self.lookup_probe(s.ident, rcvr_ty, expr, probe::ProbeScope::TraitsInScope) { + Ok(pick) => pick.self_ty, + Err(_) => rcvr_ty, + }; + // Remove one layer of references to account for `&mut self` and + // `&self`, so that we can compare it against the binding. + let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) { + (ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty), + _ => (ty, def_self_ty), + }; + let mut param_args = FxHashMap::default(); + let mut param_expected = FxHashMap::default(); + let mut param_found = FxHashMap::default(); + if self.can_eq(self.param_env, ty, found).is_ok() { + // We only point at the first place where the found type was inferred. + for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { + if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { + // We found an argument that references a type parameter in `Self`, + // so we assume that this is the argument that caused the found + // type, which we know already because of `can_eq` above was first + // inferred in this method call. + let arg = &args[i]; + let arg_ty = self.node_ty(arg.hir_id); + err.span_label( + arg.span, + &format!( + "this is of type `{arg_ty}`, which makes `{ident}` to be \ + inferred as `{ty}`", + ), + ); + param_args.insert(param_ty, (arg, arg_ty)); + } } - } else { - self.node_ty(rcvr.hir_id) + } + + // Here we find, for a type param `T`, the type that `T` is in the current + // method call *and* in the original expected type. That way, we can see if we + // can give any structured suggestion for the function argument. + let mut c = CollectAllMismatches { + infcx: &self.infcx, + param_env: self.param_env, + errors: vec![], }; + let _ = c.relate(def_self_ty, ty); + for error in c.errors { + if let TypeError::Sorts(error) = error { + param_found.insert(error.expected, error.found); + } + } + c.errors = vec![]; + let _ = c.relate(def_self_ty, expected); + for error in c.errors { + if let TypeError::Sorts(error) = error { + param_expected.insert(error.expected, error.found); + } + } + for (param, (arg,arg_ty)) in param_args.iter() { + let Some(expected) = param_expected.get(param) else { continue; }; + let Some(found) = param_found.get(param) else { continue; }; + if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } + self.suggest_deref_ref_or_into(err, arg, *expected, *found, None); + } + let ty = eraser.fold_ty(ty); if ty.references_error() { break; } - if ty != prev { - span_labels.push(( + if ty != prev + && param_args.is_empty() + && self.can_eq(self.param_env, ty, found).is_ok() + { + // We only point at the first place where the found type was inferred. + err.span_label( s.ident.span, with_forced_trimmed_paths!(format!( "here the type of `{ident}` is inferred to be `{ty}`", )), - )); - prev = ty; + ); + break; } + prev = ty; } else { - let ty = eraser.fold_ty(self.node_ty(ex.hir_id)); + let ty = eraser.fold_ty(self.node_ty(binding.hir_id)); if ty.references_error() { break; } - if ty != prev { - span_labels.push(( - ex.span, + if ty != prev && let Some(span) = prev_span && self.can_eq(self.param_env, ty, found).is_ok() { + // We only point at the first place where the found type was inferred. + // We use the *previous* span because if the type is known *here* it means + // it was *evaluated earlier*. We don't do this for method calls because we + // evaluate the method's self type eagerly, but not in any other case. + err.span_label( + span, with_forced_trimmed_paths!(format!( "here the type of `{ident}` is inferred to be `{ty}`", )), - )); + ); + break; } prev = ty; } - if ex.hir_id == expr.hir_id { - // Stop showing spans after the error type was emitted. + if binding.hir_id == expr.hir_id { + // Do not look at expressions that come after the expression we were originally + // evaluating and had a type error. break; } + prev_span = Some(binding.span); } } - if span_labels.len() < 2 { - return false; - } - for (sp, label) in span_labels { - err.span_label(sp, &label); - } true } diff --git a/src/test/ui/type/type-check/assignment-in-if.stderr b/src/test/ui/type/type-check/assignment-in-if.stderr index fb11d6160bb..de133e5599c 100644 --- a/src/test/ui/type/type-check/assignment-in-if.stderr +++ b/src/test/ui/type/type-check/assignment-in-if.stderr @@ -67,10 +67,7 @@ LL | x == 5 error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:18 | -LL | let x = 1; - | - here the type of `x` is inferred to be `{integer}` -... -LL | println!("{}", x); +LL | if y = (Foo { foo: x }) { | - here the type of `x` is inferred to be `usize` ... LL | if x == x && x = x && x == x { @@ -81,10 +78,7 @@ LL | if x == x && x = x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:44:22 | -LL | let x = 1; - | - here the type of `x` is inferred to be `{integer}` -... -LL | println!("{}", x); +LL | if y = (Foo { foo: x }) { | - here the type of `x` is inferred to be `usize` ... LL | if x == x && x = x && x == x { @@ -104,10 +98,7 @@ LL | if x == x && x == x && x == x { error[E0308]: mismatched types --> $DIR/assignment-in-if.rs:51:28 | -LL | let x = 1; - | - here the type of `x` is inferred to be `{integer}` -... -LL | println!("{}", x); +LL | if y = (Foo { foo: x }) { | - here the type of `x` is inferred to be `usize` ... LL | if x == x && x == x && x = x { diff --git a/src/test/ui/type/type-check/point-at-inference-2.rs b/src/test/ui/type/type-check/point-at-inference-2.rs new file mode 100644 index 00000000000..6557d7fa191 --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference-2.rs @@ -0,0 +1,13 @@ +fn bar(_: Vec) {} +fn baz(_: &Vec<&i32>) {} +fn main() { + let v = vec![&1]; + bar(v); //~ ERROR E0308 + let v = vec![]; + baz(&v); + baz(&v); + bar(v); //~ ERROR E0308 + let v = vec![]; + baz(&v); + bar(v); //~ ERROR E0308 +} diff --git a/src/test/ui/type/type-check/point-at-inference-2.stderr b/src/test/ui/type/type-check/point-at-inference-2.stderr new file mode 100644 index 00000000000..13227c5e245 --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference-2.stderr @@ -0,0 +1,56 @@ +error[E0308]: mismatched types + --> $DIR/point-at-inference-2.rs:5:9 + | +LL | bar(v); + | --- ^ expected `i32`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec` + found struct `Vec<&{integer}>` +note: function defined here + --> $DIR/point-at-inference-2.rs:1:4 + | +LL | fn bar(_: Vec) {} + | ^^^ ----------- + +error[E0308]: mismatched types + --> $DIR/point-at-inference-2.rs:9:9 + | +LL | baz(&v); + | - here the type of `v` is inferred to be `Vec<&i32>` +LL | baz(&v); +LL | bar(v); + | --- ^ expected `i32`, found `&i32` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec` + found struct `Vec<&i32>` +note: function defined here + --> $DIR/point-at-inference-2.rs:1:4 + | +LL | fn bar(_: Vec) {} + | ^^^ ----------- + +error[E0308]: mismatched types + --> $DIR/point-at-inference-2.rs:12:9 + | +LL | baz(&v); + | - here the type of `v` is inferred to be `Vec<&i32>` +LL | bar(v); + | --- ^ expected `i32`, found `&i32` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec` + found struct `Vec<&i32>` +note: function defined here + --> $DIR/point-at-inference-2.rs:1:4 + | +LL | fn bar(_: Vec) {} + | ^^^ ----------- + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type/type-check/point-at-inference.fixed b/src/test/ui/type/type-check/point-at-inference.fixed new file mode 100644 index 00000000000..f41fbe59fba --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference.fixed @@ -0,0 +1,13 @@ +// run-rustfix +fn bar(_: Vec) {} +fn baz(_: &impl std::any::Any) {} +fn main() { + let v = vec![1, 2, 3, 4, 5]; + let mut foo = vec![]; + baz(&foo); + for i in &v { + foo.push(*i); + } + baz(&foo); + bar(foo); //~ ERROR E0308 +} diff --git a/src/test/ui/type/type-check/point-at-inference.rs b/src/test/ui/type/type-check/point-at-inference.rs new file mode 100644 index 00000000000..6419e42e70d --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference.rs @@ -0,0 +1,13 @@ +// run-rustfix +fn bar(_: Vec) {} +fn baz(_: &impl std::any::Any) {} +fn main() { + let v = vec![1, 2, 3, 4, 5]; + let mut foo = vec![]; + baz(&foo); + for i in &v { + foo.push(i); + } + baz(&foo); + bar(foo); //~ ERROR E0308 +} diff --git a/src/test/ui/type/type-check/point-at-inference.stderr b/src/test/ui/type/type-check/point-at-inference.stderr new file mode 100644 index 00000000000..197511bf64e --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference.stderr @@ -0,0 +1,26 @@ +error[E0308]: mismatched types + --> $DIR/point-at-inference.rs:12:9 + | +LL | foo.push(i); + | - this is of type `&{integer}`, which makes `foo` to be inferred as `Vec<&{integer}>` +... +LL | bar(foo); + | --- ^^^ expected `i32`, found `&{integer}` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec` + found struct `Vec<&{integer}>` +note: function defined here + --> $DIR/point-at-inference.rs:2:4 + | +LL | fn bar(_: Vec) {} + | ^^^ ----------- +help: consider dereferencing the borrow + | +LL | foo.push(*i); + | + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 4ac7d1c3ab519c72bf10521f0675060b12b0bb0a Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 3 Jan 2023 20:32:15 -0800 Subject: Formatting --- compiler/rustc_hir_typeck/src/demand.rs | 262 ++++++++++++++++---------------- 1 file changed, 135 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 317e9b5a7a1..41bbe2d15c1 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -294,143 +294,151 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let id = map.get_parent_item(hir_id); let hir_id: hir::HirId = id.into(); - if let Some(node) = map.find(hir_id) && let Some(body_id) = node.body_id() { - let body = map.body(body_id); - expr_finder.visit_expr(body.value); - let mut eraser = TypeEraser { tcx }; - let mut prev = eraser.fold_ty(ty); - let mut prev_span = None; - - for binding in expr_finder.uses { - // In every expression where the binding is referenced, we will look at that - // expression's type and see if it is where the incorrect found type was fully - // "materialized" and point at it. We will also try to provide a suggestion there. - let parent = map.get_parent_node(binding.hir_id); - if let Some(hir::Node::Expr(expr)) - | Some(hir::Node::Stmt(hir::Stmt { - kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), - .. - })) = &map.find(parent) - && let hir::ExprKind::MethodCall(s, rcvr, args, _span) = expr.kind - && rcvr.hir_id == binding.hir_id - && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id) - { - // We special case methods, because they can influence inference through the - // call's arguments and we can provide a more explicit span. - let sig = self.tcx.fn_sig(def_id); - let def_self_ty = sig.input(0).skip_binder(); - let rcvr_ty = self.node_ty(rcvr.hir_id); - // Get the evaluated type *after* calling the method call, so that the influence - // of the arguments can be reflected in the receiver type. The receiver - // expression has the type *before* theis analysis is done. - let ty = match self.lookup_probe(s.ident, rcvr_ty, expr, probe::ProbeScope::TraitsInScope) { - Ok(pick) => pick.self_ty, - Err(_) => rcvr_ty, - }; - // Remove one layer of references to account for `&mut self` and - // `&self`, so that we can compare it against the binding. - let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) { - (ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty), - _ => (ty, def_self_ty), - }; - let mut param_args = FxHashMap::default(); - let mut param_expected = FxHashMap::default(); - let mut param_found = FxHashMap::default(); - if self.can_eq(self.param_env, ty, found).is_ok() { - // We only point at the first place where the found type was inferred. - for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { - if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { - // We found an argument that references a type parameter in `Self`, - // so we assume that this is the argument that caused the found - // type, which we know already because of `can_eq` above was first - // inferred in this method call. - let arg = &args[i]; - let arg_ty = self.node_ty(arg.hir_id); - err.span_label( - arg.span, - &format!( - "this is of type `{arg_ty}`, which makes `{ident}` to be \ - inferred as `{ty}`", - ), - ); - param_args.insert(param_ty, (arg, arg_ty)); - } + let Some(node) = map.find(hir_id) else { return false; }; + let Some(body_id) = node.body_id() else { return false; }; + let body = map.body(body_id); + expr_finder.visit_expr(body.value); + let mut eraser = TypeEraser { tcx }; + let mut prev = eraser.fold_ty(ty); + let mut prev_span = None; + + for binding in expr_finder.uses { + // In every expression where the binding is referenced, we will look at that + // expression's type and see if it is where the incorrect found type was fully + // "materialized" and point at it. We will also try to provide a suggestion there. + let parent = map.get_parent_node(binding.hir_id); + if let Some(hir::Node::Expr(expr)) + | Some(hir::Node::Stmt(hir::Stmt { + kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), + .. + })) = &map.find(parent) + && let hir::ExprKind::MethodCall(segment, rcvr, args, _span) = expr.kind + && rcvr.hir_id == binding.hir_id + && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + { + // We special case methods, because they can influence inference through the + // call's arguments and we can provide a more explicit span. + let sig = self.tcx.fn_sig(def_id); + let def_self_ty = sig.input(0).skip_binder(); + let rcvr_ty = self.node_ty(rcvr.hir_id); + // Get the evaluated type *after* calling the method call, so that the influence + // of the arguments can be reflected in the receiver type. The receiver + // expression has the type *before* theis analysis is done. + let ty = match self.lookup_probe( + segment.ident, + rcvr_ty, + expr, + probe::ProbeScope::TraitsInScope, + ) { + Ok(pick) => pick.self_ty, + Err(_) => rcvr_ty, + }; + // Remove one layer of references to account for `&mut self` and + // `&self`, so that we can compare it against the binding. + let (ty, def_self_ty) = match (ty.kind(), def_self_ty.kind()) { + (ty::Ref(_, ty, a), ty::Ref(_, self_ty, b)) if a == b => (*ty, *self_ty), + _ => (ty, def_self_ty), + }; + let mut param_args = FxHashMap::default(); + let mut param_expected = FxHashMap::default(); + let mut param_found = FxHashMap::default(); + if self.can_eq(self.param_env, ty, found).is_ok() { + // We only point at the first place where the found type was inferred. + for (i, param_ty) in sig.inputs().skip_binder().iter().skip(1).enumerate() { + if def_self_ty.contains(*param_ty) && let ty::Param(_) = param_ty.kind() { + // We found an argument that references a type parameter in `Self`, + // so we assume that this is the argument that caused the found + // type, which we know already because of `can_eq` above was first + // inferred in this method call. + let arg = &args[i]; + let arg_ty = self.node_ty(arg.hir_id); + err.span_label( + arg.span, + &format!( + "this is of type `{arg_ty}`, which makes `{ident}` to be \ + inferred as `{ty}`", + ), + ); + param_args.insert(param_ty, (arg, arg_ty)); } } + } - // Here we find, for a type param `T`, the type that `T` is in the current - // method call *and* in the original expected type. That way, we can see if we - // can give any structured suggestion for the function argument. - let mut c = CollectAllMismatches { - infcx: &self.infcx, - param_env: self.param_env, - errors: vec![], - }; - let _ = c.relate(def_self_ty, ty); - for error in c.errors { - if let TypeError::Sorts(error) = error { - param_found.insert(error.expected, error.found); - } - } - c.errors = vec![]; - let _ = c.relate(def_self_ty, expected); - for error in c.errors { - if let TypeError::Sorts(error) = error { - param_expected.insert(error.expected, error.found); - } + // Here we find, for a type param `T`, the type that `T` is in the current + // method call *and* in the original expected type. That way, we can see if we + // can give any structured suggestion for the function argument. + let mut c = CollectAllMismatches { + infcx: &self.infcx, + param_env: self.param_env, + errors: vec![], + }; + let _ = c.relate(def_self_ty, ty); + for error in c.errors { + if let TypeError::Sorts(error) = error { + param_found.insert(error.expected, error.found); } - for (param, (arg,arg_ty)) in param_args.iter() { - let Some(expected) = param_expected.get(param) else { continue; }; - let Some(found) = param_found.get(param) else { continue; }; - if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } - self.suggest_deref_ref_or_into(err, arg, *expected, *found, None); + } + c.errors = vec![]; + let _ = c.relate(def_self_ty, expected); + for error in c.errors { + if let TypeError::Sorts(error) = error { + param_expected.insert(error.expected, error.found); } + } + for (param, (arg,arg_ty)) in param_args.iter() { + let Some(expected) = param_expected.get(param) else { continue; }; + let Some(found) = param_found.get(param) else { continue; }; + if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } + self.suggest_deref_ref_or_into(err, arg, *expected, *found, None); + } - let ty = eraser.fold_ty(ty); - if ty.references_error() { - break; - } - if ty != prev - && param_args.is_empty() - && self.can_eq(self.param_env, ty, found).is_ok() - { - // We only point at the first place where the found type was inferred. - err.span_label( - s.ident.span, - with_forced_trimmed_paths!(format!( - "here the type of `{ident}` is inferred to be `{ty}`", - )), - ); - break; - } - prev = ty; - } else { - let ty = eraser.fold_ty(self.node_ty(binding.hir_id)); - if ty.references_error() { - break; - } - if ty != prev && let Some(span) = prev_span && self.can_eq(self.param_env, ty, found).is_ok() { - // We only point at the first place where the found type was inferred. - // We use the *previous* span because if the type is known *here* it means - // it was *evaluated earlier*. We don't do this for method calls because we - // evaluate the method's self type eagerly, but not in any other case. - err.span_label( - span, - with_forced_trimmed_paths!(format!( - "here the type of `{ident}` is inferred to be `{ty}`", - )), - ); - break; - } - prev = ty; + let ty = eraser.fold_ty(ty); + if ty.references_error() { + break; } - if binding.hir_id == expr.hir_id { - // Do not look at expressions that come after the expression we were originally - // evaluating and had a type error. + if ty != prev + && param_args.is_empty() + && self.can_eq(self.param_env, ty, found).is_ok() + { + // We only point at the first place where the found type was inferred. + err.span_label( + segment.ident.span, + with_forced_trimmed_paths!(format!( + "here the type of `{ident}` is inferred to be `{ty}`", + )), + ); break; } - prev_span = Some(binding.span); + prev = ty; + } else { + let ty = eraser.fold_ty(self.node_ty(binding.hir_id)); + if ty.references_error() { + break; + } + if ty != prev + && let Some(span) = prev_span + && self.can_eq(self.param_env, ty, found).is_ok() + { + // We only point at the first place where the found type was inferred. + // We use the *previous* span because if the type is known *here* it means + // it was *evaluated earlier*. We don't do this for method calls because we + // evaluate the method's self type eagerly, but not in any other case. + err.span_label( + span, + with_forced_trimmed_paths!(format!( + "here the type of `{ident}` is inferred to be `{ty}`", + )), + ); + break; + } + prev = ty; + } + if binding.hir_id == expr.hir_id { + // Do not look at expressions that come after the expression we were originally + // evaluating and had a type error. + break; } + prev_span = Some(binding.span); } true } -- cgit 1.4.1-3-g733a5 From ad82eedfa190b3cd39a535a6e858d79f69c89ff2 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 3 Jan 2023 20:49:47 -0800 Subject: Use `BottomUpFolder` --- compiler/rustc_hir_typeck/src/demand.rs | 57 ++++++++------------------ compiler/rustc_infer/src/infer/opaque_types.rs | 2 +- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 41bbe2d15c1..abff2637519 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -13,12 +13,10 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fold::TypeFolder; +use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder}; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::relate::TypeRelation; -use rustc_middle::ty::{ - self, Article, AssocItem, Ty, TyCtxt, TypeAndMut, TypeSuperFoldable, TypeVisitable, -}; +use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitable}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -222,42 +220,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { found: Ty<'tcx>, expected: Ty<'tcx>, ) -> bool { - let tcx = self.tcx; let map = self.tcx.hir(); - // Hack to make equality checks on types with inference variables and regions useful. - struct TypeEraser<'tcx> { - tcx: TyCtxt<'tcx>, - } - impl<'tcx> TypeFolder<'tcx> for TypeEraser<'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - self.tcx - } - fn fold_region(&mut self, _r: ty::Region<'tcx>) -> ty::Region<'tcx> { - self.tcx().lifetimes.re_erased - } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.needs_infer() && !t.has_erasable_regions() { - return t; - } - match *t.kind() { - ty::Infer(ty::TyVar(_) | ty::FreshTy(_)) => { - self.tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))) - } - ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => { - self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 })) - } - ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => { - self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 })) - } - _ => t.super_fold_with(self), - } - } - fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - ct.super_fold_with(self) - } - } - let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind else { return false; }; let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; }; let hir::def::Res::Local(hir_id) = p.res else { return false; }; @@ -298,7 +262,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(body_id) = node.body_id() else { return false; }; let body = map.body(body_id); expr_finder.visit_expr(body.value); - let mut eraser = TypeEraser { tcx }; + // Hack to make equality checks on types with inference variables and regions useful. + let mut eraser = BottomUpFolder { + tcx: self.tcx, + lt_op: |_| self.tcx.lifetimes.re_erased, + ct_op: |c| c, + ty_op: |t| match *t.kind() { + ty::Infer(ty::TyVar(vid)) => self.tcx.mk_ty_infer(ty::TyVar(self.root_var(vid))), + ty::Infer(ty::IntVar(_)) => { + self.tcx.mk_ty_infer(ty::IntVar(ty::IntVid { index: 0 })) + } + ty::Infer(ty::FloatVar(_)) => { + self.tcx.mk_ty_infer(ty::FloatVar(ty::FloatVid { index: 0 })) + } + _ => t, + }, + }; let mut prev = eraser.fold_ty(ty); let mut prev_span = None; diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index a130fde47ed..749e960bfd0 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -61,7 +61,7 @@ impl<'tcx> InferCtxt<'tcx> { .as_local() .map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some()) }; - let value = value.fold_with(&mut ty::fold::BottomUpFolder { + let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, lt_op: |lt| lt, ct_op: |ct| ct, -- cgit 1.4.1-3-g733a5 From c905f5e1b0315f9637b2f7e52c807e46b2e24ee6 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 00:18:57 +0000 Subject: Account for type error on method arg caused by earlier inference ```rust fn main() { let v = Vec::new(); v.push(0); v.push(0); v.push(""); } ``` now produces ``` error[E0308]: mismatched types --> $DIR/point-at-inference-3.rs:6:12 | LL | v.push(0); | - this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` ... LL | v.push(""); | ---- ^^ expected integer, found `&str` | | | arguments to this function are incorrect | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL ``` --- compiler/rustc_hir_typeck/src/demand.rs | 4 +++- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 12 ++++++++++++ src/test/ui/type/type-check/point-at-inference-3.rs | 10 ++++++++++ src/test/ui/type/type-check/point-at-inference-3.stderr | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/type/type-check/point-at-inference-3.rs create mode 100644 src/test/ui/type/type-check/point-at-inference-3.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index abff2637519..cff74cd9693 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -213,7 +213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (expected, Some(err)) } - fn point_at_expr_source_of_inferred_type( + pub fn point_at_expr_source_of_inferred_type( &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, @@ -387,6 +387,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )), ); break; + } else if !param_args.is_empty() { + break; } prev = ty; } else { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 55280487add..7d6b4aaebf4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -798,6 +798,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { full_call_span, format!("arguments to this {} are incorrect", call_name), ); + if let (Some(callee_ty), hir::ExprKind::MethodCall(_, rcvr, _, _)) = + (callee_ty, &call_expr.kind) + { + // Type that would have accepted this argument if it hadn't been inferred earlier. + // FIXME: We leave an inference variable for now, but it'd be nice to get a more + // specific type to increase the accuracy of the diagnostic. + let expected = self.infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: full_call_span, + }); + self.point_at_expr_source_of_inferred_type(&mut err, rcvr, expected, callee_ty); + } // Call out where the function is defined self.label_fn_like( &mut err, diff --git a/src/test/ui/type/type-check/point-at-inference-3.rs b/src/test/ui/type/type-check/point-at-inference-3.rs new file mode 100644 index 00000000000..893306d4105 --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference-3.rs @@ -0,0 +1,10 @@ +fn main() { + let v = Vec::new(); + v.push(0); + //~^ NOTE this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` + v.push(0); + v.push(""); //~ ERROR mismatched types + //~^ NOTE expected integer, found `&str` + //~| NOTE arguments to this function are incorrect + //~| NOTE associated function defined here +} diff --git a/src/test/ui/type/type-check/point-at-inference-3.stderr b/src/test/ui/type/type-check/point-at-inference-3.stderr new file mode 100644 index 00000000000..01264edf6b6 --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference-3.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/point-at-inference-3.rs:6:12 + | +LL | v.push(0); + | - this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` +... +LL | v.push(""); + | ---- ^^ expected integer, found `&str` + | | + | arguments to this function are incorrect + | +note: associated function defined here + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From f571862d174e3d26002bf52138ead476bf068f86 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 00:37:53 +0000 Subject: Suggest changing argument on type error --- src/test/ui/type/type-check/point-at-inference-3.fixed | 12 ++++++++++++ src/test/ui/type/type-check/point-at-inference-3.rs | 12 +++++++----- src/test/ui/type/type-check/point-at-inference-3.stderr | 14 +++++++++----- 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/type/type-check/point-at-inference-3.fixed diff --git a/src/test/ui/type/type-check/point-at-inference-3.fixed b/src/test/ui/type/type-check/point-at-inference-3.fixed new file mode 100644 index 00000000000..ff299940a57 --- /dev/null +++ b/src/test/ui/type/type-check/point-at-inference-3.fixed @@ -0,0 +1,12 @@ +// run-rustfix +fn main() { + let mut v = Vec::new(); + v.push(0i32); + //~^ NOTE this is of type `i32`, which makes `v` to be inferred as `Vec` + v.push(0); + v.push(1i32); //~ ERROR mismatched types + //~^ NOTE expected `i32`, found `u32` + //~| NOTE arguments to this function are incorrect + //~| NOTE associated function defined here + //~| HELP change the type of the numeric literal from `u32` to `i32` +} diff --git a/src/test/ui/type/type-check/point-at-inference-3.rs b/src/test/ui/type/type-check/point-at-inference-3.rs index 893306d4105..812a39e4aaf 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.rs +++ b/src/test/ui/type/type-check/point-at-inference-3.rs @@ -1,10 +1,12 @@ +// run-rustfix fn main() { - let v = Vec::new(); + let mut v = Vec::new(); + v.push(0i32); + //~^ NOTE this is of type `i32`, which makes `v` to be inferred as `Vec` v.push(0); - //~^ NOTE this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` - v.push(0); - v.push(""); //~ ERROR mismatched types - //~^ NOTE expected integer, found `&str` + v.push(1u32); //~ ERROR mismatched types + //~^ NOTE expected `i32`, found `u32` //~| NOTE arguments to this function are incorrect //~| NOTE associated function defined here + //~| HELP change the type of the numeric literal from `u32` to `i32` } diff --git a/src/test/ui/type/type-check/point-at-inference-3.stderr b/src/test/ui/type/type-check/point-at-inference-3.stderr index 01264edf6b6..4e777969466 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.stderr +++ b/src/test/ui/type/type-check/point-at-inference-3.stderr @@ -1,16 +1,20 @@ error[E0308]: mismatched types - --> $DIR/point-at-inference-3.rs:6:12 + --> $DIR/point-at-inference-3.rs:7:12 | -LL | v.push(0); - | - this is of type `{integer}`, which makes `v` to be inferred as `Vec<{integer}>` +LL | v.push(0i32); + | ---- this is of type `i32`, which makes `v` to be inferred as `Vec` ... -LL | v.push(""); - | ---- ^^ expected integer, found `&str` +LL | v.push(1u32); + | ---- ^^^^ expected `i32`, found `u32` | | | arguments to this function are incorrect | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL +help: change the type of the numeric literal from `u32` to `i32` + | +LL | v.push(1i32); + | ~~~ error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 98f3936aa7e99f54ff377a77f9b03cea2c2c29d4 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 01:00:21 +0000 Subject: review comment: potentially produce more suggestions for arg type mismatch --- compiler/rustc_hir_typeck/src/demand.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index cff74cd9693..06f34abbea2 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -364,11 +364,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param_expected.insert(error.expected, error.found); } } - for (param, (arg,arg_ty)) in param_args.iter() { + for (param, (arg, arg_ty)) in param_args.iter() { let Some(expected) = param_expected.get(param) else { continue; }; let Some(found) = param_found.get(param) else { continue; }; if self.can_eq(self.param_env, *arg_ty, *found).is_err() { continue; } - self.suggest_deref_ref_or_into(err, arg, *expected, *found, None); + self.emit_coerce_suggestions(err, arg, *found, *expected, None, None); } let ty = eraser.fold_ty(ty); -- cgit 1.4.1-3-g733a5 From b182259d391a033a3a7017a7be7d5494405fc8e9 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 01:26:44 +0000 Subject: review comments: reword --- compiler/rustc_hir_typeck/src/demand.rs | 2 +- src/test/ui/type/type-check/point-at-inference-3.fixed | 2 +- src/test/ui/type/type-check/point-at-inference-3.rs | 2 +- src/test/ui/type/type-check/point-at-inference-3.stderr | 2 +- src/test/ui/type/type-check/point-at-inference.stderr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 06f34abbea2..6cf515cbb0a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -334,7 +334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label( arg.span, &format!( - "this is of type `{arg_ty}`, which makes `{ident}` to be \ + "this is of type `{arg_ty}`, which causes `{ident}` to be \ inferred as `{ty}`", ), ); diff --git a/src/test/ui/type/type-check/point-at-inference-3.fixed b/src/test/ui/type/type-check/point-at-inference-3.fixed index ff299940a57..870f2779b8c 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.fixed +++ b/src/test/ui/type/type-check/point-at-inference-3.fixed @@ -2,7 +2,7 @@ fn main() { let mut v = Vec::new(); v.push(0i32); - //~^ NOTE this is of type `i32`, which makes `v` to be inferred as `Vec` + //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec` v.push(0); v.push(1i32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` diff --git a/src/test/ui/type/type-check/point-at-inference-3.rs b/src/test/ui/type/type-check/point-at-inference-3.rs index 812a39e4aaf..a4471e12fc2 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.rs +++ b/src/test/ui/type/type-check/point-at-inference-3.rs @@ -2,7 +2,7 @@ fn main() { let mut v = Vec::new(); v.push(0i32); - //~^ NOTE this is of type `i32`, which makes `v` to be inferred as `Vec` + //~^ NOTE this is of type `i32`, which causes `v` to be inferred as `Vec` v.push(0); v.push(1u32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` diff --git a/src/test/ui/type/type-check/point-at-inference-3.stderr b/src/test/ui/type/type-check/point-at-inference-3.stderr index 4e777969466..c373c6722fd 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.stderr +++ b/src/test/ui/type/type-check/point-at-inference-3.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/point-at-inference-3.rs:7:12 | LL | v.push(0i32); - | ---- this is of type `i32`, which makes `v` to be inferred as `Vec` + | ---- this is of type `i32`, which causes `v` to be inferred as `Vec` ... LL | v.push(1u32); | ---- ^^^^ expected `i32`, found `u32` diff --git a/src/test/ui/type/type-check/point-at-inference.stderr b/src/test/ui/type/type-check/point-at-inference.stderr index 197511bf64e..70428fe841b 100644 --- a/src/test/ui/type/type-check/point-at-inference.stderr +++ b/src/test/ui/type/type-check/point-at-inference.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/point-at-inference.rs:12:9 | LL | foo.push(i); - | - this is of type `&{integer}`, which makes `foo` to be inferred as `Vec<&{integer}>` + | - this is of type `&{integer}`, which causes `foo` to be inferred as `Vec<&{integer}>` ... LL | bar(foo); | --- ^^^ expected `i32`, found `&{integer}` -- cgit 1.4.1-3-g733a5 From 23c3a307300827dbd53637742905293b9240506a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 3 Jan 2023 17:02:25 +0000 Subject: Explain error with `&mut self` for unsized trait impls --- .../src/diagnostics/mutability_errors.rs | 27 +++++++++++++--------- src/test/ui/borrowck/issue-93078.rs | 15 ++++++++++++ src/test/ui/borrowck/issue-93078.stderr | 12 ++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/borrowck/issue-93078.rs create mode 100644 src/test/ui/borrowck/issue-93078.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6f6d1b01bd4..bf830e27699 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -344,20 +344,25 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { err.span_help(source_info.span, "try removing `&mut` here"); } - } else if decl.mutability == Mutability::Not - && !matches!( + } else if decl.mutability == Mutability::Not { + if matches!( decl.local_info, Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf( hir::ImplicitSelfKind::MutRef - )))) - ) - { - err.span_suggestion_verbose( - decl.source_info.span.shrink_to_lo(), - "consider making the binding mutable", - "mut ", - Applicability::MachineApplicable, - ); + ),))) + ) { + err.note( + "as `Self` may be unsized, this call attempts to take `&mut &mut self`", + ); + err.note("however, `&mut self` expands to `self: &mut Self`, therefore `self` cannot be borrowed mutably"); + } else { + err.span_suggestion_verbose( + decl.source_info.span.shrink_to_lo(), + "consider making the binding mutable", + "mut ", + Applicability::MachineApplicable, + ); + }; } } diff --git a/src/test/ui/borrowck/issue-93078.rs b/src/test/ui/borrowck/issue-93078.rs new file mode 100644 index 00000000000..2e608c5db3e --- /dev/null +++ b/src/test/ui/borrowck/issue-93078.rs @@ -0,0 +1,15 @@ +trait Modify { + fn modify(&mut self) ; +} + +impl Modify for T { + fn modify(&mut self) {} +} + +trait Foo { + fn mute(&mut self) { + self.modify(); //~ ERROR cannot borrow `self` as mutable + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-93078.stderr b/src/test/ui/borrowck/issue-93078.stderr new file mode 100644 index 00000000000..771a652a173 --- /dev/null +++ b/src/test/ui/borrowck/issue-93078.stderr @@ -0,0 +1,12 @@ +error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable + --> $DIR/issue-93078.rs:11:9 + | +LL | self.modify(); + | ^^^^^^^^^^^^^ cannot borrow as mutable + | + = note: as `Self` may be unsized, this call attempts to take `&mut &mut self` + = note: however, `&mut self` expands to `self: &mut Self`, therefore `self` cannot be borrowed mutably + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. -- cgit 1.4.1-3-g733a5 From f98f2fcb5e4985bd7b12bae4ec03f2d96197fb2b Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 17:06:34 +0000 Subject: fix rebase --- compiler/rustc_hir_typeck/src/demand.rs | 10 ++++------ src/test/ui/type/type-check/point-at-inference-3.fixed | 2 +- src/test/ui/type/type-check/point-at-inference-3.rs | 2 +- src/test/ui/type/type-check/point-at-inference-3.stderr | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 6cf515cbb0a..cf070eb962f 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -226,12 +226,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let [hir::PathSegment { ident, args: None, .. }] = p.segments else { return false; }; let hir::def::Res::Local(hir_id) = p.res else { return false; }; let Some(hir::Node::Pat(pat)) = map.find(hir_id) else { return false; }; - let parent = map.get_parent_node(pat.hir_id); let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. - })) = map.find(parent) else { return false; }; + })) = map.find_parent(pat.hir_id) else { return false; }; let Some(ty) = self.node_ty_opt(init.hir_id) else { return false; }; if ty.is_closure() || init.span.overlaps(expr.span) || pat.span.from_expansion() { return false; @@ -285,12 +284,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // In every expression where the binding is referenced, we will look at that // expression's type and see if it is where the incorrect found type was fully // "materialized" and point at it. We will also try to provide a suggestion there. - let parent = map.get_parent_node(binding.hir_id); - if let Some(hir::Node::Expr(expr)) - | Some(hir::Node::Stmt(hir::Stmt { + if let Some(hir::Node::Expr(expr) + | hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr), .. - })) = &map.find(parent) + })) = &map.find_parent(binding.hir_id) && let hir::ExprKind::MethodCall(segment, rcvr, args, _span) = expr.kind && rcvr.hir_id == binding.hir_id && let Some(def_id) = self.typeck_results.borrow().type_dependent_def_id(expr.hir_id) diff --git a/src/test/ui/type/type-check/point-at-inference-3.fixed b/src/test/ui/type/type-check/point-at-inference-3.fixed index 870f2779b8c..1a960133ceb 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.fixed +++ b/src/test/ui/type/type-check/point-at-inference-3.fixed @@ -6,7 +6,7 @@ fn main() { v.push(0); v.push(1i32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` - //~| NOTE arguments to this function are incorrect + //~| NOTE arguments to this method are incorrect //~| NOTE associated function defined here //~| HELP change the type of the numeric literal from `u32` to `i32` } diff --git a/src/test/ui/type/type-check/point-at-inference-3.rs b/src/test/ui/type/type-check/point-at-inference-3.rs index a4471e12fc2..92910ae1a31 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.rs +++ b/src/test/ui/type/type-check/point-at-inference-3.rs @@ -6,7 +6,7 @@ fn main() { v.push(0); v.push(1u32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` - //~| NOTE arguments to this function are incorrect + //~| NOTE arguments to this method are incorrect //~| NOTE associated function defined here //~| HELP change the type of the numeric literal from `u32` to `i32` } diff --git a/src/test/ui/type/type-check/point-at-inference-3.stderr b/src/test/ui/type/type-check/point-at-inference-3.stderr index c373c6722fd..999c3148362 100644 --- a/src/test/ui/type/type-check/point-at-inference-3.stderr +++ b/src/test/ui/type/type-check/point-at-inference-3.stderr @@ -7,7 +7,7 @@ LL | v.push(0i32); LL | v.push(1u32); | ---- ^^^^ expected `i32`, found `u32` | | - | arguments to this function are incorrect + | arguments to this method are incorrect | note: associated function defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -- cgit 1.4.1-3-g733a5 From de1859fc324a323dfd0033d666c64f82ff2f130f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 5 Jan 2023 17:57:55 +0000 Subject: Correct detection of elided lifetimes in impl-trait. --- compiler/rustc_hir_analysis/src/collect/lifetimes.rs | 6 ++++-- src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs index 0a1188c16a8..35f10dc8737 100644 --- a/compiler/rustc_hir_analysis/src/collect/lifetimes.rs +++ b/compiler/rustc_hir_analysis/src/collect/lifetimes.rs @@ -1195,8 +1195,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // Fresh lifetimes in APIT used to be allowed in async fns and forbidden in // regular fns. if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin - && let hir::LifetimeName::Param(_) = lifetime_ref.res - && lifetime_ref.is_anonymous() + && let hir::LifetimeName::Param(param_id) = lifetime_ref.res + && let Some(generics) = self.tcx.hir().get_generics(self.tcx.local_parent(param_id)) + && let Some(param) = generics.params.iter().find(|p| p.def_id == param_id) + && param.is_elided_lifetime() && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id) && !self.tcx.features().anonymous_lifetime_in_impl_trait { diff --git a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs index 9839e973bdf..a1a51c4814e 100644 --- a/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs +++ b/src/test/ui/suggestions/impl-trait-missing-lifetime-gated.rs @@ -60,4 +60,9 @@ mod in_path { //~| ERROR missing lifetime specifier } +// This must not err, as the `&` actually resolves to `'a`. +fn resolved_anonymous<'a, T>(f: impl Fn(&'a str) -> &T) { + f("f") +} + fn main() {} -- cgit 1.4.1-3-g733a5 From fd7a15971069156f1741fb3a3c34c9f0c54d5744 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 19 Dec 2022 10:31:55 +0100 Subject: Fix `uninlined_format_args` for some compiler crates Convert all the crates that have had their diagnostic migration completed (except save_analysis because that will be deleted soon and apfloat because of the licensing problem). --- compiler/rustc_ast/src/ast.rs | 6 ++-- compiler/rustc_ast/src/ast_traits.rs | 4 +-- compiler/rustc_ast/src/attr/mod.rs | 2 +- compiler/rustc_ast/src/expand/allocator.rs | 4 +-- compiler/rustc_ast/src/token.rs | 14 ++++---- compiler/rustc_ast/src/tokenstream.rs | 3 +- compiler/rustc_ast/src/util/literal.rs | 6 ++-- compiler/rustc_ast_lowering/src/asm.rs | 4 +-- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 8 ++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 16 ++++----- compiler/rustc_ast_pretty/src/pprust/state/item.rs | 4 +-- compiler/rustc_attr/src/builtin.rs | 4 +-- compiler/rustc_attr/src/session_diagnostics.rs | 2 +- .../src/graph/dominators/mod.rs | 4 +-- .../rustc_data_structures/src/graph/scc/mod.rs | 14 ++++---- .../src/obligation_forest/graphviz.rs | 4 +-- compiler/rustc_data_structures/src/profiling.rs | 2 +- compiler/rustc_data_structures/src/small_c_str.rs | 6 ++-- compiler/rustc_data_structures/src/vec_map.rs | 3 +- compiler/rustc_driver/src/args.rs | 6 ++-- compiler/rustc_driver/src/lib.rs | 41 ++++++++++------------ compiler/rustc_driver/src/pretty.rs | 6 ++-- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_feature/src/lib.rs | 2 +- compiler/rustc_graphviz/src/lib.rs | 12 +++---- compiler/rustc_hir/src/def.rs | 3 +- compiler/rustc_hir/src/definitions.rs | 11 +++--- compiler/rustc_hir/src/hir_id.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 8 ++--- compiler/rustc_index/src/bit_set.rs | 2 +- compiler/rustc_index/src/interval.rs | 5 +-- compiler/rustc_interface/src/interface.rs | 6 ++-- compiler/rustc_interface/src/passes.rs | 6 ++-- compiler/rustc_interface/src/util.rs | 13 ++++--- compiler/rustc_llvm/build.rs | 28 +++++++-------- compiler/rustc_log/src/lib.rs | 3 +- compiler/rustc_macros/src/diagnostics/error.rs | 16 ++++----- compiler/rustc_macros/src/diagnostics/fluent.rs | 4 +-- .../rustc_macros/src/diagnostics/subdiagnostic.rs | 3 +- compiler/rustc_macros/src/diagnostics/utils.rs | 8 ++--- compiler/rustc_macros/src/newtype.rs | 4 +-- compiler/rustc_macros/src/query.rs | 2 +- compiler/rustc_macros/src/symbols.rs | 6 ++-- compiler/rustc_metadata/src/creader.rs | 4 +-- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 6 ++-- .../src/rmeta/decoder/cstore_impl.rs | 2 +- .../rustc_metadata/src/rmeta/def_path_hash_map.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 18 ++++------ compiler/rustc_mir_dataflow/src/framework/fmt.rs | 4 +-- .../rustc_mir_dataflow/src/framework/graphviz.rs | 18 +++++----- compiler/rustc_mir_dataflow/src/move_paths/mod.rs | 6 ++-- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_monomorphize/src/errors.rs | 2 +- .../rustc_monomorphize/src/partitioning/mod.rs | 11 +++--- compiler/rustc_monomorphize/src/util.rs | 8 ++--- compiler/rustc_parse_format/src/lib.rs | 8 ++--- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_query_impl/src/on_disk_cache.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 2 +- compiler/rustc_query_impl/src/profiling_support.rs | 2 +- compiler/rustc_query_system/src/dep_graph/debug.rs | 4 +-- .../rustc_query_system/src/dep_graph/dep_node.rs | 2 +- compiler/rustc_query_system/src/dep_graph/graph.rs | 22 +++++------- .../rustc_query_system/src/dep_graph/serialized.rs | 13 +++---- compiler/rustc_query_system/src/query/plumbing.rs | 12 +++---- compiler/rustc_span/src/def_id.rs | 2 +- compiler/rustc_span/src/edition.rs | 2 +- compiler/rustc_span/src/hygiene.rs | 16 ++++----- compiler/rustc_span/src/lib.rs | 4 +-- compiler/rustc_span/src/profiling.rs | 2 +- compiler/rustc_symbol_mangling/src/legacy.rs | 4 +-- compiler/rustc_symbol_mangling/src/lib.rs | 3 +- compiler/rustc_symbol_mangling/src/test.rs | 2 +- .../src/typeid/typeid_itanium_cxx_abi.rs | 4 +-- compiler/rustc_symbol_mangling/src/v0.rs | 4 +-- compiler/rustc_target/src/abi/call/mod.rs | 8 ++--- compiler/rustc_target/src/asm/aarch64.rs | 2 +- compiler/rustc_target/src/asm/arm.rs | 2 +- compiler/rustc_target/src/asm/mod.rs | 14 ++++---- compiler/rustc_target/src/asm/x86.rs | 30 ++++++++-------- compiler/rustc_target/src/spec/apple_base.rs | 10 +++--- compiler/rustc_target/src/spec/mod.rs | 12 +++---- compiler/rustc_target/src/spec/solid_base.rs | 2 +- compiler/rustc_traits/src/dropck_outlives.rs | 4 +-- .../rustc_traits/src/normalize_erasing_regions.rs | 2 +- compiler/rustc_transmute/src/layout/mod.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 12 +++---- compiler/rustc_type_ir/src/sty.rs | 6 ++-- 91 files changed, 287 insertions(+), 329 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c1b26ca0925..e656fb3740b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2170,10 +2170,10 @@ impl fmt::Display for InlineAsmTemplatePiece { Ok(()) } Self::Placeholder { operand_idx, modifier: Some(modifier), .. } => { - write!(f, "{{{}:{}}}", operand_idx, modifier) + write!(f, "{{{operand_idx}:{modifier}}}") } Self::Placeholder { operand_idx, modifier: None, .. } => { - write!(f, "{{{}}}", operand_idx) + write!(f, "{{{operand_idx}}}") } } } @@ -2185,7 +2185,7 @@ impl InlineAsmTemplatePiece { use fmt::Write; let mut out = String::new(); for p in s.iter() { - let _ = write!(out, "{}", p); + let _ = write!(out, "{p}"); } out } diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 1b31be07f7a..4dc9c30a2c8 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -214,7 +214,7 @@ impl HasTokens for Attribute { match &self.kind { AttrKind::Normal(normal) => normal.tokens.as_ref(), kind @ AttrKind::DocComment(..) => { - panic!("Called tokens on doc comment attr {:?}", kind) + panic!("Called tokens on doc comment attr {kind:?}") } } } @@ -222,7 +222,7 @@ impl HasTokens for Attribute { Some(match &mut self.kind { AttrKind::Normal(normal) => &mut normal.tokens, kind @ AttrKind::DocComment(..) => { - panic!("Called tokens_mut on doc comment attr {:?}", kind) + panic!("Called tokens_mut on doc comment attr {kind:?}") } }) } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index d99f6ed2c1c..c6b6207b318 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -310,7 +310,7 @@ impl Attribute { AttrKind::Normal(normal) => normal .tokens .as_ref() - .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) + .unwrap_or_else(|| panic!("attribute is missing tokens: {self:?}")) .to_attr_token_stream() .to_tokenstream(), &AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index 1976e4ad3c9..35939496348 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -9,8 +9,8 @@ pub enum AllocatorKind { impl AllocatorKind { pub fn fn_name(&self, base: Symbol) -> String { match *self { - AllocatorKind::Global => format!("__rg_{}", base), - AllocatorKind::Default => format!("__rdl_{}", base), + AllocatorKind::Global => format!("__rg_{base}"), + AllocatorKind::Default => format!("__rdl_{base}"), } } } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 5b6cf30fa96..f947ae4d057 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -125,27 +125,27 @@ impl fmt::Display for Lit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Lit { kind, symbol, suffix } = *self; match kind { - Byte => write!(f, "b'{}'", symbol)?, - Char => write!(f, "'{}'", symbol)?, - Str => write!(f, "\"{}\"", symbol)?, + Byte => write!(f, "b'{symbol}'")?, + Char => write!(f, "'{symbol}'")?, + Str => write!(f, "\"{symbol}\"")?, StrRaw(n) => write!( f, "r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol )?, - ByteStr => write!(f, "b\"{}\"", symbol)?, + ByteStr => write!(f, "b\"{symbol}\"")?, ByteStrRaw(n) => write!( f, "br{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol )?, - Integer | Float | Bool | Err => write!(f, "{}", symbol)?, + Integer | Float | Bool | Err => write!(f, "{symbol}")?, } if let Some(suffix) = suffix { - write!(f, "{}", suffix)?; + write!(f, "{suffix}")?; } Ok(()) @@ -756,7 +756,7 @@ impl Token { _ => return None, }, SingleQuote => match joint.kind { - Ident(name, false) => Lifetime(Symbol::intern(&format!("'{}", name))), + Ident(name, false) => Lifetime(Symbol::intern(&format!("'{name}"))), _ => return None, }, diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 29a5eb4b7c5..fabd43a1618 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -258,8 +258,7 @@ impl AttrTokenStream { assert!( found, - "Failed to find trailing delimited group in: {:?}", - target_tokens + "Failed to find trailing delimited group in: {target_tokens:?}" ); } let mut flat: SmallVec<[_; 1]> = SmallVec::new(); diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 69a9a583048..74b842ac96e 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -168,7 +168,7 @@ impl fmt::Display for LitKind { match *self { LitKind::Byte(b) => { let b: String = ascii::escape_default(b).map(Into::::into).collect(); - write!(f, "b'{}'", b)?; + write!(f, "b'{b}'")?; } LitKind::Char(ch) => write!(f, "'{}'", escape_char_symbol(ch))?, LitKind::Str(sym, StrStyle::Cooked) => write!(f, "\"{}\"", escape_string_symbol(sym))?, @@ -192,7 +192,7 @@ impl fmt::Display for LitKind { )?; } LitKind::Int(n, ty) => { - write!(f, "{}", n)?; + write!(f, "{n}")?; match ty { ast::LitIntType::Unsigned(ty) => write!(f, "{}", ty.name())?, ast::LitIntType::Signed(ty) => write!(f, "{}", ty.name())?, @@ -200,7 +200,7 @@ impl fmt::Display for LitKind { } } LitKind::Float(symbol, ty) => { - write!(f, "{}", symbol)?; + write!(f, "{symbol}")?; match ty { ast::LitFloatType::Suffixed(ty) => write!(f, "{}", ty.name())?, ast::LitFloatType::Unsuffixed => {} diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index dfef6ec70fc..941d3179587 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -104,7 +104,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Err(supported_abis) => { let mut abis = format!("`{}`", supported_abis[0]); for m in &supported_abis[1..] { - let _ = write!(abis, ", `{}`", m); + let _ = write!(abis, ", `{m}`"); } self.tcx.sess.emit_err(InvalidAbiClobberAbi { abi_span: *abi_span, @@ -262,7 +262,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let sub = if !valid_modifiers.is_empty() { let mut mods = format!("`{}`", valid_modifiers[0]); for m in &valid_modifiers[1..] { - let _ = write!(mods, ", `{}`", m); + let _ = write!(mods, ", `{m}`"); } InvalidAsmTemplateModifierRegClassSub::SupportModifier { class_name: class.name(), diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index b6b242bfc27..ea30bed5ace 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1051,7 +1051,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } _ => { // Replace the ident for bindings that aren't simple. - let name = format!("__arg{}", index); + let name = format!("__arg{index}"); let ident = Ident::from_str(&name); (ident, false) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 83174afdb12..2e135aafb1e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -296,7 +296,7 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::ImplReturn => "`impl` method return", }; - write!(f, "{}", name) + write!(f, "{name}") } } @@ -503,7 +503,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn orig_local_def_id(&self, node: NodeId) -> LocalDefId { self.orig_opt_local_def_id(node) - .unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) + .unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) } /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name @@ -524,7 +524,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } fn local_def_id(&self, node: NodeId) -> LocalDefId { - self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) + self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) } /// Get the previously recorded `to` local def id given the `from` local def id, obtained using @@ -2197,7 +2197,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { hir::QPath::Resolved(None, path) => path, - qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath), + qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), }; hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 104cdd3a8e1..6a8064b0e87 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -191,23 +191,23 @@ fn doc_comment_to_string( data: Symbol, ) -> String { match (comment_kind, attr_style) { - (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{}", data), - (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{}", data), - (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{}*/", data), - (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{}*/", data), + (CommentKind::Line, ast::AttrStyle::Outer) => format!("///{data}"), + (CommentKind::Line, ast::AttrStyle::Inner) => format!("//!{data}"), + (CommentKind::Block, ast::AttrStyle::Outer) => format!("/**{data}*/"), + (CommentKind::Block, ast::AttrStyle::Inner) => format!("/*!{data}*/"), } } pub fn literal_to_string(lit: token::Lit) -> String { let token::Lit { kind, symbol, suffix } = lit; let mut out = match kind { - token::Byte => format!("b'{}'", symbol), - token::Char => format!("'{}'", symbol), - token::Str => format!("\"{}\"", symbol), + token::Byte => format!("b'{symbol}'"), + token::Char => format!("'{symbol}'"), + token::Str => format!("\"{symbol}\""), token::StrRaw(n) => { format!("r{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol) } - token::ByteStr => format!("b\"{}\"", symbol), + token::ByteStr => format!("b\"{symbol}\""), token::ByteStrRaw(n) => { format!("br{delim}\"{string}\"{delim}", delim = "#".repeat(n as usize), string = symbol) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 5b6a07721e2..bf2c73a66a2 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -411,9 +411,9 @@ impl<'a> State<'a> { ast::VisibilityKind::Restricted { path, shorthand, .. } => { let path = Self::to_string(|s| s.print_path(path, false, 0)); if *shorthand && (path == "crate" || path == "self" || path == "super") { - self.word_nbsp(format!("pub({})", path)) + self.word_nbsp(format!("pub({path})")) } else { - self.word_nbsp(format!("pub(in {})", path)) + self.word_nbsp(format!("pub(in {path})")) } } ast::VisibilityKind::Inherited => {} diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ab5e19050ea..40531c1c164 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -619,7 +619,7 @@ fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Fe fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &Features) { let (cfg, feature, has_feature) = gated_cfg; if !has_feature(features) && !cfg_span.allows_unstable(*feature) { - let explain = format!("`cfg({})` is experimental and subject to change", cfg); + let explain = format!("`cfg({cfg})` is experimental and subject to change"); feature_err(sess, *feature, cfg_span, &explain).emit(); } } @@ -975,7 +975,7 @@ pub fn find_repr_attrs(sess: &Session, attr: &Attribute) -> Vec { } pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { - assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {:?}", attr); + assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}"); use ReprAttr::*; let mut acc = Vec::new(); let diagnostic = &sess.parse_sess.span_diagnostic; diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 91c6bcb08a0..3ba7a3c5336 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -51,7 +51,7 @@ pub(crate) struct UnknownMetaItem<'a> { // Manual implementation to be able to format `expected` items correctly. impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::>(); + let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::>(); let mut diag = handler.struct_span_err_with_code( self.span, fluent::attr_unknown_meta_item, diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 94a8c1fc051..ea2a4388b92 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -277,12 +277,12 @@ impl Dominators { } pub fn immediate_dominator(&self, node: Node) -> Node { - assert!(self.is_reachable(node), "node {:?} is not reachable", node); + assert!(self.is_reachable(node), "node {node:?} is not reachable"); self.immediate_dominators[node].unwrap() } pub fn dominators(&self, node: Node) -> Iter<'_, Node> { - assert!(self.is_reachable(node), "node {:?} is not reachable", node); + assert!(self.is_reachable(node), "node {node:?} is not reachable"); Iter { dominators: self, node: Some(node) } } diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index b31092eca98..c8e66eb672c 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -233,10 +233,9 @@ where .map(G::Node::new) .map(|node| match this.start_walk_from(node) { WalkReturn::Complete { scc_index } => scc_index, - WalkReturn::Cycle { min_depth } => panic!( - "`start_walk_node({:?})` returned cycle with depth {:?}", - node, min_depth - ), + WalkReturn::Cycle { min_depth } => { + panic!("`start_walk_node({node:?})` returned cycle with depth {min_depth:?}") + } }) .collect(); @@ -272,8 +271,7 @@ where NodeState::NotVisited => return None, NodeState::InCycleWith { parent } => panic!( - "`find_state` returned `InCycleWith({:?})`, which ought to be impossible", - parent + "`find_state` returned `InCycleWith({parent:?})`, which ought to be impossible" ), }) } @@ -369,7 +367,7 @@ where previous_node = previous; } // Only InCycleWith nodes were added to the reverse linked list. - other => panic!("Invalid previous link while compressing cycle: {:?}", other), + other => panic!("Invalid previous link while compressing cycle: {other:?}"), } debug!("find_state: parent_state = {:?}", node_state); @@ -394,7 +392,7 @@ where // NotVisited can not be part of a cycle since it should // have instead gotten explored. NodeState::NotVisited | NodeState::InCycleWith { .. } => { - panic!("invalid parent state: {:?}", node_state) + panic!("invalid parent state: {node_state:?}") } } } diff --git a/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs index 3a268e4b4f4..4b6aa116520 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/graphviz.rs @@ -30,7 +30,7 @@ impl ObligationForest { let counter = COUNTER.fetch_add(1, Ordering::AcqRel); - let file_path = dir.as_ref().join(format!("{:010}_{}.gv", counter, description)); + let file_path = dir.as_ref().join(format!("{counter:010}_{description}.gv")); let mut gv_file = BufWriter::new(File::create(file_path).unwrap()); @@ -47,7 +47,7 @@ impl<'a, O: ForestObligation + 'a> dot::Labeller<'a> for &'a ObligationForest } fn node_id(&self, index: &Self::Node) -> dot::Id<'_> { - dot::Id::new(format!("obligation_{}", index)).unwrap() + dot::Id::new(format!("obligation_{index}")).unwrap() } fn node_label(&self, index: &Self::Node) -> dot::LabelText<'_> { diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 16296b22489..393f1739081 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -545,7 +545,7 @@ impl SelfProfiler { // length can behave as a source of entropy for heap addresses, when // ASLR is disabled and the heap is otherwise determinic. let pid: u32 = process::id(); - let filename = format!("{}-{:07}.rustc_profile", crate_name, pid); + let filename = format!("{crate_name}-{pid:07}.rustc_profile"); let path = output_directory.join(&filename); let profiler = Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?; diff --git a/compiler/rustc_data_structures/src/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs index 3a8ab8ff991..719e4e3d974 100644 --- a/compiler/rustc_data_structures/src/small_c_str.rs +++ b/compiler/rustc_data_structures/src/small_c_str.rs @@ -30,7 +30,7 @@ impl SmallCStr { SmallVec::from_vec(data) }; if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) { - panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e); + panic!("The string \"{s}\" cannot be converted into a CStr: {e}"); } SmallCStr { data } } @@ -39,7 +39,7 @@ impl SmallCStr { pub fn new_with_nul(s: &str) -> SmallCStr { let b = s.as_bytes(); if let Err(e) = ffi::CStr::from_bytes_with_nul(b) { - panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e); + panic!("The string \"{s}\" cannot be converted into a CStr: {e}"); } SmallCStr { data: SmallVec::from_slice(s.as_bytes()) } } @@ -74,7 +74,7 @@ impl<'a> FromIterator<&'a str> for SmallCStr { iter.into_iter().flat_map(|s| s.as_bytes()).copied().collect::>(); data.push(0); if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) { - panic!("The iterator {:?} cannot be converted into a CStr: {}", data, e); + panic!("The iterator {data:?} cannot be converted into a CStr: {e}"); } Self { data } } diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 2417df66bb9..d1a99bcaeb7 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -71,8 +71,7 @@ where // This should return just one element, otherwise it's a bug assert!( filter.next().is_none(), - "Collection {:#?} should have just one matching element", - self + "Collection {self:#?} should have just one matching element" ); Some(value) } diff --git a/compiler/rustc_driver/src/args.rs b/compiler/rustc_driver/src/args.rs index 01338359f1a..42c97cc6a9d 100644 --- a/compiler/rustc_driver/src/args.rs +++ b/compiler/rustc_driver/src/args.rs @@ -25,7 +25,7 @@ pub fn arg_expand_all(at_args: &[String]) -> Vec { Ok(arg) => args.extend(arg), Err(err) => rustc_session::early_error( rustc_session::config::ErrorOutputType::default(), - &format!("Failed to load argument file: {}", err), + &format!("Failed to load argument file: {err}"), ), } } @@ -42,8 +42,8 @@ impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::Utf8Error(None) => write!(fmt, "Utf8 error"), - Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path), - Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err), + Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {path}"), + Error::IOError(path, err) => write!(fmt, "IO Error: {path}: {err}"), } } } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 30179e97872..3cbe0052359 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -486,11 +486,8 @@ impl Compilation { fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let upper_cased_code = code.to_ascii_uppercase(); - let normalised = if upper_cased_code.starts_with('E') { - upper_cased_code - } else { - format!("E{0:0>4}", code) - }; + let normalised = + if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") }; match registry.try_find_description(&normalised) { Ok(Some(description)) => { let mut is_in_code_block = false; @@ -513,14 +510,14 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { if io::stdout().is_terminal() { show_content_with_pager(&text); } else { - print!("{}", text); + print!("{text}"); } } Ok(None) => { - early_error(output, &format!("no extended information for {}", code)); + early_error(output, &format!("no extended information for {code}")); } Err(InvalidErrorCode) => { - early_error(output, &format!("{} is not a valid error code", code)); + early_error(output, &format!("{code} is not a valid error code")); } } } @@ -552,7 +549,7 @@ fn show_content_with_pager(content: &str) { // If pager fails for whatever reason, we should still print the content // to standard output if fallback_to_println { - print!("{}", content); + print!("{content}"); } } @@ -672,7 +669,7 @@ fn print_crate_info( ); let id = rustc_session::output::find_crate_name(sess, attrs, input); if *req == PrintRequest::CrateName { - println!("{}", id); + println!("{id}"); continue; } let crate_types = collect_crate_types(sess, attrs); @@ -704,7 +701,7 @@ fn print_crate_info( } if let Some(value) = value { - Some(format!("{}=\"{}\"", name, value)) + Some(format!("{name}=\"{value}\"")) } else { Some(name.to_string()) } @@ -713,7 +710,7 @@ fn print_crate_info( cfgs.sort(); for cfg in cfgs { - println!("{}", cfg); + println!("{cfg}"); } } CallingConventions => { @@ -739,7 +736,7 @@ fn print_crate_info( let stable = sess.target.options.supported_split_debuginfo.contains(split); let unstable_ok = sess.unstable_options(); if stable || unstable_ok { - println!("{}", split); + println!("{split}"); } } } @@ -776,14 +773,14 @@ pub fn version_at_macro_invocation( ) { let verbose = matches.opt_present("verbose"); - println!("{} {}", binary, version); + println!("{binary} {version}"); if verbose { - println!("binary: {}", binary); - println!("commit-hash: {}", commit_hash); - println!("commit-date: {}", commit_date); + println!("binary: {binary}"); + println!("commit-hash: {commit_hash}"); + println!("commit-date: {commit_date}"); println!("host: {}", config::host_triple()); - println!("release: {}", release); + println!("release: {release}"); let debug_flags = matches.opt_strs("Z"); let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); @@ -1037,7 +1034,7 @@ pub fn handle_options(args: &[String]) -> Option { .map(|&(name, ..)| ('C', name)) .chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name))) .find(|&(_, name)| *opt == name.replace('_', "-")) - .map(|(flag, _)| format!("{}. Did you mean `-{} {}`?", e, flag, opt)), + .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")), _ => None, }; early_error(ErrorOutputType::default(), &msg.unwrap_or_else(|| e.to_string())); @@ -1148,7 +1145,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } else { result.push(a.to_string()); match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) { - Some(s) => result.push(format!("{}=[REDACTED]", s)), + Some(s) => result.push(format!("{s}=[REDACTED]")), None => result.push(content), } } @@ -1246,7 +1243,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let mut xs: Vec> = vec![ "the compiler unexpectedly panicked. this is a bug.".into(), - format!("we would appreciate a bug report: {}", bug_report_url).into(), + format!("we would appreciate a bug report: {bug_report_url}").into(), format!( "rustc {} running on {}", util::version_str!().unwrap_or("unknown_version"), @@ -1379,7 +1376,7 @@ pub fn main() -> ! { arg.into_string().unwrap_or_else(|arg| { early_error( ErrorOutputType::default(), - &format!("argument {} is not valid Unicode: {:?}", i, arg), + &format!("argument {i} is not valid Unicode: {arg:?}"), ) }) }) diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index f9b1316d2eb..b2451bc730f 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -360,7 +360,7 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) { fn write_or_print(out: &str, ofile: Option<&Path>, sess: &Session) { match ofile { - None => print!("{}", out), + None => print!("{out}"), Some(p) => { if let Err(e) = std::fs::write(p, out) { sess.emit_fatal(UnprettyDumpFail { @@ -402,7 +402,7 @@ pub fn print_after_parsing( } AstTree(PpAstTreeMode::Normal) => { debug!("pretty printing AST tree"); - format!("{:#?}", krate) + format!("{krate:#?}") } _ => unreachable!(), }; @@ -446,7 +446,7 @@ pub fn print_after_hir_lowering<'tcx>( AstTree(PpAstTreeMode::Expanded) => { debug!("pretty-printing expanded AST"); - format!("{:#?}", krate) + format!("{krate:#?}") } Hir(s) => call_with_pp_support_hir(&s, tcx, move |annotation, hir_map| { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6d8e78a0f18..ad85231860d 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -70,7 +70,7 @@ impl std::fmt::Debug for AttributeGate { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { Self::Gated(ref stab, name, expl, _) => { - write!(fmt, "Gated({:?}, {}, {})", stab, name, expl) + write!(fmt, "Gated({stab:?}, {name}, {expl})") } Self::Ungated => write!(fmt, "Ungated"), } diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index bdaa0ee88eb..8e2a13a6c0a 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -120,7 +120,7 @@ fn find_lang_feature_issue(feature: Symbol) -> Option { .find(|t| t.name == feature); match found { Some(found) => found.issue, - None => panic!("feature `{}` is not declared anywhere", feature), + None => panic!("feature `{feature}` is not declared anywhere"), } } } diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 434f0a53b78..b70a55e8953 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -516,7 +516,7 @@ impl<'a> LabelText<'a> { match *self { LabelStr(ref s) => format!("\"{}\"", s.escape_default()), EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(s)), - HtmlStr(ref s) => format!("<{}>", s), + HtmlStr(ref s) => format!("<{s}>"), } } @@ -622,7 +622,7 @@ where if let Some(fontname) = options.iter().find_map(|option| { if let RenderOption::Fontname(fontname) = option { Some(fontname) } else { None } }) { - font = format!(r#"fontname="{}""#, fontname); + font = format!(r#"fontname="{fontname}""#); graph_attrs.push(&font[..]); content_attrs.push(&font[..]); } @@ -635,8 +635,8 @@ where if !(graph_attrs.is_empty() && content_attrs.is_empty()) { writeln!(w, r#" graph[{}];"#, graph_attrs.join(" "))?; let content_attrs_str = content_attrs.join(" "); - writeln!(w, r#" node[{}];"#, content_attrs_str)?; - writeln!(w, r#" edge[{}];"#, content_attrs_str)?; + writeln!(w, r#" node[{content_attrs_str}];"#)?; + writeln!(w, r#" edge[{content_attrs_str}];"#)?; } let mut text = Vec::new(); @@ -649,7 +649,7 @@ where write!(text, "{}", id.as_slice()).unwrap(); if !options.contains(&RenderOption::NoNodeLabels) { - write!(text, "[label={}]", escaped).unwrap(); + write!(text, "[label={escaped}]").unwrap(); } let style = g.node_style(n); @@ -678,7 +678,7 @@ where write!(text, "{} -> {}", source_id.as_slice(), target_id.as_slice()).unwrap(); if !options.contains(&RenderOption::NoEdgeLabels) { - write!(text, "[label={}]", escaped_label).unwrap(); + write!(text, "[label={escaped_label}]").unwrap(); } let style = g.edge_style(e); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 149cf4ece37..92103979786 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -597,8 +597,7 @@ impl Res { where Id: Debug, { - self.opt_def_id() - .unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {:?}", self)) + self.opt_def_id().unwrap_or_else(|| panic!("attempted .def_id() on invalid res: {self:?}")) } /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`. diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index dd37efb6983..21cf214e47c 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -53,9 +53,8 @@ impl DefPathTable { // // See the documentation for DefPathHash for more information. panic!( - "found DefPathHash collision between {:?} and {:?}. \ - Compilation cannot continue.", - def_path1, def_path2 + "found DefPathHash collision between {def_path1:?} and {def_path2:?}. \ + Compilation cannot continue." ); } @@ -224,7 +223,7 @@ impl DefPath { let mut s = String::with_capacity(self.data.len() * 16); for component in &self.data { - write!(s, "::{}", component).unwrap(); + write!(s, "::{component}").unwrap(); } s @@ -240,7 +239,7 @@ impl DefPath { for component in &self.data { s.extend(opt_delimiter); opt_delimiter = Some('-'); - write!(s, "{}", component).unwrap(); + write!(s, "{component}").unwrap(); } s @@ -433,7 +432,7 @@ impl fmt::Display for DefPathData { match self.name() { DefPathDataName::Named(name) => f.write_str(name.as_str()), // FIXME(#70334): this will generate legacy {{closure}}, {{impl}}, etc - DefPathDataName::Anon { namespace } => write!(f, "{{{{{}}}}}", namespace), + DefPathDataName::Anon { namespace } => write!(f, "{{{{{namespace}}}}}"), } } } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 5d05adfb556..3b4add0cf4d 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -119,7 +119,7 @@ impl HirId { impl fmt::Display for HirId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) + write!(f, "{self:?}") } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 24a67cc14c4..3e3af8395a1 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1268,7 +1268,7 @@ impl<'a> State<'a> { hir::InlineAsmOperand::In { reg, ref expr } => { s.word("in"); s.popen(); - s.word(format!("{}", reg)); + s.word(format!("{reg}")); s.pclose(); s.space(); s.print_expr(expr); @@ -1276,7 +1276,7 @@ impl<'a> State<'a> { hir::InlineAsmOperand::Out { reg, late, ref expr } => { s.word(if late { "lateout" } else { "out" }); s.popen(); - s.word(format!("{}", reg)); + s.word(format!("{reg}")); s.pclose(); s.space(); match expr { @@ -1287,7 +1287,7 @@ impl<'a> State<'a> { hir::InlineAsmOperand::InOut { reg, late, ref expr } => { s.word(if late { "inlateout" } else { "inout" }); s.popen(); - s.word(format!("{}", reg)); + s.word(format!("{reg}")); s.pclose(); s.space(); s.print_expr(expr); @@ -1295,7 +1295,7 @@ impl<'a> State<'a> { hir::InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => { s.word(if late { "inlateout" } else { "inout" }); s.popen(); - s.word(format!("{}", reg)); + s.word(format!("{reg}")); s.pclose(); s.space(); s.print_expr(in_expr); diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 686cb6dac49..15179392c88 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1091,7 +1091,7 @@ impl ToString for BitSet { assert!(mask <= 0xFF); let byte = word & mask; - result.push_str(&format!("{}{:02x}", sep, byte)); + result.push_str(&format!("{sep}{byte:02x}")); if remain <= 8 { break; diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs index 3592fb33077..d809740c6ab 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -135,10 +135,7 @@ impl IntervalSet { }; debug_assert!( self.check_invariants(), - "wrong intervals after insert {:?}..={:?} to {:?}", - start, - end, - self + "wrong intervals after insert {start:?}..={end:?} to {self:?}" ); result } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 4c22ab68a56..7f761b005ed 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -90,8 +90,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec) -> FxHashSet<(String, Option) -> CheckCfg { 'specs: for s in specs { let sess = ParseSess::with_silent_emitter(Some(format!( - "this error occurred on the command line: `--check-cfg={}`", - s + "this error occurred on the command line: `--check-cfg={s}`" ))); let filename = FileName::cfg_spec_source_code(&s); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 89d9450cf4e..86d56385bc9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -620,7 +620,7 @@ fn write_out_deps( // prevents `make` from spitting out an error if a file is later // deleted. For more info see #28735 for path in files { - writeln!(file, "{}:", path)?; + writeln!(file, "{path}:")?; } // Emit special comments with information about accessed environment variables. @@ -633,9 +633,9 @@ fn write_out_deps( envs.sort_unstable(); writeln!(file)?; for (k, v) in envs { - write!(file, "# env-dep:{}", k)?; + write!(file, "# env-dep:{k}")?; if let Some(v) = v { - write!(file, "={}", v)?; + write!(file, "={v}")?; } writeln!(file)?; } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 4142964a0da..02a7756c8d4 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -205,13 +205,13 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( fn load_backend_from_dylib(path: &Path) -> MakeBackendFn { let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| { - let err = format!("couldn't load codegen backend {:?}: {}", path, err); + let err = format!("couldn't load codegen backend {path:?}: {err}"); early_error(ErrorOutputType::default(), &err); }); let backend_sym = unsafe { lib.get::(b"__rustc_codegen_backend") } .unwrap_or_else(|e| { - let err = format!("couldn't load codegen backend: {}", e); + let err = format!("couldn't load codegen backend: {e}"); early_error(ErrorOutputType::default(), &err); }); @@ -304,8 +304,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> M .join("\n* "); let err = format!( "failed to find a `codegen-backends` folder \ - in the sysroot candidates:\n* {}", - candidates + in the sysroot candidates:\n* {candidates}" ); early_error(ErrorOutputType::default(), &err); }); @@ -325,7 +324,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> M let expected_names = &[ format!("rustc_codegen_{}-{}", backend_name, env!("CFG_RELEASE")), - format!("rustc_codegen_{}", backend_name), + format!("rustc_codegen_{backend_name}"), ]; for entry in d.filter_map(|e| e.ok()) { let path = entry.path(); @@ -354,7 +353,7 @@ fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> M match file { Some(ref s) => load_backend_from_dylib(s), None => { - let err = format!("unsupported builtin codegen backend `{}`", backend_name); + let err = format!("unsupported builtin codegen backend `{backend_name}`"); early_error(ErrorOutputType::default(), &err); } } @@ -389,7 +388,7 @@ pub(crate) fn check_attr_crate_type( BuiltinLintDiagnostics::UnknownCrateTypes( span, "did you mean".to_string(), - format!("\"{}\"", candidate), + format!("\"{candidate}\""), ), ); } else { diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 0b3c057345a..9fe59a1d826 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -58,7 +58,7 @@ fn restore_library_path() { /// Supposed to be used for all variables except those set for build scripts by cargo /// fn tracked_env_var_os + Display>(key: K) -> Option { - println!("cargo:rerun-if-env-changed={}", key); + println!("cargo:rerun-if-env-changed={key}"); env::var_os(key) } @@ -84,7 +84,7 @@ fn output(cmd: &mut Command) -> String { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, Err(e) => { - println!("\n\nfailed to execute command: {:?}\nerror: {}\n\n", cmd, e); + println!("\n\nfailed to execute command: {cmd:?}\nerror: {e}\n\n"); std::process::exit(1); } }; @@ -100,7 +100,7 @@ fn output(cmd: &mut Command) -> String { fn main() { for component in REQUIRED_COMPONENTS.iter().chain(OPTIONAL_COMPONENTS.iter()) { - println!("cargo:rustc-check-cfg=values(llvm_component,\"{}\")", component); + println!("cargo:rustc-check-cfg=values(llvm_component,\"{component}\")"); } if tracked_env_var_os("RUST_CHECK").is_some() { @@ -164,12 +164,12 @@ fn main() { for component in REQUIRED_COMPONENTS { if !components.contains(component) { - panic!("require llvm component {} but wasn't found", component); + panic!("require llvm component {component} but wasn't found"); } } for component in components.iter() { - println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); + println!("cargo:rustc-cfg=llvm_component=\"{component}\""); } // Link in our own LLVM shims, compiled with the same flags as LLVM @@ -283,7 +283,7 @@ fn main() { } let kind = if name.starts_with("LLVM") { llvm_kind } else { "dylib" }; - println!("cargo:rustc-link-lib={}={}", kind, name); + println!("cargo:rustc-link-lib={kind}={name}"); } // LLVM ldflags @@ -302,11 +302,11 @@ fn main() { println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target)); } } else if let Some(stripped) = lib.strip_prefix("-LIBPATH:") { - println!("cargo:rustc-link-search=native={}", stripped); + println!("cargo:rustc-link-search=native={stripped}"); } else if let Some(stripped) = lib.strip_prefix("-l") { - println!("cargo:rustc-link-lib={}", stripped); + println!("cargo:rustc-link-lib={stripped}"); } else if let Some(stripped) = lib.strip_prefix("-L") { - println!("cargo:rustc-link-search=native={}", stripped); + println!("cargo:rustc-link-search=native={stripped}"); } } @@ -318,9 +318,9 @@ fn main() { if let Some(s) = llvm_linker_flags { for lib in s.into_string().unwrap().split_whitespace() { if let Some(stripped) = lib.strip_prefix("-l") { - println!("cargo:rustc-link-lib={}", stripped); + println!("cargo:rustc-link-lib={stripped}"); } else if let Some(stripped) = lib.strip_prefix("-L") { - println!("cargo:rustc-link-search=native={}", stripped); + println!("cargo:rustc-link-search=native={stripped}"); } } } @@ -359,14 +359,14 @@ fn main() { let path = PathBuf::from(s); println!("cargo:rustc-link-search=native={}", path.parent().unwrap().display()); if target.contains("windows") { - println!("cargo:rustc-link-lib=static:-bundle={}", stdcppname); + println!("cargo:rustc-link-lib=static:-bundle={stdcppname}"); } else { - println!("cargo:rustc-link-lib=static={}", stdcppname); + println!("cargo:rustc-link-lib=static={stdcppname}"); } } else if cxxflags.contains("stdlib=libc++") { println!("cargo:rustc-link-lib=c++"); } else { - println!("cargo:rustc-link-lib={}", stdcppname); + println!("cargo:rustc-link-lib={stdcppname}"); } } diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index ddf29c488c9..4cac88aff64 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -114,8 +114,7 @@ impl Display for Error { match self { Error::InvalidColorValue(value) => write!( formatter, - "invalid log color value '{}': expected one of always, never, or auto", - value, + "invalid log color value '{value}': expected one of always, never, or auto", ), Error::NonUnicodeColorValue => write!( formatter, diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index 4612f54e4b1..2d62d593163 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -76,11 +76,11 @@ pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic { let span = attr.span().unwrap(); let path = path_to_string(&attr.path); match meta { - Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", path)), + Meta::Path(_) => span_err(span, &format!("`#[{path}]` is not a valid attribute")), Meta::NameValue(_) => { - span_err(span, &format!("`#[{} = ...]` is not a valid attribute", path)) + span_err(span, &format!("`#[{path} = ...]` is not a valid attribute")) } - Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", path)), + Meta::List(_) => span_err(span, &format!("`#[{path}(...)]` is not a valid attribute")), } } @@ -107,7 +107,7 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag let meta = match nested { syn::NestedMeta::Meta(meta) => meta, syn::NestedMeta::Lit(_) => { - return span_err(span, &format!("`#[{}(\"...\")]` is not a valid attribute", name)); + return span_err(span, &format!("`#[{name}(\"...\")]` is not a valid attribute")); } }; @@ -115,13 +115,11 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag let path = path_to_string(meta.path()); match meta { Meta::NameValue(..) => { - span_err(span, &format!("`#[{}({} = ...)]` is not a valid attribute", name, path)) - } - Meta::Path(..) => { - span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, path)) + span_err(span, &format!("`#[{name}({path} = ...)]` is not a valid attribute")) } + Meta::Path(..) => span_err(span, &format!("`#[{name}({path})]` is not a valid attribute")), Meta::List(..) => { - span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, path)) + span_err(span, &format!("`#[{name}({path}(...))]` is not a valid attribute")) } } } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 3e447c94ef1..32338f9dfc5 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -178,7 +178,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok opt: Default::default(), }; let dl = DisplayList::from(snippet); - eprintln!("{}\n", dl); + eprintln!("{dl}\n"); } continue; } @@ -265,7 +265,7 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok Diagnostic::spanned( path_span, Level::Error, - format!("overrides existing {}: `{}`", kind, id), + format!("overrides existing {kind}: `{id}`"), ) .span_help(previous_defns[&id], "previously defined in this resource") .emit(); diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 767db367322..baffd3cec9c 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -198,8 +198,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { throw_span_err!( attr.span().unwrap(), &format!( - "diagnostic slug must be first argument of a `#[{}(...)]` attribute", - name + "diagnostic slug must be first argument of a `#[{name}(...)]` attribute" ) ); }; diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 4ff9c777ad8..6f52a3de1b1 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -322,7 +322,7 @@ pub(crate) trait HasFieldMap { None => { span_err( span.unwrap(), - &format!("`{}` doesn't refer to a field on this type", field), + &format!("`{field}` doesn't refer to a field on this type"), ) .emit(); quote! { @@ -603,8 +603,7 @@ impl SubdiagnosticKind { if suggestion_kind != SuggestionKind::Normal { invalid_attr(attr, &meta) .help(format!( - r#"Use `#[suggestion(..., style = "{}")]` instead"#, - suggestion_kind + r#"Use `#[suggestion(..., style = "{suggestion_kind}")]` instead"# )) .emit(); } @@ -621,8 +620,7 @@ impl SubdiagnosticKind { if suggestion_kind != SuggestionKind::Normal { invalid_attr(attr, &meta) .help(format!( - r#"Use `#[multipart_suggestion(..., style = "{}")]` instead"#, - suggestion_kind + r#"Use `#[multipart_suggestion(..., style = "{suggestion_kind}")]` instead"# )) .emit(); } diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index 153473de624..89ea89cf502 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -41,7 +41,7 @@ impl Parse for Newtype { }; if let Some(old) = max.replace(literal.lit) { - panic!("Specified multiple max: {:?}", old); + panic!("Specified multiple max: {old:?}"); } false @@ -52,7 +52,7 @@ impl Parse for Newtype { }; if let Some(old) = debug_format.replace(literal.lit) { - panic!("Specified multiple debug format options: {:?}", old); + panic!("Specified multiple debug format options: {old:?}"); } false diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 789d83a0dd0..08e42a8a08f 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -239,7 +239,7 @@ fn doc_comment_from_desc(list: &Punctuated) -> Result (TokenStream, Vec) { let mut check_dup = |span: Span, str: &str, errors: &mut Errors| { if let Some(prev_span) = keys.get(str) { - errors.error(span, format!("Symbol `{}` is duplicated", str)); + errors.error(span, format!("Symbol `{str}` is duplicated")); errors.error(*prev_span, "location of previous definition".to_string()); } else { keys.insert(str.to_string(), span); @@ -144,8 +144,8 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec) { let mut check_order = |span: Span, str: &str, errors: &mut Errors| { if let Some((prev_span, ref prev_str)) = prev_key { if str < prev_str { - errors.error(span, format!("Symbol `{}` must precede `{}`", str, prev_str)); - errors.error(prev_span, format!("location of previous symbol `{}`", prev_str)); + errors.error(span, format!("Symbol `{str}` must precede `{prev_str}`")); + errors.error(prev_span, format!("location of previous symbol `{prev_str}`")); } } prev_key = Some((span, str.to_string())); diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index b34dc0df1e2..653f2b39d3e 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -112,7 +112,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> { writeln!(fmt, "resolved crates:")?; for (cnum, data) in self.0.iter_crate_data() { writeln!(fmt, " name: {}", data.name())?; - writeln!(fmt, " cnum: {}", cnum)?; + writeln!(fmt, " cnum: {cnum}")?; writeln!(fmt, " hash: {}", data.hash())?; writeln!(fmt, " reqd: {:?}", data.dep_kind())?; let CrateSource { dylib, rlib, rmeta } = data.source(); @@ -150,7 +150,7 @@ impl CStore { pub(crate) fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> { let cdata = self.metas[cnum] .as_ref() - .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)); + .unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}")); CrateMetadataRef { cdata, cstore: self } } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 1fd35adf1bd..59869ee4173 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -45,7 +45,7 @@ pub fn find_native_static_library( for path in search_paths { for (prefix, suffix) in &formats { - let test = path.join(format!("{}{}{}", prefix, name, suffix)); + let test = path.join(format!("{prefix}{name}{suffix}")); if test.exists() { return test; } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 99d8225a4c3..143d8f2f1e1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -462,7 +462,7 @@ impl<'a, 'tcx> Decodable> for SyntaxContext { .root .syntax_contexts .get(cdata, id) - .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname)) + .unwrap_or_else(|| panic!("Missing SyntaxContext {id:?} for crate {cname:?}")) .decode((cdata, sess)) }) } @@ -806,7 +806,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .def_span .get(self, index) - .unwrap_or_else(|| panic!("Missing span for {:?}", index)) + .unwrap_or_else(|| panic!("Missing span for {index:?}")) .decode((self, sess)) } @@ -1249,7 +1249,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .tables .proc_macro_quoted_spans .get(self, index) - .unwrap_or_else(|| panic!("Missing proc macro quoted span: {:?}", index)) + .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) .decode((self, sess)) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index e167bbf57e6..cb451931dfe 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -230,7 +230,7 @@ provide! { tcx, def_id, other, cdata, .trait_impl_trait_tys .get(cdata, def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) - .process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id))) + .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } visibility => { cdata.get_visibility(def_id.index) } diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 40c94b372bb..a6133f1b417 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> Decodable> for DefPathHashMapRef<'static> let _ = d.read_raw_bytes(len); let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| { - panic!("decode error: {}", e); + panic!("decode error: {e}"); }); DefPathHashMapRef::OwnedFromMetadata(inner) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 214a5842233..0d9f216700f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -145,7 +145,7 @@ impl<'a, 'tcx, I, T> Encodable> for LazyTable { impl<'a, 'tcx> Encodable> for CrateNum { fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { if *self != LOCAL_CRATE && s.is_proc_macro { - panic!("Attempted to encode non-local CrateNum {:?} for proc-macro crate", self); + panic!("Attempted to encode non-local CrateNum {self:?} for proc-macro crate"); } s.emit_u32(self.as_u32()); } @@ -276,7 +276,7 @@ impl<'a, 'tcx> Encodable> for Span { // Introduce a new scope so that we drop the 'lock()' temporary match &*source_file.external_src.lock() { ExternalSource::Foreign { metadata_index, .. } => *metadata_index, - src => panic!("Unexpected external source {:?}", src), + src => panic!("Unexpected external source {src:?}"), } }; @@ -733,12 +733,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let prefix = "meta-stats"; let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64; - eprintln!("{} METADATA STATS", prefix); + eprintln!("{prefix} METADATA STATS"); eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size"); - eprintln!( - "{} ----------------------------------------------------------------", - prefix - ); + eprintln!("{prefix} ----------------------------------------------------------------"); for (label, size) in stats { eprintln!( "{} {:<23}{:>10} ({:4.1}%)", @@ -748,10 +745,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { perc(size) ); } - eprintln!( - "{} ----------------------------------------------------------------", - prefix - ); + eprintln!("{prefix} ----------------------------------------------------------------"); eprintln!( "{} {:<23}{:>10} (of which {:.1}% are zero bytes)", prefix, @@ -759,7 +753,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { to_readable_str(total_bytes), perc(zero_bytes) ); - eprintln!("{}", prefix); + eprintln!("{prefix}"); } root diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs index 209e6f7ac9f..490be166a91 100644 --- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs +++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs @@ -143,7 +143,7 @@ where ", " }; - write!(f, "{}", delim)?; + write!(f, "{delim}")?; idx.fmt_with(ctxt, f)?; first = false; } @@ -164,7 +164,7 @@ where ", " }; - write!(f, "{}", delim)?; + write!(f, "{delim}")?; idx.fmt_with(ctxt, f)?; first = false; } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c9d5601f207..96c42894b69 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -71,7 +71,7 @@ where fn graph_id(&self) -> dot::Id<'_> { let name = graphviz_safe_def_name(self.body.source.def_id()); - dot::Id::new(format!("graph_for_def_id_{}", name)).unwrap() + dot::Id::new(format!("graph_for_def_id_{name}")).unwrap() } fn node_id(&self, n: &Self::Node) -> dot::Id<'_> { @@ -190,7 +190,7 @@ where " cellpadding=\"3\"", " sides=\"rb\"", ); - write!(w, r#""#, fmt = table_fmt)?; + write!(w, r#""#)?; // A + B: Block header match self.style { @@ -372,7 +372,7 @@ where write!(w, concat!("", r#"MIR"#,), fmt = fmt,)?; for name in state_column_names { - write!(w, "{name}", fmt = fmt, name = name)?; + write!(w, "{name}")?; } write!(w, "") @@ -394,18 +394,18 @@ where }; for (i, statement) in body[block].statements.iter().enumerate() { - let statement_str = format!("{:?}", statement); - let index_str = format!("{}", i); + let statement_str = format!("{statement:?}"); + let index_str = format!("{i}"); let after = next_in_dataflow_order(&mut afters); let before = befores.as_mut().map(next_in_dataflow_order); self.write_row(w, &index_str, &statement_str, |_this, w, fmt| { if let Some(before) = before { - write!(w, r#"{diff}"#, fmt = fmt, diff = before)?; + write!(w, r#"{before}"#)?; } - write!(w, r#"{diff}"#, fmt = fmt, diff = after) + write!(w, r#"{after}"#) })?; } @@ -421,10 +421,10 @@ where self.write_row(w, "T", &terminator_str, |_this, w, fmt| { if let Some(before) = before { - write!(w, r#"{diff}"#, fmt = fmt, diff = before)?; + write!(w, r#"{before}"#)?; } - write!(w, r#"{diff}"#, fmt = fmt, diff = after) + write!(w, r#"{after}"#) }) } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 9b053985bed..5f22a418de8 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -129,13 +129,13 @@ impl<'tcx> fmt::Debug for MovePath<'tcx> { fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { write!(w, "MovePath {{")?; if let Some(parent) = self.parent { - write!(w, " parent: {:?},", parent)?; + write!(w, " parent: {parent:?},")?; } if let Some(first_child) = self.first_child { - write!(w, " first_child: {:?},", first_child)?; + write!(w, " first_child: {first_child:?},")?; } if let Some(next_sibling) = self.next_sibling { - write!(w, " next_sibling: {:?}", next_sibling)?; + write!(w, " next_sibling: {next_sibling:?}")?; } write!(w, " place: {:?} }}", self.place) } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index fe5ee4011ab..0522c657939 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -920,7 +920,7 @@ fn debug_with_context( ) -> std::fmt::Result { for (local, place) in map.locals.iter_enumerated() { if let Some(place) = place { - debug_with_context_rec(*place, &format!("{:?}", local), new, old, map, f)?; + debug_with_context_rec(*place, &format!("{local:?}"), new, old, map, f)?; } } Ok(()) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 59cc500a99d..b573df43250 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -526,7 +526,7 @@ fn collect_items_rec<'tcx>( let formatted_item = with_no_trimmed_paths!(starting_point.node.to_string()); tcx.sess.span_note_without_error( starting_point.span, - &format!("the above error was encountered while instantiating `{}`", formatted_item), + &format!("the above error was encountered while instantiating `{formatted_item}`"), ); } inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items); diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index f15cf54718e..aa3227cac2d 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -50,7 +50,7 @@ impl IntoDiagnostic<'_> for UnusedGenericParams { // FIXME: I can figure out how to do a label with a fluent string with a fixed message, // or a label with a dynamic value in a hard-coded string, but I haven't figured out // how to combine the two. 😢 - diag.span_label(span, format!("generic parameter `{}` is unused", name)); + diag.span_label(span, format!("generic parameter `{name}` is unused")); } diag } diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 97fbb458e79..fd6bcad1898 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -285,7 +285,7 @@ where use std::fmt::Write; let s = &mut String::new(); - let _ = writeln!(s, "{}", label); + let _ = writeln!(s, "{label}"); for cgu in cgus { let _ = writeln!(s, "CodegenUnit {} estimated size {} :", cgu.name(), cgu.size_estimate()); @@ -355,9 +355,8 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co } else { if mode_string != "lazy" { let message = format!( - "Unknown codegen-item collection mode '{}'. \ - Falling back to 'lazy' mode.", - mode_string + "Unknown codegen-item collection mode '{mode_string}'. \ + Falling back to 'lazy' mode." ); tcx.sess.warn(&message); } @@ -470,7 +469,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co item_keys.sort(); for item in item_keys { - println!("MONO_ITEM {}", item); + println!("MONO_ITEM {item}"); } } @@ -596,6 +595,6 @@ pub fn provide(providers: &mut Providers) { let (_, all) = tcx.collect_and_partition_mono_items(()); all.iter() .find(|cgu| cgu.name() == name) - .unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name)) + .unwrap_or_else(|| panic!("failed to find cgu with name {name:?}")) }; } diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index 6a4d2df1ead..33e1f6ce342 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -40,12 +40,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let new_size = tcx .layout_of(param_env.and(after_feature_tys)) .map(|l| format!("{:?}", l.size.bytes())) - .unwrap_or_else(|e| format!("Failed {:?}", e)); + .unwrap_or_else(|e| format!("Failed {e:?}")); let old_size = tcx .layout_of(param_env.and(before_feature_tys)) .map(|l| format!("{:?}", l.size.bytes())) - .unwrap_or_else(|e| format!("Failed {:?}", e)); + .unwrap_or_else(|e| format!("Failed {e:?}")); let closure_span = tcx.def_span(closure_def_id); let src_file = tcx.sess.source_map().span_to_filename(closure_span); @@ -54,7 +54,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In .source_map() .span_to_lines(closure_span) .map(|l| format!("{:?} {:?}", l.lines.first(), l.lines.last())) - .unwrap_or_else(|e| format!("{:?}", e)); + .unwrap_or_else(|e| format!("{e:?}")); if let Err(e) = writeln!( file, @@ -64,7 +64,7 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In src_file.prefer_local(), line_nos ) { - eprintln!("Error writing to file {}", e) + eprintln!("Error writing to file {e}") } } } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 9f2aaca0acf..1eb227503f2 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -447,7 +447,7 @@ impl<'a> Parser<'a> { Some(pos) } else { let pos = self.to_span_index(pos); - let description = format!("expected `'}}'`, found `{:?}`", maybe); + let description = format!("expected `'}}'`, found `{maybe:?}`"); let label = "expected `}`".to_owned(); let (note, secondary_label) = if c == '}' { ( @@ -471,12 +471,12 @@ impl<'a> Parser<'a> { None } } else { - let description = format!("expected `{:?}` but string was terminated", c); + let description = format!("expected `{c:?}` but string was terminated"); // point at closing `"` let pos = self.input.len() - if self.append_newline { 1 } else { 0 }; let pos = self.to_span_index(pos); if c == '}' { - let label = format!("expected `{:?}`", c); + let label = format!("expected `{c:?}`"); let (note, secondary_label) = if c == '}' { ( Some( @@ -497,7 +497,7 @@ impl<'a> Parser<'a> { should_be_replaced_with_positional_argument: false, }); } else { - self.err(description, format!("expected `{:?}`", c), pos.to(pos)); + self.err(description, format!("expected `{c:?}`"), pos.to(pos)); } None } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ef241c5398d..e337cf16f22 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -915,7 +915,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { if level != Level::Direct { error_msg.push_str(", "); } - error_msg.push_str(&format!("{:?}: {}", level, vis_str)); + error_msg.push_str(&format!("{level:?}: {vis_str}")); } } else { error_msg.push_str("not in the table"); diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 2bcfdab03c8..70c481fb0ee 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -787,7 +787,7 @@ impl<'a, 'tcx> Decodable> for DefId { // which means that the definition with this hash is guaranteed to // still exist in the current compilation session. d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || { - panic!("Failed to convert DefPathHash {:?}", def_path_hash) + panic!("Failed to convert DefPathHash {def_path_hash:?}") }) } } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 535445e70bc..6125ad4eff1 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -321,7 +321,7 @@ pub(crate) fn create_query_frame< ty::print::with_forced_impl_filename_line!(do_describe(tcx.tcx, key)) ); let description = - if tcx.sess.verbose() { format!("{} [{:?}]", description, name) } else { description }; + if tcx.sess.verbose() { format!("{description} [{name:?}]") } else { description }; let span = if kind == dep_graph::DepKind::def_span { // The `def_span` query is used to calculate `default_span`, // so exit to avoid infinite recursion. diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 5f54bab9c31..4743170e9bf 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -111,7 +111,7 @@ impl IntoSelfProfilingString for T { &self, builder: &mut QueryKeyStringBuilder<'_, '_>, ) -> StringId { - let s = format!("{:?}", self); + let s = format!("{self:?}"); builder.profiler.alloc_string(&s[..]) } } diff --git a/compiler/rustc_query_system/src/dep_graph/debug.rs b/compiler/rustc_query_system/src/dep_graph/debug.rs index f9f3169af69..c2c9600f555 100644 --- a/compiler/rustc_query_system/src/dep_graph/debug.rs +++ b/compiler/rustc_query_system/src/dep_graph/debug.rs @@ -29,7 +29,7 @@ impl DepNodeFilter { /// Tests whether `node` meets the filter, returning true if so. pub fn test(&self, node: &DepNode) -> bool { - let debug_str = format!("{:?}", node); + let debug_str = format!("{node:?}"); self.text.split('&').map(|s| s.trim()).all(|f| debug_str.contains(f)) } } @@ -46,7 +46,7 @@ impl EdgeFilter { pub fn new(test: &str) -> Result, Box> { let parts: Vec<_> = test.split("->").collect(); if parts.len() != 2 { - Err(format!("expected a filter like `a&b -> c&d`, not `{}`", test).into()) + Err(format!("expected a filter like `a&b -> c&d`, not `{test}`").into()) } else { Ok(EdgeFilter { source: DepNodeFilter::new(parts[0]), diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs index d79c5816a9c..9e1ca6ab515 100644 --- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs +++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs @@ -120,7 +120,7 @@ pub trait DepNodeParams: fmt::Debug + Sized { } fn to_debug_str(&self, _: Tcx) -> String { - format!("{:?}", self) + format!("{self:?}") } /// This method tries to recover the query key from the given `DepNode`, diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 0b1ff5d709f..53c9da15737 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -316,10 +316,8 @@ impl DepGraph { assert!( !self.dep_node_exists(&key), "forcing query with already existing `DepNode`\n\ - - query-key: {:?}\n\ - - dep-node: {:?}", - arg, - key + - query-key: {arg:?}\n\ + - dep-node: {key:?}" ); let task_deps = if cx.dep_context().is_eval_always(key.kind) { @@ -365,8 +363,7 @@ impl DepGraph { debug_assert!( data.colors.get(prev_index).is_none(), "DepGraph::with_task() - Duplicate DepNodeColor \ - insertion for {:?}", - key + insertion for {key:?}" ); data.colors.insert(prev_index, color); @@ -447,7 +444,7 @@ impl DepGraph { TaskDepsRef::Allow(deps) => deps.lock(), TaskDepsRef::Ignore => return, TaskDepsRef::Forbid => { - panic!("Illegal read of: {:?}", dep_node_index) + panic!("Illegal read of: {dep_node_index:?}") } }; let task_deps = &mut *task_deps; @@ -824,8 +821,7 @@ impl DepGraph { debug_assert!( data.colors.get(prev_dep_node_index).is_none(), "DepGraph::try_mark_previous_green() - Duplicate DepNodeColor \ - insertion for {:?}", - dep_node + insertion for {dep_node:?}" ); if !side_effects.is_empty() { @@ -1164,7 +1160,7 @@ impl CurrentDepGraph { if let Some(fingerprint) = fingerprint { if fingerprint == prev_graph.fingerprint_by_index(prev_index) { if print_status { - eprintln!("[task::green] {:?}", key); + eprintln!("[task::green] {key:?}"); } // This is a green node: it existed in the previous compilation, @@ -1186,7 +1182,7 @@ impl CurrentDepGraph { (dep_node_index, Some((prev_index, DepNodeColor::Green(dep_node_index)))) } else { if print_status { - eprintln!("[task::red] {:?}", key); + eprintln!("[task::red] {key:?}"); } // This is a red node: it existed in the previous compilation, its query @@ -1209,7 +1205,7 @@ impl CurrentDepGraph { } } else { if print_status { - eprintln!("[task::unknown] {:?}", key); + eprintln!("[task::unknown] {key:?}"); } // This is a red node, effectively: it existed in the previous compilation @@ -1234,7 +1230,7 @@ impl CurrentDepGraph { } } else { if print_status { - eprintln!("[task::new] {:?}", key); + eprintln!("[task::new] {key:?}"); } let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index a918328d413..dfc1344f85c 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -270,17 +270,14 @@ impl> GraphEncoder { eprintln!("[incremental]"); eprintln!("[incremental] DepGraph Statistics"); - eprintln!("{}", SEPARATOR); + eprintln!("{SEPARATOR}"); eprintln!("[incremental]"); eprintln!("[incremental] Total Node Count: {}", status.total_node_count); eprintln!("[incremental] Total Edge Count: {}", status.total_edge_count); if cfg!(debug_assertions) { - eprintln!("[incremental] Total Edge Reads: {}", total_read_count); - eprintln!( - "[incremental] Total Duplicate Edge Reads: {}", - total_duplicate_read_count - ); + eprintln!("[incremental] Total Edge Reads: {total_read_count}"); + eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}"); } eprintln!("[incremental]"); @@ -288,7 +285,7 @@ impl> GraphEncoder { "[incremental] {:<36}| {:<17}| {:<12}| {:<17}|", "Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count" ); - eprintln!("{}", SEPARATOR); + eprintln!("{SEPARATOR}"); for stat in stats { let node_kind_ratio = @@ -304,7 +301,7 @@ impl> GraphEncoder { ); } - eprintln!("{}", SEPARATOR); + eprintln!("{SEPARATOR}"); eprintln!("[incremental]"); } } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index da1ac6a5fb2..b3b939eae88 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -549,8 +549,7 @@ where // can be forced from `DepNode`. debug_assert!( !qcx.dep_context().fingerprint_style(dep_node.kind).reconstructible(), - "missing on-disk cache entry for {:?}", - dep_node + "missing on-disk cache entry for {dep_node:?}" ); } @@ -589,8 +588,7 @@ where { assert!( tcx.dep_graph().is_green(dep_node), - "fingerprint for green query instance not loaded from cache: {:?}", - dep_node, + "fingerprint for green query instance not loaded from cache: {dep_node:?}", ); let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { @@ -669,16 +667,16 @@ fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: sess.emit_err(crate::error::Reentrant); } else { let run_cmd = if let Some(crate_name) = &sess.opts.crate_name { - format!("`cargo clean -p {}` or `cargo clean`", crate_name) + format!("`cargo clean -p {crate_name}` or `cargo clean`") } else { "`cargo clean`".to_string() }; sess.emit_err(crate::error::IncrementCompilation { run_cmd, - dep_node: format!("{:?}", dep_node), + dep_node: format!("{dep_node:?}"), }); - panic!("Found unstable fingerprints for {:?}: {:?}", dep_node, result); + panic!("Found unstable fingerprints for {dep_node:?}: {result:?}"); } INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic)); diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 221f65b66e6..7c5e1427d1e 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -303,7 +303,7 @@ impl DefId { // i.e. don't use closures. match self.as_local() { Some(local_def_id) => local_def_id, - None => panic!("DefId::expect_local: `{:?}` isn't local", self), + None => panic!("DefId::expect_local: `{self:?}` isn't local"), } } diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 065d3660e50..b43183916bc 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -44,7 +44,7 @@ impl fmt::Display for Edition { Edition::Edition2021 => "2021", Edition::Edition2024 => "2024", }; - write!(f, "{}", s) + write!(f, "{s}") } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 4e70dfb6147..a9a9a3fbf9d 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -110,7 +110,7 @@ fn assert_default_hashing_controls(ctx: &CTX, msg: &str) // Such configuration must not be used for metadata. HashingControls { hash_spans } if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {} - other => panic!("Attempted hashing of {msg} with non-default HashingControls: {:?}", other), + other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"), } } @@ -629,7 +629,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb pub fn debug_hygiene_data(verbose: bool) -> String { HygieneData::with(|data| { if verbose { - format!("{:#?}", data) + format!("{data:#?}") } else { let mut s = String::from("Expansions:"); let mut debug_expn_data = |(id, expn_data): (&ExpnId, &ExpnData)| { @@ -1067,9 +1067,9 @@ impl ExpnKind { match *self { ExpnKind::Root => kw::PathRoot.to_string(), ExpnKind::Macro(macro_kind, name) => match macro_kind { - MacroKind::Bang => format!("{}!", name), - MacroKind::Attr => format!("#[{}]", name), - MacroKind::Derive => format!("#[derive({})]", name), + MacroKind::Bang => format!("{name}!"), + MacroKind::Attr => format!("#[{name}]"), + MacroKind::Derive => format!("#[derive({name})]"), }, ExpnKind::AstPass(kind) => kind.descr().to_string(), ExpnKind::Desugaring(kind) => format!("desugaring of {}", kind.descr()), @@ -1466,11 +1466,7 @@ impl Decodable for SyntaxContext { /// collisions are only possible between `ExpnId`s within the same crate. fn update_disambiguator(expn_data: &mut ExpnData, mut ctx: impl HashStableContext) -> ExpnHash { // This disambiguator should not have been set yet. - assert_eq!( - expn_data.disambiguator, 0, - "Already set disambiguator for ExpnData: {:?}", - expn_data - ); + assert_eq!(expn_data.disambiguator, 0, "Already set disambiguator for ExpnData: {expn_data:?}"); assert_default_hashing_controls(&ctx, "ExpnData (disambiguator)"); let mut expn_hash = expn_data.hash_expn(&mut ctx); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index bee4b0a2332..7e61f2f9f73 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -329,7 +329,7 @@ impl fmt::Display for FileNameDisplay<'_> { ProcMacroSourceCode(_) => write!(fmt, ""), CfgSpec(_) => write!(fmt, ""), CliCrateAttr(_) => write!(fmt, ""), - Custom(ref s) => write!(fmt, "<{}>", s), + Custom(ref s) => write!(fmt, "<{s}>"), DocTest(ref path, _) => write!(fmt, "{}", path.display()), InlineAsm(_) => write!(fmt, ""), } @@ -1074,7 +1074,7 @@ impl NonNarrowChar { 0 => NonNarrowChar::ZeroWidth(pos), 2 => NonNarrowChar::Wide(pos), 4 => NonNarrowChar::Tab(pos), - _ => panic!("width {} given for non-narrow character", width), + _ => panic!("width {width} given for non-narrow character"), } } diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs index f169007fab4..0ab890b9f01 100644 --- a/compiler/rustc_span/src/profiling.rs +++ b/compiler/rustc_span/src/profiling.rs @@ -27,7 +27,7 @@ impl SpannedEventArgRecorder for EventArgRecorder<'_> { if let Some(source_map) = &*session_globals.source_map.borrow() { source_map.span_to_embeddable_string(span) } else { - format!("{:?}", span) + format!("{span:?}") } }); self.record_arg(span_arg); diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index a59c9011ab2..23ff6b333f0 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -175,7 +175,7 @@ impl SymbolPath { fn finish(mut self, hash: u64) -> String { self.finalize_pending_component(); // E = end name-sequence - let _ = write!(self.result, "17h{:016x}E", hash); + let _ = write!(self.result, "17h{hash:016x}E"); self.result } } @@ -227,7 +227,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> { self = self.print_type(ty)?; self.write_str("; ")?; if let Some(size) = size.kind().try_to_bits(self.tcx().data_layout.pointer_size) { - write!(self, "{}", size)? + write!(self, "{size}")? } else if let ty::ConstKind::Param(param) = size.kind() { self = param.print(self)? } else { diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 62f44a48032..547a5907660 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -269,8 +269,7 @@ fn compute_symbol_name<'tcx>( debug_assert!( rustc_demangle::try_demangle(&symbol).is_ok(), - "compute_symbol_name: `{}` cannot be demangled", - symbol + "compute_symbol_name: `{symbol}` cannot be demangled" ); symbol diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 150459ce0f5..c6899f8f244 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -74,7 +74,7 @@ impl SymbolNamesTest<'_> { tcx.sess.emit_err(TestOutput { span: attr.span, kind: Kind::DemanglingAlt, - content: format!("{:#}", demangling), + content: format!("{demangling:#}"), }); } } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index e9b85705086..0759b95bd94 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -126,11 +126,11 @@ fn encode_const<'tcx>( if value < zero { s.push('n') }; - let _ = write!(s, "{}", value); + let _ = write!(s, "{value}"); } fn push_unsigned_value(s: &mut String, value: T) { - let _ = write!(s, "{}", value); + let _ = write!(s, "{value}"); } if let Some(scalar_int) = c.kind().try_to_scalar_int() { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 4285aa62cb9..9e8117c6a85 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -609,7 +609,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { bits = val.unsigned_abs(); } - let _ = write!(self.out, "{:x}_", bits); + let _ = write!(self.out, "{bits:x}_"); } // FIXME(valtrees): Remove the special case for `str` @@ -637,7 +637,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // FIXME(eddyb) use a specialized hex-encoding loop. for byte in s.bytes() { - let _ = write!(self.out, "{:02x}", byte); + let _ = write!(self.out, "{byte:02x}"); } self.push("_"); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index a5ffaebea0b..280924bca41 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -177,12 +177,12 @@ impl Reg { 17..=32 => dl.i32_align.abi, 33..=64 => dl.i64_align.abi, 65..=128 => dl.i128_align.abi, - _ => panic!("unsupported integer: {:?}", self), + _ => panic!("unsupported integer: {self:?}"), }, RegKind::Float => match self.size.bits() { 32 => dl.f32_align.abi, 64 => dl.f64_align.abi, - _ => panic!("unsupported float: {:?}", self), + _ => panic!("unsupported float: {self:?}"), }, RegKind::Vector => dl.vector_align(self.size).abi, } @@ -642,7 +642,7 @@ impl fmt::Display for AdjustForForeignAbiError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Unsupported { arch, abi } => { - write!(f, "target architecture {:?} does not support `extern {}` ABI", arch, abi) + write!(f, "target architecture {arch:?} does not support `extern {abi}` ABI") } } } @@ -760,7 +760,7 @@ impl FromStr for Conv { "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), "AvrInterrupt" => Ok(Conv::AvrInterrupt), "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), - _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)), + _ => Err(format!("'{s}' is not a valid value for entry function call convetion.")), } } } diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 62a0f9fb034..28493c7700f 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -195,6 +195,6 @@ impl AArch64InlineAsmReg { (modifier.unwrap_or('v'), self as u32 - Self::v0 as u32) }; assert!(index < 32); - write!(out, "{}{}", prefix, index) + write!(out, "{prefix}{index}") } } diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 0db3eb6fcac..ec7429a3065 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -249,7 +249,7 @@ impl ArmInlineAsmReg { let index = self as u32 - Self::q0 as u32; assert!(index < 16); let index = index * 2 + (modifier == 'f') as u32; - write!(out, "d{}", index) + write!(out, "d{index}") } else { out.write_str(self.name()) } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 65d2cd64bf6..7f01f33d39c 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -679,13 +679,13 @@ impl fmt::Display for InlineAsmType { Self::I128 => f.write_str("i128"), Self::F32 => f.write_str("f32"), Self::F64 => f.write_str("f64"), - Self::VecI8(n) => write!(f, "i8x{}", n), - Self::VecI16(n) => write!(f, "i16x{}", n), - Self::VecI32(n) => write!(f, "i32x{}", n), - Self::VecI64(n) => write!(f, "i64x{}", n), - Self::VecI128(n) => write!(f, "i128x{}", n), - Self::VecF32(n) => write!(f, "f32x{}", n), - Self::VecF64(n) => write!(f, "f64x{}", n), + Self::VecI8(n) => write!(f, "i8x{n}"), + Self::VecI16(n) => write!(f, "i16x{n}"), + Self::VecI32(n) => write!(f, "i32x{n}"), + Self::VecI64(n) => write!(f, "i64x{n}"), + Self::VecI128(n) => write!(f, "i128x{n}"), + Self::VecF32(n) => write!(f, "f32x{n}"), + Self::VecF64(n) => write!(f, "f64x{n}"), } } } diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index 238c365093f..5eae07f141f 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -357,28 +357,28 @@ impl X86InlineAsmReg { if self as u32 <= Self::dx as u32 { let root = ['a', 'b', 'c', 'd'][self as usize - Self::ax as usize]; match modifier.unwrap_or(reg_default_modifier) { - 'l' => write!(out, "{}l", root), - 'h' => write!(out, "{}h", root), - 'x' => write!(out, "{}x", root), - 'e' => write!(out, "e{}x", root), - 'r' => write!(out, "r{}x", root), + 'l' => write!(out, "{root}l"), + 'h' => write!(out, "{root}h"), + 'x' => write!(out, "{root}x"), + 'e' => write!(out, "e{root}x"), + 'r' => write!(out, "r{root}x"), _ => unreachable!(), } } else if self as u32 <= Self::di as u32 { let root = self.name(); match modifier.unwrap_or(reg_default_modifier) { - 'l' => write!(out, "{}l", root), - 'x' => write!(out, "{}", root), - 'e' => write!(out, "e{}", root), - 'r' => write!(out, "r{}", root), + 'l' => write!(out, "{root}l"), + 'x' => write!(out, "{root}"), + 'e' => write!(out, "e{root}"), + 'r' => write!(out, "r{root}"), _ => unreachable!(), } } else if self as u32 <= Self::r15 as u32 { let root = self.name(); match modifier.unwrap_or(reg_default_modifier) { - 'l' => write!(out, "{}b", root), - 'x' => write!(out, "{}w", root), - 'e' => write!(out, "{}d", root), + 'l' => write!(out, "{root}b"), + 'x' => write!(out, "{root}w"), + 'e' => write!(out, "{root}d"), 'r' => out.write_str(root), _ => unreachable!(), } @@ -387,15 +387,15 @@ impl X86InlineAsmReg { } else if self as u32 <= Self::xmm15 as u32 { let prefix = modifier.unwrap_or('x'); let index = self as u32 - Self::xmm0 as u32; - write!(out, "{}{}", prefix, index) + write!(out, "{prefix}{index}") } else if self as u32 <= Self::ymm15 as u32 { let prefix = modifier.unwrap_or('y'); let index = self as u32 - Self::ymm0 as u32; - write!(out, "{}{}", prefix, index) + write!(out, "{prefix}{index}") } else if self as u32 <= Self::zmm31 as u32 { let prefix = modifier.unwrap_or('z'); let index = self as u32 - Self::zmm0 as u32; - write!(out, "{}{}", prefix, index) + write!(out, "{prefix}{index}") } else { out.write_str(self.name()) } diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 44644c4733e..5c6dcc0aba9 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -76,7 +76,7 @@ impl Arch { fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { let platform_name: StaticCow = match abi { - "sim" => format!("{}-simulator", os).into(), + "sim" => format!("{os}-simulator").into(), "macabi" => "mac-catalyst".into(), _ => os.into(), }; @@ -193,7 +193,7 @@ fn macos_deployment_target(arch: Arch) -> (u32, u32) { fn macos_lld_platform_version(arch: Arch) -> String { let (major, minor) = macos_deployment_target(arch); - format!("{}.{}", major, minor) + format!("{major}.{minor}") } pub fn macos_llvm_target(arch: Arch) -> String { @@ -252,7 +252,7 @@ pub fn ios_llvm_target(arch: Arch) -> String { fn ios_lld_platform_version() -> String { let (major, minor) = ios_deployment_target(); - format!("{}.{}", major, minor) + format!("{major}.{minor}") } pub fn ios_sim_llvm_target(arch: Arch) -> String { @@ -266,7 +266,7 @@ fn tvos_deployment_target() -> (u32, u32) { fn tvos_lld_platform_version() -> String { let (major, minor) = tvos_deployment_target(); - format!("{}.{}", major, minor) + format!("{major}.{minor}") } fn watchos_deployment_target() -> (u32, u32) { @@ -275,7 +275,7 @@ fn watchos_deployment_target() -> (u32, u32) { fn watchos_lld_platform_version() -> String { let (major, minor) = watchos_deployment_target(); - format!("{}.{}", major, minor) + format!("{major}.{minor}") } pub fn watchos_sim_llvm_target(arch: Arch) -> String { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index b7ec1612e8e..5bbd86bb5b9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -840,7 +840,7 @@ impl fmt::Display for SanitizerSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut first = true; for s in *self { - let name = s.as_str().unwrap_or_else(|| panic!("unrecognized sanitizer {:?}", s)); + let name = s.as_str().unwrap_or_else(|| panic!("unrecognized sanitizer {s:?}")); if !first { f.write_str(", ")?; } @@ -2074,7 +2074,7 @@ impl Target { let mut get_req_field = |name: &str| { obj.remove(name) .and_then(|j| j.as_str().map(str::to_string)) - .ok_or_else(|| format!("Field {} in target specification is required", name)) + .ok_or_else(|| format!("Field {name} in target specification is required")) }; let mut base = Target { @@ -2480,7 +2480,7 @@ impl Target { if let Some(s) = fp.as_str() { base.frame_pointer = s .parse() - .map_err(|()| format!("'{}' is not a valid value for frame-pointer", s))?; + .map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?; } else { incorrect_type.push("frame-pointer".into()) } @@ -2672,7 +2672,7 @@ impl Target { return load_file(&p); } - Err(format!("Could not find specification for target {:?}", target_triple)) + Err(format!("Could not find specification for target {target_triple:?}")) } TargetTriple::TargetJson { ref contents, .. } => { let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?; @@ -2936,7 +2936,7 @@ impl TargetTriple { let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| { io::Error::new( io::ErrorKind::InvalidInput, - format!("target path {:?} is not a valid file: {}", canonicalized_path, err), + format!("target path {canonicalized_path:?} is not a valid file: {err}"), ) })?; let triple = canonicalized_path @@ -2971,7 +2971,7 @@ impl TargetTriple { let mut hasher = DefaultHasher::new(); content.hash(&mut hasher); let hash = hasher.finish(); - format!("{}-{}", triple, hash) + format!("{triple}-{hash}") } } } diff --git a/compiler/rustc_target/src/spec/solid_base.rs b/compiler/rustc_target/src/spec/solid_base.rs index c585a6cd58e..eaf72b7616c 100644 --- a/compiler/rustc_target/src/spec/solid_base.rs +++ b/compiler/rustc_target/src/spec/solid_base.rs @@ -3,7 +3,7 @@ use crate::spec::TargetOptions; pub fn opts(kernel: &str) -> TargetOptions { TargetOptions { - os: format!("solid_{}", kernel).into(), + os: format!("solid_{kernel}").into(), vendor: "kmc".into(), executables: false, frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 3f661ce6923..481b56e111e 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -189,7 +189,7 @@ fn dtorck_constraint_for_ty<'tcx>( tcx.sess.delay_span_bug( span, - &format!("upvar_tys for closure not found. Expected capture information for closure {}", ty,), + &format!("upvar_tys for closure not found. Expected capture information for closure {ty}",), ); return Err(NoSolution); } @@ -231,7 +231,7 @@ fn dtorck_constraint_for_ty<'tcx>( // be fully resolved. tcx.sess.delay_span_bug( span, - &format!("upvar_tys for generator not found. Expected capture information for generator {}", ty,), + &format!("upvar_tys for generator not found. Expected capture information for generator {ty}",), ); return Err(NoSolution); } diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 6e6bc62a040..5cad2c2ccb0 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -47,7 +47,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + // us a test case. debug_assert_eq!(normalized_value, resolved_value); let erased = infcx.tcx.erase_regions(resolved_value); - debug_assert!(!erased.needs_infer(), "{:?}", erased); + debug_assert!(!erased.needs_infer(), "{erased:?}"); Ok(erased) } Err(NoSolution) => Err(NoSolution), diff --git a/compiler/rustc_transmute/src/layout/mod.rs b/compiler/rustc_transmute/src/layout/mod.rs index 07035ebdfb1..f8d05bc89d2 100644 --- a/compiler/rustc_transmute/src/layout/mod.rs +++ b/compiler/rustc_transmute/src/layout/mod.rs @@ -24,7 +24,7 @@ impl fmt::Debug for Byte { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self { Self::Uninit => f.write_str("??u8"), - Self::Init(b) => write!(f, "{:#04x}u8", b), + Self::Init(b) => write!(f, "{b:#04x}u8"), } } } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index dd36a5c7a21..fed070408f3 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -718,9 +718,9 @@ impl fmt::Debug for InferTy { TyVar(ref v) => v.fmt(f), IntVar(ref v) => v.fmt(f), FloatVar(ref v) => v.fmt(f), - FreshTy(v) => write!(f, "FreshTy({:?})", v), - FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), - FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v), + FreshTy(v) => write!(f, "FreshTy({v:?})"), + FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"), + FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"), } } } @@ -743,9 +743,9 @@ impl fmt::Display for InferTy { TyVar(_) => write!(f, "_"), IntVar(_) => write!(f, "{}", "{integer}"), FloatVar(_) => write!(f, "{}", "{float}"), - FreshTy(v) => write!(f, "FreshTy({})", v), - FreshIntTy(v) => write!(f, "FreshIntTy({})", v), - FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v), + FreshTy(v) => write!(f, "FreshTy({v})"), + FreshIntTy(v) => write!(f, "FreshIntTy({v})"), + FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"), } } } diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index f30ae82d7cd..b944cbd698d 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -1028,10 +1028,10 @@ impl hash::Hash for RegionKind { impl fmt::Debug for RegionKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - ReEarlyBound(data) => write!(f, "ReEarlyBound({:?})", data), + ReEarlyBound(data) => write!(f, "ReEarlyBound({data:?})"), ReLateBound(binder_id, bound_region) => { - write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region) + write!(f, "ReLateBound({binder_id:?}, {bound_region:?})") } ReFree(fr) => fr.fmt(f), @@ -1040,7 +1040,7 @@ impl fmt::Debug for RegionKind { ReVar(vid) => vid.fmt(f), - RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder), + RePlaceholder(placeholder) => write!(f, "RePlaceholder({placeholder:?})"), ReErased => f.write_str("ReErased"), } -- cgit 1.4.1-3-g733a5 From 0de182a5810d6c732eb2bcd40d1b98eef884dd27 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 5 Jan 2023 10:59:21 -0700 Subject: rustdoc: remove legacy user-select CSS According to [caniuse], the only supported browser that requires the vendor prefix, as defined in [RFC 1985], is Safari. * The last version of Chrome that required a vendor prefix was version 53. The current version is 108. * Firefox 68 is the last version that required a vendor prefix. The [current Firefox ESR] is version 102. * The current version of Safari for Mac and iOS still requires a prefix. * The last version of Edge that required a vendor frefix was 18. The current version of Edge is 108. * UCAndroid support is unknown, but if it still requires a vendor prefix, it's more likely to be `-webkit-` than `-moz-` or `-ms-`, since they would want to emulate iOS for compatibility. [caniuse]: https://caniuse.com/?search=user-select [RFC 1985]: https://rust-lang.github.io/rfcs/1985-tiered-browser-support.html [current Firefox ESR]: https://wiki.mozilla.org/Releases --- src/librustdoc/html/static/css/rustdoc.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index cdc077e26bf..0e609a6f970 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -538,8 +538,6 @@ ul.block, .block li { overflow: initial; text-align: right; -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; padding: 14px 8px; color: var(--src-line-numbers-span-color); -- cgit 1.4.1-3-g733a5 From f2ad85a930539986517747729df6082553d195f8 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 5 Jan 2023 11:07:11 -0800 Subject: Fix error-index redirect to work with back button. --- src/tools/error_index_generator/main.rs | 11 +++++++---- src/tools/error_index_generator/redirect.js | 10 +++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 1bde8e00782..2ccb6b81233 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -98,8 +98,7 @@ fn add_rust_attribute_on_codeblock(explanation: &str) -> String { fn render_html(output_path: &Path) -> Result<(), Box> { let mut introduction = format!( - " -# Rust error codes index + "# Rust error codes index This page lists all the error codes emitted by the Rust compiler. @@ -149,7 +148,12 @@ This page lists all the error codes emitted by the Rust compiler. book.book.sections.push(BookItem::Chapter(chapter)); book.build()?; - // We can't put this content into another file, otherwise `mbdbook` will also put it into the + // The error-index used to be generated manually (without mdbook), and the + // index was located at the top level. Now that it is generated with + // mdbook, error-index.html has moved to error_codes/error-index.html. + // This adds a redirect so that old links go to the new location. + // + // We can't put this content into another file, otherwise `mdbook` will also put it into the // output directory, making a duplicate. fs::write( output_path.join("error-index.html"), @@ -163,7 +167,6 @@ This page lists all the error codes emitted by the Rust compiler.

If you are not automatically redirected to the error code index, please here. - "#, )?; diff --git a/src/tools/error_index_generator/redirect.js b/src/tools/error_index_generator/redirect.js index 8c907f5795d..c80cbf297af 100644 --- a/src/tools/error_index_generator/redirect.js +++ b/src/tools/error_index_generator/redirect.js @@ -3,14 +3,10 @@ let code = window.location.hash.replace(/^#/, ''); // We have to make sure this pattern matches to avoid inadvertently creating an // open redirect. - if (!/^E[0-9]+$/.test(code)) { + if (/^E[0-9]+$/.test(code)) { + window.location.replace('./error_codes/' + code + '.html'); return; } - if (window.location.pathname.indexOf("/error_codes/") !== -1) { - // We're not at the top level, so we don't prepend with "./error_codes/". - window.location = './' + code + '.html'; - } else { - window.location = './error_codes/' + code + '.html'; - } } + window.location.replace('./error_codes/error-index.html'); })() -- cgit 1.4.1-3-g733a5 From 72c3082aab3e2df801deeefcc65c7469d93274ca Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 5 Jan 2023 06:44:11 -0800 Subject: error-index: Don't generate 404 instead of removing it. --- src/tools/error_index_generator/book_config.toml | 1 + src/tools/error_index_generator/main.rs | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/error_index_generator/book_config.toml b/src/tools/error_index_generator/book_config.toml index 885100ae3a4..2701ad917bb 100644 --- a/src/tools/error_index_generator/book_config.toml +++ b/src/tools/error_index_generator/book_config.toml @@ -7,6 +7,7 @@ src = "" git-repository-url = "https://github.com/rust-lang/rust/" additional-css = ["error-index.css"] additional-js = ["error-index.js"] +input-404 = "" [output.html.search] enable = true diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 2ccb6b81233..98eda97e236 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -171,9 +171,6 @@ This page lists all the error codes emitted by the Rust compiler. "#, )?; - // No need for a 404 file, it's already handled by the server. - fs::remove_file(output_path.join("error_codes/404.html"))?; - Ok(()) } -- cgit 1.4.1-3-g733a5 From 5112f0281d4bff402843bef88dbc13b33358cc1c Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 3 Jan 2023 19:28:28 +0100 Subject: Shrink `ParseResult` in the hot path. A recent PR increased the size, which caused regressions. This uses the existing generic infrastructure to differentiate between the hot path and the diagnostics path. --- compiler/rustc_expand/src/mbe/diagnostics.rs | 25 ++++++++++- compiler/rustc_expand/src/mbe/macro_parser.rs | 26 ++++++------ compiler/rustc_expand/src/mbe/macro_rules.rs | 60 ++++++++++++++++++++------- 3 files changed, 81 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 3a38d7a9669..f469b2daef5 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -114,6 +114,12 @@ impl BestFailure { } impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> { + type Failure = (Token, usize, &'static str); + + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + (tok, position, msg) + } + fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) { if self.remaining_matcher.is_none() || (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof) @@ -122,7 +128,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, } } - fn after_arm(&mut self, result: &NamedParseResult) { + fn after_arm(&mut self, result: &NamedParseResult) { match result { Success(_) => { // Nonterminal parser recovery might turn failed matches into successful ones, @@ -132,7 +138,7 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, "should not collect detailed info for successful macro match", ); } - Failure(token, approx_position, msg) => { + Failure((token, approx_position, msg)) => { debug!(?token, ?msg, "a new failure of an arm"); if self @@ -175,6 +181,21 @@ impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> { } } +/// Currently used by macro_rules! compilation to extract a little information from the `Failure` case. +pub struct FailureForwarder; + +impl<'matcher> Tracker<'matcher> for FailureForwarder { + type Failure = (Token, usize, &'static str); + + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure { + (tok, position, msg) + } + + fn description() -> &'static str { + "failure-forwarder" + } +} + pub(super) fn emit_frag_parse_err( mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>, parser: &Parser<'_>, diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index df1c1834c1d..2e199541b92 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -305,13 +305,13 @@ enum EofMatcherPositions { } /// Represents the possible results of an attempted parse. -pub(crate) enum ParseResult { +pub(crate) enum ParseResult { /// Parsed successfully. Success(T), /// Arm failed to match. If the second parameter is `token::Eof`, it indicates an unexpected /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. /// The usize is the approximate position of the token in the input token stream. - Failure(Token, usize, &'static str), + Failure(F), /// Fatal error (malformed macro?). Abort compilation. Error(rustc_span::Span, String), ErrorReported(ErrorGuaranteed), @@ -320,7 +320,7 @@ pub(crate) enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of /// `MacroRulesNormalizedIdent`s to `NamedMatch`es. This represents the mapping /// of metavars to the token trees they bind to. -pub(crate) type NamedParseResult = ParseResult; +pub(crate) type NamedParseResult = ParseResult; /// Contains a mapping of `MacroRulesNormalizedIdent`s to `NamedMatch`es. /// This represents the mapping of metavars to the token trees they bind to. @@ -458,7 +458,7 @@ impl TtParser { token: &Token, approx_position: usize, track: &mut T, - ) -> Option { + ) -> Option> { // Matcher positions that would be valid if the macro invocation was over now. Only // modified if `token == Eof`. let mut eof_mps = EofMatcherPositions::None; @@ -595,14 +595,14 @@ impl TtParser { EofMatcherPositions::Multiple => { Error(token.span, "ambiguity: multiple successful parses".to_string()) } - EofMatcherPositions::None => Failure( + EofMatcherPositions::None => Failure(T::build_failure( Token::new( token::Eof, if token.span.is_dummy() { token.span } else { token.span.shrink_to_hi() }, ), approx_position, "missing tokens in macro arguments", - ), + )), }) } else { None @@ -615,7 +615,7 @@ impl TtParser { parser: &mut Cow<'_, Parser<'_>>, matcher: &'matcher [MatcherLoc], track: &mut T, - ) -> NamedParseResult { + ) -> NamedParseResult { // A queue of possible matcher positions. We initialize it with the matcher position in // which the "dot" is before the first token of the first token tree in `matcher`. // `parse_tt_inner` then processes all of these possible matcher positions and produces @@ -648,11 +648,11 @@ impl TtParser { (0, 0) => { // There are no possible next positions AND we aren't waiting for the black-box // parser: syntax error. - return Failure( + return Failure(T::build_failure( parser.token.clone(), parser.approx_token_stream_pos(), "no rules expected this token in macro call", - ); + )); } (_, 0) => { @@ -711,11 +711,11 @@ impl TtParser { } } - fn ambiguity_error( + fn ambiguity_error( &self, matcher: &[MatcherLoc], token_span: rustc_span::Span, - ) -> NamedParseResult { + ) -> NamedParseResult { let nts = self .bb_mps .iter() @@ -741,11 +741,11 @@ impl TtParser { ) } - fn nameize>( + fn nameize, F>( &self, matcher: &[MatcherLoc], mut res: I, - ) -> NamedParseResult { + ) -> NamedParseResult { // Make that each metavar has _exactly one_ binding. If so, insert the binding into the // `NamedParseResult`. Otherwise, it's an error. let mut ret_val = FxHashMap::default(); diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index fbb806fe81b..c0489f68633 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -141,31 +141,40 @@ fn trace_macros_note(cx_expansions: &mut FxIndexMap>, sp: Span } pub(super) trait Tracker<'matcher> { + /// The contents of `ParseResult::Failure`. + type Failure; + + /// Arm failed to match. If the token is `token::Eof`, it indicates an unexpected + /// end of macro invocation. Otherwise, it indicates that no rules expected the given token. + /// The usize is the approximate position of the token in the input token stream. + fn build_failure(tok: Token, position: usize, msg: &'static str) -> Self::Failure; + /// This is called before trying to match next MatcherLoc on the current token. - fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc); + fn before_match_loc(&mut self, _parser: &TtParser, _matcher: &'matcher MatcherLoc) {} /// This is called after an arm has been parsed, either successfully or unsuccessfully. When this is called, /// `before_match_loc` was called at least once (with a `MatcherLoc::Eof`). - fn after_arm(&mut self, result: &NamedParseResult); + fn after_arm(&mut self, _result: &NamedParseResult) {} /// For tracing. fn description() -> &'static str; - fn recovery() -> Recovery; + fn recovery() -> Recovery { + Recovery::Forbidden + } } /// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization. pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { - fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {} - fn after_arm(&mut self, _: &NamedParseResult) {} + type Failure = (); + + fn build_failure(_tok: Token, _position: usize, _msg: &'static str) -> Self::Failure {} + fn description() -> &'static str { "none" } - fn recovery() -> Recovery { - Recovery::Forbidden - } } /// Expands the rules based macro defined by `lhses` and `rhses` for a given @@ -326,8 +335,8 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( return Ok((i, named_matches)); } - Failure(_, reached_position, _) => { - trace!(%reached_position, "Failed to match arm, trying the next one"); + Failure(_) => { + trace!("Failed to match arm, trying the next one"); // Try the next arm. } Error(_, _) => { @@ -381,11 +390,13 @@ pub fn compile_declarative_macro( let rhs_nm = Ident::new(sym::rhs, def.span); let tt_spec = Some(NonterminalKind::TT); - // Parse the macro_rules! invocation - let (macro_rules, body) = match &def.kind { - ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()), + let macro_def = match &def.kind { + ast::ItemKind::MacroDef(def) => def, _ => unreachable!(), }; + let macro_rules = macro_def.macro_rules; + + // Parse the macro_rules! invocation // The pattern that macro_rules matches. // The grammar for macro_rules! is: @@ -426,13 +437,32 @@ pub fn compile_declarative_macro( // Convert it into `MatcherLoc` form. let argument_gram = mbe::macro_parser::compute_locs(&argument_gram); - let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS); + let create_parser = || { + let body = macro_def.body.tokens.clone(); + Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS) + }; + + let parser = create_parser(); let mut tt_parser = TtParser::new(Ident::with_dummy_span(if macro_rules { kw::MacroRules } else { kw::Macro })); let argument_map = match tt_parser.parse_tt(&mut Cow::Owned(parser), &argument_gram, &mut NoopTracker) { Success(m) => m, - Failure(token, _, msg) => { + Failure(()) => { + // The fast `NoopTracker` doesn't have any info on failure, so we need to retry it with another one + // that gives us the information we need. + // For this we need to reclone the macro body as the previous parser consumed it. + let retry_parser = create_parser(); + + let parse_result = tt_parser.parse_tt( + &mut Cow::Owned(retry_parser), + &argument_gram, + &mut diagnostics::FailureForwarder, + ); + let Failure((token, _, msg)) = parse_result else { + unreachable!("matcher returned something other than Failure after retry"); + }; + let s = parse_failure_msg(&token); let sp = token.span.substitute_dummy(def.span); let mut err = sess.parse_sess.span_diagnostic.struct_span_err(sp, &s); -- cgit 1.4.1-3-g733a5 From ce6b7179afcdf6ae2dad7e69c56f1f5c957b47bd Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 21:29:36 +0000 Subject: Detect closures assigned to binding in block Fix #58497. --- compiler/rustc_borrowck/src/borrowck_errors.rs | 7 +++-- .../src/diagnostics/conflict_errors.rs | 31 +++++++++++++++++++--- .../src/diagnostics/explain_borrow.rs | 12 +++++++-- .../rustc_borrowck/src/diagnostics/region_name.rs | 2 +- .../diagnostics/borrowck/borrowck-3.rs | 3 +-- .../diagnostics/borrowck/borrowck-3.stderr | 26 ++++++++++-------- .../ui/unboxed-closures/unboxed-closure-region.rs | 2 +- .../unboxed-closures/unboxed-closure-region.stderr | 25 ++++++++++------- src/tools/rustfmt/tests/target/issue_4110.rs | 1 + 9 files changed, 74 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index e4942f9b666..a4943d11204 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -440,15 +440,14 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { closure_kind: &str, borrowed_path: &str, capture_span: Span, + scope: &str, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let mut err = struct_span_err!( self, closure_span, E0373, - "{} may outlive the current function, but it borrows {}, which is owned by the current \ - function", - closure_kind, - borrowed_path, + "{closure_kind} may outlive the current {scope}, but it borrows {borrowed_path}, \ + which is owned by the current {scope}", ); err.span_label(capture_span, format!("{} is borrowed here", borrowed_path)) .span_label(closure_span, format!("may outlive borrowed value {}", borrowed_path)); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 492c8d02012..d99bfc01a42 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1423,6 +1423,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // // then just use the normal error. The closure isn't escaping // and `move` will not help here. + ( + Some(name), + BorrowExplanation::UsedLater(LaterUseKind::ClosureCapture, var_or_use_span, _), + ) => self.report_escaping_closure_capture( + borrow_spans, + borrow_span, + &RegionName { + name: self.synthesize_region_name(), + source: RegionNameSource::Static, + }, + ConstraintCategory::CallArgument(None), + var_or_use_span, + &format!("`{}`", name), + "block", + ), ( Some(name), BorrowExplanation::MustBeValidFor { @@ -1443,6 +1458,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { category, span, &format!("`{}`", name), + "function", ), ( name, @@ -1895,6 +1911,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(err) } + #[instrument(level = "debug", skip(self))] fn report_escaping_closure_capture( &mut self, use_span: UseSpans<'tcx>, @@ -1903,6 +1920,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { category: ConstraintCategory<'tcx>, constraint_span: Span, captured_var: &str, + scope: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { let tcx = self.infcx.tcx; let args_span = use_span.args_or_use(); @@ -1933,8 +1951,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None => "closure", }; - let mut err = - self.cannot_capture_in_long_lived_closure(args_span, kind, captured_var, var_span); + let mut err = self.cannot_capture_in_long_lived_closure( + args_span, + kind, + captured_var, + var_span, + scope, + ); err.span_suggestion_verbose( sugg_span, &format!( @@ -1956,10 +1979,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if matches!(use_span.generator_kind(), Some(GeneratorKind::Async(_))) { err.note( "async blocks are not executed immediately and must either take a \ - reference or ownership of outside variables they use", + reference or ownership of outside variables they use", ); } else { - let msg = format!("function requires argument type to outlive `{}`", fr_name); + let msg = format!("{scope} requires argument type to outlive `{fr_name}`"); err.span_note(constraint_span, &msg); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 00f5e8a8397..c4ae30151c4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -444,6 +444,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// First span returned points to the location of the conflicting use /// Second span if `Some` is returned in the case of closures and points /// to the use of the path + #[instrument(level = "debug", skip(self))] fn later_use_kind( &self, borrow: &BorrowData<'tcx>, @@ -461,11 +462,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let block = &self.body.basic_blocks[location.block]; let kind = if let Some(&Statement { - kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)), + kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), place)), .. }) = block.statements.get(location.statement_index) { - LaterUseKind::FakeLetRead + if let Some(l) = place.as_local() + && let local_decl = &self.body.local_decls[l] + && local_decl.ty.is_closure() + { + LaterUseKind::ClosureCapture + } else { + LaterUseKind::FakeLetRead + } } else if self.was_captured_by_trait_object(borrow) { LaterUseKind::TraitCapture } else if location.statement_index == block.statements.len() { diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index dbd4cac7b14..579ce90a760 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -200,7 +200,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// increment the counter. /// /// This is _not_ idempotent. Call `give_region_a_name` when possible. - fn synthesize_region_name(&self) -> Symbol { + pub(crate) fn synthesize_region_name(&self) -> Symbol { let c = self.next_region_name.replace_with(|counter| *counter + 1); Symbol::intern(&format!("'{:?}", c)) } diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs index bdd6cb79b60..00f50c33e1c 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs @@ -8,10 +8,9 @@ struct Point { fn main() { let mut c = { let mut p = Point {x: "1".to_string(), y: "2".to_string() }; - || { + || { //~ ERROR closure may outlive the current block, but it borrows `p` let x = &mut p.x; println!("{:?}", p); - //~^ ERROR `p` does not live long enough } }; c(); diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr index dab1809a381..ee923804786 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr @@ -1,18 +1,22 @@ -error[E0597]: `p` does not live long enough - --> $DIR/borrowck-3.rs:13:29 +error[E0373]: closure may outlive the current block, but it borrows `p`, which is owned by the current block + --> $DIR/borrowck-3.rs:11:9 | -LL | let mut c = { - | ----- borrow later stored here -LL | let mut p = Point {x: "1".to_string(), y: "2".to_string() }; LL | || { - | -- value captured here + | ^^ may outlive borrowed value `p` LL | let x = &mut p.x; LL | println!("{:?}", p); - | ^ borrowed value does not live long enough -... -LL | }; - | - `p` dropped here while still borrowed + | - `p` is borrowed here + | +note: block requires argument type to outlive `'1` + --> $DIR/borrowck-3.rs:9:9 + | +LL | let mut c = { + | ^^^^^ +help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.rs b/src/test/ui/unboxed-closures/unboxed-closure-region.rs index f202492eda5..51fe118c93f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-region.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-region.rs @@ -5,7 +5,7 @@ fn main() { let _f = { let x = 0; - || x //~ ERROR `x` does not live long enough + || x //~ ERROR closure may outlive the current block, but it borrows `x` }; _f; } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.stderr b/src/test/ui/unboxed-closures/unboxed-closure-region.stderr index b40b2f67d9b..43e9af24a7c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-region.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-region.stderr @@ -1,16 +1,21 @@ -error[E0597]: `x` does not live long enough - --> $DIR/unboxed-closure-region.rs:8:12 +error[E0373]: closure may outlive the current block, but it borrows `x`, which is owned by the current block + --> $DIR/unboxed-closure-region.rs:8:9 | -LL | let _f = { - | -- borrow later stored here -LL | let x = 0; LL | || x - | -- ^ borrowed value does not live long enough + | ^^ - `x` is borrowed here | | - | value captured here -LL | }; - | - `x` dropped here while still borrowed + | may outlive borrowed value `x` + | +note: block requires argument type to outlive `'1` + --> $DIR/unboxed-closure-region.rs:6:9 + | +LL | let _f = { + | ^^ +help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword + | +LL | move || x + | ++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0373`. diff --git a/src/tools/rustfmt/tests/target/issue_4110.rs b/src/tools/rustfmt/tests/target/issue_4110.rs index 4a58c3946e1..d3734e90b7f 100644 --- a/src/tools/rustfmt/tests/target/issue_4110.rs +++ b/src/tools/rustfmt/tests/target/issue_4110.rs @@ -20,6 +20,7 @@ fn bindings() { category, span, &format!("`{}`", name), + "function", ), ( ref name, -- cgit 1.4.1-3-g733a5 From 1983a627b37c98e6660dd74ea3a56ac157fc2777 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 6 Jan 2023 00:45:10 +0000 Subject: Detect bindings assigned blocks without tail expressions Address #44173 for type check errors. --- compiler/rustc_hir_typeck/src/demand.rs | 45 ++++++++++++ ...nding-assigned-block-without-tail-expression.rs | 16 +++++ ...g-assigned-block-without-tail-expression.stderr | 79 ++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 src/test/ui/type/binding-assigned-block-without-tail-expression.rs create mode 100644 src/test/ui/type/binding-assigned-block-without-tail-expression.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 9c6c53abf07..a9e6b141170 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -75,6 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.note_need_for_fn_pointer(err, expected, expr_ty); self.note_internal_mutation_in_method(err, expr, expected, expr_ty); self.check_for_range_as_method_call(err, expr, expr_ty, expected); + self.check_for_binding_assigned_block_without_tail_expression(err, expr, expr_ty, expected); } /// Requires that the two types unify, and prints an error message if @@ -1670,4 +1671,48 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } + + /// Identify when the type error is because `()` is found in a binding that was assigned a + /// block without a tail expression. + fn check_for_binding_assigned_block_without_tail_expression( + &self, + err: &mut Diagnostic, + expr: &hir::Expr<'_>, + checked_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>, + ) { + if !checked_ty.is_unit() { + return; + } + let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else { return; }; + let hir::def::Res::Local(hir_id) = path.res else { return; }; + let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else { + return; + }; + let Some(hir::Node::Local(hir::Local { + ty: None, + init: Some(init), + .. + })) = self.tcx.hir().find_parent(pat.hir_id) else { return; }; + let hir::ExprKind::Block(block, None) = init.kind else { return; }; + if block.expr.is_some() { + return; + } + let [.., stmt] = block.stmts else { + err.span_help(block.span, "this empty block is missing a tail expression"); + return; + }; + let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; + let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; + if self.can_eq(self.param_env, expected_ty, ty).is_ok() { + err.span_suggestion_verbose( + stmt.span.with_lo(tail_expr.span.hi()), + "remove this semicolon", + "", + Applicability::MachineApplicable, + ); + } else { + err.span_help(block.span, "this block is missing a tail expression"); + } + } } diff --git a/src/test/ui/type/binding-assigned-block-without-tail-expression.rs b/src/test/ui/type/binding-assigned-block-without-tail-expression.rs new file mode 100644 index 00000000000..b5b23a9e672 --- /dev/null +++ b/src/test/ui/type/binding-assigned-block-without-tail-expression.rs @@ -0,0 +1,16 @@ +fn main() { + let x = { + println!("foo"); + 42; + }; + let y = {}; + let z = { + "hi"; + }; + println!("{}", x); //~ ERROR E0277 + println!("{}", y); //~ ERROR E0277 + println!("{}", z); //~ ERROR E0277 + let _: i32 = x; //~ ERROR E0308 + let _: i32 = y; //~ ERROR E0308 + let _: i32 = z; //~ ERROR E0308 +} diff --git a/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr new file mode 100644 index 00000000000..46300104b05 --- /dev/null +++ b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr @@ -0,0 +1,79 @@ +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/binding-assigned-block-without-tail-expression.rs:10:20 + | +LL | println!("{}", x); + | ^ `()` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/binding-assigned-block-without-tail-expression.rs:11:20 + | +LL | println!("{}", y); + | ^ `()` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/binding-assigned-block-without-tail-expression.rs:12:20 + | +LL | println!("{}", z); + | ^ `()` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/binding-assigned-block-without-tail-expression.rs:13:18 + | +LL | let _: i32 = x; + | --- ^ expected `i32`, found `()` + | | + | expected due to this + | +help: remove this semicolon + | +LL - 42; +LL + 42 + | + +error[E0308]: mismatched types + --> $DIR/binding-assigned-block-without-tail-expression.rs:14:18 + | +LL | let _: i32 = y; + | --- ^ expected `i32`, found `()` + | | + | expected due to this + | +help: this empty block is missing a tail expression + --> $DIR/binding-assigned-block-without-tail-expression.rs:6:13 + | +LL | let y = {}; + | ^^ + +error[E0308]: mismatched types + --> $DIR/binding-assigned-block-without-tail-expression.rs:15:18 + | +LL | let _: i32 = z; + | --- ^ expected `i32`, found `()` + | | + | expected due to this + | +help: this block is missing a tail expression + --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 + | +LL | let z = { + | _____________^ +LL | | "hi"; +LL | | }; + | |_____^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From 1fa6ada9dd3a17fc8c99b6b559a2835946803d21 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 6 Jan 2023 02:43:16 +0000 Subject: Detect bindings assigned blocks without tail expressions in trait errors Address #44173 for trait errors. --- .../src/traits/error_reporting/mod.rs | 54 ++++++++++------ .../src/traits/error_reporting/suggestions.rs | 72 +++++++++++++++++++++- ...nding-assigned-block-without-tail-expression.rs | 6 ++ ...g-assigned-block-without-tail-expression.stderr | 68 +++++++++++++++++--- 4 files changed, 172 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 6996ddd8729..714fbcf4eaa 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -771,7 +771,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ), } }; - + self.check_for_binding_assigned_block_without_tail_expression( + &obligation, + &mut err, + trait_predicate, + ); if self.suggest_add_reference_to_arg( &obligation, &mut err, @@ -2267,23 +2271,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) = (body_id, subst.map(|subst| subst.unpack())) { - struct FindExprBySpan<'hir> { - span: Span, - result: Option<&'hir hir::Expr<'hir>>, - } - - impl<'v> hir::intravisit::Visitor<'v> for FindExprBySpan<'v> { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if self.span == ex.span { - self.result = Some(ex); - } else { - hir::intravisit::walk_expr(self, ex); - } - } - } - - let mut expr_finder = FindExprBySpan { span, result: None }; - + let mut expr_finder = FindExprBySpan::new(span); expr_finder.visit_expr(&self.tcx.hir().body(body_id).value); if let Some(hir::Expr { @@ -2770,6 +2758,36 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } +/// Crude way of getting back an `Expr` from a `Span`. +pub struct FindExprBySpan<'hir> { + pub span: Span, + pub result: Option<&'hir hir::Expr<'hir>>, + pub ty_result: Option<&'hir hir::Ty<'hir>>, +} + +impl<'hir> FindExprBySpan<'hir> { + fn new(span: Span) -> Self { + Self { span, result: None, ty_result: None } + } +} + +impl<'v> Visitor<'v> for FindExprBySpan<'v> { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if self.span == ex.span { + self.result = Some(ex); + } else { + hir::intravisit::walk_expr(self, ex); + } + } + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { + if self.span == ty.span { + self.ty_result = Some(ty); + } else { + hir::intravisit::walk_ty(self, ty); + } + } +} + /// Look for type `param` in an ADT being used only through a reference to confirm that suggesting /// `param: ?Sized` would be a valid constraint. struct FindTypeParam { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 8c2c1828774..ad2711209e2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1,6 +1,9 @@ // ignore-tidy-filelength -use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use super::{ + DefIdOrName, FindExprBySpan, Obligation, ObligationCause, ObligationCauseCode, + PredicateObligation, +}; use crate::autoderef::Autoderef; use crate::infer::InferCtxt; @@ -196,6 +199,13 @@ pub trait TypeErrCtxtExt<'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool; + fn check_for_binding_assigned_block_without_tail_expression( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ); + fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, @@ -1032,6 +1042,66 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { true } + fn check_for_binding_assigned_block_without_tail_expression( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) { + let mut span = obligation.cause.span; + while span.from_expansion() { + // Remove all the desugaring and macro contexts. + span.remove_mark(); + } + let mut expr_finder = FindExprBySpan::new(span); + let Some(hir::Node::Expr(body)) = self.tcx.hir().find(obligation.cause.body_id) else { return; }; + expr_finder.visit_expr(&body); + let Some(expr) = expr_finder.result else { return; }; + let Some(typeck) = &self.typeck_results else { return; }; + let Some(ty) = typeck.expr_ty_adjusted_opt(expr) else { return; }; + if !ty.is_unit() { + return; + }; + let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind else { return; }; + let hir::def::Res::Local(hir_id) = path.res else { return; }; + let Some(hir::Node::Pat(pat)) = self.tcx.hir().find(hir_id) else { + return; + }; + let Some(hir::Node::Local(hir::Local { + ty: None, + init: Some(init), + .. + })) = self.tcx.hir().find_parent(pat.hir_id) else { return; }; + let hir::ExprKind::Block(block, None) = init.kind else { return; }; + if block.expr.is_some() { + return; + } + let [.., stmt] = block.stmts else { + err.span_help(block.span, "this empty block is missing a tail expression"); + return; + }; + let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; + let Some(ty) = typeck.expr_ty_opt(tail_expr) else { + err.span_help(block.span, "this block is missing a tail expression"); + return; + }; + let ty = self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(ty)); + let trait_pred_and_self = trait_pred.map_bound(|trait_pred| (trait_pred, ty)); + + let new_obligation = + self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self); + if self.predicate_must_hold_modulo_regions(&new_obligation) { + err.span_suggestion_verbose( + stmt.span.with_lo(tail_expr.span.hi()), + "remove this semicolon", + "", + Applicability::MachineApplicable, + ); + } else { + err.span_help(block.span, "this block is missing a tail expression"); + } + } + fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, diff --git a/src/test/ui/type/binding-assigned-block-without-tail-expression.rs b/src/test/ui/type/binding-assigned-block-without-tail-expression.rs index b5b23a9e672..09afd27a079 100644 --- a/src/test/ui/type/binding-assigned-block-without-tail-expression.rs +++ b/src/test/ui/type/binding-assigned-block-without-tail-expression.rs @@ -1,3 +1,4 @@ +struct S; fn main() { let x = { println!("foo"); @@ -7,10 +8,15 @@ fn main() { let z = { "hi"; }; + let s = { + S; + }; println!("{}", x); //~ ERROR E0277 println!("{}", y); //~ ERROR E0277 println!("{}", z); //~ ERROR E0277 + println!("{}", s); //~ ERROR E0277 let _: i32 = x; //~ ERROR E0308 let _: i32 = y; //~ ERROR E0308 let _: i32 = z; //~ ERROR E0308 + let _: i32 = s; //~ ERROR E0308 } diff --git a/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr index 46300104b05..646c632517a 100644 --- a/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr +++ b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr @@ -1,5 +1,5 @@ error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/binding-assigned-block-without-tail-expression.rs:10:20 + --> $DIR/binding-assigned-block-without-tail-expression.rs:14:20 | LL | println!("{}", x); | ^ `()` cannot be formatted with the default formatter @@ -7,19 +7,29 @@ LL | println!("{}", x); = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: remove this semicolon + | +LL - 42; +LL + 42 + | error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/binding-assigned-block-without-tail-expression.rs:11:20 + --> $DIR/binding-assigned-block-without-tail-expression.rs:15:20 | LL | println!("{}", y); | ^ `()` cannot be formatted with the default formatter | +help: this empty block is missing a tail expression + --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 + | +LL | let y = {}; + | ^^ = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/binding-assigned-block-without-tail-expression.rs:12:20 + --> $DIR/binding-assigned-block-without-tail-expression.rs:16:20 | LL | println!("{}", z); | ^ `()` cannot be formatted with the default formatter @@ -27,9 +37,32 @@ LL | println!("{}", z); = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: remove this semicolon + | +LL - "hi"; +LL + "hi" + | + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/binding-assigned-block-without-tail-expression.rs:17:20 + | +LL | println!("{}", s); + | ^ `()` cannot be formatted with the default formatter + | +help: this block is missing a tail expression + --> $DIR/binding-assigned-block-without-tail-expression.rs:11:13 + | +LL | let s = { + | _____________^ +LL | | S; +LL | | }; + | |_____^ + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types - --> $DIR/binding-assigned-block-without-tail-expression.rs:13:18 + --> $DIR/binding-assigned-block-without-tail-expression.rs:18:18 | LL | let _: i32 = x; | --- ^ expected `i32`, found `()` @@ -43,7 +76,7 @@ LL + 42 | error[E0308]: mismatched types - --> $DIR/binding-assigned-block-without-tail-expression.rs:14:18 + --> $DIR/binding-assigned-block-without-tail-expression.rs:19:18 | LL | let _: i32 = y; | --- ^ expected `i32`, found `()` @@ -51,13 +84,13 @@ LL | let _: i32 = y; | expected due to this | help: this empty block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:6:13 + --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 | LL | let y = {}; | ^^ error[E0308]: mismatched types - --> $DIR/binding-assigned-block-without-tail-expression.rs:15:18 + --> $DIR/binding-assigned-block-without-tail-expression.rs:20:18 | LL | let _: i32 = z; | --- ^ expected `i32`, found `()` @@ -65,7 +98,7 @@ LL | let _: i32 = z; | expected due to this | help: this block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 + --> $DIR/binding-assigned-block-without-tail-expression.rs:8:13 | LL | let z = { | _____________^ @@ -73,7 +106,24 @@ LL | | "hi"; LL | | }; | |_____^ -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/binding-assigned-block-without-tail-expression.rs:21:18 + | +LL | let _: i32 = s; + | --- ^ expected `i32`, found `()` + | | + | expected due to this + | +help: this block is missing a tail expression + --> $DIR/binding-assigned-block-without-tail-expression.rs:11:13 + | +LL | let s = { + | _____________^ +LL | | S; +LL | | }; + | |_____^ + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From a9d093bd6b88e0f129cfd9d063337940dd8823b8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 6 Jan 2023 00:28:39 +0000 Subject: Report WF error for new solver too --- compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 4 ++-- src/test/ui/chalkify/recursive_where_clause_on_type.rs | 4 ++-- src/test/ui/chalkify/recursive_where_clause_on_type.stderr | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 6996ddd8729..571067cc221 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1168,7 +1168,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::WellFormed(ty) => { - if self.tcx.sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk { + if self.tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Classic { // WF predicates cannot themselves make // errors. They can only block due to // ambiguity; otherwise, they always @@ -1180,7 +1180,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // which bounds actually failed to hold. self.tcx.sess.struct_span_err( span, - &format!("the type `{}` is not well-formed (chalk)", ty), + &format!("the type `{}` is not well-formed", ty), ) } } diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.rs b/src/test/ui/chalkify/recursive_where_clause_on_type.rs index 5855f000c7b..c2c8aa6aabe 100644 --- a/src/test/ui/chalkify/recursive_where_clause_on_type.rs +++ b/src/test/ui/chalkify/recursive_where_clause_on_type.rs @@ -25,6 +25,6 @@ fn foo() { fn main() { // For some reason, the error is duplicated... - foo::() //~ ERROR the type `S` is not well-formed (chalk) - //~^ ERROR the type `S` is not well-formed (chalk) + foo::() //~ ERROR the type `S` is not well-formed + //~^ ERROR the type `S` is not well-formed } diff --git a/src/test/ui/chalkify/recursive_where_clause_on_type.stderr b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr index fddd5895927..cead5adeaaa 100644 --- a/src/test/ui/chalkify/recursive_where_clause_on_type.stderr +++ b/src/test/ui/chalkify/recursive_where_clause_on_type.stderr @@ -1,10 +1,10 @@ -error: the type `S` is not well-formed (chalk) +error: the type `S` is not well-formed --> $DIR/recursive_where_clause_on_type.rs:28:11 | LL | foo::() | ^ -error: the type `S` is not well-formed (chalk) +error: the type `S` is not well-formed --> $DIR/recursive_where_clause_on_type.rs:28:5 | LL | foo::() -- cgit 1.4.1-3-g733a5 From 031e0854509759ccf7dbc697bfd5d958adac83f7 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 6 Jan 2023 02:49:15 +0000 Subject: Tweak output --- compiler/rustc_hir_typeck/src/_match.rs | 6 +- compiler/rustc_hir_typeck/src/demand.rs | 6 +- .../src/traits/error_reporting/suggestions.rs | 8 +- ...g-assigned-block-without-tail-expression.stderr | 90 +++++++++------------- 4 files changed, 44 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index b47a5cf993b..b6f19d3cc68 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -224,14 +224,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut ret_span: MultiSpan = semi_span.into(); ret_span.push_span_label( expr.span, - "this could be implicitly returned but it is a statement, not a \ - tail expression", + "this could be implicitly returned but it is a statement, not a tail expression", ); ret_span.push_span_label(ret, "the `match` arms can conform to this return type"); ret_span.push_span_label( semi_span, - "the `match` is a statement because of this semicolon, consider \ - removing it", + "the `match` is a statement because of this semicolon, consider removing it", ); diag.span_note(ret_span, "you might have meant to return the `match` expression"); diag.tool_only_span_suggestion( diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index a9e6b141170..bbe15eb589d 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1699,20 +1699,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } let [.., stmt] = block.stmts else { - err.span_help(block.span, "this empty block is missing a tail expression"); + err.span_label(block.span, "this empty block is missing a tail expression"); return; }; let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else { return; }; if self.can_eq(self.param_env, expected_ty, ty).is_ok() { - err.span_suggestion_verbose( + err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", "", Applicability::MachineApplicable, ); } else { - err.span_help(block.span, "this block is missing a tail expression"); + err.span_label(block.span, "this block is missing a tail expression"); } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index ad2711209e2..d0c2359f06f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1077,12 +1077,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { return; } let [.., stmt] = block.stmts else { - err.span_help(block.span, "this empty block is missing a tail expression"); + err.span_label(block.span, "this empty block is missing a tail expression"); return; }; let hir::StmtKind::Semi(tail_expr) = stmt.kind else { return; }; let Some(ty) = typeck.expr_ty_opt(tail_expr) else { - err.span_help(block.span, "this block is missing a tail expression"); + err.span_label(block.span, "this block is missing a tail expression"); return; }; let ty = self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(ty)); @@ -1091,14 +1091,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let new_obligation = self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self); if self.predicate_must_hold_modulo_regions(&new_obligation) { - err.span_suggestion_verbose( + err.span_suggestion_short( stmt.span.with_lo(tail_expr.span.hi()), "remove this semicolon", "", Applicability::MachineApplicable, ); } else { - err.span_help(block.span, "this block is missing a tail expression"); + err.span_label(block.span, "this block is missing a tail expression"); } } diff --git a/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr index 646c632517a..3e96d7f317b 100644 --- a/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr +++ b/src/test/ui/type/binding-assigned-block-without-tail-expression.stderr @@ -1,29 +1,25 @@ error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:14:20 | +LL | 42; + | - help: remove this semicolon +... LL | println!("{}", x); | ^ `()` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -help: remove this semicolon - | -LL - 42; -LL + 42 - | error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:15:20 | +LL | let y = {}; + | -- this empty block is missing a tail expression +... LL | println!("{}", y); | ^ `()` cannot be formatted with the default formatter | -help: this empty block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 - | -LL | let y = {}; - | ^^ = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -31,32 +27,28 @@ LL | let y = {}; error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:16:20 | +LL | "hi"; + | - help: remove this semicolon +... LL | println!("{}", z); | ^ `()` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -help: remove this semicolon - | -LL - "hi"; -LL + "hi" - | error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:17:20 | -LL | println!("{}", s); - | ^ `()` cannot be formatted with the default formatter - | -help: this block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:11:13 - | LL | let s = { - | _____________^ + | _____________- LL | | S; LL | | }; - | |_____^ + | |_____- this block is missing a tail expression +... +LL | println!("{}", s); + | ^ `()` cannot be formatted with the default formatter + | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -64,64 +56,52 @@ LL | | }; error[E0308]: mismatched types --> $DIR/binding-assigned-block-without-tail-expression.rs:18:18 | +LL | 42; + | - help: remove this semicolon +... LL | let _: i32 = x; | --- ^ expected `i32`, found `()` | | | expected due to this - | -help: remove this semicolon - | -LL - 42; -LL + 42 - | error[E0308]: mismatched types --> $DIR/binding-assigned-block-without-tail-expression.rs:19:18 | +LL | let y = {}; + | -- this empty block is missing a tail expression +... LL | let _: i32 = y; | --- ^ expected `i32`, found `()` | | | expected due to this - | -help: this empty block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:7:13 - | -LL | let y = {}; - | ^^ error[E0308]: mismatched types --> $DIR/binding-assigned-block-without-tail-expression.rs:20:18 | -LL | let _: i32 = z; - | --- ^ expected `i32`, found `()` - | | - | expected due to this - | -help: this block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:8:13 - | LL | let z = { - | _____________^ + | _____________- LL | | "hi"; LL | | }; - | |_____^ + | |_____- this block is missing a tail expression +... +LL | let _: i32 = z; + | --- ^ expected `i32`, found `()` + | | + | expected due to this error[E0308]: mismatched types --> $DIR/binding-assigned-block-without-tail-expression.rs:21:18 | -LL | let _: i32 = s; - | --- ^ expected `i32`, found `()` - | | - | expected due to this - | -help: this block is missing a tail expression - --> $DIR/binding-assigned-block-without-tail-expression.rs:11:13 - | LL | let s = { - | _____________^ + | _____________- LL | | S; LL | | }; - | |_____^ + | |_____- this block is missing a tail expression +... +LL | let _: i32 = s; + | --- ^ expected `i32`, found `()` + | | + | expected due to this error: aborting due to 8 previous errors -- cgit 1.4.1-3-g733a5 From 523fe7a121e80b5959bfa6203268a46e9d9e7dd4 Mon Sep 17 00:00:00 2001 From: yanchen4791 Date: Fri, 16 Dec 2022 14:47:24 -0800 Subject: Suggests adding named lifetime when the return contains value borrowed from more than one lifetimes of the function's inputs --- .../src/diagnostics/region_errors.rs | 13 +++- .../rustc_infer/src/infer/error_reporting/mod.rs | 1 + .../nice_region_error/static_impl_trait.rs | 77 ++++++++++++++++++++-- .../impl-trait/static-return-lifetime-infered.rs | 2 - .../static-return-lifetime-infered.stderr | 32 +-------- src/test/ui/lifetimes/issue-105227.fixed | 26 ++++++++ src/test/ui/lifetimes/issue-105227.rs | 26 ++++++++ src/test/ui/lifetimes/issue-105227.stderr | 47 +++++++++++++ 8 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 src/test/ui/lifetimes/issue-105227.fixed create mode 100644 src/test/ui/lifetimes/issue-105227.rs create mode 100644 src/test/ui/lifetimes/issue-105227.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 567a9814fcc..cc33ef14756 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -192,6 +192,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // buffered in the `MirBorrowckCtxt`. let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); + let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> = + None; for nll_error in nll_errors.into_iter() { match nll_error { @@ -234,13 +236,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty); let named_key = self.regioncx.name_regions(self.infcx.tcx, key); let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region); - self.buffer_error(unexpected_hidden_region_diagnostic( + let mut diag = unexpected_hidden_region_diagnostic( self.infcx.tcx, span, named_ty, named_region, named_key, - )); + ); + if last_unexpected_hidden_region != Some((span, named_ty, named_key)) { + self.buffer_error(diag); + last_unexpected_hidden_region = Some((span, named_ty, named_key)); + } else { + diag.delay_as_bug(); + } } RegionErrorKind::BoundUniversalRegionError { @@ -730,6 +738,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some(arg), captures, Some((param.param_ty_span, param.param_ty.to_string())), + self.infcx.tcx.is_suitable_region(f).map(|r| r.def_id), ); } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 7222eb77682..0644c7ada10 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -303,6 +303,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( None, format!("captures `{}`", hidden_region), None, + Some(reg_info.def_id), ) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index d9cdfa9dd4f..94662780c36 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -8,13 +8,17 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, Visitor}; -use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; +use rustc_hir::{ + self as hir, GenericBound, GenericParamKind, Item, ItemKind, Lifetime, LifetimeName, Node, + TyKind, +}; use rustc_middle::ty::{ self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, }; use rustc_span::symbol::Ident; use rustc_span::Span; +use rustc_span::def_id::LocalDefId; use std::ops::ControlFlow; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { @@ -268,6 +272,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { Some(arg), captures, Some((param.param_ty_span, param.param_ty.to_string())), + Some(anon_reg_sup.def_id), ); let reported = err.emit(); @@ -283,6 +288,7 @@ pub fn suggest_new_region_bound( arg: Option, captures: String, param: Option<(Span, String)>, + scope_def_id: Option, ) { debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns); // FIXME: account for the need of parens in `&(dyn Trait + '_)` @@ -340,12 +346,69 @@ pub fn suggest_new_region_bound( _ => false, }) { } else { - err.span_suggestion_verbose( - fn_return.span.shrink_to_hi(), - &format!("{declare} `{ty}` {captures}, {explicit}",), - &plus_lt, - Applicability::MaybeIncorrect, - ); + // get a lifetime name of existing named lifetimes if any + let existing_lt_name = if let Some(id) = scope_def_id + && let Some(generics) = tcx.hir().get_generics(id) + && let named_lifetimes = generics + .params + .iter() + .filter(|p| matches!(p.kind, GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit })) + .map(|p| { if let hir::ParamName::Plain(name) = p.name {Some(name.to_string())} else {None}}) + .filter(|n| ! matches!(n, None)) + .collect::>() + && named_lifetimes.len() > 0 { + named_lifetimes[0].clone() + } else { + None + }; + let name = if let Some(name) = &existing_lt_name { + format!("{}", name) + } else { + format!("'a") + }; + // if there are more than one elided lifetimes in inputs, the explicit `'_` lifetime cannot be used. + // introducing a new lifetime `'a` or making use of one from existing named lifetimes if any + if let Some(id) = scope_def_id + && let Some(generics) = tcx.hir().get_generics(id) + && let mut spans_suggs = generics + .params + .iter() + .filter(|p| p.is_elided_lifetime()) + .map(|p| + if p.span.hi() - p.span.lo() == rustc_span::BytePos(1) { // Ampersand (elided without '_) + (p.span.shrink_to_hi(),format!("{name} ")) + } else { // Underscore (elided with '_) + (p.span, format!("{name}")) + } + ) + .collect::>() + && spans_suggs.len() > 1 + { + let use_lt = + if existing_lt_name == None { + spans_suggs.push((generics.span.shrink_to_hi(), format!("<{name}>"))); + format!("you can introduce a named lifetime parameter `{name}`") + } else { + // make use the existing named lifetime + format!("you can use the named lifetime parameter `{name}`") + }; + spans_suggs + .push((fn_return.span.shrink_to_hi(), format!(" + {name} "))); + err.multipart_suggestion_verbose( + &format!( + "{declare} `{ty}` {captures}, {use_lt}", + ), + spans_suggs, + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_verbose( + fn_return.span.shrink_to_hi(), + &format!("{declare} `{ty}` {captures}, {explicit}",), + &plus_lt, + Applicability::MaybeIncorrect, + ); + } } } TyKind::TraitObject(_, lt, _) => { diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.rs b/src/test/ui/impl-trait/static-return-lifetime-infered.rs index f940c1949d0..36ef9ea4443 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.rs +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.rs @@ -6,12 +6,10 @@ impl A { fn iter_values_anon(&self) -> impl Iterator { self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds - //~| ERROR: captures lifetime that does not appear in bounds } fn iter_values<'a>(&'a self) -> impl Iterator { self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds - //~| ERROR: captures lifetime that does not appear in bounds } } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index b365bd88454..c451f8e37c4 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -12,36 +12,10 @@ LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ++++ error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:7:9 - | -LL | fn iter_values_anon(&self) -> impl Iterator { - | ----- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:7:27: 7:30]>` captures the anonymous lifetime defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: to declare that `impl Iterator` captures `'_`, you can add an explicit `'_` lifetime bound - | -LL | fn iter_values_anon(&self) -> impl Iterator + '_ { - | ++++ - -error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:12:9 - | -LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:30]>` captures the lifetime `'a` as defined here -LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: to declare that `impl Iterator` captures `'a`, you can add an explicit `'a` lifetime bound - | -LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { - | ++++ - -error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:12:9 + --> $DIR/static-return-lifetime-infered.rs:11:9 | LL | fn iter_values<'a>(&'a self) -> impl Iterator { - | -- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:30]>` captures the lifetime `'a` as defined here + | -- hidden type `Map, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:30]>` captures the lifetime `'a` as defined here LL | self.x.iter().map(|a| a.0) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -50,6 +24,6 @@ help: to declare that `impl Iterator` captures `'a`, you can add an LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/lifetimes/issue-105227.fixed b/src/test/ui/lifetimes/issue-105227.fixed new file mode 100644 index 00000000000..f6ed9c82e91 --- /dev/null +++ b/src/test/ui/lifetimes/issue-105227.fixed @@ -0,0 +1,26 @@ +// Regression test for issue #105227. + +// run-rustfix +#![allow(warnings)] +fn chars0<'a>(v :(&'a str, &'a str)) -> impl Iterator + 'a { +//~^ HELP to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + v.0.chars().chain(v.1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds +} + +fn chars1<'a>(v0 : &'a str, v1 : &'a str) -> impl Iterator + 'a { +//~^ HELP to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + v0.chars().chain(v1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn chars2<'b>(v0 : &'b str, v1 : &'b str, v2 : &'b str) -> +//~^ HELP to declare that `impl Iterator` captures `'_`, you can use the named lifetime parameter `'b` + (impl Iterator + 'b , &'b str) +{ + (v0.chars().chain(v1.chars()), v2) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn main() { +} diff --git a/src/test/ui/lifetimes/issue-105227.rs b/src/test/ui/lifetimes/issue-105227.rs new file mode 100644 index 00000000000..6427a50bb87 --- /dev/null +++ b/src/test/ui/lifetimes/issue-105227.rs @@ -0,0 +1,26 @@ +// Regression test for issue #105227. + +// run-rustfix +#![allow(warnings)] +fn chars0(v :(& str, &str)) -> impl Iterator { +//~^ HELP to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + v.0.chars().chain(v.1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bounds +} + +fn chars1(v0 : & str, v1 : &str) -> impl Iterator { +//~^ HELP to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + v0.chars().chain(v1.chars()) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) -> +//~^ HELP to declare that `impl Iterator` captures `'_`, you can use the named lifetime parameter `'b` + (impl Iterator, &'b str) +{ + (v0.chars().chain(v1.chars()), v2) + //~^ ERROR hidden type for `impl Iterator` captures lifetime that does not appear in bound +} + +fn main() { +} diff --git a/src/test/ui/lifetimes/issue-105227.stderr b/src/test/ui/lifetimes/issue-105227.stderr new file mode 100644 index 00000000000..d2114593735 --- /dev/null +++ b/src/test/ui/lifetimes/issue-105227.stderr @@ -0,0 +1,47 @@ +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds + --> $DIR/issue-105227.rs:7:5 + | +LL | fn chars0(v :(& str, &str)) -> impl Iterator { + | ----- hidden type `std::iter::Chain, Chars<'_>>` captures the anonymous lifetime defined here +LL | +LL | v.0.chars().chain(v.1.chars()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + | +LL | fn chars0<'a>(v :(&'a str, &'a str)) -> impl Iterator + 'a { + | ++++ ++ ++ ++++ + +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds + --> $DIR/issue-105227.rs:13:5 + | +LL | fn chars1(v0 : & str, v1 : &str) -> impl Iterator { + | ----- hidden type `std::iter::Chain, Chars<'_>>` captures the anonymous lifetime defined here +LL | +LL | v0.chars().chain(v1.chars()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Iterator` captures `'_`, you can introduce a named lifetime parameter `'a` + | +LL | fn chars1<'a>(v0 : &'a str, v1 : &'a str) -> impl Iterator + 'a { + | ++++ ++ ++ ++++ + +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds + --> $DIR/issue-105227.rs:21:5 + | +LL | fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) -> + | ---- hidden type `std::iter::Chain, Chars<'_>>` captures the anonymous lifetime defined here +... +LL | (v0.chars().chain(v1.chars()), v2) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Iterator` captures `'_`, you can use the named lifetime parameter `'b` + | +LL ~ fn chars2<'b>(v0 : &'b str, v1 : &'b str, v2 : &'b str) -> +LL | +LL ~ (impl Iterator + 'b , &'b str) + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0700`. -- cgit 1.4.1-3-g733a5 From 10dbcf063033eb842a80ff386e268f8448ccf1ed Mon Sep 17 00:00:00 2001 From: Yiming Lei Date: Thu, 5 Jan 2023 09:12:37 -0800 Subject: fix [type error] for error E0029 and E0277 check explicitly for the type references error if ty.references_error() is true change the error to be err.delay_as_bug() and prevent the error E0029 and E0277 from emitting out this fix #105946 --- compiler/rustc_hir_typeck/src/pat.rs | 3 ++ .../src/traits/error_reporting/mod.rs | 1 - .../src/traits/error_reporting/suggestions.rs | 14 +++++-- src/test/ui/typeck/issue-105946.rs | 12 ++++++ src/test/ui/typeck/issue-105946.stderr | 49 ++++++++++++++++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/typeck/issue-105946.rs create mode 100644 src/test/ui/typeck/issue-105946.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 28e959b7c6a..1dff671b8c6 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -553,6 +553,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (lhs, Some((true, rhs_ty, rhs_sp))) => one_side_err(rhs_sp, rhs_ty, lhs), _ => span_bug!(span, "Impossible, verified above."), } + if (lhs, rhs).references_error() { + err.downgrade_to_delayed_bug(); + } if self.tcx.sess.teach(&err.get_code().unwrap()) { err.note( "In a match expression, only numbers and characters can be matched \ diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 8a08c7533aa..8ec14526d15 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1387,7 +1387,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.note_obligation_cause(&mut err, &obligation); self.point_at_returns_when_relevant(&mut err, &obligation); - err.emit(); } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 7c21a1047bc..83e3486540a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -248,7 +248,7 @@ pub trait TypeErrCtxtExt<'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut Diagnostic, + err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, obligation: &PredicateObligation<'tcx>, ); @@ -1686,7 +1686,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn point_at_returns_when_relevant( &self, - err: &mut Diagnostic, + err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, obligation: &PredicateObligation<'tcx>, ) { match obligation.cause.code().peel_derives() { @@ -1708,7 +1708,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { for expr in &visitor.returns { if let Some(returned_ty) = typeck_results.node_type_opt(expr.hir_id) { let ty = self.resolve_vars_if_possible(returned_ty); - err.span_label(expr.span, &format!("this returned value is of type `{}`", ty)); + if ty.references_error() { + // don't print out the [type error] here + err.delay_as_bug(); + } else { + err.span_label( + expr.span, + &format!("this returned value is of type `{}`", ty), + ); + } } } } diff --git a/src/test/ui/typeck/issue-105946.rs b/src/test/ui/typeck/issue-105946.rs new file mode 100644 index 00000000000..bf01751d5f6 --- /dev/null +++ b/src/test/ui/typeck/issue-105946.rs @@ -0,0 +1,12 @@ +fn digit() -> str { + return {}; + //~^ ERROR: mismatched types [E0308] +} +fn main() { + let [_y..] = [box 1, box 2]; + //~^ ERROR: cannot find value `_y` in this scope [E0425] + //~| ERROR: `X..` patterns in slices are experimental [E0658] + //~| ERROR: box expression syntax is experimental; you can call `Box::new` instead [E0658] + //~| ERROR: box expression syntax is experimental; you can call `Box::new` instead [E0658] + //~| ERROR: pattern requires 1 element but array has 2 [E0527] +} diff --git a/src/test/ui/typeck/issue-105946.stderr b/src/test/ui/typeck/issue-105946.stderr new file mode 100644 index 00000000000..d803de4df47 --- /dev/null +++ b/src/test/ui/typeck/issue-105946.stderr @@ -0,0 +1,49 @@ +error[E0425]: cannot find value `_y` in this scope + --> $DIR/issue-105946.rs:6:10 + | +LL | let [_y..] = [box 1, box 2]; + | ^^ not found in this scope + +error[E0658]: `X..` patterns in slices are experimental + --> $DIR/issue-105946.rs:6:10 + | +LL | let [_y..] = [box 1, box 2]; + | ^^^^ + | + = note: see issue #67264 for more information + = help: add `#![feature(half_open_range_patterns_in_slices)]` to the crate attributes to enable + +error[E0658]: box expression syntax is experimental; you can call `Box::new` instead + --> $DIR/issue-105946.rs:6:19 + | +LL | let [_y..] = [box 1, box 2]; + | ^^^^^ + | + = note: see issue #49733 for more information + = help: add `#![feature(box_syntax)]` to the crate attributes to enable + +error[E0658]: box expression syntax is experimental; you can call `Box::new` instead + --> $DIR/issue-105946.rs:6:26 + | +LL | let [_y..] = [box 1, box 2]; + | ^^^^^ + | + = note: see issue #49733 for more information + = help: add `#![feature(box_syntax)]` to the crate attributes to enable + +error[E0308]: mismatched types + --> $DIR/issue-105946.rs:2:10 + | +LL | return {}; + | ^^ expected `str`, found `()` + +error[E0527]: pattern requires 1 element but array has 2 + --> $DIR/issue-105946.rs:6:9 + | +LL | let [_y..] = [box 1, box 2]; + | ^^^^^^ expected 2 elements + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0308, E0425, E0527, E0658. +For more information about an error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From 0edca66a905d4c9c7292a2f89421a07389c8ade6 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 6 Jan 2023 05:34:56 +0000 Subject: Tiny formatting fix --- compiler/rustc_parse/src/parser/expr.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1fc1ffd6cb6..9f436783ced 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1503,12 +1503,13 @@ impl<'a> Parser<'a> { prior_type_ascription: self.last_type_ascription, }); (lo.to(self.prev_token.span), ExprKind::MacCall(mac)) - } else if self.check(&token::OpenDelim(Delimiter::Brace)) && - let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) { - if qself.is_some() { - self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); - } - return expr; + } else if self.check(&token::OpenDelim(Delimiter::Brace)) + && let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) + { + if qself.is_some() { + self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); + } + return expr; } else { (path.span, ExprKind::Path(qself, path)) }; -- cgit 1.4.1-3-g733a5 From ae667be0f6017002587a28be257238655d34fa54 Mon Sep 17 00:00:00 2001 From: Gijs Burghoorn Date: Fri, 6 Jan 2023 13:20:58 +0100 Subject: Remove HTML tags around warning --- library/core/src/macros/mod.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index be13317008c..3b026bc0e0f 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1315,9 +1315,6 @@ pub(crate) mod builtin { /// Parses a file as an expression or an item according to the context. /// - ///
- ///
-    ///
     /// **Warning**: For multi-file Rust projects, the `include!` macro is probably not what you
     /// are looking for. Usually, multi-file Rust projects use
     /// [modules](https://doc.rust-lang.org/reference/items/modules.html). Multi-file projects and
@@ -1326,9 +1323,6 @@ pub(crate) mod builtin {
     /// explained in the Rust Book
     /// [here](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html).
     ///
-    /// 
- ///
- /// /// The included file is placed in the surrounding code /// [unhygienically](https://doc.rust-lang.org/reference/macros-by-example.html#hygiene). If /// the included file is parsed as an expression and variables or functions share names across -- cgit 1.4.1-3-g733a5 From 804dea9ca6a02baedb1efc639b848fa080dbf51d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 6 Jan 2023 20:55:10 +0900 Subject: use smaller spans for missing lifetime/generic args fix rustdoc ui test --- .../wrong_number_of_generic_args.rs | 20 +++++++--- src/test/rustdoc-ui/issue-105742.stderr | 44 +++++++++++----------- src/test/ui/consts/issue-103790.stderr | 2 +- .../elided-in-expr-position.stderr | 4 +- .../gat-trait-path-missing-lifetime.stderr | 4 +- .../ui/generic-associated-types/issue-71176.stderr | 2 +- .../issue-76535.base.stderr | 2 +- .../issue-76535.extended.stderr | 2 +- .../issue-78671.base.stderr | 2 +- .../issue-78671.extended.stderr | 2 +- .../issue-79422.base.stderr | 2 +- .../issue-79422.extended.stderr | 2 +- .../generic-associated-types/issue-79636-1.stderr | 2 +- .../generic-associated-types/issue-79636-2.stderr | 2 +- .../ui/generic-associated-types/issue-80433.stderr | 2 +- .../issue-81712-cyclic-traits.stderr | 2 +- .../ui/generic-associated-types/issue-81862.stderr | 2 +- .../missing_lifetime_args.stderr | 2 +- .../generic-type-less-params-with-defaults.stderr | 2 +- src/test/ui/generics/wrong-number-of-args.stderr | 12 +++--- src/test/ui/impl-trait/issues/issue-92305.stderr | 2 +- src/test/ui/issues/issue-14092.stderr | 2 +- src/test/ui/issues/issue-23024.stderr | 2 +- src/test/ui/issues/issue-86756.stderr | 2 +- .../ui/lifetimes/missing-lifetime-in-alias.stderr | 2 +- src/test/ui/tag-type-args.stderr | 2 +- src/test/ui/type/ascription/issue-34255-1.stderr | 2 +- src/test/ui/ufcs/ufcs-qpath-missing-params.stderr | 4 +- 28 files changed, 70 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 3df8f776ede..574b1e8b485 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -597,11 +597,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let span = self.path_segment.ident.span; // insert a suggestion of the form "Y<'a, 'b>" - let ident = self.path_segment.ident.name.to_ident_string(); - let sugg = format!("{}<{}>", ident, suggested_args); + let sugg = format!("<{}>", suggested_args); debug!("sugg: {:?}", sugg); - err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders); + err.span_suggestion_verbose( + span.shrink_to_hi(), + &msg, + sugg, + Applicability::HasPlaceholders, + ); } AngleBrackets::Available => { @@ -643,11 +647,15 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let span = self.path_segment.ident.span; // insert a suggestion of the form "Y" - let ident = self.path_segment.ident.name.to_ident_string(); - let sugg = format!("{}<{}>", ident, suggested_args); + let sugg = format!("<{}>", suggested_args); debug!("sugg: {:?}", sugg); - err.span_suggestion_verbose(span, &msg, sugg, Applicability::HasPlaceholders); + err.span_suggestion_verbose( + span.shrink_to_hi(), + &msg, + sugg, + Applicability::HasPlaceholders, + ); } AngleBrackets::Available => { let gen_args_span = self.gen_args.span().unwrap(); diff --git a/src/test/rustdoc-ui/issue-105742.stderr b/src/test/rustdoc-ui/issue-105742.stderr index cc101b7ff37..ffb602cf861 100644 --- a/src/test/rustdoc-ui/issue-105742.stderr +++ b/src/test/rustdoc-ui/issue-105742.stderr @@ -12,7 +12,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | ::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:13:21 @@ -28,7 +28,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | ::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:18:37 @@ -44,7 +44,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:18:37 @@ -60,7 +60,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:30 @@ -76,7 +76,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item<'a>> as SVec>::Item, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:30 @@ -92,7 +92,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:46 @@ -108,7 +108,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item> as SVec>::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:46 @@ -124,7 +124,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:5:40 @@ -140,7 +140,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:5:40 @@ -156,7 +156,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:13:21 @@ -172,7 +172,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | ::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:13:21 @@ -188,7 +188,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | ::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:18:37 @@ -204,7 +204,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:18:37 @@ -220,7 +220,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:30 @@ -236,7 +236,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item<'a>> as SVec>::Item, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:30 @@ -252,7 +252,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:46 @@ -268,7 +268,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | Output = ::Item> as SVec>::Item<'a>, - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:23:46 @@ -284,7 +284,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | Output = ::Item> as SVec>::Item, - | ~~~~~~~ + | +++ error[E0038]: the trait `SVec` cannot be made into an object --> $DIR/issue-105742.rs:5:31 @@ -329,7 +329,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | fn len(&self) -> ::Item<'_>; - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:35:38 @@ -345,7 +345,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | fn len(&self) -> ::Item; - | ~~~~~~~ + | +++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:35:38 @@ -361,7 +361,7 @@ LL | type Item<'a, T>; help: add missing lifetime argument | LL | fn len(&self) -> ::Item<'_>; - | ~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `SVec::Item` --> $DIR/issue-105742.rs:35:38 @@ -377,7 +377,7 @@ LL | type Item<'a, T>; help: add missing generic argument | LL | fn len(&self) -> ::Item; - | ~~~~~~~ + | +++ error: aborting due to 23 previous errors diff --git a/src/test/ui/consts/issue-103790.stderr b/src/test/ui/consts/issue-103790.stderr index 41b0816dc32..34d8ee281cf 100644 --- a/src/test/ui/consts/issue-103790.stderr +++ b/src/test/ui/consts/issue-103790.stderr @@ -20,7 +20,7 @@ LL | struct S; help: add missing generic argument | LL | struct S = { S }>; - | ~~~~ + | +++ error[E0391]: cycle detected when computing type of `S::S` --> $DIR/issue-103790.rs:4:32 diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr index a9996123f23..842b23bd49d 100644 --- a/src/test/ui/generic-associated-types/elided-in-expr-position.stderr +++ b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr @@ -12,7 +12,7 @@ LL | type Assoc<'a> where Self: 'a; help: add missing lifetime argument | LL | fn g(&self) -> Self::Assoc<'_>; - | ~~~~~~~~~ + | ++++ error[E0107]: missing generics for associated type `Trait::Assoc` --> $DIR/elided-in-expr-position.rs:31:26 @@ -28,7 +28,7 @@ LL | type Assoc<'a> where Self: 'a; help: add missing lifetime argument | LL | fn g(&self) -> Self::Assoc<'_> { - | ~~~~~~~~~ + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 452dfefd1e3..499221637ba 100644 --- a/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -12,7 +12,7 @@ LL | type Y<'a>; help: add missing lifetime argument | LL | fn foo<'a, T1: X = T1>>(t : T1) -> T1::Y<'a> { - | ~~~~~ + | ++++ error[E0107]: missing generics for associated type `X::Y` --> $DIR/gat-trait-path-missing-lifetime.rs:8:20 @@ -28,7 +28,7 @@ LL | type Y<'a>; help: add missing lifetime argument | LL | fn foo<'a, T1: X = T1>>(t : T1) -> T1::Y<'a> { - | ~~~~~ + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-71176.stderr b/src/test/ui/generic-associated-types/issue-71176.stderr index 386c97161c8..4b4fe43e8c4 100644 --- a/src/test/ui/generic-associated-types/issue-71176.stderr +++ b/src/test/ui/generic-associated-types/issue-71176.stderr @@ -12,7 +12,7 @@ LL | type A<'a>; help: add missing lifetime argument | LL | inner: Box = B>>, - | ~~~~~ + | ++++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-76535.base.stderr b/src/test/ui/generic-associated-types/issue-76535.base.stderr index 088f69b09f7..52c6e3eec60 100644 --- a/src/test/ui/generic-associated-types/issue-76535.base.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.base.stderr @@ -12,7 +12,7 @@ LL | type SubType<'a>: SubTrait where Self: 'a; help: add missing lifetime argument | LL | let sub: Box = SubStruct>> = Box::new(SuperStruct::new(0)); - | ~~~~~~~~~~~ + | ++++ error[E0038]: the trait `SuperTrait` cannot be made into an object --> $DIR/issue-76535.rs:39:14 diff --git a/src/test/ui/generic-associated-types/issue-76535.extended.stderr b/src/test/ui/generic-associated-types/issue-76535.extended.stderr index e79f0a73f5b..369b86d2928 100644 --- a/src/test/ui/generic-associated-types/issue-76535.extended.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.extended.stderr @@ -12,7 +12,7 @@ LL | type SubType<'a>: SubTrait where Self: 'a; help: add missing lifetime argument | LL | let sub: Box = SubStruct>> = Box::new(SuperStruct::new(0)); - | ~~~~~~~~~~~ + | ++++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-78671.base.stderr b/src/test/ui/generic-associated-types/issue-78671.base.stderr index 514f8d45a15..bad8c1c9dba 100644 --- a/src/test/ui/generic-associated-types/issue-78671.base.stderr +++ b/src/test/ui/generic-associated-types/issue-78671.base.stderr @@ -12,7 +12,7 @@ LL | type Member; help: add missing generic argument | LL | Box::new(Family) as &dyn CollectionFamily=usize> - | ~~~~~~~~~ + | +++ error[E0038]: the trait `CollectionFamily` cannot be made into an object --> $DIR/issue-78671.rs:10:25 diff --git a/src/test/ui/generic-associated-types/issue-78671.extended.stderr b/src/test/ui/generic-associated-types/issue-78671.extended.stderr index 6fa09a4c7e5..1d8a3d410f8 100644 --- a/src/test/ui/generic-associated-types/issue-78671.extended.stderr +++ b/src/test/ui/generic-associated-types/issue-78671.extended.stderr @@ -12,7 +12,7 @@ LL | type Member; help: add missing generic argument | LL | Box::new(Family) as &dyn CollectionFamily=usize> - | ~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-79422.base.stderr b/src/test/ui/generic-associated-types/issue-79422.base.stderr index 3c1a29d48b2..f1de77bc3c0 100644 --- a/src/test/ui/generic-associated-types/issue-79422.base.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.base.stderr @@ -12,7 +12,7 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; help: add missing lifetime argument | LL | as Box = dyn RefCont<'_, u8>>>; - | ~~~~~~~~~~~~ + | ++++ error[E0038]: the trait `MapLike` cannot be made into an object --> $DIR/issue-79422.rs:47:12 diff --git a/src/test/ui/generic-associated-types/issue-79422.extended.stderr b/src/test/ui/generic-associated-types/issue-79422.extended.stderr index 58c921bf09f..d79de0ca627 100644 --- a/src/test/ui/generic-associated-types/issue-79422.extended.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.extended.stderr @@ -12,7 +12,7 @@ LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; help: add missing lifetime argument | LL | as Box = dyn RefCont<'_, u8>>>; - | ~~~~~~~~~~~~ + | ++++ error[E0271]: type mismatch resolving ` as MapLike>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)` --> $DIR/issue-79422.rs:44:13 diff --git a/src/test/ui/generic-associated-types/issue-79636-1.stderr b/src/test/ui/generic-associated-types/issue-79636-1.stderr index 155477048ca..6e0d2ff4ded 100644 --- a/src/test/ui/generic-associated-types/issue-79636-1.stderr +++ b/src/test/ui/generic-associated-types/issue-79636-1.stderr @@ -12,7 +12,7 @@ LL | type Wrapped; help: add missing generic argument | LL | MInner: Monad = MOuter::Wrapped>, - | ~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-79636-2.stderr b/src/test/ui/generic-associated-types/issue-79636-2.stderr index 6a36bfc37f2..16287323995 100644 --- a/src/test/ui/generic-associated-types/issue-79636-2.stderr +++ b/src/test/ui/generic-associated-types/issue-79636-2.stderr @@ -12,7 +12,7 @@ LL | type Wrapped: SomeTrait; help: add missing generic argument | LL | W: SomeTrait = W>, - | ~~~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-80433.stderr b/src/test/ui/generic-associated-types/issue-80433.stderr index 20a407dd412..4f4f96a4b92 100644 --- a/src/test/ui/generic-associated-types/issue-80433.stderr +++ b/src/test/ui/generic-associated-types/issue-80433.stderr @@ -12,7 +12,7 @@ LL | type Output<'a>; help: add missing lifetime argument | LL | fn test_simpler<'a>(dst: &'a mut impl TestMut = &'a mut f32>) - | ~~~~~~~~~~ + | ++++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr index c8961e28ede..e0fc225f463 100644 --- a/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr +++ b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr @@ -12,7 +12,7 @@ LL | type DType: D; help: add missing generic argument | LL | type CType: C = Self>; - | ~~~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-81862.stderr b/src/test/ui/generic-associated-types/issue-81862.stderr index 9e21c567c73..df30be65ec5 100644 --- a/src/test/ui/generic-associated-types/issue-81862.stderr +++ b/src/test/ui/generic-associated-types/issue-81862.stderr @@ -12,7 +12,7 @@ LL | type Item<'a>; help: add missing lifetime argument | LL | fn next(&mut self) -> Option>; - | ~~~~~~~~ + | ++++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr index 752587c25a7..8f74b12c008 100644 --- a/src/test/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr @@ -12,7 +12,7 @@ LL | type Y<'a, 'b>; help: add missing lifetime arguments | LL | fn foo<'c, 'd>(_arg: Box = (&'c u32, &'d u32)>>) {} - | ~~~~~~~~~ + | ++++++++ error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied --> $DIR/missing_lifetime_args.rs:14:26 diff --git a/src/test/ui/generics/generic-type-less-params-with-defaults.stderr b/src/test/ui/generics/generic-type-less-params-with-defaults.stderr index e45a0d9ca77..6450bbd8b43 100644 --- a/src/test/ui/generics/generic-type-less-params-with-defaults.stderr +++ b/src/test/ui/generics/generic-type-less-params-with-defaults.stderr @@ -12,7 +12,7 @@ LL | struct Vec( help: add missing generic argument | LL | let _: Vec; - | ~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/generics/wrong-number-of-args.stderr b/src/test/ui/generics/wrong-number-of-args.stderr index b48966a1a1e..75e33f680ea 100644 --- a/src/test/ui/generics/wrong-number-of-args.stderr +++ b/src/test/ui/generics/wrong-number-of-args.stderr @@ -251,7 +251,7 @@ LL | struct Ty; help: add missing generic arguments | LL | type A = Ty; - | ~~~~~~~~ + | ++++++ error[E0107]: this struct takes 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:30:14 @@ -315,7 +315,7 @@ LL | struct Ty<'a, T>; help: add missing generic argument | LL | type A = Ty; - | ~~~~~ + | +++ error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:54:14 @@ -391,7 +391,7 @@ LL | struct Ty; help: add missing generic arguments | LL | type A = Ty; - | ~~~~~~~~ + | ++++++ error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:84:14 @@ -483,7 +483,7 @@ LL | trait GenericType { help: add missing generic argument | LL | type D = Box>; - | ~~~~~~~~~~~~~~ + | +++ error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:133:22 @@ -892,7 +892,7 @@ LL | type A = HashMap; help: add missing generic arguments | LL | type A = HashMap; - | ~~~~~~~~~~~~~ + | ++++++ error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:314:18 @@ -954,7 +954,7 @@ LL | type A = Result; help: add missing generic arguments | LL | type A = Result; - | ~~~~~~~~~~~~ + | ++++++ error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:338:18 diff --git a/src/test/ui/impl-trait/issues/issue-92305.stderr b/src/test/ui/impl-trait/issues/issue-92305.stderr index f09c14d3df1..86d7184da7a 100644 --- a/src/test/ui/impl-trait/issues/issue-92305.stderr +++ b/src/test/ui/impl-trait/issues/issue-92305.stderr @@ -7,7 +7,7 @@ LL | fn f(data: &[T]) -> impl Iterator { help: add missing generic argument | LL | fn f(data: &[T]) -> impl Iterator> { - | ~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-14092.stderr b/src/test/ui/issues/issue-14092.stderr index 132e2b101a5..3a43627e691 100644 --- a/src/test/ui/issues/issue-14092.stderr +++ b/src/test/ui/issues/issue-14092.stderr @@ -7,7 +7,7 @@ LL | fn fn1(0: Box) {} help: add missing generic argument | LL | fn fn1(0: Box) {} - | ~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 014eb2897b4..2c325ffccee 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -16,7 +16,7 @@ LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); help: add missing generic argument | LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3)); - | ~~~~~~~~ + | ++++++ error[E0191]: the value of the associated type `Output` (from trait `FnOnce`) must be specified --> $DIR/issue-23024.rs:8:39 diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr index 693cfecedc4..6c5917bdf6e 100644 --- a/src/test/ui/issues/issue-86756.stderr +++ b/src/test/ui/issues/issue-86756.stderr @@ -42,7 +42,7 @@ LL | trait Foo {} help: add missing generic argument | LL | eq::> - | ~~~~~~ + | +++ error: aborting due to 3 previous errors; 1 warning emitted diff --git a/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr b/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr index 428b8f14b6f..20159e14407 100644 --- a/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr +++ b/src/test/ui/lifetimes/missing-lifetime-in-alias.stderr @@ -39,7 +39,7 @@ LL | type Bar<'b> help: add missing lifetime argument | LL | type C<'a, 'b> = as Trait>::Bar<'a>; - | ~~~~~~~ + | ++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/tag-type-args.stderr b/src/test/ui/tag-type-args.stderr index 107af76413d..5b54880a685 100644 --- a/src/test/ui/tag-type-args.stderr +++ b/src/test/ui/tag-type-args.stderr @@ -12,7 +12,7 @@ LL | enum Quux { Bar } help: add missing generic argument | LL | fn foo(c: Quux) { assert!((false)); } - | ~~~~~~~ + | +++ error: aborting due to previous error diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr index fd43e1114c8..fafff19f8f6 100644 --- a/src/test/ui/type/ascription/issue-34255-1.stderr +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -28,7 +28,7 @@ LL | input_cells: Vec::new() help: add missing generic argument | LL | input_cells: Vec::new() - | ~~~~~~ + | +++ error: aborting due to 3 previous errors diff --git a/src/test/ui/ufcs/ufcs-qpath-missing-params.stderr b/src/test/ui/ufcs/ufcs-qpath-missing-params.stderr index a832964d220..d0ec47d6132 100644 --- a/src/test/ui/ufcs/ufcs-qpath-missing-params.stderr +++ b/src/test/ui/ufcs/ufcs-qpath-missing-params.stderr @@ -12,7 +12,7 @@ LL | pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { help: add missing generic argument | LL | >::into_cow("foo".to_string()); - | ~~~~~~~~~~ + | +++ error[E0107]: missing generics for trait `IntoCow` --> $DIR/ufcs-qpath-missing-params.rs:17:16 @@ -28,7 +28,7 @@ LL | pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { help: add missing generic argument | LL | >::into_cow::("foo".to_string()); - | ~~~~~~~~~~ + | +++ error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/ufcs-qpath-missing-params.rs:17:26 -- cgit 1.4.1-3-g733a5 From f67aa04114f348c07f8a83cfa1b126aebbe8c636 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 6 Jan 2023 15:18:36 +0100 Subject: Update browser-ui-test version --- src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 475434e5aef..c39e9c5fbc9 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.13.4 \ No newline at end of file +0.14.1 \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 4a68f7ecae0bc69915b33018aac4df199dba9885 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 4 Jan 2023 20:56:46 +0000 Subject: Correctly render sidebar for relative module paths --- src/librustdoc/html/render/context.rs | 22 +++++++++-- src/librustdoc/html/render/write_shared.rs | 62 ++++++++++++++++++++---------- src/librustdoc/html/sources.rs | 60 +++++++++++++++++++++-------- 3 files changed, 103 insertions(+), 41 deletions(-) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index d4d3e4f6ea7..c8899ee62b5 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -309,7 +309,7 @@ impl<'tcx> Context<'tcx> { pub(crate) fn href_from_span(&self, span: clean::Span, with_lines: bool) -> Option { let mut root = self.root_path(); - let mut path = String::new(); + let mut path: String; let cnum = span.cnum(self.sess()); // We can safely ignore synthetic `SourceFile`s. @@ -340,10 +340,24 @@ impl<'tcx> Context<'tcx> { ExternalLocation::Unknown => return None, }; - sources::clean_path(&src_root, file, false, |component| { - path.push_str(&component.to_string_lossy()); + let href = RefCell::new(PathBuf::new()); + sources::clean_path( + &src_root, + file, + |component| { + href.borrow_mut().push(component); + }, + || { + href.borrow_mut().pop(); + }, + ); + + path = href.into_inner().to_string_lossy().to_string(); + + if let Some(c) = path.as_bytes().last() && *c != b'/' { path.push('/'); - }); + } + let mut fname = file.file_name().expect("source has no filename").to_os_string(); fname.push(".html"); path.push_str(&fname.to_string_lossy()); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index eaf149a4300..3ea4c4bea88 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -1,8 +1,9 @@ +use std::cell::RefCell; use std::fs::{self, File}; use std::io::prelude::*; use std::io::{self, BufReader}; use std::path::{Component, Path}; -use std::rc::Rc; +use std::rc::{Rc, Weak}; use itertools::Itertools; use rustc_data_structures::flock; @@ -184,23 +185,26 @@ pub(super) fn write_shared( use std::ffi::OsString; - #[derive(Debug)] + #[derive(Debug, Default)] struct Hierarchy { + parent: Weak, elem: OsString, - children: FxHashMap, - elems: FxHashSet, + children: RefCell>>, + elems: RefCell>, } impl Hierarchy { - fn new(elem: OsString) -> Hierarchy { - Hierarchy { elem, children: FxHashMap::default(), elems: FxHashSet::default() } + fn with_parent(elem: OsString, parent: &Rc) -> Self { + Self { elem, parent: Rc::downgrade(parent), ..Self::default() } } fn to_json_string(&self) -> String { - let mut subs: Vec<&Hierarchy> = self.children.values().collect(); + let borrow = self.children.borrow(); + let mut subs: Vec<_> = borrow.values().collect(); subs.sort_unstable_by(|a, b| a.elem.cmp(&b.elem)); let mut files = self .elems + .borrow() .iter() .map(|s| format!("\"{}\"", s.to_str().expect("invalid osstring conversion"))) .collect::>(); @@ -220,36 +224,52 @@ pub(super) fn write_shared( files = files ) } - } - if cx.include_sources { - let mut hierarchy = Hierarchy::new(OsString::new()); - for source in cx - .shared - .local_sources - .iter() - .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root).ok()) - { - let mut h = &mut hierarchy; - let mut elems = source + fn add_path(self: &Rc, path: &Path) { + let mut h = Rc::clone(&self); + let mut elems = path .components() .filter_map(|s| match s { Component::Normal(s) => Some(s.to_owned()), + Component::ParentDir => Some(OsString::from("..")), _ => None, }) .peekable(); loop { let cur_elem = elems.next().expect("empty file path"); + if cur_elem == ".." { + if let Some(parent) = h.parent.upgrade() { + h = parent; + } + continue; + } if elems.peek().is_none() { - h.elems.insert(cur_elem); + h.elems.borrow_mut().insert(cur_elem); break; } else { - let e = cur_elem.clone(); - h = h.children.entry(cur_elem.clone()).or_insert_with(|| Hierarchy::new(e)); + let entry = Rc::clone( + h.children + .borrow_mut() + .entry(cur_elem.clone()) + .or_insert_with(|| Rc::new(Self::with_parent(cur_elem, &h))), + ); + h = entry; } } } + } + if cx.include_sources { + let hierarchy = Rc::new(Hierarchy::default()); + for source in cx + .shared + .local_sources + .iter() + .filter_map(|p| p.0.strip_prefix(&cx.shared.src_root).ok()) + { + hierarchy.add_path(source); + } + let hierarchy = Rc::try_unwrap(hierarchy).unwrap(); let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); let make_sources = || { let (mut all_sources, _krates) = diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index e639fadeb96..799c497d137 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_span::source_map::FileName; +use std::cell::RefCell; use std::ffi::OsStr; use std::fs; use std::path::{Component, Path, PathBuf}; @@ -72,12 +73,22 @@ impl LocalSourcesCollector<'_, '_> { return; } - let mut href = String::new(); - clean_path(self.src_root, &p, false, |component| { - href.push_str(&component.to_string_lossy()); - href.push('/'); - }); + let href = RefCell::new(PathBuf::new()); + clean_path( + &self.src_root, + &p, + |component| { + href.borrow_mut().push(component); + }, + || { + href.borrow_mut().pop(); + }, + ); + let mut href = href.into_inner().to_string_lossy().to_string(); + if let Some(c) = href.as_bytes().last() && *c != b'/' { + href.push('/'); + } let mut src_fname = p.file_name().expect("source has no filename").to_os_string(); src_fname.push(".html"); href.push_str(&src_fname.to_string_lossy()); @@ -180,13 +191,28 @@ impl SourceCollector<'_, '_> { let shared = Rc::clone(&self.cx.shared); // Create the intermediate directories - let mut cur = self.dst.clone(); - let mut root_path = String::from("../../"); - clean_path(&shared.src_root, &p, false, |component| { - cur.push(component); - root_path.push_str("../"); - }); + let cur = RefCell::new(PathBuf::new()); + let root_path = RefCell::new(PathBuf::new()); + + clean_path( + &shared.src_root, + &p, + |component| { + cur.borrow_mut().push(component); + root_path.borrow_mut().push(".."); + }, + || { + cur.borrow_mut().pop(); + root_path.borrow_mut().pop(); + }, + ); + let root_path = PathBuf::from("../../").join(root_path.into_inner()); + let mut root_path = root_path.to_string_lossy(); + if let Some(c) = root_path.as_bytes().last() && *c != b'/' { + root_path += "/"; + } + let mut cur = self.dst.join(cur.into_inner()); shared.ensure_dir(&cur)?; let src_fname = p.file_name().expect("source has no filename").to_os_string(); @@ -232,11 +258,13 @@ impl SourceCollector<'_, '_> { /// Takes a path to a source file and cleans the path to it. This canonicalizes /// things like ".." to components which preserve the "top down" hierarchy of a /// static HTML tree. Each component in the cleaned path will be passed as an -/// argument to `f`. The very last component of the path (ie the file name) will -/// be passed to `f` if `keep_filename` is true, and ignored otherwise. -pub(crate) fn clean_path(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) +/// argument to `f`. The very last component of the path (ie the file name) is ignored. +/// If a `..` is encountered, the `parent` closure will be called to allow the callee to +/// handle it. +pub(crate) fn clean_path(src_root: &Path, p: &Path, mut f: F, mut parent: P) where F: FnMut(&OsStr), + P: FnMut(), { // make it relative, if possible let p = p.strip_prefix(src_root).unwrap_or(p); @@ -244,12 +272,12 @@ where let mut iter = p.components().peekable(); while let Some(c) = iter.next() { - if !keep_filename && iter.peek().is_none() { + if iter.peek().is_none() { break; } match c { - Component::ParentDir => f("up".as_ref()), + Component::ParentDir => parent(), Component::Normal(c) => f(c), _ => continue, } -- cgit 1.4.1-3-g733a5 From d5d1c5716747ded8ca9746be71e70cceeaa9f422 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 5 Jan 2023 04:17:57 +0000 Subject: Update tests --- src/test/rustdoc/src-links.rs | 5 +++++ src/test/rustdoc/src-links/fizz.rs | 1 + 2 files changed, 6 insertions(+) create mode 100644 src/test/rustdoc/src-links/fizz.rs diff --git a/src/test/rustdoc/src-links.rs b/src/test/rustdoc/src-links.rs index 353ce10243e..7a6c733d464 100644 --- a/src/test/rustdoc/src-links.rs +++ b/src/test/rustdoc/src-links.rs @@ -7,6 +7,11 @@ #[path = "src-links/mod.rs"] pub mod qux; +// @has src/foo/src-links.rs.html +// @has foo/fizz/index.html '//a/@href' '../src/foo/src-links/fizz.rs.html' +#[path = "src-links/../src-links/fizz.rs"] +pub mod fizz; + // @has foo/bar/index.html '//a/@href' '../../src/foo/src-links.rs.html' pub mod bar { diff --git a/src/test/rustdoc/src-links/fizz.rs b/src/test/rustdoc/src-links/fizz.rs new file mode 100644 index 00000000000..d2b76b1cec8 --- /dev/null +++ b/src/test/rustdoc/src-links/fizz.rs @@ -0,0 +1 @@ +pub struct Buzz; -- cgit 1.4.1-3-g733a5 From 009064f8902d89e71230af8188a3241d97477d37 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 6 Jan 2023 15:18:51 +0100 Subject: Use new block syntax for define-function in goml scripts --- src/test/rustdoc-gui/anchors.goml | 80 +++++++++---------- src/test/rustdoc-gui/code-color.goml | 12 +-- src/test/rustdoc-gui/codeblock-tooltip.goml | 86 ++++++++++---------- .../docblock-code-block-line-number.goml | 16 ++-- src/test/rustdoc-gui/docblock-table.goml | 32 ++++---- src/test/rustdoc-gui/headers-color.goml | 40 +++++----- src/test/rustdoc-gui/headings.goml | 46 +++++------ src/test/rustdoc-gui/help-page.goml | 12 +-- src/test/rustdoc-gui/highlight-colors.goml | 36 ++++----- src/test/rustdoc-gui/item-decl-colors.goml | 31 ++++---- src/test/rustdoc-gui/jump-to-def-background.goml | 12 +-- src/test/rustdoc-gui/links-color.goml | 36 ++++----- src/test/rustdoc-gui/notable-trait.goml | 32 ++++---- src/test/rustdoc-gui/run-on-hover.goml | 22 +++--- src/test/rustdoc-gui/rust-logo.goml | 30 +++---- src/test/rustdoc-gui/scrape-examples-color.goml | 30 +++---- src/test/rustdoc-gui/scrape-examples-toggle.goml | 24 +++--- src/test/rustdoc-gui/search-no-result.goml | 20 ++--- src/test/rustdoc-gui/search-result-color.goml | 91 +++++++++------------- src/test/rustdoc-gui/search-result-display.goml | 22 +++--- src/test/rustdoc-gui/search-tab.goml | 30 +++---- src/test/rustdoc-gui/sidebar-links-color.goml | 78 +++++++++---------- src/test/rustdoc-gui/sidebar-mobile.goml | 14 ++-- .../rustdoc-gui/sidebar-source-code-display.goml | 84 ++++++++++---------- src/test/rustdoc-gui/sidebar-source-code.goml | 54 ++++++------- src/test/rustdoc-gui/sidebar.goml | 54 ++++++------- src/test/rustdoc-gui/source-code-page.goml | 40 +++++----- src/test/rustdoc-gui/stab-badge.goml | 58 +++++++------- src/test/rustdoc-gui/target.goml | 12 +-- src/test/rustdoc-gui/toggle-docs.goml | 20 ++--- src/test/rustdoc-gui/unsafe-fn.goml | 10 +-- 31 files changed, 573 insertions(+), 591 deletions(-) diff --git a/src/test/rustdoc-gui/anchors.goml b/src/test/rustdoc-gui/anchors.goml index fb8e288fae8..c9b53a1a0f7 100644 --- a/src/test/rustdoc-gui/anchors.goml +++ b/src/test/rustdoc-gui/anchors.goml @@ -3,70 +3,72 @@ define-function: ( "check-colors", (theme, main_color, title_color, fqn_color, fqn_type_color, src_link_color, sidebar_link_color), - [ - ("goto", "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html"), + block { + goto: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html" // This is needed to ensure that the text color is computed. - ("show-text", true), + show-text: true // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), + reload: - ("assert-css", ("#toggle-all-docs", {"color": |main_color|})), - ("assert-css", (".fqn a:nth-of-type(1)", {"color": |fqn_color|})), - ("assert-css", (".fqn a:nth-of-type(2)", {"color": |fqn_type_color|})), - ("assert-css", ( + assert-css: ("#toggle-all-docs", {"color": |main_color|}) + assert-css: (".fqn a:nth-of-type(1)", {"color": |fqn_color|}) + assert-css: (".fqn a:nth-of-type(2)", {"color": |fqn_type_color|}) + assert-css: ( ".rightside .srclink", {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, ALL, - )), - ( - "compare-elements-css", - (".rightside .srclink", ".rightside.srclink", ["color", "text-decoration"]), - ), - ( - "compare-elements-css", - (".main-heading .srclink", ".rightside.srclink", ["color", "text-decoration"]), - ), + ) + compare-elements-css: ( + ".rightside .srclink", + ".rightside.srclink", + ["color", "text-decoration"], + ) + compare-elements-css: ( + ".main-heading .srclink", + ".rightside.srclink", + ["color", "text-decoration"], + ) - ("move-cursor-to", ".main-heading .srclink"), - ("assert-css", ( + move-cursor-to: ".main-heading .srclink" + assert-css: ( ".main-heading .srclink", {"color": |src_link_color|, "text-decoration": "underline solid " + |src_link_color|}, - )), - ("move-cursor-to", ".impl-items .rightside .srclink"), - ("assert-css", ( + ) + move-cursor-to: ".impl-items .rightside .srclink" + assert-css: ( ".impl-items .rightside .srclink", {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, - )), - ("move-cursor-to", ".impl-items .rightside.srclink"), - ("assert-css", ( + ) + move-cursor-to: ".impl-items .rightside.srclink" + assert-css: ( ".impl-items .rightside.srclink", {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, - )), + ) - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"), + goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // Since we changed page, we need to set the theme again. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), + reload: - ("assert-css", ("#top-doc-prose-title", {"color": |title_color|})), + assert-css: ("#top-doc-prose-title", {"color": |title_color|}) - ("assert-css", (".sidebar a", {"color": |sidebar_link_color|})), - ("assert-css", ("h1.fqn a", {"color": |title_color|})), + assert-css: (".sidebar a", {"color": |sidebar_link_color|}) + assert-css: ("h1.fqn a", {"color": |title_color|}) // We move the cursor over the "Implementations" title so the anchor is displayed. - ("move-cursor-to", "h2#implementations"), - ("assert-css", ("h2#implementations a.anchor", {"color": |main_color|})), + move-cursor-to: "h2#implementations" + assert-css: ("h2#implementations a.anchor", {"color": |main_color|}) // Same thing with the impl block title. - ("move-cursor-to", "#impl-HeavilyDocumentedStruct"), - ("assert-css", ("#impl-HeavilyDocumentedStruct a.anchor", {"color": |main_color|})), + move-cursor-to: "#impl-HeavilyDocumentedStruct" + assert-css: ("#impl-HeavilyDocumentedStruct a.anchor", {"color": |main_color|}) - ("assert-css", ("#title-for-struct-impl-item-doc", {"margin-left": "0px"})), - ], + assert-css: ("#title-for-struct-impl-item-doc", {"margin-left": "0px"}) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/code-color.goml b/src/test/rustdoc-gui/code-color.goml index 118f04ad6dc..cb550a4573a 100644 --- a/src/test/rustdoc-gui/code-color.goml +++ b/src/test/rustdoc-gui/code-color.goml @@ -9,14 +9,14 @@ show-text: true define-function: ( "check-colors", (theme, doc_code_color, doc_inline_code_color), - [ + block { // Set the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), - ("assert-css", (".docblock pre > code", {"color": |doc_code_color|}, ALL)), - ("assert-css", (".docblock > p > code", {"color": |doc_inline_code_color|}, ALL)), - ], + reload: + assert-css: (".docblock pre > code", {"color": |doc_code_color|}, ALL) + assert-css: (".docblock > p > code", {"color": |doc_inline_code_color|}, ALL) + }, ) call-function: ("check-colors", ("ayu", "rgb(230, 225, 207)", "rgb(255, 180, 84)")) diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml index d4443f821d2..a3ef4e77b54 100644 --- a/src/test/rustdoc-gui/codeblock-tooltip.goml +++ b/src/test/rustdoc-gui/codeblock-tooltip.goml @@ -5,32 +5,32 @@ show-text: true define-function: ( "check-colors", (theme, background, color, border), - [ + block { // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: // compile_fail block - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.compile_fail .tooltip", {"color": "rgba(255, 0, 0, 0.5)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"}, - )), + ) - ("move-cursor-to", ".docblock .example-wrap.compile_fail .tooltip"), + move-cursor-to: ".docblock .example-wrap.compile_fail .tooltip" - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.compile_fail .tooltip", {"color": "rgb(255, 0, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.compile_fail", {"border-left": "2px solid rgb(255, 0, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.compile_fail .tooltip::after", { "content": '"This example deliberately fails to compile"', @@ -39,37 +39,37 @@ define-function: ( "color": |color|, "border": "1px solid " + |border|, }, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.compile_fail .tooltip::before", { "border-width": "5px", "border-style": "solid", "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", }, - )), + ) // should_panic block - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.should_panic .tooltip", {"color": "rgba(255, 0, 0, 0.5)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.should_panic", {"border-left": "2px solid rgba(255, 0, 0, 0.5)"}, - )), + ) - ("move-cursor-to", ".docblock .example-wrap.should_panic .tooltip"), + move-cursor-to: ".docblock .example-wrap.should_panic .tooltip" - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.should_panic .tooltip", {"color": "rgb(255, 0, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.should_panic", {"border-left": "2px solid rgb(255, 0, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.should_panic .tooltip::after", { "content": '"This example panics"', @@ -78,37 +78,37 @@ define-function: ( "color": |color|, "border": "1px solid " + |border|, }, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.should_panic .tooltip::before", { "border-width": "5px", "border-style": "solid", "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", }, - )), + ) // ignore block - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.ignore .tooltip", {"color": "rgba(255, 142, 0, 0.6)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.ignore", {"border-left": "2px solid rgba(255, 142, 0, 0.6)"}, - )), + ) - ("move-cursor-to", ".docblock .example-wrap.ignore .tooltip"), + move-cursor-to: ".docblock .example-wrap.ignore .tooltip" - ("assert-css", ( + assert-css: ( ".docblock .example-wrap.ignore .tooltip", {"color": "rgb(255, 142, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.ignore", {"border-left": "2px solid rgb(255, 142, 0)"}, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.ignore .tooltip::after", { "content": '"This example is not tested"', @@ -117,16 +117,16 @@ define-function: ( "color": |color|, "border": "1px solid " + |border|, }, - )), - ("assert-css", ( + ) + assert-css: ( ".docblock .example-wrap.ignore .tooltip::before", { "border-width": "5px", "border-style": "solid", "border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)", }, - )), - ], + ) + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/docblock-code-block-line-number.goml b/src/test/rustdoc-gui/docblock-code-block-line-number.goml index a3ed008719c..69bcf5339ef 100644 --- a/src/test/rustdoc-gui/docblock-code-block-line-number.goml +++ b/src/test/rustdoc-gui/docblock-code-block-line-number.goml @@ -11,19 +11,19 @@ assert-false: "pre.example-line-numbers" define-function: ( "check-colors", (theme, color), - [ + block { // We now set the setting to show the line numbers on code examples. - ("local-storage", { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", "rustdoc-line-numbers": "true" - }), + } // We reload to make the line numbers appear and change theme. - ("reload"), + reload: // We wait for them to be added into the DOM by the JS... - ("wait-for", "pre.example-line-numbers"), + wait-for: "pre.example-line-numbers" // If the test didn't fail, it means that it was found! - ("assert-css", ( + assert-css: ( "pre.example-line-numbers", { "color": |color|, @@ -32,8 +32,8 @@ define-function: ( "text-align": "right", }, ALL, - )), - ], + ) + }, ) call-function: ("check-colors", { "theme": "ayu", diff --git a/src/test/rustdoc-gui/docblock-table.goml b/src/test/rustdoc-gui/docblock-table.goml index 6f9209e0ab4..3dcb8abd415 100644 --- a/src/test/rustdoc-gui/docblock-table.goml +++ b/src/test/rustdoc-gui/docblock-table.goml @@ -7,32 +7,32 @@ compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock tab define-function: ( "check-colors", (theme, border_color, zebra_stripe_color), - [ - ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), - ("reload"), - ("assert-css", (".top-doc .docblock table tbody tr:nth-child(1)", { + block { + local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} + reload: + assert-css: (".top-doc .docblock table tbody tr:nth-child(1)", { "background-color": "rgba(0, 0, 0, 0)", - })), - ("assert-css", (".top-doc .docblock table tbody tr:nth-child(2)", { + }) + assert-css: (".top-doc .docblock table tbody tr:nth-child(2)", { "background-color": |zebra_stripe_color|, - })), - ("assert-css", (".top-doc .docblock table tbody tr:nth-child(3)", { + }) + assert-css: (".top-doc .docblock table tbody tr:nth-child(3)", { "background-color": "rgba(0, 0, 0, 0)", - })), - ("assert-css", (".top-doc .docblock table tbody tr:nth-child(4)", { + }) + assert-css: (".top-doc .docblock table tbody tr:nth-child(4)", { "background-color": |zebra_stripe_color|, - })), - ("assert-css", (".top-doc .docblock table td", { + }) + assert-css: (".top-doc .docblock table td", { "border-style": "solid", "border-width": "1px", "border-color": |border_color|, - })), - ("assert-css", (".top-doc .docblock table th", { + }) + assert-css: (".top-doc .docblock table th", { "border-style": "solid", "border-width": "1px", "border-color": |border_color|, - })), - ] + }) + } ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/headers-color.goml b/src/test/rustdoc-gui/headers-color.goml index c80a49c52f0..92cf050a514 100644 --- a/src/test/rustdoc-gui/headers-color.goml +++ b/src/test/rustdoc-gui/headers-color.goml @@ -3,39 +3,39 @@ define-function: ( "check-colors", (theme, color, code_header_color, focus_background_color, headings_color), - [ - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"), + block { + goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // This is needed so that the text color is computed. - ("show-text", true), - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", ( + show-text: true + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: ( ".impl", {"color": |color|, "background-color": "rgba(0, 0, 0, 0)"}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".impl .code-header", {"color": |code_header_color|, "background-color": "rgba(0, 0, 0, 0)"}, ALL, - )), - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#impl-Foo"), - ("assert-css", ( + ) + goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#impl-Foo" + assert-css: ( "#impl-Foo", {"color": |color|, "background-color": |focus_background_color|}, - )), - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#method.must_use"), - ("assert-css", ( + ) + goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html#method.must_use" + assert-css: ( "#method\.must_use", {"color": |color|, "background-color": |focus_background_color|}, ALL, - )), - ("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"), - ("assert-css", (".small-section-header a", {"color": |color|}, ALL)), - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"), + ) + goto: "file://" + |DOC_PATH| + "/test_docs/index.html" + assert-css: (".small-section-header a", {"color": |color|}, ALL) + goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // We select headings (h2, h3, h...). - ("assert-css", (".docblock > :not(p) > a", {"color": |headings_color|}, ALL)), - ], + assert-css: (".docblock > :not(p) > a", {"color": |headings_color|}, ALL) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/headings.goml b/src/test/rustdoc-gui/headings.goml index 85e17ca9551..45b3fee26e4 100644 --- a/src/test/rustdoc-gui/headings.goml +++ b/src/test/rustdoc-gui/headings.goml @@ -157,38 +157,38 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" define-function: ( "check-colors", (theme, heading_color, small_heading_color, heading_border_color), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", ( + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: ( ".top-doc .docblock h2", {"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|}, - )), - ("assert-css", ( + ) + assert-css: ( ".top-doc .docblock h3", {"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|}, - )), - ("assert-css", ( + ) + assert-css: ( ".top-doc .docblock h4", {"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|}, - )), - ("assert-css", ( + ) + assert-css: ( ".top-doc .docblock h5", {"color": |small_heading_color|, "border-bottom-width": "0px"}, - )), - ("assert-css", ( + ) + assert-css: ( "#implementations-list .docblock h4", {"color": |heading_color|, "border-bottom-width": "0px"}, - )), - ("assert-css", ( + ) + assert-css: ( "#implementations-list .docblock h5", {"color": |small_heading_color|, "border-bottom-width": "0px"}, - )), - ("assert-css", ( + ) + assert-css: ( "#implementations-list .docblock h6", {"color": |small_heading_color|, "border-bottom-width": "0px"}, - )), - ], + ) + }, ) call-function: ( "check-colors", @@ -221,11 +221,11 @@ call-function: ( define-function: ( "check-since-color", (theme), - [ - ("local-storage", {"rustdoc-theme": |theme|}), - ("reload"), - ("assert-css", (".since", {"color": "rgb(128, 128, 128)"}, ALL)), - ], + block { + local-storage: {"rustdoc-theme": |theme|} + reload: + assert-css: (".since", {"color": "rgb(128, 128, 128)"}, ALL) + }, ) goto: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html" diff --git a/src/test/rustdoc-gui/help-page.goml b/src/test/rustdoc-gui/help-page.goml index 62cc9ac6497..5f4c1ba2f85 100644 --- a/src/test/rustdoc-gui/help-page.goml +++ b/src/test/rustdoc-gui/help-page.goml @@ -18,17 +18,17 @@ show-text: true define-function: ( "check-colors", (theme, color, background, box_shadow), - [ + block { // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), - ("assert-css", ("#help kbd", { + reload: + assert-css: ("#help kbd", { "color": |color|, "background-color": |background|, "box-shadow": |box_shadow| + " 0px -1px 0px 0px inset", - }, ALL)), - ], + }, ALL) + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/highlight-colors.goml b/src/test/rustdoc-gui/highlight-colors.goml index ff1be389dcb..b182150a577 100644 --- a/src/test/rustdoc-gui/highlight-colors.goml +++ b/src/test/rustdoc-gui/highlight-colors.goml @@ -21,24 +21,24 @@ define-function: ( comment, doc_comment, ), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", ("pre.rust .kw", {"color": |kw|}, ALL)), - ("assert-css", ("pre.rust .kw-2", {"color": |kw2|}, ALL)), - ("assert-css", ("pre.rust .prelude-ty", {"color": |prelude_ty|}, ALL)), - ("assert-css", ("pre.rust .prelude-val", {"color": |prelude_val|}, ALL)), - ("assert-css", ("pre.rust .lifetime", {"color": |lifetime|}, ALL)), - ("assert-css", ("pre.rust .number", {"color": |number|}, ALL)), - ("assert-css", ("pre.rust .string", {"color": |string|}, ALL)), - ("assert-css", ("pre.rust .bool-val", {"color": |bool_val|}, ALL)), - ("assert-css", ("pre.rust .self", {"color": |self|}, ALL)), - ("assert-css", ("pre.rust .attr", {"color": |attr|}, ALL)), - ("assert-css", ("pre.rust .macro", {"color": |macro|}, ALL)), - ("assert-css", ("pre.rust .question-mark", {"color": |question_mark|}, ALL)), - ("assert-css", ("pre.rust .comment", {"color": |comment|}, ALL)), - ("assert-css", ("pre.rust .doccomment", {"color": |doc_comment|}, ALL)), - ], + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: ("pre.rust .kw", {"color": |kw|}, ALL) + assert-css: ("pre.rust .kw-2", {"color": |kw2|}, ALL) + assert-css: ("pre.rust .prelude-ty", {"color": |prelude_ty|}, ALL) + assert-css: ("pre.rust .prelude-val", {"color": |prelude_val|}, ALL) + assert-css: ("pre.rust .lifetime", {"color": |lifetime|}, ALL) + assert-css: ("pre.rust .number", {"color": |number|}, ALL) + assert-css: ("pre.rust .string", {"color": |string|}, ALL) + assert-css: ("pre.rust .bool-val", {"color": |bool_val|}, ALL) + assert-css: ("pre.rust .self", {"color": |self|}, ALL) + assert-css: ("pre.rust .attr", {"color": |attr|}, ALL) + assert-css: ("pre.rust .macro", {"color": |macro|}, ALL) + assert-css: ("pre.rust .question-mark", {"color": |question_mark|}, ALL) + assert-css: ("pre.rust .comment", {"color": |comment|}, ALL) + assert-css: ("pre.rust .doccomment", {"color": |doc_comment|}, ALL) + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/item-decl-colors.goml b/src/test/rustdoc-gui/item-decl-colors.goml index 2e07f19b13d..c58e3eb7c23 100644 --- a/src/test/rustdoc-gui/item-decl-colors.goml +++ b/src/test/rustdoc-gui/item-decl-colors.goml @@ -17,22 +17,23 @@ define-function: ( fn_color, assoc_type_color, ), - [ - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html"), - ("show-text", true), - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", (".item-decl .code-attribute", {"color": |attr_color|}, ALL)), - ("assert-css", (".item-decl .trait", {"color": |trait_color|}, ALL)), + block { + goto: "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html" + show-text: true + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: (".item-decl .code-attribute", {"color": |attr_color|}, ALL) + assert-css: (".item-decl .trait", {"color": |trait_color|}, ALL) // We need to add `code` here because otherwise it would select the parent too. - ("assert-css", (".item-decl code .struct", {"color": |struct_color|}, ALL)), - ("assert-css", (".item-decl .enum", {"color": |enum_color|}, ALL)), - ("assert-css", (".item-decl .primitive", {"color": |primitive_color|}, ALL)), - ("goto", "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithoutGenerics.html"), - ("assert-css", (".item-decl .constant", {"color": |constant_color|}, ALL)), - ("assert-css", (".item-decl .fn", {"color": |fn_color|}, ALL)), - ("assert-css", (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL)), - ], + assert-css: (".item-decl code .struct", {"color": |struct_color|}, ALL) + assert-css: (".item-decl .enum", {"color": |enum_color|}, ALL) + assert-css: (".item-decl .primitive", {"color": |primitive_color|}, ALL) + + goto: "file://" + |DOC_PATH| + "/test_docs/trait.TraitWithoutGenerics.html" + assert-css: (".item-decl .constant", {"color": |constant_color|}, ALL) + assert-css: (".item-decl .fn", {"color": |fn_color|}, ALL) + assert-css: (".item-decl .associatedtype", {"color": |assoc_type_color|}, ALL) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/jump-to-def-background.goml b/src/test/rustdoc-gui/jump-to-def-background.goml index b65faf13d0c..8ee3ccf4a21 100644 --- a/src/test/rustdoc-gui/jump-to-def-background.goml +++ b/src/test/rustdoc-gui/jump-to-def-background.goml @@ -4,17 +4,17 @@ goto: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html" define-function: ( "check-background-color", (theme, background_color), - [ + block { // Set the theme. - ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }), + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" } // We reload the page so the local storage settings are being used. - ("reload"), - ("assert-css", ( + reload: + assert-css: ( "body.source .example-wrap pre.rust a", {"background-color": |background_color|}, ALL, - )), - ], + ) + }, ) call-function: ("check-background-color", ("ayu", "rgb(51, 51, 51)")) diff --git a/src/test/rustdoc-gui/links-color.goml b/src/test/rustdoc-gui/links-color.goml index 9402c09eb69..14f7d99351a 100644 --- a/src/test/rustdoc-gui/links-color.goml +++ b/src/test/rustdoc-gui/links-color.goml @@ -8,29 +8,29 @@ define-function: ( "check-colors", (theme, mod, macro, struct, enum, trait, fn, type, union, keyword, sidebar, sidebar_current, sidebar_current_background), - [ - ("local-storage", { + block { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", - }), - ("reload"), + } + reload: // Checking results colors. - ("assert-css", (".item-table .mod", {"color": |mod|}, ALL)), - ("assert-css", (".item-table .macro", {"color": |macro|}, ALL)), - ("assert-css", (".item-table .struct", {"color": |struct|}, ALL)), - ("assert-css", (".item-table .enum", {"color": |enum|}, ALL)), - ("assert-css", (".item-table .trait", {"color": |trait|}, ALL)), - ("assert-css", (".item-table .fn", {"color": |fn|}, ALL)), - ("assert-css", (".item-table .type", {"color": |type|}, ALL)), - ("assert-css", (".item-table .union", {"color": |union|}, ALL)), - ("assert-css", (".item-table .keyword", {"color": |keyword|}, ALL)), + assert-css: (".item-table .mod", {"color": |mod|}, ALL) + assert-css: (".item-table .macro", {"color": |macro|}, ALL) + assert-css: (".item-table .struct", {"color": |struct|}, ALL) + assert-css: (".item-table .enum", {"color": |enum|}, ALL) + assert-css: (".item-table .trait", {"color": |trait|}, ALL) + assert-css: (".item-table .fn", {"color": |fn|}, ALL) + assert-css: (".item-table .type", {"color": |type|}, ALL) + assert-css: (".item-table .union", {"color": |union|}, ALL) + assert-css: (".item-table .keyword", {"color": |keyword|}, ALL) // Checking sidebar elements. - ("assert-css", ( + assert-css: ( ".sidebar-elems a:not(.current)", {"color": |sidebar|, "background-color": "rgba(0, 0, 0, 0)", "font-weight": "400"}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".sidebar-elems a.current", { "color": |sidebar_current|, @@ -38,8 +38,8 @@ define-function: ( "font-weight": "500", }, ALL, - )), - ], + ) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index 7d4bd27d42d..b4fa7d0dbf0 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -123,40 +123,40 @@ assert-count: ("//*[@class='notable popover']", 0) define-function: ( "check-colors", (theme, header_color, content_color, type_color, trait_color), - [ - ("goto", "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"), + block { + goto: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" // This is needed to ensure that the text color is computed. - ("show-text", true), + show-text: true // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), + reload: - ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"), - ("assert-count", (".notable.popover", 1)), + move-cursor-to: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" + assert-count: (".notable.popover", 1) - ("assert-css", ( + assert-css: ( ".notable.popover h3", {"color": |header_color|}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".notable.popover pre", {"color": |content_color|}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".notable.popover pre a.struct", {"color": |type_color|}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".notable.popover pre a.trait", {"color": |trait_color|}, ALL, - )), - ] + ) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/run-on-hover.goml b/src/test/rustdoc-gui/run-on-hover.goml index 57d63049f28..8dcb62c10aa 100644 --- a/src/test/rustdoc-gui/run-on-hover.goml +++ b/src/test/rustdoc-gui/run-on-hover.goml @@ -8,27 +8,27 @@ show-text: true define-function: ( "check-run-button", (theme, color, background, hover_color, hover_background), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", (".test-arrow", {"visibility": "hidden"})), - ("move-cursor-to", ".example-wrap"), - ("assert-css", (".test-arrow", { + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: (".test-arrow", {"visibility": "hidden"}) + move-cursor-to: ".example-wrap" + assert-css: (".test-arrow", { "visibility": "visible", "color": |color|, "background-color": |background|, "font-size": "22px", "border-radius": "5px", - })), - ("move-cursor-to", ".test-arrow"), - ("assert-css", (".test-arrow:hover", { + }) + move-cursor-to: ".test-arrow" + assert-css: (".test-arrow:hover", { "visibility": "visible", "color": |hover_color|, "background-color": |hover_background|, "font-size": "22px", "border-radius": "5px", - })), - ], + }) + }, ) call-function: ("check-run-button", { diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml index 816cc9abd69..e94dc9a964d 100644 --- a/src/test/rustdoc-gui/rust-logo.goml +++ b/src/test/rustdoc-gui/rust-logo.goml @@ -4,29 +4,29 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" define-function: ( "check-logo", (theme, filter), - [ + block { // Going to the doc page. - ("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"), + goto: "file://" + |DOC_PATH| + "/test_docs/index.html" // Changing theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", (".rust-logo", {"filter": |filter|})), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: (".rust-logo", {"filter": |filter|}) // Going to the source code page. - ("goto", "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"), + goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" // Changing theme (since it's local files, the local storage works by folder). - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", (".rust-logo", {"filter": |filter|})), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: (".rust-logo", {"filter": |filter|}) // Now we check that the non-rust logos don't have a CSS filter set. - ("goto", "file://" + |DOC_PATH| + "/huge_logo/index.html"), + goto: "file://" + |DOC_PATH| + "/huge_logo/index.html" // Changing theme on the new page (again...). - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: // Check there is no rust logo - ("assert-false", ".rust-logo"), + assert-false: ".rust-logo" // Check there is no filter. - ("assert-css", (".sidebar .logo-container img", {"filter": "none"})), - ], + assert-css: (".sidebar .logo-container img", {"filter": "none"}) + }, ) call-function: ( diff --git a/src/test/rustdoc-gui/scrape-examples-color.goml b/src/test/rustdoc-gui/scrape-examples-color.goml index 360e2af8ba4..40f31b2771b 100644 --- a/src/test/rustdoc-gui/scrape-examples-color.goml +++ b/src/test/rustdoc-gui/scrape-examples-color.goml @@ -6,29 +6,29 @@ define-function: ( "check-colors", (theme, highlight, highlight_focus, help_border, help_color, help_hover_border, help_hover_color), - [ - ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }), - ("reload"), - ("wait-for", ".more-examples-toggle"), - ("assert-css", (".scraped-example .example-wrap .rust span.highlight:not(.focus)", { + block { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", } + reload: + wait-for: ".more-examples-toggle" + assert-css: (".scraped-example .example-wrap .rust span.highlight:not(.focus)", { "background-color": |highlight|, - }, ALL)), - ("assert-css", (".scraped-example .example-wrap .rust span.highlight.focus", { + }, ALL) + assert-css: (".scraped-example .example-wrap .rust span.highlight.focus", { "background-color": |highlight_focus|, - }, ALL)), + }, ALL) - ("assert-css", (".scraped-example-list .scrape-help", { + assert-css: (".scraped-example-list .scrape-help", { "border-color": |help_border|, "color": |help_color|, - })), - ("move-cursor-to", ".scraped-example-list .scrape-help"), - ("assert-css", (".scraped-example-list .scrape-help:hover", { + }) + move-cursor-to: ".scraped-example-list .scrape-help" + assert-css: (".scraped-example-list .scrape-help:hover", { "border-color": |help_hover_border|, "color": |help_hover_color|, - })), + }) // Moving the cursor to another item to not break next runs. - ("move-cursor-to", ".search-input"), - ] + move-cursor-to: ".search-input" + } ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/scrape-examples-toggle.goml b/src/test/rustdoc-gui/scrape-examples-toggle.goml index 8c84fbc0c30..2d5df6a5d25 100644 --- a/src/test/rustdoc-gui/scrape-examples-toggle.goml +++ b/src/test/rustdoc-gui/scrape-examples-toggle.goml @@ -6,24 +6,24 @@ show-text: true define-function: ( "check-color", (theme, toggle_line_color, toggle_line_hover_color), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: // Clicking "More examples..." will open additional examples - ("assert-attribute-false", (".more-examples-toggle", {"open": ""})), - ("click", ".more-examples-toggle"), - ("assert-attribute", (".more-examples-toggle", {"open": ""})), + assert-attribute-false: (".more-examples-toggle", {"open": ""}) + click: ".more-examples-toggle" + assert-attribute: (".more-examples-toggle", {"open": ""}) - ("assert-css", (".toggle-line-inner", {"background-color": |toggle_line_color|}, ALL)), - ("move-cursor-to", ".toggle-line"), - ("assert-css", ( + assert-css: (".toggle-line-inner", {"background-color": |toggle_line_color|}, ALL) + move-cursor-to: ".toggle-line" + assert-css: ( ".toggle-line:hover .toggle-line-inner", {"background-color": |toggle_line_hover_color|}, - )), + ) // Moving cursor away from the toggle line to prevent disrupting next test. - ("move-cursor-to", ".search-input"), - ], + move-cursor-to: ".search-input" + }, ) call-function: ("check-color", { diff --git a/src/test/rustdoc-gui/search-no-result.goml b/src/test/rustdoc-gui/search-no-result.goml index b88be32c94a..b76a44fa992 100644 --- a/src/test/rustdoc-gui/search-no-result.goml +++ b/src/test/rustdoc-gui/search-no-result.goml @@ -5,18 +5,18 @@ show-text: true define-function: ( "check-no-result", (theme, link, link_hover), - [ + block { // Changing theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("wait-for", "#results"), - ("assert", ".search-failed.active"), - ("assert-css", ("#results a", {"color": |link|}, ALL)), - ("move-cursor-to", "#results a"), - ("assert-css", ("#results a:hover", {"color": |link_hover|})), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + wait-for: "#results" + assert: ".search-failed.active" + assert-css: ("#results a", {"color": |link|}, ALL) + move-cursor-to: "#results a" + assert-css: ("#results a:hover", {"color": |link_hover|}) // Moving the cursor to some other place to not create issues with next function run. - ("move-cursor-to", ".search-input"), - ] + move-cursor-to: ".search-input" + }, ) call-function: ("check-no-result", { diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index 3c5fe9b74b7..d6d54ec4bee 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -3,53 +3,32 @@ define-function: ( "check-result-color", (result_kind, color, hover_color), - [ - ( - "assert-css", - (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL), - ), - ( - "assert-css", - ( - ".result-" + |result_kind|, - {"color": |entry_color|, "background-color": |background_color|}, - ), - ), - ( - "move-cursor-to", + block { + assert-css: (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL) + assert-css: ( ".result-" + |result_kind|, - ), - ( - "assert-css", - ( - ".result-" + |result_kind| + ":hover", - {"color": |hover_entry_color|, "background-color": |hover_background_color|}, - ), - ), - ( - "assert-css", - (".result-" + |result_kind| + ":hover ." + |result_kind|, {"color": |hover_color|}), - ), - ( - "move-cursor-to", - ".search-input", - ), - ( - "focus", - ".result-" + |result_kind|, - ), - ( - "assert-css", - ( - ".result-" + |result_kind| + ":focus", - {"color": |hover_entry_color|, "background-color": |hover_background_color|}, - ), - ), - ( - "assert-css", - (".result-" + |result_kind| + ":focus ." + |result_kind|, {"color": |hover_color|}), - ), - ], + {"color": |entry_color|, "background-color": |background_color|}, + ) + move-cursor-to: ".result-" + |result_kind| + assert-css: ( + ".result-" + |result_kind| + ":hover", + {"color": |hover_entry_color|, "background-color": |hover_background_color|}, + ) + assert-css: ( + ".result-" + |result_kind| + ":hover ." + |result_kind|, + {"color": |hover_color|}, + ) + move-cursor-to: ".search-input" + focus: ".result-" + |result_kind| + assert-css: ( + ".result-" + |result_kind| + ":focus", + {"color": |hover_entry_color|, "background-color": |hover_background_color|}, + ) + assert-css: ( + ".result-" + |result_kind| + ":focus ." + |result_kind|, + {"color": |hover_color|}, + ) + }, ) goto: "file://" + |DOC_PATH| + "/test_docs/index.html?search=coo" @@ -389,20 +368,20 @@ show-text: true define-function: ( "check-alias", (theme, alias, grey), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("write", (".search-input", "thisisanalias")), + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + write: (".search-input", "thisisanalias") // To be SURE that the search will be run. - ("press-key", 'Enter'), + press-key: 'Enter' // Waiting for the search results to appear... - ("wait-for", "#search-tabs"), + wait-for: "#search-tabs" // Checking that the colors for the alias element are the ones expected. - ("assert-css", (".result-name > .alias", {"color": |alias|})), - ("assert-css", (".result-name > .alias > .grey", {"color": |grey|})), + assert-css: (".result-name > .alias", {"color": |alias|}) + assert-css: (".result-name > .alias > .grey", {"color": |grey|}) // Leave the search results to prevent reloading with an already filled search input. - ("press-key", "Escape"), - ], + press-key: "Escape" + }, ) call-function: ("check-alias", { diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml index 13a5e4c717b..43e608228d8 100644 --- a/src/test/rustdoc-gui/search-result-display.goml +++ b/src/test/rustdoc-gui/search-result-display.goml @@ -42,17 +42,17 @@ show-text: true define-function: ( "check-filter", (theme, border, filter, hover_border, hover_filter), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("wait-for", "#crate-search"), - ("assert-css", ("#crate-search", {"border": "1px solid " + |border|})), - ("assert-css", ("#crate-search-div::after", {"filter": |filter|})), - ("move-cursor-to", "#crate-search"), - ("assert-css", ("#crate-search", {"border": "1px solid " + |hover_border|})), - ("assert-css", ("#crate-search-div::after", {"filter": |hover_filter|})), - ("move-cursor-to", ".search-input"), - ], + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + wait-for: "#crate-search" + assert-css: ("#crate-search", {"border": "1px solid " + |border|}) + assert-css: ("#crate-search-div::after", {"filter": |filter|}) + move-cursor-to: "#crate-search" + assert-css: ("#crate-search", {"border": "1px solid " + |hover_border|}) + assert-css: ("#crate-search-div::after", {"filter": |hover_filter|}) + move-cursor-to: ".search-input" + }, ) call-function: ("check-filter", { diff --git a/src/test/rustdoc-gui/search-tab.goml b/src/test/rustdoc-gui/search-tab.goml index c2634a04c8a..36958f70044 100644 --- a/src/test/rustdoc-gui/search-tab.goml +++ b/src/test/rustdoc-gui/search-tab.goml @@ -7,35 +7,35 @@ define-function: ( (theme, background, background_selected, background_hover, border_bottom, border_bottom_selected, border_bottom_hover, border_top, border_top_selected, border_top_hover), - [ + block { // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: // These two commands are used to be sure the search will be run. - ("focus", ".search-input"), - ("press-key", "Enter"), + focus: ".search-input" + press-key: "Enter" - ("wait-for", "#search-tabs"), - ("assert-css", ("#search-tabs > button:not(.selected)", { + wait-for: "#search-tabs" + assert-css: ("#search-tabs > button:not(.selected)", { "background-color": |background|, "border-bottom": |border_bottom|, "border-top": |border_top|, - })), - ("assert-css", ("#search-tabs > button.selected", { + }) + assert-css: ("#search-tabs > button.selected", { "background-color": |background_selected|, "border-bottom": |border_bottom_selected|, "border-top": |border_top_selected|, - })), - ("move-cursor-to", "#search-tabs > button:not(.selected)"), - ("assert-css", ("#search-tabs > button:not(.selected):hover", { + }) + move-cursor-to: "#search-tabs > button:not(.selected)" + assert-css: ("#search-tabs > button:not(.selected):hover", { "background-color": |background_hover|, "border-bottom": |border_bottom_hover|, "border-top": |border_top_hover|, - })), + }) // To prevent disrupting next run of this function. - ("move-cursor-to", ".search-input"), - ], + move-cursor-to: ".search-input" + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml index 7ef7ec90cd2..1d5fdb7a48f 100644 --- a/src/test/rustdoc-gui/sidebar-links-color.goml +++ b/src/test/rustdoc-gui/sidebar-links-color.goml @@ -12,80 +12,80 @@ define-function: ( trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover, type_hover_background, keyword, keyword_hover, keyword_hover_background, ), - [ - ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }), - ("reload"), + block { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" } + reload: // Struct - ("assert-css", ( + assert-css: ( ".sidebar .block.struct a:not(.current)", {"color": |struct|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.struct a:not(.current)"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.struct a:not(.current)" + assert-css: ( ".sidebar .block.struct a:hover", {"color": |struct_hover|, "background-color": |struct_hover_background|}, - )), + ) // Enum - ("assert-css", ( + assert-css: ( ".sidebar .block.enum a", {"color": |enum|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.enum a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.enum a" + assert-css: ( ".sidebar .block.enum a:hover", {"color": |enum_hover|, "background-color": |enum_hover_background|}, - )), + ) // Union - ("assert-css", ( + assert-css: ( ".sidebar .block.union a", {"color": |union|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.union a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.union a" + assert-css: ( ".sidebar .block.union a:hover", {"color": |union_hover|, "background-color": |union_hover_background|}, - )), + ) // Trait - ("assert-css", ( + assert-css: ( ".sidebar .block.trait a", {"color": |trait|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.trait a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.trait a" + assert-css: ( ".sidebar .block.trait a:hover", {"color": |trait_hover|, "background-color": |trait_hover_background|}, - )), + ) // Function - ("assert-css", ( + assert-css: ( ".sidebar .block.fn a", {"color": |fn|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.fn a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.fn a" + assert-css: ( ".sidebar .block.fn a:hover", {"color": |fn_hover|, "background-color": |fn_hover_background|}, - )), + ) // Type definition - ("assert-css", ( + assert-css: ( ".sidebar .block.type a", {"color": |type|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.type a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.type a" + assert-css: ( ".sidebar .block.type a:hover", {"color": |type_hover|, "background-color": |type_hover_background|}, - )), + ) // Keyword - ("assert-css", ( + assert-css: ( ".sidebar .block.keyword a", {"color": |keyword|, "background-color": "rgba(0, 0, 0, 0)"}, - )), - ("move-cursor-to", ".sidebar .block.keyword a"), - ("assert-css", ( + ) + move-cursor-to: ".sidebar .block.keyword a" + assert-css: ( ".sidebar .block.keyword a:hover", {"color": |keyword_hover|, "background-color": |keyword_hover_background|}, - )), - ] + ) + } ) call-function: ( diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml index 38d01f7f612..d5f4b619629 100644 --- a/src/test/rustdoc-gui/sidebar-mobile.goml +++ b/src/test/rustdoc-gui/sidebar-mobile.goml @@ -58,17 +58,17 @@ show-text: true define-function: ( "check-colors", (theme, color, background), - [ - ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), - ("reload"), + block { + local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} + reload: // Open the sidebar menu. - ("click", ".sidebar-menu-toggle"), - ("assert-css", (".sidebar", { + click: ".sidebar-menu-toggle" + assert-css: (".sidebar", { "background-color": |background|, "color": |color|, - })), - ], + }) + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index df4506e1119..d74d9420389 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml @@ -35,88 +35,88 @@ define-function: ( theme, color, color_hover, background, background_hover, background_toggle, background_toggle_hover, ), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("wait-for-css", ("#src-sidebar-toggle", {"visibility": "visible"})), - ("assert-css", ( + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + wait-for-css: ("#src-sidebar-toggle", {"visibility": "visible"}) + assert-css: ( "#source-sidebar details[open] > .files a.selected", {"color": |color_hover|, "background-color": |background|}, - )), + ) // Without hover or focus. - ("assert-css", ("#src-sidebar-toggle > button", {"background-color": |background_toggle|})), + assert-css: ("#src-sidebar-toggle > button", {"background-color": |background_toggle|}) // With focus. - ("focus", "#src-sidebar-toggle > button"), - ("assert-css", ( + focus: "#src-sidebar-toggle > button" + assert-css: ( "#src-sidebar-toggle > button:focus", {"background-color": |background_toggle_hover|}, - )), - ("focus", ".search-input"), + ) + focus: ".search-input" // With hover. - ("move-cursor-to", "#src-sidebar-toggle > button"), - ("assert-css", ( + move-cursor-to: "#src-sidebar-toggle > button" + assert-css: ( "#src-sidebar-toggle > button:hover", {"background-color": |background_toggle_hover|}, - )), + ) // Without hover or focus. - ("assert-css", ( + assert-css: ( "#source-sidebar details[open] > .files a:not(.selected)", {"color": |color|, "background-color": |background_toggle|}, - )), + ) // With focus. - ("focus", "#source-sidebar details[open] > .files a:not(.selected)"), - ("wait-for-css", ( + focus: "#source-sidebar details[open] > .files a:not(.selected)" + wait-for-css: ( "#source-sidebar details[open] > .files a:not(.selected):focus", {"color": |color_hover|, "background-color": |background_hover|}, - )), - ("focus", ".search-input"), + ) + focus: ".search-input" // With hover. - ("move-cursor-to", "#source-sidebar details[open] > .files a:not(.selected)"), - ("assert-css", ( + move-cursor-to: "#source-sidebar details[open] > .files a:not(.selected)" + assert-css: ( "#source-sidebar details[open] > .files a:not(.selected):hover", {"color": |color_hover|, "background-color": |background_hover|}, - )), + ) // Without hover or focus. - ("assert-css", ( + assert-css: ( "#source-sidebar .dir-entry summary", {"color": |color|, "background-color": |background_toggle|}, - )), + ) // With focus. - ("focus", "#source-sidebar .dir-entry summary"), - ("wait-for-css", ( + focus: "#source-sidebar .dir-entry summary" + wait-for-css: ( "#source-sidebar .dir-entry summary:focus", {"color": |color_hover|, "background-color": |background_hover|}, - )), - ("focus", ".search-input"), + ) + focus: ".search-input" // With hover. - ("move-cursor-to", "#source-sidebar .dir-entry summary"), - ("assert-css", ( + move-cursor-to: "#source-sidebar .dir-entry summary" + assert-css: ( "#source-sidebar .dir-entry summary:hover", {"color": |color_hover|, "background-color": |background_hover|}, - )), + ) // Without hover or focus. - ("assert-css", ( + assert-css: ( "#source-sidebar details[open] > .folders > details > summary", {"color": |color|, "background-color": |background_toggle|}, - )), + ) // With focus. - ("focus", "#source-sidebar details[open] > .folders > details > summary"), - ("wait-for-css", ( + focus: "#source-sidebar details[open] > .folders > details > summary" + wait-for-css: ( "#source-sidebar details[open] > .folders > details > summary:focus", {"color": |color_hover|, "background-color": |background_hover|}, - )), - ("focus", ".search-input"), + ) + focus: ".search-input" // With hover. - ("move-cursor-to", "#source-sidebar details[open] > .folders > details > summary"), - ("assert-css", ( + move-cursor-to: "#source-sidebar details[open] > .folders > details > summary" + assert-css: ( "#source-sidebar details[open] > .folders > details > summary:hover", {"color": |color_hover|, "background-color": |background_hover|}, - )), - ], + ) + }, ) call-function: ("check-colors", { diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 6bc07fbae04..3ee83d6f475 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -7,43 +7,43 @@ show-text: true define-function: ( "check-colors", (theme, color, background_color), - [ - ("local-storage", { + block { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", - }), - ("reload"), + } + reload: // Checking results colors. - ("assert-css", (".source .sidebar", { - "color": |color|, - "background-color": |background_color| - }, ALL)), - ], + assert-css: (".source .sidebar", { + "color": |color|, + "background-color": |background_color| + }, ALL) + }, ) call-function: ( - "check-colors", - { - "theme": "ayu", - "color": "rgb(197, 197, 197)", - "background_color": "rgb(20, 25, 31)", - } + "check-colors", + { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background_color": "rgb(20, 25, 31)", + } ) call-function: ( - "check-colors", - { - "theme": "dark", - "color": "rgb(221, 221, 221)", - "background_color": "rgb(80, 80, 80)", - } + "check-colors", + { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background_color": "rgb(80, 80, 80)", + } ) call-function: ( - "check-colors", - { - "theme": "light", - "color": "rgb(0, 0, 0)", - "background_color": "rgb(245, 245, 245)", - } + "check-colors", + { + "theme": "light", + "color": "rgb(0, 0, 0)", + "background_color": "rgb(245, 245, 245)", + } ) // Next, desktop mode layout. diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml index bfd7567a224..9db7f59695b 100644 --- a/src/test/rustdoc-gui/sidebar.goml +++ b/src/test/rustdoc-gui/sidebar.goml @@ -7,43 +7,43 @@ show-text: true define-function: ( "check-colors", (theme, color, background_color), - [ - ("local-storage", { + block { + local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", - }), - ("reload"), + } + reload: // Checking results colors. - ("assert-css", (".sidebar", { - "color": |color|, - "background-color": |background_color| - }, ALL)), - ], + assert-css: (".sidebar", { + "color": |color|, + "background-color": |background_color| + }, ALL) + }, ) call-function: ( - "check-colors", - { - "theme": "ayu", - "color": "rgb(197, 197, 197)", - "background_color": "rgb(20, 25, 31)", - } + "check-colors", + { + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background_color": "rgb(20, 25, 31)", + } ) call-function: ( - "check-colors", - { - "theme": "dark", - "color": "rgb(221, 221, 221)", - "background_color": "rgb(80, 80, 80)", - } + "check-colors", + { + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background_color": "rgb(80, 80, 80)", + } ) call-function: ( - "check-colors", - { - "theme": "light", - "color": "rgb(0, 0, 0)", - "background_color": "rgb(245, 245, 245)", - } + "check-colors", + { + "theme": "light", + "color": "rgb(0, 0, 0)", + "background_color": "rgb(245, 245, 245)", + } ) local-storage: {"rustdoc-theme": "light"} diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index e0397890519..7c35119e695 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -22,20 +22,20 @@ assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-h define-function: ( "check-colors", (theme, color, background_color, highlight_color, highlight_background_color), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", ( + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: ( ".src-line-numbers > a:not(.line-highlighted)", {"color": |color|, "background-color": |background_color|}, ALL, - )), - ("assert-css", ( + ) + assert-css: ( ".src-line-numbers > a.line-highlighted", {"color": |highlight_color|, "background-color": |highlight_background_color|}, ALL, - )), - ], + ) + }, ) call-function: ("check-colors", { @@ -124,28 +124,28 @@ store-property: ( define-function: ( "check-sidebar-dir-entry", (x, y), - [ - ("assert", "details:first-of-type.dir-entry[open] > summary::marker"), - ("assert-css", ("#source-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"})), + block { + assert: "details:first-of-type.dir-entry[open] > summary::marker" + assert-css: ("#source-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"}) // This check ensures that the summary is only one line. - ("assert-property", ( + assert-property: ( "#source-sidebar > details:first-of-type.dir-entry[open] > summary", {"offsetHeight": |link_height|} - )), - ("assert-position", ( + ) + assert-position: ( "#source-sidebar > details:first-of-type.dir-entry[open] > summary", {"x": |x|, "y": |y|} - )), - ("assert-property", ( + ) + assert-property: ( "#source-sidebar > details:first-of-type.dir-entry[open] > .files > a", {"offsetHeight": |link_height|} - )), - ("assert-position", ( + ) + assert-position: ( "#source-sidebar > details:first-of-type.dir-entry[open] > .files > a", // left margin {"x": |x| + 27, "y": |y| + |link_height|} - )), - ] + ) + } ) store-property: ( source_sidebar_title_height, diff --git a/src/test/rustdoc-gui/stab-badge.goml b/src/test/rustdoc-gui/stab-badge.goml index aaed8440a40..50ba1ba62db 100644 --- a/src/test/rustdoc-gui/stab-badge.goml +++ b/src/test/rustdoc-gui/stab-badge.goml @@ -2,40 +2,40 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" show-text: true define-function: ( - "check-badge", - (theme, background, color), - [ - ("local-storage", {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}), - ("goto", "file://" + |DOC_PATH| + "/test_docs/index.html"), - ("assert", (".docblock .stab")), - ("assert", (".item-table .stab")), - ("assert-css", (".stab", { - "border-radius": "3px", - "color": |color|, - "background-color": |background|, - })), - ("goto", "file://" + |DOC_PATH| + "/test_docs/fn.replaced_function.html"), - ("assert", (".item-info .stab")), - ("assert-css", (".stab", { - "border-radius": "3px", - "color": |color|, - "background-color": |background|, - })), - ] + "check-badge", + (theme, background, color), + block { + local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} + goto: "file://" + |DOC_PATH| + "/test_docs/index.html" + assert: ".docblock .stab" + assert: ".item-table .stab" + assert-css: (".stab", { + "border-radius": "3px", + "color": |color|, + "background-color": |background|, + }) + goto: "file://" + |DOC_PATH| + "/test_docs/fn.replaced_function.html" + assert: (".item-info .stab") + assert-css: (".stab", { + "border-radius": "3px", + "color": |color|, + "background-color": |background|, + }) + }, ) call-function: ("check-badge", { - "theme": "ayu", - "color": "rgb(197, 197, 197)", - "background": "rgb(49, 69, 89)", + "theme": "ayu", + "color": "rgb(197, 197, 197)", + "background": "rgb(49, 69, 89)", }) call-function: ("check-badge", { - "theme": "dark", - "color": "rgb(221, 221, 221)", - "background": "rgb(49, 69, 89)", + "theme": "dark", + "color": "rgb(221, 221, 221)", + "background": "rgb(49, 69, 89)", }) call-function: ("check-badge", { - "theme": "light", - "color": "rgb(0, 0, 0)", - "background": "rgb(255, 245, 214)", + "theme": "light", + "color": "rgb(0, 0, 0)", + "background": "rgb(255, 245, 214)", }) diff --git a/src/test/rustdoc-gui/target.goml b/src/test/rustdoc-gui/target.goml index 3e5c30dc7ea..ca393ee5891 100644 --- a/src/test/rustdoc-gui/target.goml +++ b/src/test/rustdoc-gui/target.goml @@ -8,14 +8,14 @@ assert: "#method\.a_method:target" define-function: ( "check-style", (theme, background, border), - [ - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), - ("reload"), - ("assert-css", ("#method\.a_method:target", { + block { + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} + reload: + assert-css: ("#method\.a_method:target", { "background-color": |background|, "border-right": "3px solid " + |border|, - })), - ], + }) + }, ) call-function: ("check-style", { diff --git a/src/test/rustdoc-gui/toggle-docs.goml b/src/test/rustdoc-gui/toggle-docs.goml index 45bb8daf1f2..89ce78e3aab 100644 --- a/src/test/rustdoc-gui/toggle-docs.goml +++ b/src/test/rustdoc-gui/toggle-docs.goml @@ -50,24 +50,24 @@ show-text: true define-function: ( "check-color", (theme, filter), - [ + block { // Setting the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), + reload: - ("assert-css", ("details.rustdoc-toggle > summary::before", { + assert-css: ("details.rustdoc-toggle > summary::before", { "opacity": "0.5", "filter": |filter|, - }, ALL)), - ("move-cursor-to", "details.rustdoc-toggle summary"), - ("assert-css", ("details.rustdoc-toggle > summary:hover::before", { + }, ALL) + move-cursor-to: "details.rustdoc-toggle summary" + assert-css: ("details.rustdoc-toggle > summary:hover::before", { "opacity": "1", "filter": |filter|, - })), + }) // moving the cursor somewhere else to not mess with next function calls. - ("move-cursor-to", ".search-input"), - ] + move-cursor-to: ".search-input" + }, ) call-function: ("check-color", {"theme": "ayu", "filter": "invert(1)"}) diff --git a/src/test/rustdoc-gui/unsafe-fn.goml b/src/test/rustdoc-gui/unsafe-fn.goml index 5e43b85fce0..d3a672ddde6 100644 --- a/src/test/rustdoc-gui/unsafe-fn.goml +++ b/src/test/rustdoc-gui/unsafe-fn.goml @@ -14,13 +14,13 @@ define-function: ( // `theme` is the theme being tested. // `color` is the expected color of the `` element. (theme, color), - [ + block { // Set the theme. - ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), + local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} // We reload the page so the local storage settings are being used. - ("reload"), - ("assert-css", (".item-left sup", {"color": |color|})), - ], + reload: + assert-css: (".item-left sup", {"color": |color|}) + }, ) call-function: ("sup-check", ("dark", "rgb(221, 221, 221)")) -- cgit 1.4.1-3-g733a5 From ff46d116c1fec1a1ceb988e0e31263c00a5d521b Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Fri, 6 Jan 2023 17:57:03 +0000 Subject: rustdoc: Strip imports of items which are `#[doc(hidden)]` Closes #106379 --- src/librustdoc/clean/types.rs | 11 +++++++++++ src/librustdoc/passes/stripper.rs | 1 + src/test/rustdoc-json/doc_hidden_failure.rs | 3 ++- src/test/rustdoc-json/reexport/pub_use_doc_hidden.rs | 15 +++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc-json/reexport/pub_use_doc_hidden.rs diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6d55a6794f5..827afafbba3 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2494,6 +2494,17 @@ impl Import { pub(crate) fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self { Self { kind: ImportKind::Glob, source, should_be_displayed } } + + pub(crate) fn imported_item_is_doc_hidden(&self, tcx: TyCtxt<'_>) -> bool { + match self.source.did { + Some(did) => tcx + .get_attrs(did, sym::doc) + .filter_map(ast::Attribute::meta_item_list) + .flatten() + .has_word(sym::hidden), + None => false, + } + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index bf111133b9f..f8a0d77538d 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -248,6 +248,7 @@ pub(crate) struct ImportStripper<'tcx> { impl<'tcx> DocFolder for ImportStripper<'tcx> { fn fold_item(&mut self, i: Item) -> Option { match *i.kind { + clean::ImportItem(imp) if imp.imported_item_is_doc_hidden(self.tcx) => None, clean::ExternCrateItem { .. } | clean::ImportItem(..) if i.visibility(self.tcx) != Some(Visibility::Public) => { diff --git a/src/test/rustdoc-json/doc_hidden_failure.rs b/src/test/rustdoc-json/doc_hidden_failure.rs index 6573166c47f..0d2c6b2209b 100644 --- a/src/test/rustdoc-json/doc_hidden_failure.rs +++ b/src/test/rustdoc-json/doc_hidden_failure.rs @@ -14,7 +14,8 @@ mod auto { } } -// @count "$.index[*][?(@.name=='builders')]" 2 +// @count "$.index[*][?(@.name=='builders')]" 1 +// @has "$.index[*][?(@.name == 'ActionRowBuilder')"] pub use auto::*; pub mod builders { diff --git a/src/test/rustdoc-json/reexport/pub_use_doc_hidden.rs b/src/test/rustdoc-json/reexport/pub_use_doc_hidden.rs new file mode 100644 index 00000000000..a2a25d08448 --- /dev/null +++ b/src/test/rustdoc-json/reexport/pub_use_doc_hidden.rs @@ -0,0 +1,15 @@ +// Regression test for + +#![feature(no_core)] +#![no_core] + +mod repeat_n { + #[doc(hidden)] + pub struct RepeatN {} +} + +pub use repeat_n::RepeatN; + +// @count "$.index[*][?(@.name=='pub_use_doc_hidden')].inner.items[*]" 0 +// @!has "$.index[*][?(@.kind=='struct')]" +// @!has "$.index[*][?(@.kind=='import')]" -- cgit 1.4.1-3-g733a5 From 5cda0a2f39930daaeb1e71e9027be0e28fe55cfd Mon Sep 17 00:00:00 2001 From: Matthew Esposito Date: Fri, 6 Jan 2023 14:07:12 -0500 Subject: Add default and latest stable edition to --edition in rustc --- compiler/rustc_session/src/config.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a87e820386e..233343febff 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -35,6 +35,7 @@ use std::hash::Hash; use std::iter; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; +use std::sync::LazyLock; pub mod sigpipe; @@ -1322,7 +1323,12 @@ mod opt { unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d)) } } - +static EDITION_STRING: LazyLock = LazyLock::new(|| { + format!( + "Specify which edition of the compiler to use when compiling code.\ +The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}." + ) +}); /// Returns the "short" subset of the rustc command line options, /// including metadata for each option, such as whether the option is /// part of the stable long-term interface for rustc. @@ -1355,7 +1361,7 @@ pub fn rustc_short_optgroups() -> Vec { opt::opt_s( "", "edition", - "Specify which edition of the compiler to use when compiling code.", + &*EDITION_STRING, EDITION_NAME_LIST, ), opt::multi_s( -- cgit 1.4.1-3-g733a5 From d5e5762211a6c8ee22b789c15596d2b49a45ed3f Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:18:06 +0100 Subject: Handle non-existant upstream master branches in `x fmt` --- Cargo.lock | 1 - src/bootstrap/format.rs | 52 ++++++++++++++++++++++++++------------- src/bootstrap/util.rs | 17 +++++++++++++ src/tools/build_helper/src/git.rs | 49 ++++++++++++++++++++++++++++++++++-- 4 files changed, 99 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a86a1012a7..bfca4531c18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5308,7 +5308,6 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ - "build_helper", "cargo_metadata 0.14.0", "ignore", "lazy_static", diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index cca45f4a634..bfc57a85cdb 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,8 +1,8 @@ //! Runs rustfmt on the repository. use crate::builder::Builder; -use crate::util::{output, program_out_of_date, t}; -use build_helper::git::get_rust_lang_rust_remote; +use crate::util::{output, output_result, program_out_of_date, t}; +use build_helper::git::updated_master_branch; use ignore::WalkBuilder; use std::collections::VecDeque; use std::path::{Path, PathBuf}; @@ -79,21 +79,24 @@ fn update_rustfmt_version(build: &Builder<'_>) { /// rust-lang/master and what is now on the disk. /// /// Returns `None` if all files should be formatted. -fn get_modified_rs_files(build: &Builder<'_>) -> Option> { - let Ok(remote) = get_rust_lang_rust_remote() else { return None; }; +fn get_modified_rs_files(build: &Builder<'_>) -> Result>, String> { + let Ok(updated_master) = updated_master_branch(Some(&build.config.src)) else { return Ok(None); }; + if !verify_rustfmt_version(build) { - return None; + return Ok(None); } let merge_base = - output(build.config.git().arg("merge-base").arg(&format!("{remote}/master")).arg("HEAD")); - Some( - output(build.config.git().arg("diff-index").arg("--name-only").arg(merge_base.trim())) - .lines() - .map(|s| s.trim().to_owned()) - .filter(|f| Path::new(f).extension().map_or(false, |ext| ext == "rs")) - .collect(), - ) + output_result(build.config.git().arg("merge-base").arg(&updated_master).arg("HEAD"))?; + Ok(Some( + output_result( + build.config.git().arg("diff-index").arg("--name-only").arg(merge_base.trim()), + )? + .lines() + .map(|s| s.trim().to_owned()) + .filter(|f| Path::new(f).extension().map_or(false, |ext| ext == "rs")) + .collect(), + )) } #[derive(serde::Deserialize)] @@ -130,6 +133,9 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { Ok(status) => status.success(), Err(_) => false, }; + + let mut paths = paths.to_vec(); + if git_available { let in_working_tree = match build .config @@ -163,10 +169,21 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path); } if !check && paths.is_empty() { - if let Some(files) = get_modified_rs_files(build) { - for file in files { - println!("formatting modified file {file}"); - ignore_fmt.add(&format!("/{file}")).expect(&file); + match get_modified_rs_files(build) { + Ok(Some(files)) => { + for file in files { + println!("formatting modified file {file}"); + ignore_fmt.add(&format!("/{file}")).expect(&file); + } + } + Ok(None) => {} + Err(err) => { + println!( + "WARN: Something went wrong when running git commands:\n{err}\n\ + Falling back to formatting all files." + ); + // Something went wrong when getting the version. Just format all the files. + paths.push(".".into()); } } } @@ -176,6 +193,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { } else { println!("Could not find usable git. Skipping git-aware format checks"); } + let ignore_fmt = ignore_fmt.build().unwrap(); let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| { diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 8ce9a9ce38c..93e53d383cd 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -412,6 +412,23 @@ pub fn output(cmd: &mut Command) -> String { String::from_utf8(output.stdout).unwrap() } +pub fn output_result(cmd: &mut Command) -> Result { + let output = match cmd.stderr(Stdio::inherit()).output() { + Ok(status) => status, + Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)), + }; + if !output.status.success() { + return Err(format!( + "command did not execute successfully: {:?}\n\ + expected success, got: {}\n{}", + cmd, + output.status, + String::from_utf8(output.stderr).map_err(|err| format!("{err:?}"))? + )); + } + Ok(String::from_utf8(output.stdout).map_err(|err| format!("{err:?}"))?) +} + /// Returns the last-modified time for `path`, or zero if it doesn't exist. pub fn mtime(path: &Path) -> SystemTime { fs::metadata(path).and_then(|f| f.modified()).unwrap_or(UNIX_EPOCH) diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs index e9638206e67..dc62051cb85 100644 --- a/src/tools/build_helper/src/git.rs +++ b/src/tools/build_helper/src/git.rs @@ -1,4 +1,4 @@ -use std::process::Command; +use std::{path::Path, process::Command}; /// Finds the remote for rust-lang/rust. /// For example for these remotes it will return `upstream`. @@ -8,8 +8,11 @@ use std::process::Command; /// upstream https://github.com/rust-lang/rust (fetch) /// upstream https://github.com/rust-lang/rust (push) /// ``` -pub fn get_rust_lang_rust_remote() -> Result { +pub fn get_rust_lang_rust_remote(git_dir: Option<&Path>) -> Result { let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } git.args(["config", "--local", "--get-regex", "remote\\..*\\.url"]); let output = git.output().map_err(|err| format!("{err:?}"))?; @@ -28,3 +31,45 @@ pub fn get_rust_lang_rust_remote() -> Result { rust_lang_remote.split('.').nth(1).ok_or_else(|| "remote name not found".to_owned())?; Ok(remote_name.into()) } + +pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result { + let mut git = Command::new("git"); + if let Some(git_dir) = git_dir { + git.current_dir(git_dir); + } + git.args(["rev-parse", rev]); + let output = git.output().map_err(|err| format!("{err:?}"))?; + + match output.status.code() { + Some(0) => Ok(true), + Some(128) => Ok(false), + None => { + return Err(format!( + "git didn't exit properly: {}", + String::from_utf8(output.stderr).map_err(|err| format!("{err:?}"))? + )); + } + Some(code) => { + return Err(format!( + "git command exited with status code: {code}: {}", + String::from_utf8(output.stderr).map_err(|err| format!("{err:?}"))? + )); + } + } +} + +/// Returns the master branch from which we can take diffs to see changes. +/// This will usually be rust-lang/rust master, but sometimes this might not exist. +/// This could be because the user is updating their forked master branch using the GitHub UI +/// and therefore doesn't need an upstream master branch checked out. +/// We will then fall back to origin/master in the hope that at least this exists. +pub fn updated_master_branch(git_dir: Option<&Path>) -> Result { + let upstream_remote = get_rust_lang_rust_remote(git_dir)?; + let upstream_master = format!("{upstream_remote}/master"); + if rev_exists(&upstream_master, git_dir)? { + return Ok(upstream_master); + } + + // We could implement smarter logic here in the future. + Ok("origin/master".into()) +} -- cgit 1.4.1-3-g733a5 From 893938f64f7a9ff531b3968c9a9e79e0524606bd Mon Sep 17 00:00:00 2001 From: Matthew E Date: Fri, 6 Jan 2023 14:36:52 -0500 Subject: Update compiler/rustc_session/src/config.rs Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com> --- compiler/rustc_session/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 233343febff..1ccfc59f7a9 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1325,7 +1325,7 @@ mod opt { } static EDITION_STRING: LazyLock = LazyLock::new(|| { format!( - "Specify which edition of the compiler to use when compiling code.\ + "Specify which edition of the compiler to use when compiling code. \ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}." ) }); -- cgit 1.4.1-3-g733a5 From 16a3c8032e634d3da53f8d4c0a875f369a9d4394 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 6 Jan 2023 12:20:03 -0700 Subject: rustdoc: remove no-op CSS `.rustdoc.source .sidebar { width: 0 }` This CSS was added in dc2c9723343c985740be09919236a6e96c4e4433, before 6a5f8b1aef1417d7dc85b5d0a229d2db1930eb7c when the sidebars were merged. Now that they are merged, the source sidebar is being pushed off-screen anyway, so giving it zero width doesn't do much. --- src/librustdoc/html/static/css/rustdoc.css | 6 +----- src/test/rustdoc-gui/sidebar-source-code-display.goml | 6 +++--- src/test/rustdoc-gui/sidebar-source-code.goml | 6 +++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 05a12d3d4d4..d77b65ac603 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1598,14 +1598,10 @@ in storage.js .sidebar.shown, .source-sidebar-expanded .source .sidebar, - .sidebar:focus-within { + .rustdoc:not(.source) .sidebar:focus-within { left: 0; } - .rustdoc.source > .sidebar { - width: 0; - } - .mobile-topbar h2 { padding-bottom: 0; margin: auto 0.5em auto auto; diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index df4506e1119..d0e2c8a6adc 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml @@ -171,15 +171,15 @@ assert-css: ( // We now check that the scroll position is kept when opening the sidebar. click: "#src-sidebar-toggle" -wait-for-css: (".sidebar", {"width": "0px"}) +wait-for-css: (".sidebar", {"left": "-1000px"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' assert-window-property: {"pageYOffset": "2542"} // Expanding the sidebar... click: "#src-sidebar-toggle" -wait-for-css: (".sidebar", {"width": "500px"}) +wait-for-css: (".sidebar", {"left": "0px"}) click: "#src-sidebar-toggle" -wait-for-css: (".sidebar", {"width": "0px"}) +wait-for-css: (".sidebar", {"left": "-1000px"}) // The "scrollTop" property should be the same. assert-window-property: {"pageYOffset": "2542"} diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 6bc07fbae04..08a237e49da 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -77,11 +77,11 @@ assert-count: ("//*[@id='source-sidebar']/details[not(text()='lib2') and not(@op // We now switch to mobile mode. size: (600, 600) -wait-for-css: (".source-sidebar-expanded nav.sidebar", {"width": "600px"}) +wait-for-css: (".source-sidebar-expanded nav.sidebar", {"left": "0px"}) // We collapse the sidebar. click: (10, 10) -// We check that the sidebar has the expected width (0). -assert-css: ("nav.sidebar", {"width": "0px"}) +// We check that the sidebar has been moved off-screen. +assert-css: ("nav.sidebar", {"left": "-1000px"}) // We ensure that the class has been removed. assert-false: ".source-sidebar-expanded" assert: "nav.sidebar" -- cgit 1.4.1-3-g733a5 From e7a777805a63266292bb715e283db4107fb6e394 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 3 Jan 2023 13:27:49 +0800 Subject: Suggest possible clone when we have &T --- compiler/rustc_hir_typeck/src/demand.rs | 1 + .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 29 +++++++++ .../src/traits/error_reporting/mod.rs | 5 ++ .../src/traits/error_reporting/suggestions.rs | 72 +++++++++++++++++++++- .../suggestions/issue-106443-sugg-clone-for-arg.rs | 23 +++++++ .../issue-106443-sugg-clone-for-arg.stderr | 35 +++++++++++ .../issue-106443-sugg-clone-for-bound.rs | 20 ++++++ .../issue-106443-sugg-clone-for-bound.stderr | 29 +++++++++ 8 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs create mode 100644 src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.stderr create mode 100644 src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs create mode 100644 src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 0f191c21a0a..52778747987 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -57,6 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty) || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) + || self.suggest_clone_for_ref(err, expr, expr_ty, expected) || self.suggest_into(err, expr, expr_ty, expected) || self.suggest_floating_point_literal(err, expr, expected); if !suggested { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 066e98c7457..991b0399542 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1014,6 +1014,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(crate) fn suggest_clone_for_ref( + &self, + diag: &mut Diagnostic, + expr: &hir::Expr<'_>, + expr_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>, + ) -> bool { + if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind() && + let Some(clone_trait_def) = self.tcx.lang_items().clone_trait() && + expected_ty == *inner_ty && + self + .infcx + .type_implements_trait( + clone_trait_def, + [self.tcx.erase_regions(expected_ty)], + self.param_env + ) + .must_apply_modulo_regions() { + diag.span_suggestion_verbose( + expr.span.shrink_to_hi(), + "consider using clone here", + ".clone()", + Applicability::MachineApplicable, + ); + return true; + } + false + } + pub(crate) fn suggest_copied_or_cloned( &self, diag: &mut Diagnostic, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 17331a50105..9c098e1a2fc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -873,6 +873,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } + if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) { + err.emit(); + return; + } + if self.suggest_impl_trait(&mut err, span, &obligation, trait_predicate) { err.emit(); return; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 28f76b14146..d15196a9577 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -10,7 +10,7 @@ use crate::infer::InferCtxt; use crate::traits::{NormalizeExt, ObligationCtxt}; use hir::def::CtorOf; -use hir::HirId; +use hir::{Expr, HirId}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ @@ -206,11 +206,15 @@ pub trait TypeErrCtxtExt<'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ); - fn suggest_add_reference_to_arg( + fn suggest_add_clone_to_arg( &self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, + ); + + fn suggest_add_reference_to_arg( + err: &mut Diagnostic, has_custom_message: bool, ) -> bool; @@ -1102,6 +1106,70 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } + fn suggest_add_clone_to_arg( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) -> bool { + let span = obligation.cause.span; + let body_id = obligation.cause.body_id; + let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); + let ty = self.tcx.erase_late_bound_regions(self_ty); + let owner = self.tcx.hir().get_parent_item(body_id); + if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() && + let arg_node = self.tcx.hir().get(*arg_hir_id) && + let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node && + let Some(generics) = self.tcx.hir().get_generics(owner.def_id) && + let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() && + let ty::Param(param) = inner_ty.kind() && + let Some(generic_param) = + generics.params.iter().find(|p| p.name.ident().as_str() == param.name.as_str()) + { + let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); + let has_clone = self + .type_implements_trait(clone_trait, [ty], obligation.param_env) + .must_apply_modulo_regions(); + + let trait_pred_and_suggested_ty = + trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)); + let new_obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + trait_pred_and_suggested_ty, + ); + + if has_clone && self.predicate_may_hold(&new_obligation) { + let clone_bound = generics.bounds_for_param(generic_param.def_id) + .flat_map(|bp| bp.bounds) + .any(|bound| { + if let hir::GenericBound::Trait( hir::PolyTraitRef { trait_ref, ..}, ..) = bound { + Some(clone_trait) == trait_ref.trait_def_id() + } else { + false + } + }); + if !clone_bound { + suggest_constraining_type_param( + self.tcx, + generics, + err, + param.name.as_str(), + "Clone", + Some(clone_trait) + ); + } + err.span_suggestion_verbose( + span.shrink_to_hi(), + "consider using clone here", + ".clone()".to_string(), + Applicability::MaybeIncorrect, + ); + return true; + } + } + false + } + fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs b/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs new file mode 100644 index 00000000000..48efdb82c46 --- /dev/null +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.rs @@ -0,0 +1,23 @@ +#[derive(Clone)] +struct S; + +// without Clone +struct T; + +fn foo(_: S) {} + +fn test1() { + let s = &S; + foo(s); //~ ERROR mismatched types +} + +fn bar(_: T) {} +fn test2() { + let t = &T; + bar(t); //~ ERROR mismatched types +} + +fn main() { + test1(); + test2(); +} diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.stderr b/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.stderr new file mode 100644 index 00000000000..1e66fe3af24 --- /dev/null +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-arg.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/issue-106443-sugg-clone-for-arg.rs:11:9 + | +LL | foo(s); + | --- ^ expected struct `S`, found `&S` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-106443-sugg-clone-for-arg.rs:7:4 + | +LL | fn foo(_: S) {} + | ^^^ ---- +help: consider using clone here + | +LL | foo(s.clone()); + | ++++++++ + +error[E0308]: mismatched types + --> $DIR/issue-106443-sugg-clone-for-arg.rs:17:9 + | +LL | bar(t); + | --- ^ expected struct `T`, found `&T` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/issue-106443-sugg-clone-for-arg.rs:14:4 + | +LL | fn bar(_: T) {} + | ^^^ ---- + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs new file mode 100644 index 00000000000..4e4d4c044c9 --- /dev/null +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs @@ -0,0 +1,20 @@ +#[derive(Clone)] +struct S; + +trait X {} + +impl X for S {} + +fn foo(_: T) {} +fn bar(s: &T) { + foo(s); //~ ERROR the trait bound `&T: X` is not satisfied +} + +fn bar_with_clone(s: &T) { + foo(s); //~ ERROR the trait bound `&T: X` is not satisfied +} + +fn main() { + let s = &S; + bar(s); +} diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr new file mode 100644 index 00000000000..22bafc6cc8b --- /dev/null +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr @@ -0,0 +1,29 @@ +error[E0277]: the trait bound `&T: X` is not satisfied + --> $DIR/issue-106443-sugg-clone-for-bound.rs:10:9 + | +LL | foo(s); + | ^ the trait `X` is not implemented for `&T` + | +help: consider further restricting this bound + | +LL | fn bar(s: &T) { + | +++++++ +help: consider using clone here + | +LL | foo(s.clone()); + | ++++++++ + +error[E0277]: the trait bound `&T: X` is not satisfied + --> $DIR/issue-106443-sugg-clone-for-bound.rs:14:9 + | +LL | foo(s); + | ^ the trait `X` is not implemented for `&T` + | +help: consider using clone here + | +LL | foo(s.clone()); + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From 1a0a6132a8f4f3d54971c11c74035c5872a72a1f Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 6 Jan 2023 15:03:05 +0800 Subject: Apply suggestions from code review Co-authored-by: Esteban Kuber --- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 991b0399542..236bdc60e67 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1021,25 +1021,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_ty: Ty<'tcx>, expected_ty: Ty<'tcx>, ) -> bool { - if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind() && - let Some(clone_trait_def) = self.tcx.lang_items().clone_trait() && - expected_ty == *inner_ty && - self + if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind() + && let Some(clone_trait_def) = self.tcx.lang_items().clone_trait() + && expected_ty == *inner_ty + && self .infcx .type_implements_trait( clone_trait_def, [self.tcx.erase_regions(expected_ty)], self.param_env ) - .must_apply_modulo_regions() { - diag.span_suggestion_verbose( - expr.span.shrink_to_hi(), - "consider using clone here", - ".clone()", - Applicability::MachineApplicable, - ); - return true; - } + .must_apply_modulo_regions() + { + diag.span_suggestion_verbose( + expr.span.shrink_to_hi(), + "consider using clone here", + ".clone()", + Applicability::MachineApplicable, + ); + return true; + } false } -- cgit 1.4.1-3-g733a5 From ce4afed2efdaaceb2624021df3a8d8fff892415a Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 6 Jan 2023 07:44:10 +0800 Subject: comments feedback --- .../src/traits/error_reporting/suggestions.rs | 101 +++++++++++---------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d15196a9577..727bdc391bb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -211,10 +211,13 @@ pub trait TypeErrCtxtExt<'tcx> { obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, - ); + ) -> bool; fn suggest_add_reference_to_arg( + &self, + obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic, + trait_pred: ty::PolyTraitPredicate<'tcx>, has_custom_message: bool, ) -> bool; @@ -1112,60 +1115,58 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { - let span = obligation.cause.span; - let body_id = obligation.cause.body_id; let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let ty = self.tcx.erase_late_bound_regions(self_ty); - let owner = self.tcx.hir().get_parent_item(body_id); - if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() && - let arg_node = self.tcx.hir().get(*arg_hir_id) && - let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node && - let Some(generics) = self.tcx.hir().get_generics(owner.def_id) && - let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() && - let ty::Param(param) = inner_ty.kind() && - let Some(generic_param) = - generics.params.iter().find(|p| p.name.ident().as_str() == param.name.as_str()) - { - let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); - let has_clone = self - .type_implements_trait(clone_trait, [ty], obligation.param_env) - .must_apply_modulo_regions(); - - let trait_pred_and_suggested_ty = - trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)); - let new_obligation = self.mk_trait_obligation_with_new_self_ty( - obligation.param_env, - trait_pred_and_suggested_ty, - ); + let owner = self.tcx.hir().get_parent_item(obligation.cause.body_id); + let Some(generics) = self.tcx.hir().get_generics(owner.def_id) else { return false }; + let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false }; + let ty::Param(param) = inner_ty.kind() else { return false }; + let Some(generic_param) = generics.get_named(param.name) else { return false }; + let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { return false }; + let arg_node = self.tcx.hir().get(*arg_hir_id); + let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node else { return false }; + + let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); + let has_clone = self + .type_implements_trait(clone_trait, [ty], obligation.param_env) + .must_apply_modulo_regions(); + + let trait_pred_and_suggested_ty = + trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)); + let new_obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + trait_pred_and_suggested_ty, + ); - if has_clone && self.predicate_may_hold(&new_obligation) { - let clone_bound = generics.bounds_for_param(generic_param.def_id) - .flat_map(|bp| bp.bounds) - .any(|bound| { - if let hir::GenericBound::Trait( hir::PolyTraitRef { trait_ref, ..}, ..) = bound { - Some(clone_trait) == trait_ref.trait_def_id() - } else { - false - } - }); - if !clone_bound { - suggest_constraining_type_param( - self.tcx, - generics, - err, - param.name.as_str(), - "Clone", - Some(clone_trait) - ); - } - err.span_suggestion_verbose( - span.shrink_to_hi(), - "consider using clone here", - ".clone()".to_string(), - Applicability::MaybeIncorrect, + if has_clone && self.predicate_may_hold(&new_obligation) { + let clone_bound = generics + .bounds_for_param(generic_param.def_id) + .flat_map(|bp| bp.bounds) + .any(|bound| { + if let hir::GenericBound::Trait(hir::PolyTraitRef { trait_ref, .. }, ..) = bound + { + Some(clone_trait) == trait_ref.trait_def_id() + } else { + false + } + }); + if !clone_bound { + suggest_constraining_type_param( + self.tcx, + generics, + err, + param.name.as_str(), + "Clone", + Some(clone_trait), ); - return true; } + err.span_suggestion_verbose( + obligation.cause.span.shrink_to_hi(), + "consider using clone here", + ".clone()".to_string(), + Applicability::MaybeIncorrect, + ); + return true; } false } -- cgit 1.4.1-3-g733a5 From 1eb828ecb1675073c7995db80be2e63719fd73c9 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 1 Jan 2023 21:28:03 -0800 Subject: Structured suggestion for `&mut dyn Iterator` when possible Fix #37914. --- compiler/rustc_hir_typeck/src/method/mod.rs | 4 +-- compiler/rustc_hir_typeck/src/method/suggest.rs | 31 ++++++++++++++++++++-- .../mutability-mismatch-arg.fixed | 9 +++++++ .../illegal-sized-bound/mutability-mismatch-arg.rs | 9 +++++++ .../mutability-mismatch-arg.stderr | 16 +++++++++++ .../ui/illegal-sized-bound/mutability-mismatch.rs | 4 +-- .../illegal-sized-bound/mutability-mismatch.stderr | 4 +-- .../ui/suggestions/imm-ref-trait-object.stderr | 5 +++- 8 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed create mode 100644 src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs create mode 100644 src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index b9b27e8627a..f3c43e3f497 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -57,7 +57,7 @@ pub enum MethodError<'tcx> { PrivateMatch(DefKind, DefId, Vec), // Found a `Self: Sized` bound where `Self` is a trait object. - IllegalSizedBound(Vec, bool, Span), + IllegalSizedBound(Vec, bool, Span, &'tcx hir::Expr<'tcx>), // Found a match, but the return type is wrong BadReturnType, @@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Vec::new(), }; - return Err(IllegalSizedBound(candidates, needs_mut, span)); + return Err(IllegalSizedBound(candidates, needs_mut, span, self_expr)); } Ok(result.callee) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 1a42f9d07b1..5a43db69fd4 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - MethodError::IllegalSizedBound(candidates, needs_mut, bound_span) => { + MethodError::IllegalSizedBound(candidates, needs_mut, bound_span, self_expr) => { let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); let mut err = self.sess().struct_span_err(span, &msg); err.span_label(bound_span, "this has a `Sized` requirement"); @@ -197,7 +197,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { *region, ty::TypeAndMut { ty: *t_type, mutbl: mutability.invert() }, ); - err.note(&format!("you need `{}` instead of `{}`", trait_type, rcvr_ty)); + let msg = format!("you need `{}` instead of `{}`", trait_type, rcvr_ty); + let mut kind = &self_expr.kind; + while let hir::ExprKind::AddrOf(_, _, expr) + | hir::ExprKind::Unary(hir::UnOp::Deref, expr) = kind + { + kind = &expr.kind; + } + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind + && let hir::def::Res::Local(hir_id) = path.res + && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id) + && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id) + && let Some(hir::Node::Param(param)) = self.tcx.hir().find(parent_hir_id) + && let parent_hir_id = self.tcx.hir().get_parent_node(param.hir_id) + && let Some(node) = self.tcx.hir().find(parent_hir_id) + && let Some(decl) = node.fn_decl() + && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == param.ty_span) + && let hir::TyKind::Ref(_, mut_ty) = &ty.kind + && let hir::Mutability::Not = mut_ty.mutbl + { + err.span_suggestion_verbose( + mut_ty.ty.span.shrink_to_lo(), + &msg, + "mut ", + Applicability::MachineApplicable, + ); + } else { + err.help(&msg); + } } } err.emit(); diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed new file mode 100644 index 00000000000..260ef5458d4 --- /dev/null +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed @@ -0,0 +1,9 @@ +// run-rustfix +fn test(t: &mut dyn Iterator) -> u64 { + *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object +} + +fn main() { + let array = [0u64]; + test(&mut array.iter()); +} diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs new file mode 100644 index 00000000000..7a1656507f2 --- /dev/null +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs @@ -0,0 +1,9 @@ +// run-rustfix +fn test(t: &dyn Iterator) -> u64 { + *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object +} + +fn main() { + let array = [0u64]; + test(&mut array.iter()); +} diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr new file mode 100644 index 00000000000..9b4b9b65d10 --- /dev/null +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr @@ -0,0 +1,16 @@ +error: the `min` method cannot be invoked on a trait object + --> $DIR/mutability-mismatch-arg.rs:3:9 + | +LL | *t.min().unwrap() + | ^^^ + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | + = note: this has a `Sized` requirement + | +help: you need `&mut dyn Iterator` instead of `&dyn Iterator` + | +LL | fn test(t: &mut dyn Iterator) -> u64 { + | +++ + +error: aborting due to previous error + diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs index deb84f6fe97..aa9b3d03891 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs @@ -27,8 +27,8 @@ impl Trait for Type { fn main() { (&MutType as &dyn MutTrait).function(); //~^ ERROR the `function` method cannot be invoked on a trait object - //~| NOTE you need `&mut dyn MutTrait` instead of `&dyn MutTrait` + //~| HELP you need `&mut dyn MutTrait` instead of `&dyn MutTrait` (&mut Type as &mut dyn Trait).function(); //~^ ERROR the `function` method cannot be invoked on a trait object - //~| NOTE you need `&dyn Trait` instead of `&mut dyn Trait` + //~| HELP you need `&dyn Trait` instead of `&mut dyn Trait` } diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr index dbbf79a4f1a..0120b9f91e9 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr @@ -7,7 +7,7 @@ LL | Self: Sized; LL | (&MutType as &dyn MutTrait).function(); | ^^^^^^^^ | - = note: you need `&mut dyn MutTrait` instead of `&dyn MutTrait` + = help: you need `&mut dyn MutTrait` instead of `&dyn MutTrait` error: the `function` method cannot be invoked on a trait object --> $DIR/mutability-mismatch.rs:31:35 @@ -18,7 +18,7 @@ LL | Self: Sized; LL | (&mut Type as &mut dyn Trait).function(); | ^^^^^^^^ | - = note: you need `&dyn Trait` instead of `&mut dyn Trait` + = help: you need `&dyn Trait` instead of `&mut dyn Trait` error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 7791b308d5d..02847ed8c4c 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -7,7 +7,10 @@ LL | t.min().unwrap() | = note: this has a `Sized` requirement | - = note: you need `&mut dyn Iterator` instead of `&dyn Iterator` +help: you need `&mut dyn Iterator` instead of `&dyn Iterator` + | +LL | fn test(t: &mut dyn Iterator) -> u64 { + | +++ error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 670a6f1ef5d895d8b9ef5bba6f71576a4428b47a Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 2 Jan 2023 09:55:13 -0800 Subject: Change wording to avoid being misleading --- compiler/rustc_hir_typeck/src/method/suggest.rs | 12 ++++++++++-- .../ui/illegal-sized-bound/mutability-mismatch-arg.fixed | 2 +- src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs | 2 +- .../ui/illegal-sized-bound/mutability-mismatch-arg.stderr | 5 +---- src/test/ui/illegal-sized-bound/mutability-mismatch.rs | 6 ++---- src/test/ui/illegal-sized-bound/mutability-mismatch.stderr | 14 ++++---------- src/test/ui/suggestions/imm-ref-trait-object.rs | 2 +- src/test/ui/suggestions/imm-ref-trait-object.stderr | 5 +---- 8 files changed, 21 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 5a43db69fd4..fedffe3d81e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -177,9 +177,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } MethodError::IllegalSizedBound(candidates, needs_mut, bound_span, self_expr) => { - let msg = format!("the `{}` method cannot be invoked on a trait object", item_name); + let msg = if needs_mut { + with_forced_trimmed_paths!(format!( + "the `{item_name}` method cannot be invoked on `{rcvr_ty}`" + )) + } else { + format!("the `{item_name}` method cannot be invoked on a trait object") + }; let mut err = self.sess().struct_span_err(span, &msg); - err.span_label(bound_span, "this has a `Sized` requirement"); + if !needs_mut { + err.span_label(bound_span, "this has a `Sized` requirement"); + } if !candidates.is_empty() { let help = format!( "{an}other candidate{s} {were} found in the following trait{s}, perhaps \ diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed index 260ef5458d4..74f3c887f02 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.fixed @@ -1,6 +1,6 @@ // run-rustfix fn test(t: &mut dyn Iterator) -> u64 { - *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object + *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on } fn main() { diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs index 7a1656507f2..3b02c5a5ad1 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.rs @@ -1,6 +1,6 @@ // run-rustfix fn test(t: &dyn Iterator) -> u64 { - *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object + *t.min().unwrap() //~ ERROR the `min` method cannot be invoked on } fn main() { diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr index 9b4b9b65d10..89613bd5c20 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch-arg.stderr @@ -1,11 +1,8 @@ -error: the `min` method cannot be invoked on a trait object +error: the `min` method cannot be invoked on `&dyn Iterator` --> $DIR/mutability-mismatch-arg.rs:3:9 | LL | *t.min().unwrap() | ^^^ - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this has a `Sized` requirement | help: you need `&mut dyn Iterator` instead of `&dyn Iterator` | diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs index aa9b3d03891..01bb3537c2d 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch.rs +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.rs @@ -4,7 +4,6 @@ pub trait MutTrait { fn function(&mut self) where Self: Sized; - //~^ this has a `Sized` requirement } impl MutTrait for MutType { @@ -17,7 +16,6 @@ pub trait Trait { fn function(&self) where Self: Sized; - //~^ this has a `Sized` requirement } impl Trait for Type { @@ -26,9 +24,9 @@ impl Trait for Type { fn main() { (&MutType as &dyn MutTrait).function(); - //~^ ERROR the `function` method cannot be invoked on a trait object + //~^ ERROR the `function` method cannot be invoked on `&dyn MutTrait` //~| HELP you need `&mut dyn MutTrait` instead of `&dyn MutTrait` (&mut Type as &mut dyn Trait).function(); - //~^ ERROR the `function` method cannot be invoked on a trait object + //~^ ERROR the `function` method cannot be invoked on `&mut dyn Trait` //~| HELP you need `&dyn Trait` instead of `&mut dyn Trait` } diff --git a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr index 0120b9f91e9..2ca571d9b79 100644 --- a/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr +++ b/src/test/ui/illegal-sized-bound/mutability-mismatch.stderr @@ -1,20 +1,14 @@ -error: the `function` method cannot be invoked on a trait object - --> $DIR/mutability-mismatch.rs:28:33 +error: the `function` method cannot be invoked on `&dyn MutTrait` + --> $DIR/mutability-mismatch.rs:26:33 | -LL | Self: Sized; - | ----- this has a `Sized` requirement -... LL | (&MutType as &dyn MutTrait).function(); | ^^^^^^^^ | = help: you need `&mut dyn MutTrait` instead of `&dyn MutTrait` -error: the `function` method cannot be invoked on a trait object - --> $DIR/mutability-mismatch.rs:31:35 +error: the `function` method cannot be invoked on `&mut dyn Trait` + --> $DIR/mutability-mismatch.rs:29:35 | -LL | Self: Sized; - | ----- this has a `Sized` requirement -... LL | (&mut Type as &mut dyn Trait).function(); | ^^^^^^^^ | diff --git a/src/test/ui/suggestions/imm-ref-trait-object.rs b/src/test/ui/suggestions/imm-ref-trait-object.rs index 288d6c699f5..c1c969b90e4 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.rs +++ b/src/test/ui/suggestions/imm-ref-trait-object.rs @@ -1,5 +1,5 @@ fn test(t: &dyn Iterator) -> u64 { - t.min().unwrap() //~ ERROR the `min` method cannot be invoked on a trait object + t.min().unwrap() //~ ERROR the `min` method cannot be invoked on `&dyn Iterator` } fn main() { diff --git a/src/test/ui/suggestions/imm-ref-trait-object.stderr b/src/test/ui/suggestions/imm-ref-trait-object.stderr index 02847ed8c4c..f7f7902c17d 100644 --- a/src/test/ui/suggestions/imm-ref-trait-object.stderr +++ b/src/test/ui/suggestions/imm-ref-trait-object.stderr @@ -1,11 +1,8 @@ -error: the `min` method cannot be invoked on a trait object +error: the `min` method cannot be invoked on `&dyn Iterator` --> $DIR/imm-ref-trait-object.rs:2:8 | LL | t.min().unwrap() | ^^^ - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this has a `Sized` requirement | help: you need `&mut dyn Iterator` instead of `&dyn Iterator` | -- cgit 1.4.1-3-g733a5 From 2631a5df6135b8cf877fa2464fe428a6bc704048 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Thu, 5 Jan 2023 07:12:04 +0000 Subject: Turn `IllegalSizedBound` into struct variant --- compiler/rustc_hir_typeck/src/method/mod.rs | 11 ++++++++--- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index f3c43e3f497..d276bcdb81e 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -57,7 +57,12 @@ pub enum MethodError<'tcx> { PrivateMatch(DefKind, DefId, Vec), // Found a `Self: Sized` bound where `Self` is a trait object. - IllegalSizedBound(Vec, bool, Span, &'tcx hir::Expr<'tcx>), + IllegalSizedBound { + candidates: Vec, + needs_mut: bool, + bound_span: Span, + self_expr: &'tcx hir::Expr<'tcx>, + }, // Found a match, but the return type is wrong BadReturnType, @@ -112,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(NoMatch(..)) => false, Err(Ambiguity(..)) => true, Err(PrivateMatch(..)) => allow_private, - Err(IllegalSizedBound(..)) => true, + Err(IllegalSizedBound { .. }) => true, Err(BadReturnType) => bug!("no return type expectations but got BadReturnType"), } } @@ -236,7 +241,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Vec::new(), }; - return Err(IllegalSizedBound(candidates, needs_mut, span, self_expr)); + return Err(IllegalSizedBound { candidates, needs_mut, bound_span: span, self_expr }); } Ok(result.callee) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index fedffe3d81e..bcdb557be21 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - MethodError::IllegalSizedBound(candidates, needs_mut, bound_span, self_expr) => { + MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { let msg = if needs_mut { with_forced_trimmed_paths!(format!( "the `{item_name}` method cannot be invoked on `{rcvr_ty}`" -- cgit 1.4.1-3-g733a5 From b693365b846b13c1da6c5158cc7f4598a1aaa2e4 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Fri, 6 Jan 2023 21:08:56 +0000 Subject: fix rebase --- compiler/rustc_hir_typeck/src/method/suggest.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index bcdb557be21..536c4270659 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -214,13 +214,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind && let hir::def::Res::Local(hir_id) = path.res - && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(hir_id) - && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id) - && let Some(hir::Node::Param(param)) = self.tcx.hir().find(parent_hir_id) - && let parent_hir_id = self.tcx.hir().get_parent_node(param.hir_id) - && let Some(node) = self.tcx.hir().find(parent_hir_id) + && let Some(hir::Node::Pat(b)) = self.tcx.hir().find(hir_id) + && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id) + && let Some(node) = self.tcx.hir().find_parent(p.hir_id) && let Some(decl) = node.fn_decl() - && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == param.ty_span) + && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span) && let hir::TyKind::Ref(_, mut_ty) = &ty.kind && let hir::Mutability::Not = mut_ty.mutbl { -- cgit 1.4.1-3-g733a5 From d4139b36cf8bdc3c46616112fed42b589dec5395 Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Fri, 6 Jan 2023 23:10:14 +0000 Subject: jsondoclint: Check local items in `paths` are also in `index`. --- src/tools/jsondoclint/src/validator.rs | 29 +++++++- src/tools/jsondoclint/src/validator/tests.rs | 100 ++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index f1b9c1acbae..c6f55410e44 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -3,14 +3,17 @@ use std::hash::Hash; use rustdoc_json_types::{ Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs, - GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Module, OpaqueTy, Path, - Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding, - TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate, + GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, ItemSummary, Module, + OpaqueTy, Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, + Type, TypeBinding, TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate, }; use serde_json::Value; use crate::{item_kind::Kind, json_find, Error, ErrorKind}; +// This is a rustc implementation detail that we rely on here +const LOCAL_CRATE_ID: u32 = 0; + /// The Validator walks over the JSON tree, and ensures it is well formed. /// It is made of several parts. /// @@ -53,12 +56,19 @@ impl<'a> Validator<'a> { } pub fn check_crate(&mut self) { + // Graph traverse the index let root = &self.krate.root; self.add_mod_id(root); while let Some(id) = set_remove(&mut self.todo) { self.seen_ids.insert(id); self.check_item(id); } + + let root_crate_id = self.krate.index[root].crate_id; + assert_eq!(root_crate_id, LOCAL_CRATE_ID, "LOCAL_CRATE_ID is wrong"); + for (id, item_info) in &self.krate.paths { + self.check_item_info(id, item_info); + } } fn check_item(&mut self, id: &'a Id) { @@ -364,6 +374,19 @@ impl<'a> Validator<'a> { fp.generic_params.iter().for_each(|gpd| self.check_generic_param_def(gpd)); } + fn check_item_info(&mut self, id: &Id, item_info: &ItemSummary) { + // FIXME: Their should be a better way to determine if an item is local, rather than relying on `LOCAL_CRATE_ID`, + // which encodes rustc implementation details. + if item_info.crate_id == LOCAL_CRATE_ID && !self.krate.index.contains_key(id) { + self.errs.push(Error { + id: id.clone(), + kind: ErrorKind::Custom( + "Id for local item in `paths` but not in `index`".to_owned(), + ), + }) + } + } + fn add_id_checked(&mut self, id: &'a Id, valid: fn(Kind) -> bool, expected: &str) { if let Some(kind) = self.kind_of(id) { if valid(kind) { diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs index 37b826153ef..1ef41ff123a 100644 --- a/src/tools/jsondoclint/src/validator/tests.rs +++ b/src/tools/jsondoclint/src/validator/tests.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use rustdoc_json_types::{Crate, Item, Visibility}; +use rustdoc_json_types::{Crate, Item, ItemKind, ItemSummary, Visibility, FORMAT_VERSION}; use crate::json_find::SelectorPart; @@ -64,3 +64,101 @@ fn errors_on_missing_links() { }], ); } + +// Test we would catch +// https://github.com/rust-lang/rust/issues/104064#issuecomment-1368589718 +#[test] +fn errors_on_local_in_paths_and_not_index() { + let krate = Crate { + root: id("0:0:1572"), + crate_version: None, + includes_private: false, + index: HashMap::from_iter([ + ( + id("0:0:1572"), + Item { + id: id("0:0:1572"), + crate_id: 0, + name: Some("microcore".to_owned()), + span: None, + visibility: Visibility::Public, + docs: None, + links: HashMap::from_iter([(("prim@i32".to_owned(), id("0:1:1571")))]), + attrs: Vec::new(), + deprecation: None, + inner: ItemEnum::Module(Module { + is_crate: true, + items: vec![id("0:1:717")], + is_stripped: false, + }), + }, + ), + ( + id("0:1:717"), + Item { + id: id("0:1:717"), + crate_id: 0, + name: Some("i32".to_owned()), + span: None, + visibility: Visibility::Public, + docs: None, + links: HashMap::default(), + attrs: Vec::new(), + deprecation: None, + inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }), + }, + ), + ]), + paths: HashMap::from_iter([( + id("0:1:1571"), + ItemSummary { + crate_id: 0, + path: vec!["microcore".to_owned(), "i32".to_owned()], + kind: ItemKind::Primitive, + }, + )]), + external_crates: HashMap::default(), + format_version: rustdoc_json_types::FORMAT_VERSION, + }; + + check( + &krate, + &[Error { + id: id("0:1:1571"), + kind: ErrorKind::Custom("Id for local item in `paths` but not in `index`".to_owned()), + }], + ); +} + +#[test] +#[should_panic = "LOCAL_CRATE_ID is wrong"] +fn checks_local_crate_id_is_correct() { + let krate = Crate { + root: id("root"), + crate_version: None, + includes_private: false, + index: HashMap::from_iter([( + id("root"), + Item { + id: id("root"), + crate_id: LOCAL_CRATE_ID.wrapping_add(1), + name: Some("irrelavent".to_owned()), + span: None, + visibility: Visibility::Public, + docs: None, + links: HashMap::default(), + attrs: Vec::new(), + deprecation: None, + inner: ItemEnum::Module(Module { + is_crate: true, + items: vec![], + is_stripped: false, + }), + }, + )]), + paths: HashMap::default(), + external_crates: HashMap::default(), + format_version: FORMAT_VERSION, + }; + check(&krate, &[]); +} -- cgit 1.4.1-3-g733a5 From 6082729646e3530ecdd522921837806db83b27e3 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 7 Jan 2023 07:16:48 +0800 Subject: use type_implements_trait to check Param clone --- .../src/traits/error_reporting/suggestions.rs | 27 ++++++---------------- .../issue-106443-sugg-clone-for-bound.rs | 4 ++-- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 727bdc391bb..c52365ae3b7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1121,36 +1121,23 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let Some(generics) = self.tcx.hir().get_generics(owner.def_id) else { return false }; let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false }; let ty::Param(param) = inner_ty.kind() else { return false }; - let Some(generic_param) = generics.get_named(param.name) else { return false }; let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { return false }; let arg_node = self.tcx.hir().get(*arg_hir_id); let Node::Expr(Expr { kind: hir::ExprKind::Path(_), ..}) = arg_node else { return false }; let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None); - let has_clone = self - .type_implements_trait(clone_trait, [ty], obligation.param_env) - .must_apply_modulo_regions(); + let has_clone = |ty| { + self.type_implements_trait(clone_trait, [ty], obligation.param_env) + .must_apply_modulo_regions() + }; - let trait_pred_and_suggested_ty = - trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)); let new_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, - trait_pred_and_suggested_ty, + trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)), ); - if has_clone && self.predicate_may_hold(&new_obligation) { - let clone_bound = generics - .bounds_for_param(generic_param.def_id) - .flat_map(|bp| bp.bounds) - .any(|bound| { - if let hir::GenericBound::Trait(hir::PolyTraitRef { trait_ref, .. }, ..) = bound - { - Some(clone_trait) == trait_ref.trait_def_id() - } else { - false - } - }); - if !clone_bound { + if self.predicate_may_hold(&new_obligation) && has_clone(ty) { + if !has_clone(param.to_ty(self.tcx)) { suggest_constraining_type_param( self.tcx, generics, diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs index 4e4d4c044c9..3b2e316b296 100644 --- a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.rs @@ -6,11 +6,11 @@ trait X {} impl X for S {} fn foo(_: T) {} -fn bar(s: &T) { +fn bar(s: &T) { foo(s); //~ ERROR the trait bound `&T: X` is not satisfied } -fn bar_with_clone(s: &T) { +fn bar_with_clone(s: &T) { foo(s); //~ ERROR the trait bound `&T: X` is not satisfied } -- cgit 1.4.1-3-g733a5 From 43bec832667252ea2e78abe17918ba5fbbc1e27d Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 7 Jan 2023 17:08:04 +1300 Subject: docs: make `HashSet::retain` doctest more clear --- library/std/src/collections/hash/set.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index cee884145c7..b59f89d321c 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -317,7 +317,7 @@ impl HashSet { /// /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]); /// set.retain(|&k| k % 2 == 0); - /// assert_eq!(set.len(), 3); + /// assert_eq!(set, HashSet::from([2, 4, 6])); /// ``` /// /// # Performance -- cgit 1.4.1-3-g733a5 From dc0e4207d4d621d031ef25395f93cc43d36a08f2 Mon Sep 17 00:00:00 2001 From: LingMan Date: Sat, 7 Jan 2023 05:10:53 +0100 Subject: Fix a typo in the explanation of E0588 --- compiler/rustc_error_codes/src/error_codes/E0588.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0588.md b/compiler/rustc_error_codes/src/error_codes/E0588.md index 040c7a02ef4..995d945f158 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0588.md +++ b/compiler/rustc_error_codes/src/error_codes/E0588.md @@ -11,7 +11,7 @@ struct Aligned(i32); struct Packed(Aligned); ``` -Just like you cannot have both `align` and `packed` representation hints on a +Just like you cannot have both `align` and `packed` representation hints on the same type, a `packed` type cannot contain another type with the `align` representation hint. However, you can do the opposite: -- cgit 1.4.1-3-g733a5 From a7ac923088e6088be6c16c27dd9dca07bad7a391 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 6 Jan 2023 22:21:54 -0700 Subject: rustdoc: remove no-op mobile CSS `.content { margin-left: 0 }` This rule was added to override non-zero left margin on `.content`, which was removed in 135281ed1525db15edd8ebd092aa10aa40df2386 and the margin-left was put on the docblock. --- src/librustdoc/html/static/css/rustdoc.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 05a12d3d4d4..c1ed0ccef88 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1655,10 +1655,6 @@ in storage.js margin-top: 1em; } - .content { - margin-left: 0px; - } - .anchor { display: none !important; } -- cgit 1.4.1-3-g733a5 From 09382db78b293a649115fbd3d5bc79aaaf7b8deb Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 7 Jan 2023 18:36:32 +1300 Subject: minor fixes for `error_codes.rs` tidy check --- src/tools/tidy/src/error_codes.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index fdc9d789905..4b0a62fac83 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -15,8 +15,6 @@ //! //! 4. We check that the error code is actually emitted by the compiler. //! - This is done by searching `compiler/` with a regex. -//! -//! This tidy check was merged and refactored from two others. See #PR_NUM for information about linting changes that occurred during this refactor. use std::{ffi::OsStr, fs, path::Path}; @@ -57,7 +55,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose); // Stage 3: check list has UI tests - check_error_codes_tests(root_path, &error_codes, &mut errors, verbose); + check_error_codes_tests(root_path, &error_codes, &mut errors, verbose, &no_longer_emitted); // Stage 4: check list is emitted by compiler check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted, verbose); @@ -174,8 +172,9 @@ fn check_error_codes_docs( return; } - let (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) = + let (found_code_example, found_proper_doctest, emit_ignore_warning, no_longer_emitted) = check_explanation_has_doctest(&contents, &err_code); + if emit_ignore_warning { verbose_print!( verbose, @@ -183,13 +182,11 @@ fn check_error_codes_docs( `IGNORE_DOCTEST_CHECK` constant instead." ); } - if emit_no_longer_warning { + + if no_longer_emitted { no_longer_emitted_codes.push(err_code.to_owned()); - verbose_print!( - verbose, - "warning: Error code `{err_code}` is no longer emitted and should be removed entirely." - ); } + if !found_code_example { verbose_print!( verbose, @@ -226,7 +223,7 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo let mut found_proper_doctest = false; let mut emit_ignore_warning = false; - let mut emit_no_longer_warning = false; + let mut no_longer_emitted = false; for line in explanation.lines() { let line = line.trim(); @@ -246,13 +243,13 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo } else if line .starts_with("#### Note: this error code is no longer emitted by the compiler") { - emit_no_longer_warning = true; + no_longer_emitted = true; found_code_example = true; found_proper_doctest = true; } } - (found_code_example, found_proper_doctest, emit_ignore_warning, emit_no_longer_warning) + (found_code_example, found_proper_doctest, emit_ignore_warning, no_longer_emitted) } // Stage 3: Checks that each error code has a UI test in the correct directory @@ -261,6 +258,7 @@ fn check_error_codes_tests( error_codes: &[String], errors: &mut Vec, verbose: bool, + no_longer_emitted: &[String], ) { let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH)); @@ -295,6 +293,11 @@ fn check_error_codes_tests( } }; + if no_longer_emitted.contains(code) { + // UI tests *can't* contain error codes that are no longer emitted. + continue; + } + let mut found_code = false; for line in file.lines() { -- cgit 1.4.1-3-g733a5 From 75f1dfcc3236029bbd33799b94742424711e0376 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 22 Dec 2022 20:18:30 +0900 Subject: Add regression test for #86106 Signed-off-by: Yuki Okushi --- src/test/codegen/issue-86106.rs | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/codegen/issue-86106.rs diff --git a/src/test/codegen/issue-86106.rs b/src/test/codegen/issue-86106.rs new file mode 100644 index 00000000000..e81cab9f1df --- /dev/null +++ b/src/test/codegen/issue-86106.rs @@ -0,0 +1,56 @@ +// min-llvm-version: 15.0 +// compile-flags: -C opt-level=3 -C target-cpu=native + +// The below two functions ensure that both `String::new()` and `"".to_string()` +// produce the identical code. + +#![crate_type = "lib"] + +// CHECK-LABEL: @string_new = unnamed_addr alias void (ptr), ptr @empty_to_string +// CHECK: define void @empty_to_string +#[no_mangle] +pub fn string_new() -> String { + String::new() +} + +#[no_mangle] +pub fn empty_to_string() -> String { + // CHECK-NOT: load i8 + // CHECK: store i64 + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NOT: store i8 + // CHECK-NEXT: store i64 + // CHECK-NEXT: ret void + "".to_string() +} + +// The below two functions ensure that both `vec![]` and `vec![].clone()` +// produce the identical code. + +// CHECK-LABEL: @empty_vec +#[no_mangle] +pub fn empty_vec() -> Vec { + // CHECK: store i64 + // CHECK-NOT: load i8 + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i64 + // CHECK-NEXT: ret void + vec![] +} + +// CHECK-LABEL: @empty_vec_clone +#[no_mangle] +pub fn empty_vec_clone() -> Vec { + // CHECK: store i64 + // CHECK-NOT: load i8 + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i64 + // CHECK-NEXT: ret void + vec![].clone() +} -- cgit 1.4.1-3-g733a5 From 78e11a45564e1e8a67f0078fe89659032aed41a6 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 22 Dec 2022 20:45:36 +0900 Subject: Apply review suggestions Signed-off-by: Yuki Okushi --- src/test/codegen/issue-86106.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test/codegen/issue-86106.rs b/src/test/codegen/issue-86106.rs index e81cab9f1df..e647dbe2514 100644 --- a/src/test/codegen/issue-86106.rs +++ b/src/test/codegen/issue-86106.rs @@ -1,5 +1,5 @@ // min-llvm-version: 15.0 -// compile-flags: -C opt-level=3 -C target-cpu=native +// compile-flags: -C opt-level=3 // The below two functions ensure that both `String::new()` and `"".to_string()` // produce the identical code. @@ -7,21 +7,20 @@ #![crate_type = "lib"] // CHECK-LABEL: @string_new = unnamed_addr alias void (ptr), ptr @empty_to_string -// CHECK: define void @empty_to_string #[no_mangle] pub fn string_new() -> String { String::new() } +// CHECK-LABEL: define void @empty_to_string #[no_mangle] pub fn empty_to_string() -> String { // CHECK-NOT: load i8 - // CHECK: store i64 + // CHECK: store i{{32|64}} // CHECK-NEXT: getelementptr // CHECK-NEXT: store ptr // CHECK-NEXT: getelementptr - // CHECK-NOT: store i8 - // CHECK-NEXT: store i64 + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void "".to_string() } @@ -32,12 +31,12 @@ pub fn empty_to_string() -> String { // CHECK-LABEL: @empty_vec #[no_mangle] pub fn empty_vec() -> Vec { - // CHECK: store i64 + // CHECK: store i{{32|64}} // CHECK-NOT: load i8 // CHECK-NEXT: getelementptr // CHECK-NEXT: store ptr // CHECK-NEXT: getelementptr - // CHECK-NEXT: store i64 + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void vec![] } @@ -45,12 +44,12 @@ pub fn empty_vec() -> Vec { // CHECK-LABEL: @empty_vec_clone #[no_mangle] pub fn empty_vec_clone() -> Vec { - // CHECK: store i64 + // CHECK: store i{{32|64}} // CHECK-NOT: load i8 // CHECK-NEXT: getelementptr // CHECK-NEXT: store ptr // CHECK-NEXT: getelementptr - // CHECK-NEXT: store i64 + // CHECK-NEXT: store i{{32|64}} // CHECK-NEXT: ret void vec![].clone() } -- cgit 1.4.1-3-g733a5 From ab9313e624d581a75f4b886c0adf351f848d725a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 7 Jan 2023 19:03:07 +0900 Subject: Apply `merge-functions=disabled` Signed-off-by: Yuki Okushi --- src/test/codegen/issue-86106.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/issue-86106.rs b/src/test/codegen/issue-86106.rs index e647dbe2514..9ccbcb24f56 100644 --- a/src/test/codegen/issue-86106.rs +++ b/src/test/codegen/issue-86106.rs @@ -1,14 +1,21 @@ // min-llvm-version: 15.0 -// compile-flags: -C opt-level=3 +// compile-flags: -C opt-level=3 -Z merge-functions=disabled // The below two functions ensure that both `String::new()` and `"".to_string()` // produce the identical code. #![crate_type = "lib"] -// CHECK-LABEL: @string_new = unnamed_addr alias void (ptr), ptr @empty_to_string +// CHECK-LABEL: define void @string_new #[no_mangle] pub fn string_new() -> String { + // CHECK-NOT: load i8 + // CHECK: store i{{32|64}} + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store ptr + // CHECK-NEXT: getelementptr + // CHECK-NEXT: store i{{32|64}} + // CHECK-NEXT: ret void String::new() } -- cgit 1.4.1-3-g733a5 From fed349957dc774b4f5f614e030fe61304e9325f8 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 7 Jan 2023 14:38:21 +0000 Subject: Clarify examples for `VecDeque::get/get_mut` --- library/alloc/src/collections/vec_deque/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index c955db46d29..1b576521a91 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -636,6 +636,7 @@ impl VecDeque { /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); + /// buf.push_back(6); /// assert_eq!(buf.get(1), Some(&4)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -661,10 +662,11 @@ impl VecDeque { /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); + /// buf.push_back(6); + /// assert_eq!(buf[1], 4); /// if let Some(elem) = buf.get_mut(1) { /// *elem = 7; /// } - /// /// assert_eq!(buf[1], 7); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -- cgit 1.4.1-3-g733a5 From a139fd06277dd714b5244fcbb621488e1da2d518 Mon Sep 17 00:00:00 2001 From: Folyd Date: Sat, 7 Jan 2023 23:50:07 +0800 Subject: Change to immutable borrow when cloning element of RepeatN --- library/core/src/iter/sources/repeat_n.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index fd8d25ce1a5..dc61d6065b8 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -126,7 +126,7 @@ impl Iterator for RepeatN { // zero so it won't be dropped later, and thus it's okay to take it here. unsafe { ManuallyDrop::take(&mut self.element) } } else { - A::clone(&mut self.element) + A::clone(&self.element) }) } -- cgit 1.4.1-3-g733a5 From eddb479ad36841a858f186af81d4ac360d2a2058 Mon Sep 17 00:00:00 2001 From: Sky Date: Sat, 7 Jan 2023 14:16:59 -0500 Subject: Don't derive Debug for `OnceWith` & `RepeatWith` --- library/core/src/iter/sources/once_with.rs | 14 +++++++++++++- library/core/src/iter/sources/repeat_with.rs | 10 +++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/sources/once_with.rs b/library/core/src/iter/sources/once_with.rs index d79f85c2559..080ae27a30f 100644 --- a/library/core/src/iter/sources/once_with.rs +++ b/library/core/src/iter/sources/once_with.rs @@ -1,3 +1,4 @@ +use crate::fmt; use crate::iter::{FusedIterator, TrustedLen}; /// Creates an iterator that lazily generates a value exactly once by invoking @@ -66,12 +67,23 @@ pub fn once_with A>(gen: F) -> OnceWith { /// /// This `struct` is created by the [`once_with()`] function. /// See its documentation for more. -#[derive(Clone, Debug)] +#[derive(Clone)] #[stable(feature = "iter_once_with", since = "1.43.0")] pub struct OnceWith { gen: Option, } +#[stable(feature = "iter_once_with_debug", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Debug for OnceWith { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.gen.is_some() { + f.write_str("OnceWith(Some(_))") + } else { + f.write_str("OnceWith(None)") + } + } +} + #[stable(feature = "iter_once_with", since = "1.43.0")] impl A> Iterator for OnceWith { type Item = A; diff --git a/library/core/src/iter/sources/repeat_with.rs b/library/core/src/iter/sources/repeat_with.rs index ab2d0472b47..20420a3ad8e 100644 --- a/library/core/src/iter/sources/repeat_with.rs +++ b/library/core/src/iter/sources/repeat_with.rs @@ -1,3 +1,4 @@ +use crate::fmt; use crate::iter::{FusedIterator, TrustedLen}; use crate::ops::Try; @@ -71,12 +72,19 @@ pub fn repeat_with A>(repeater: F) -> RepeatWith { /// /// This `struct` is created by the [`repeat_with()`] function. /// See its documentation for more. -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone)] #[stable(feature = "iterator_repeat_with", since = "1.28.0")] pub struct RepeatWith { repeater: F, } +#[stable(feature = "iterator_repeat_with_debug", since = "CURRENT_RUSTC_VERSION")] +impl fmt::Debug for RepeatWith { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("RepeatWith").finish_non_exhaustive() + } +} + #[stable(feature = "iterator_repeat_with", since = "1.28.0")] impl A> Iterator for RepeatWith { type Item = A; -- cgit 1.4.1-3-g733a5 From 288e89bf76856653b69c8db77003ab190e86272b Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 7 Jan 2023 15:56:36 -0800 Subject: Document that `Vec::from_raw_parts[_in]` must be given a pointer from the correct allocator. --- library/alloc/src/vec/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1da73862d4a..36cfac8ee9e 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -490,6 +490,8 @@ impl Vec { /// This is highly unsafe, due to the number of invariants that aren't /// checked: /// + /// * `ptr` must have been allocated using the global allocator, such as via + /// the [`alloc::alloc`] function. /// * `T` needs to have the same alignment as what `ptr` was allocated with. /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be @@ -526,6 +528,7 @@ impl Vec { /// function. /// /// [`String`]: crate::string::String + /// [`alloc::alloc`]: crate::alloc::alloc /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc /// /// # Examples @@ -681,6 +684,7 @@ impl Vec { /// This is highly unsafe, due to the number of invariants that aren't /// checked: /// + /// * `ptr` must be [*currently allocated*] via the given allocator `alloc`. /// * `T` needs to have the same alignment as what `ptr` was allocated with. /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be @@ -714,6 +718,7 @@ impl Vec { /// /// [`String`]: crate::string::String /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc + /// [*currently allocated*]: crate::alloc::Allocator#currently-allocated-memory /// [*fit*]: crate::alloc::Allocator#memory-fitting /// /// # Examples -- cgit 1.4.1-3-g733a5 From ae61c250cd6124d0ec5095acb3be64b633268ab3 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 7 Jan 2023 18:37:40 +1300 Subject: doc/test: add UI test and reword docs for `E0013` and `E0015` --- .../rustc_error_codes/src/error_codes/E0015.md | 23 ++++++++-------------- src/test/ui/error-codes/E0013.rs | 4 ++++ src/test/ui/error-codes/E0013.stderr | 11 +++++++++++ src/test/ui/error-codes/E0015.rs | 8 ++++++++ src/test/ui/error-codes/E0015.stderr | 11 +++++++++++ 5 files changed, 42 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/error-codes/E0013.rs create mode 100644 src/test/ui/error-codes/E0013.stderr create mode 100644 src/test/ui/error-codes/E0015.rs create mode 100644 src/test/ui/error-codes/E0015.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0015.md b/compiler/rustc_error_codes/src/error_codes/E0015.md index 021a0219d13..ac78f66adad 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0015.md +++ b/compiler/rustc_error_codes/src/error_codes/E0015.md @@ -1,5 +1,4 @@ -A constant item was initialized with something that is not a constant -expression. +A non-`const` function was called in a `const` context. Erroneous code example: @@ -8,26 +7,20 @@ fn create_some() -> Option { Some(1) } -const FOO: Option = create_some(); // error! +// error: cannot call non-const fn `create_some` in constants +const FOO: Option = create_some(); ``` -The only functions that can be called in static or constant expressions are -`const` functions, and struct/enum constructors. +All functions used in a `const` context (constant or static expression) must +be marked `const`. To fix this error, you can declare `create_some` as a constant function: ``` -const fn create_some() -> Option { // declared as a const function +// declared as a `const` function: +const fn create_some() -> Option { Some(1) } -const FOO: Option = create_some(); // ok! - -// These are also working: -struct Bar { - x: u8, -} - -const OTHER_FOO: Option = Some(1); -const BAR: Bar = Bar {x: 1}; +const FOO: Option = create_some(); // no error! ``` diff --git a/src/test/ui/error-codes/E0013.rs b/src/test/ui/error-codes/E0013.rs new file mode 100644 index 00000000000..9b3982a785b --- /dev/null +++ b/src/test/ui/error-codes/E0013.rs @@ -0,0 +1,4 @@ +static X: i32 = 42; +const Y: i32 = X; //~ ERROR constants cannot refer to statics [E0013] + +fn main() {} diff --git a/src/test/ui/error-codes/E0013.stderr b/src/test/ui/error-codes/E0013.stderr new file mode 100644 index 00000000000..dc22053a638 --- /dev/null +++ b/src/test/ui/error-codes/E0013.stderr @@ -0,0 +1,11 @@ +error[E0013]: constants cannot refer to statics + --> $DIR/E0013.rs:2:16 + | +LL | const Y: i32 = X; + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/error-codes/E0015.rs b/src/test/ui/error-codes/E0015.rs new file mode 100644 index 00000000000..b0211358d81 --- /dev/null +++ b/src/test/ui/error-codes/E0015.rs @@ -0,0 +1,8 @@ +fn create_some() -> Option { + Some(1) +} + +const FOO: Option = create_some(); +//~^ ERROR cannot call non-const fn `create_some` in constants [E0015] + +fn main() {} diff --git a/src/test/ui/error-codes/E0015.stderr b/src/test/ui/error-codes/E0015.stderr new file mode 100644 index 00000000000..ec1ce47b2ce --- /dev/null +++ b/src/test/ui/error-codes/E0015.stderr @@ -0,0 +1,11 @@ +error[E0015]: cannot call non-const fn `create_some` in constants + --> $DIR/E0015.rs:5:25 + | +LL | const FOO: Option = create_some(); + | ^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0015`. -- cgit 1.4.1-3-g733a5 From 93c0d8d5d59e096dc2ed545d1eba09f16f0b5874 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sun, 8 Jan 2023 14:46:01 +1300 Subject: remove unreachable error code `E0313` --- compiler/rustc_error_codes/src/error_codes.rs | 3 +- .../rustc_infer/src/infer/error_reporting/mod.rs | 1 - .../rustc_infer/src/infer/error_reporting/note.rs | 37 ---------------------- compiler/rustc_infer/src/infer/mod.rs | 4 --- src/tools/tidy/src/error_codes.rs | 4 +-- 5 files changed, 3 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 3fba2cf5749..76d5da19399 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -579,8 +579,7 @@ E0791: include_str!("./error_codes/E0791.md"), // E0300, // unexpanded macro // E0304, // expected signed integer constant // E0305, // expected constant - E0313, // lifetime of borrowed pointer outlives lifetime of captured - // variable +// E0313, // removed: found unreachable // E0314, // closure outlives stack frame // E0315, // cannot invoke closure outside of its lifetime // E0319, // trait impls for defaulted traits allowed just for structs/enums diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 0644c7ada10..b02e7d73c51 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1,4 +1,3 @@ -// ignore-tidy-filelength //! Error Reporting Code for the inference engine //! //! Because of the way inference, and in particular region inference, diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index d91ef882bc4..7bb79d7bda8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -25,16 +25,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Reborrow(span) => { RegionOriginNote::Plain { span, msg: fluent::infer_reborrow }.add_to_diagnostic(err) } - infer::ReborrowUpvar(span, ref upvar_id) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - RegionOriginNote::WithName { - span, - msg: fluent::infer_reborrow, - name: &var_name.to_string(), - continues: false, - } - .add_to_diagnostic(err); - } infer::RelateObjectBound(span) => { RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound } .add_to_diagnostic(err); @@ -162,33 +152,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); err } - infer::ReborrowUpvar(span, ref upvar_id) => { - let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0313, - "lifetime of borrowed pointer outlives lifetime of captured variable `{}`...", - var_name - ); - note_and_explain_region( - self.tcx, - &mut err, - "...the borrowed pointer is valid for ", - sub, - "...", - None, - ); - note_and_explain_region( - self.tcx, - &mut err, - &format!("...but `{}` is only valid for ", var_name), - sup, - "", - None, - ); - err - } infer::RelateObjectBound(span) => { let mut err = struct_span_err!( self.tcx.sess, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b17a465eb38..bc8bbd4be6a 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -409,9 +409,6 @@ pub enum SubregionOrigin<'tcx> { /// Creating a pointer `b` to contents of another reference Reborrow(Span), - /// Creating a pointer `b` to contents of an upvar - ReborrowUpvar(Span, ty::UpvarId), - /// Data with type `Ty<'tcx>` was borrowed DataBorrowed(Ty<'tcx>, Span), @@ -1954,7 +1951,6 @@ impl<'tcx> SubregionOrigin<'tcx> { RelateParamBound(a, ..) => a, RelateRegionParamBound(a) => a, Reborrow(a) => a, - ReborrowUpvar(a, _) => a, DataBorrowed(_, a) => a, ReferenceOutlivesReferent(_, a) => a, CompareImplItemObligation { span, .. } => span, diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index fdc9d789905..adc07446741 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -33,8 +33,8 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602"]; // Error codes that don't yet have a UI test. This list will eventually be removed. const IGNORE_UI_TEST_CHECK: &[&str] = &[ - "E0313", "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", - "E0729", "E0789", + "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729", + "E0789", ]; macro_rules! verbose_print { -- cgit 1.4.1-3-g733a5 From d85d38b7b8ad9faa12231bbcc9a0214410c0719c Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 8 Jan 2023 01:53:08 +0000 Subject: Add test --- src/test/ui/type/closure-with-wrong-borrows.rs | 10 ++++++++++ src/test/ui/type/closure-with-wrong-borrows.stderr | 23 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/test/ui/type/closure-with-wrong-borrows.rs create mode 100644 src/test/ui/type/closure-with-wrong-borrows.stderr diff --git a/src/test/ui/type/closure-with-wrong-borrows.rs b/src/test/ui/type/closure-with-wrong-borrows.rs new file mode 100644 index 00000000000..5f6a78351a2 --- /dev/null +++ b/src/test/ui/type/closure-with-wrong-borrows.rs @@ -0,0 +1,10 @@ +struct S<'a>(&'a str); + +fn f(inner: fn(&str, &S)) { +} + +#[allow(unreachable_code)] +fn main() { + let inner: fn(_, _) = unimplemented!(); + f(inner); //~ ERROR mismatched types +} diff --git a/src/test/ui/type/closure-with-wrong-borrows.stderr b/src/test/ui/type/closure-with-wrong-borrows.stderr new file mode 100644 index 00000000000..e13db6c325a --- /dev/null +++ b/src/test/ui/type/closure-with-wrong-borrows.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/closure-with-wrong-borrows.rs:9:7 + | +LL | f(inner); + | - ^^^^^ one type is more general than the other + | | + | arguments to this function are incorrect + | + = note: expected fn pointer `for<'a, 'b, 'c> fn(&'a str, &'b S<'c>)` + found fn pointer `fn(_, _)` +note: function defined here + --> $DIR/closure-with-wrong-borrows.rs:3:4 + | +LL | fn f(inner: fn(&str, &S)) { + | ^ ------------------- +help: consider removing the `` + | +LL | f(inner); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5 From ebbc5dafd351551bdeab3e4edbdf9a03898a9017 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 8 Jan 2023 01:53:39 +0000 Subject: Do not emit wrong E0308 suggestion for closure mismatch --- compiler/rustc_hir_typeck/src/demand.rs | 5 ++++- src/test/ui/type/closure-with-wrong-borrows.stderr | 4 ---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 0f191c21a0a..f15cf5e3ef9 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1379,7 +1379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } // If we've reached our target type with just removing `&`, then just print now. - if steps == 0 { + if steps == 0 && !remove.trim().is_empty() { return Some(( prefix_span, format!("consider removing the `{}`", remove.trim()), @@ -1438,6 +1438,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { (prefix_span, format!("{}{}", prefix, "*".repeat(steps))) }; + if suggestion.trim().is_empty() { + return None; + } return Some(( span, diff --git a/src/test/ui/type/closure-with-wrong-borrows.stderr b/src/test/ui/type/closure-with-wrong-borrows.stderr index e13db6c325a..7370bc76467 100644 --- a/src/test/ui/type/closure-with-wrong-borrows.stderr +++ b/src/test/ui/type/closure-with-wrong-borrows.stderr @@ -13,10 +13,6 @@ note: function defined here | LL | fn f(inner: fn(&str, &S)) { | ^ ------------------- -help: consider removing the `` - | -LL | f(inner); - | error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 3c41003873ed16dc415b18ee65602438be3fe1e4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 15 Dec 2022 02:38:39 +0000 Subject: Add type flags support for Ty and Const late-bound regions --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_middle/src/ty/erase_regions.rs | 2 +- compiler/rustc_middle/src/ty/flags.rs | 16 ++++++++++++++-- compiler/rustc_middle/src/ty/visit.rs | 8 ++++++++ compiler/rustc_symbol_mangling/src/v0.rs | 1 + .../rustc_trait_selection/src/traits/select/mod.rs | 7 +++---- compiler/rustc_type_ir/src/lib.rs | 20 ++++++++++++++------ 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0d1aa39c5d9..1afe6242403 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1912,7 +1912,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } let pred = obligation.predicate; // Match the existing behavior. - if pred.is_global() && !pred.has_late_bound_regions() { + if pred.is_global() && !pred.has_late_bound_vars() { let pred = self.normalize(span, None, pred); let hir_node = tcx.hir().find(self.body_id); diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index ffdac93bcd0..9e4f90caab0 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -21,7 +21,7 @@ impl<'tcx> TyCtxt<'tcx> { T: TypeFoldable<'tcx>, { // If there's nothing to erase avoid performing the query at all - if !value.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { + if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { return value; } debug!("erase_regions({:?})", value); diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 8306d670a65..b7eafc4b437 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -59,8 +59,18 @@ impl FlagComputation { { let mut computation = FlagComputation::new(); - if !value.bound_vars().is_empty() { - computation.flags = computation.flags | TypeFlags::HAS_RE_LATE_BOUND; + for bv in value.bound_vars() { + match bv { + ty::BoundVariableKind::Ty(_) => { + computation.flags |= TypeFlags::HAS_TY_LATE_BOUND; + } + ty::BoundVariableKind::Region(_) => { + computation.flags |= TypeFlags::HAS_RE_LATE_BOUND; + } + ty::BoundVariableKind::Const => { + computation.flags |= TypeFlags::HAS_CT_LATE_BOUND; + } + } } f(&mut computation, value.skip_binder()); @@ -131,6 +141,7 @@ impl FlagComputation { &ty::Bound(debruijn, _) => { self.add_bound_var(debruijn); + self.add_flags(TypeFlags::HAS_TY_LATE_BOUND); } &ty::Placeholder(..) => { @@ -303,6 +314,7 @@ impl FlagComputation { } ty::ConstKind::Bound(debruijn, _) => { self.add_bound_var(debruijn); + self.add_flags(TypeFlags::HAS_CT_LATE_BOUND); } ty::ConstKind::Param(_) => { self.add_flags(TypeFlags::HAS_CT_PARAM); diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index d5553f84f75..ca445558131 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -165,6 +165,14 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { fn has_late_bound_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND) } + /// True if there are any late-bound non-region variables + fn has_non_region_late_bound(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_LATE_BOUND - TypeFlags::HAS_RE_LATE_BOUND) + } + /// True if there are any late-bound variables + fn has_late_bound_vars(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_LATE_BOUND) + } /// Indicates whether this value still has parameters/placeholders/inference variables /// which could be replaced later, in a way that would change the results of `impl` diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 9e8117c6a85..0d446d654dc 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -206,6 +206,7 @@ impl<'tcx> SymbolMangler<'tcx> { where T: TypeVisitable<'tcx>, { + // FIXME(non-lifetime-binders): What to do here? let regions = if value.has_late_bound_regions() { self.tcx.collect_referenced_late_bound_regions(value) } else { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 760b4585f4e..3f14491f803 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -755,7 +755,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // contain the "'static" lifetime (any other lifetime // would either be late-bound or local), so it is guaranteed // to outlive any other lifetime - if pred.0.is_global() && !pred.0.has_late_bound_regions() { + if pred.0.is_global() && !pred.0.has_late_bound_vars() { Ok(EvaluatedToOk) } else { Ok(EvaluatedToOkModuloRegions) @@ -1785,9 +1785,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check if a bound would previously have been removed when normalizing // the param_env so that it can be given the lowest priority. See // #50825 for the motivation for this. - let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| { - cand.is_global() && !cand.has_late_bound_regions() - }; + let is_global = + |cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_late_bound_vars(); // (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`, // `DiscriminantKindCandidate`, `ConstDestructCandidate` diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index fed070408f3..44004cb0be1 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -241,22 +241,30 @@ bitflags! { /// Basically anything but `ReLateBound` and `ReErased`. const HAS_FREE_REGIONS = 1 << 14; - /// Does this have any `ReLateBound` regions? Used to check - /// if a global bound is safe to evaluate. + /// Does this have any `ReLateBound` regions? const HAS_RE_LATE_BOUND = 1 << 15; + /// Does this have any `Bound` types? + const HAS_TY_LATE_BOUND = 1 << 16; + /// Does this have any `ConstKind::Bound` consts? + const HAS_CT_LATE_BOUND = 1 << 17; + /// Does this have any bound variables? + /// Used to check if a global bound is safe to evaluate. + const HAS_LATE_BOUND = TypeFlags::HAS_RE_LATE_BOUND.bits + | TypeFlags::HAS_TY_LATE_BOUND.bits + | TypeFlags::HAS_CT_LATE_BOUND.bits; /// Does this have any `ReErased` regions? - const HAS_RE_ERASED = 1 << 16; + const HAS_RE_ERASED = 1 << 18; /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? - const STILL_FURTHER_SPECIALIZABLE = 1 << 17; + const STILL_FURTHER_SPECIALIZABLE = 1 << 19; /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`? - const HAS_TY_FRESH = 1 << 18; + const HAS_TY_FRESH = 1 << 20; /// Does this value have `InferConst::Fresh`? - const HAS_CT_FRESH = 1 << 19; + const HAS_CT_FRESH = 1 << 21; } } -- cgit 1.4.1-3-g733a5 From 49f849a3d26059cfd89b96a7be7f3bf6ad3058de Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 24 Dec 2022 23:17:25 +0000 Subject: Mention signature rather than fn pointers when comparing impl/trait methods --- .../rustc_error_messages/locales/en-US/infer.ftl | 4 +-- .../src/check/compare_impl_item.rs | 36 +++++++++------------- compiler/rustc_infer/src/infer/at.rs | 12 ++++++++ .../rustc_infer/src/infer/error_reporting/mod.rs | 20 ++++++++++-- .../nice_region_error/trait_impl_difference.rs | 34 +++++++++++--------- compiler/rustc_infer/src/infer/mod.rs | 1 + .../defaults-specialization.stderr | 8 ++--- .../async-example-desugared-boxed-in-trait.stderr | 4 +-- .../regions-bound-missing-bound-in-impl.stderr | 8 ++--- src/test/ui/compare-method/bad-self-type.stderr | 12 ++++---- src/test/ui/compare-method/issue-90444.stderr | 8 ++--- .../ui/compare-method/reordered-type-param.stderr | 4 +-- .../ui/impl-trait/impl-generic-mismatch-ab.stderr | 4 +-- .../in-trait/method-signature-matches.stderr | 12 ++++---- .../impl-trait/in-trait/signature-mismatch.stderr | 4 +-- .../in-trait/specialization-broken.stderr | 4 +-- ...-alias-impl-trait-declaration-too-subtle.stderr | 8 ++--- src/test/ui/impl-trait/trait_type.stderr | 4 +-- src/test/ui/issues/issue-13033.rs | 4 +-- src/test/ui/issues/issue-13033.stderr | 4 +-- src/test/ui/issues/issue-15094.rs | 4 +-- src/test/ui/issues/issue-15094.stderr | 4 +-- src/test/ui/issues/issue-20225.stderr | 12 ++++---- src/test/ui/issues/issue-21332.stderr | 4 +-- src/test/ui/issues/issue-37884.stderr | 4 +-- ...lifetime-mismatch-between-trait-and-impl.stderr | 4 +-- src/test/ui/mismatched_types/E0053.stderr | 8 ++--- .../issue-74918-missing-lifetime.stderr | 4 +-- .../issue-75361-mismatched-impl.stderr | 4 +-- .../trait-impl-fn-incompatibility.stderr | 8 ++--- src/test/ui/traits/impl-method-mismatch.rs | 4 +-- src/test/ui/traits/impl-method-mismatch.stderr | 4 +-- src/test/ui/traits/issue-35869.stderr | 16 +++++----- src/test/ui/traits/matching-lifetimes.stderr | 8 ++--- .../param-without-lifetime-constraint.stderr | 4 +-- .../traits/self-without-lifetime-constraint.stderr | 4 +-- src/test/ui/unsafe/unsafe-trait-impl.rs | 4 +-- src/test/ui/unsafe/unsafe-trait-impl.stderr | 4 +-- src/test/ui/wrong-mul-method-signature.stderr | 12 ++++---- 39 files changed, 169 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 52babec4f9e..c1cb07cf0df 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -253,8 +253,8 @@ infer_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not ge infer_trait_impl_diff = `impl` item signature doesn't match `trait` item signature .found = found `{$found}` .expected = expected `{$expected}` - .expected_found = expected `{$expected}` - {" "}found `{$found}` + .expected_found = expected signature `{$expected}` + {" "}found signature `{$found}` infer_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output infer_tid_consider_borrowing = consider borrowing this type parameter in the trait 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 a767338ab85..0d3391bbc1e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -270,8 +270,8 @@ fn compare_method_predicate_entailment<'tcx>( let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig)); let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id); - let impl_fty = ocx.normalize(&norm_cause, param_env, unnormalized_impl_fty); - debug!("compare_impl_method: impl_fty={:?}", impl_fty); + let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig); + debug!("compare_impl_method: impl_fty={:?}", impl_sig); let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs); let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, trait_sig); @@ -294,18 +294,17 @@ fn compare_method_predicate_entailment<'tcx>( // type would be more appropriate. In other places we have a `Vec` // corresponding to their `Vec`, but we don't have that here. // Fixing this would improve the output of test `issue-83765.rs`. - let result = ocx.sup(&cause, param_env, trait_fty, impl_fty); + let result = ocx.sup(&cause, param_env, trait_sig, impl_sig); if let Err(terr) = result { - debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty); + debug!(?impl_sig, ?trait_sig, ?terr, "sub_types failed"); let emitted = report_trait_method_mismatch( &infcx, cause, terr, - (trait_m, trait_fty), - (impl_m, impl_fty), - trait_sig, + (trait_m, trait_sig), + (impl_m, impl_sig), impl_trait_ref, ); return Err(emitted); @@ -484,7 +483,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap(); let param_env = tcx.param_env(def_id); - // First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later. + // First, check a few of the same things as `compare_impl_method`, + // just so we don't ICE during substitution later. compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?; compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?; @@ -577,14 +577,11 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( debug!(?trait_sig, ?impl_sig, "equating function signatures"); - let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig)); - let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig)); - // Unify the whole function signature. We need to do this to fully infer // the lifetimes of the return type, but do this after unifying just the // return types, since we want to avoid duplicating errors from // `compare_method_predicate_entailment`. - match ocx.eq(&cause, param_env, trait_fty, impl_fty) { + match ocx.eq(&cause, param_env, trait_sig, impl_sig) { Ok(()) => {} Err(terr) => { // This function gets called during `compare_method_predicate_entailment` when normalizing a @@ -595,9 +592,8 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( infcx, cause, terr, - (trait_m, trait_fty), - (impl_m, impl_fty), - trait_sig, + (trait_m, trait_sig), + (impl_m, impl_sig), impl_trait_ref, ); return Err(emitted); @@ -771,9 +767,8 @@ fn report_trait_method_mismatch<'tcx>( infcx: &InferCtxt<'tcx>, mut cause: ObligationCause<'tcx>, terr: TypeError<'tcx>, - (trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>), - (impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>), - trait_sig: ty::FnSig<'tcx>, + (trait_m, trait_sig): (&ty::AssocItem, ty::FnSig<'tcx>), + (impl_m, impl_sig): (&ty::AssocItem, ty::FnSig<'tcx>), impl_trait_ref: ty::TraitRef<'tcx>, ) -> ErrorGuaranteed { let tcx = infcx.tcx; @@ -858,10 +853,7 @@ fn report_trait_method_mismatch<'tcx>( &mut diag, &cause, trait_err_span.map(|sp| (sp, "type in trait".to_owned())), - Some(infer::ValuePairs::Terms(ExpectedFound { - expected: trait_fty.into(), - found: impl_fty.into(), - })), + Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })), terr, false, false, diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index e9186540a7b..d816a9ed3d7 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -427,3 +427,15 @@ impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { } } } + +impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { + fn to_trace( + _: TyCtxt<'tcx>, + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) } + } +} diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 0644c7ada10..391804e35e2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1429,8 +1429,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> OpaqueTypesVisitor<'tcx> { fn visit_expected_found( tcx: TyCtxt<'tcx>, - expected: Ty<'tcx>, - found: Ty<'tcx>, + expected: impl TypeVisitable<'tcx>, + found: impl TypeVisitable<'tcx>, ignore_span: Span, ) -> Self { let mut types_visitor = OpaqueTypesVisitor { @@ -1570,6 +1570,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => (false, Mismatch::Fixed("type")), } } + ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => { + OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span) + .report(diag); + (false, Mismatch::Fixed("signature")) + } ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => { (false, Mismatch::Fixed("trait")) } @@ -2041,6 +2046,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ret => ret, } } + infer::Sigs(exp_found) => { + let exp_found = self.resolve_vars_if_possible(exp_found); + if exp_found.references_error() { + return None; + } + let (exp, fnd) = self.cmp_fn_sig( + &ty::Binder::dummy(exp_found.expected), + &ty::Binder::dummy(exp_found.found), + ); + Some((exp, fnd, None, None)) + } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 17c887a132a..40c0c806e1f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -3,7 +3,7 @@ use crate::errors::{ConsiderBorrowingParamHelp, RelationshipHelp, TraitImplDiff}; use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::lexical_region_resolve::RegionResolutionError; -use crate::infer::Subtype; +use crate::infer::{Subtype, ValuePairs}; use crate::traits::ObligationCauseCode::CompareImplItemObligation; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -11,6 +11,7 @@ use rustc_hir::def::Res; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; +use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::Span; @@ -23,22 +24,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let error = self.error.as_ref()?; debug!("try_report_impl_not_conforming_to_trait {:?}", error); if let RegionResolutionError::SubSupConflict( - _, - var_origin, - sub_origin, - _sub, - sup_origin, - _sup, - _, - ) = error.clone() + _, + var_origin, + sub_origin, + _sub, + sup_origin, + _sup, + _, + ) = error.clone() && let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin) - && let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty() - && let sup_expected_found @ Some(_) = sup_trace.values.ty() && let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code() - && sup_expected_found == sub_expected_found + && sub_trace.values == sup_trace.values + && let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values { - let guar = - self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id); + // FIXME(compiler-errors): Don't like that this needs `Ty`s, but + // all of the region highlighting machinery only deals with those. + let guar = self.emit_err( + var_origin.span(), + self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(expected)), + self.cx.tcx.mk_fn_ptr(ty::Binder::dummy(found)), + *trait_item_def_id, + ); return Some(guar); } None diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b17a465eb38..f81ab60c5f6 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -361,6 +361,7 @@ pub enum ValuePairs<'tcx> { Terms(ExpectedFound>), TraitRefs(ExpectedFound>), PolyTraitRefs(ExpectedFound>), + Sigs(ExpectedFound>), } impl<'tcx> ValuePairs<'tcx> { diff --git a/src/test/ui/associated-types/defaults-specialization.stderr b/src/test/ui/associated-types/defaults-specialization.stderr index 8df326351fa..7e21f7fc306 100644 --- a/src/test/ui/associated-types/defaults-specialization.stderr +++ b/src/test/ui/associated-types/defaults-specialization.stderr @@ -22,8 +22,8 @@ note: type in trait | LL | fn make() -> Self::Ty { | ^^^^^^^^ - = note: expected fn pointer `fn() -> as Tr>::Ty` - found fn pointer `fn() -> u8` + = note: expected signature `fn() -> as Tr>::Ty` + found signature `fn() -> u8` error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:35:18 @@ -42,8 +42,8 @@ note: type in trait | LL | fn make() -> Self::Ty { | ^^^^^^^^ - = note: expected fn pointer `fn() -> as Tr>::Ty` - found fn pointer `fn() -> bool` + = note: expected signature `fn() -> as Tr>::Ty` + found signature `fn() -> bool` error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:10:9 diff --git a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 22d2928f2f5..13e7222551a 100644 --- a/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/src/test/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -9,8 +9,8 @@ note: type in trait | LL | fn foo(&self) -> Pin + '_>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected fn pointer `fn(&i32) -> Pin>>` - found fn pointer `fn(&i32) -> impl Future` + = note: expected signature `fn(&i32) -> Pin>>` + found signature `fn(&i32) -> impl Future` error: aborting due to previous error diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 1e3b071ef92..930fea9158d 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -22,8 +22,8 @@ error[E0308]: method not compatible with trait LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)` - found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)` + = note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)` + found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)` note: the lifetime `'c` as defined here... --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 | @@ -41,8 +41,8 @@ error[E0308]: method not compatible with trait LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected fn pointer `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)` - found fn pointer `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)` + = note: expected signature `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'_>)` + found signature `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'_>)` note: the lifetime `'c` as defined here... --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 | diff --git a/src/test/ui/compare-method/bad-self-type.stderr b/src/test/ui/compare-method/bad-self-type.stderr index 90e907157a5..cad942e646e 100644 --- a/src/test/ui/compare-method/bad-self-type.stderr +++ b/src/test/ui/compare-method/bad-self-type.stderr @@ -7,8 +7,8 @@ LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> { | expected struct `Pin`, found struct `MyFuture` | help: change the self-receiver type to match the trait: `self: Pin<&mut MyFuture>` | - = note: expected fn pointer `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>` - found fn pointer `fn(MyFuture, &mut Context<'_>) -> Poll<_>` + = note: expected signature `fn(Pin<&mut MyFuture>, &mut Context<'_>) -> Poll<_>` + found signature `fn(MyFuture, &mut Context<'_>) -> Poll<_>` error[E0053]: method `foo` has an incompatible type for trait --> $DIR/bad-self-type.rs:22:18 @@ -24,8 +24,8 @@ note: type in trait | LL | fn foo(self); | ^^^^ - = note: expected fn pointer `fn(MyFuture)` - found fn pointer `fn(Box)` + = note: expected signature `fn(MyFuture)` + found signature `fn(Box)` error[E0053]: method `bar` has an incompatible type for trait --> $DIR/bad-self-type.rs:24:18 @@ -38,8 +38,8 @@ note: type in trait | LL | fn bar(self) -> Option<()>; | ^^^^^^^^^^ - = note: expected fn pointer `fn(MyFuture) -> Option<()>` - found fn pointer `fn(MyFuture)` + = note: expected signature `fn(MyFuture) -> Option<()>` + found signature `fn(MyFuture)` help: change the output type to match the trait | LL | fn bar(self) -> Option<()> {} diff --git a/src/test/ui/compare-method/issue-90444.stderr b/src/test/ui/compare-method/issue-90444.stderr index ee63f34b799..52e23d03b14 100644 --- a/src/test/ui/compare-method/issue-90444.stderr +++ b/src/test/ui/compare-method/issue-90444.stderr @@ -7,8 +7,8 @@ LL | fn from(_: fn((), (), &mut ())) -> Self { | types differ in mutability | help: change the parameter type to match the trait: `for<'a> fn((), (), &'a ())` | - = note: expected fn pointer `fn(for<'a> fn((), (), &'a ())) -> A` - found fn pointer `fn(for<'a> fn((), (), &'a mut ())) -> A` + = note: expected signature `fn(for<'a> fn((), (), &'a ())) -> A` + found signature `fn(for<'a> fn((), (), &'a mut ())) -> A` error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:11:16 @@ -19,8 +19,8 @@ LL | fn from(_: fn((), (), u64)) -> Self { | expected `u32`, found `u64` | help: change the parameter type to match the trait: `fn((), (), u32)` | - = note: expected fn pointer `fn(fn((), (), u32)) -> B` - found fn pointer `fn(fn((), (), u64)) -> B` + = note: expected signature `fn(fn((), (), u32)) -> B` + found signature `fn(fn((), (), u64)) -> B` error: aborting due to 2 previous errors diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr index 49b5b1b92cd..1552d542d15 100644 --- a/src/test/ui/compare-method/reordered-type-param.stderr +++ b/src/test/ui/compare-method/reordered-type-param.stderr @@ -14,8 +14,8 @@ note: type in trait | LL | fn b(&self, x: C) -> C; | ^ - = note: expected fn pointer `fn(&E, F) -> F` - found fn pointer `fn(&E, G) -> G` + = note: expected signature `fn(&E, F) -> F` + found signature `fn(&E, G) -> G` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters diff --git a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr index acf768d5795..db97fc2bdc4 100644 --- a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr +++ b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr @@ -13,8 +13,8 @@ note: type in trait | LL | fn foo(&self, a: &A, b: &impl Debug); | ^^ - = note: expected fn pointer `fn(&(), &B, &impl Debug)` - found fn pointer `fn(&(), &impl Debug, &B)` + = note: expected signature `fn(&(), &B, &impl Debug)` + found signature `fn(&(), &impl Debug, &B)` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters diff --git a/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr b/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr index 2b32c52c829..4dfd772222e 100644 --- a/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr +++ b/src/test/ui/impl-trait/in-trait/method-signature-matches.stderr @@ -12,8 +12,8 @@ note: type in trait | LL | fn owo(x: ()) -> impl Sized; | ^^ - = note: expected fn pointer `fn(())` - found fn pointer `fn(u8)` + = note: expected signature `fn(())` + found signature `fn(u8)` error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:20:21 @@ -39,8 +39,8 @@ note: type in trait | LL | async fn owo(x: ()) {} | ^^ - = note: expected fn pointer `fn(()) -> _` - found fn pointer `fn(u8) -> _` + = note: expected signature `fn(()) -> _` + found signature `fn(u8) -> _` error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0 --> $DIR/method-signature-matches.rs:29:28 @@ -75,8 +75,8 @@ note: type in trait | LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ - = note: expected fn pointer `fn(&'early T)` - found fn pointer `fn(&())` + = note: expected signature `fn(&'early T)` + found signature `fn(&())` error: aborting due to 5 previous errors diff --git a/src/test/ui/impl-trait/in-trait/signature-mismatch.stderr b/src/test/ui/impl-trait/in-trait/signature-mismatch.stderr index 6663d7faa1e..e105660173b 100644 --- a/src/test/ui/impl-trait/in-trait/signature-mismatch.stderr +++ b/src/test/ui/impl-trait/in-trait/signature-mismatch.stderr @@ -7,8 +7,8 @@ LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` | - = note: expected `fn(&'1 Struct, &'2 [u8]) -> impl Future> + 'static` - found `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` + = note: expected signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + 'static` + found signature `fn(&'1 Struct, &'2 [u8]) -> impl Future> + '2` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output diff --git a/src/test/ui/impl-trait/in-trait/specialization-broken.stderr b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr index a30e6346b29..37cfd74498d 100644 --- a/src/test/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/src/test/ui/impl-trait/in-trait/specialization-broken.stderr @@ -15,8 +15,8 @@ note: type in trait | LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ - = note: expected fn pointer `fn(&U) -> impl Sized` - found fn pointer `fn(&U) -> U` + = note: expected signature `fn(&U) -> impl Sized` + found signature `fn(&U) -> U` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 3ee26f74a78..c7c6ca44012 100644 --- a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -18,8 +18,8 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool { | expected struct `Bar`, found opaque type | help: change the parameter type to match the trait: `&(a::Bar, i32)` | - = note: expected fn pointer `fn(&a::Bar, &(a::Bar, i32)) -> _` - found fn pointer `fn(&a::Bar, &(a::Foo, i32)) -> _` + = note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _` + found signature `fn(&a::Bar, &(a::Foo, i32)) -> _` error: unconstrained opaque type --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16 @@ -41,8 +41,8 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | expected opaque type, found struct `Bar` | help: change the parameter type to match the trait: `&(b::Foo, i32)` | - = note: expected fn pointer `fn(&b::Bar, &(b::Foo, i32)) -> _` - found fn pointer `fn(&b::Bar, &(b::Bar, i32)) -> _` + = note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _` + found signature `fn(&b::Bar, &(b::Bar, i32)) -> _` error: aborting due to 4 previous errors diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr index bea24339837..81e4c933e53 100644 --- a/src/test/ui/impl-trait/trait_type.stderr +++ b/src/test/ui/impl-trait/trait_type.stderr @@ -7,8 +7,8 @@ LL | fn fmt(&self, x: &str) -> () { } | types differ in mutability | help: change the parameter type to match the trait: `&mut Formatter<'_>` | - = note: expected fn pointer `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>` - found fn pointer `fn(&MyType, &str)` + = note: expected signature `fn(&MyType, &mut Formatter<'_>) -> Result<(), std::fmt::Error>` + found signature `fn(&MyType, &str)` error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2 --> $DIR/trait_type.rs:12:11 diff --git a/src/test/ui/issues/issue-13033.rs b/src/test/ui/issues/issue-13033.rs index 7631831a81a..fdb356e70c5 100644 --- a/src/test/ui/issues/issue-13033.rs +++ b/src/test/ui/issues/issue-13033.rs @@ -7,8 +7,8 @@ struct Baz; impl Foo for Baz { fn bar(&mut self, other: &dyn Foo) {} //~^ ERROR method `bar` has an incompatible type for trait - //~| expected fn pointer `fn(&mut Baz, &mut dyn Foo)` - //~| found fn pointer `fn(&mut Baz, &dyn Foo)` + //~| expected signature `fn(&mut Baz, &mut dyn Foo)` + //~| found signature `fn(&mut Baz, &dyn Foo)` } fn main() {} diff --git a/src/test/ui/issues/issue-13033.stderr b/src/test/ui/issues/issue-13033.stderr index 72e549813e8..db2c1189e1e 100644 --- a/src/test/ui/issues/issue-13033.stderr +++ b/src/test/ui/issues/issue-13033.stderr @@ -12,8 +12,8 @@ note: type in trait | LL | fn bar(&mut self, other: &mut dyn Foo); | ^^^^^^^^^^^^ - = note: expected fn pointer `fn(&mut Baz, &mut dyn Foo)` - found fn pointer `fn(&mut Baz, &dyn Foo)` + = note: expected signature `fn(&mut Baz, &mut dyn Foo)` + found signature `fn(&mut Baz, &dyn Foo)` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-15094.rs b/src/test/ui/issues/issue-15094.rs index 71b75a6e7e0..cb27e2bcfb6 100644 --- a/src/test/ui/issues/issue-15094.rs +++ b/src/test/ui/issues/issue-15094.rs @@ -10,8 +10,8 @@ impl ops::FnOnce<(),> for Debuger { type Output = (); fn call_once(self, _args: ()) { //~^ ERROR `call_once` has an incompatible type for trait - //~| expected fn pointer `extern "rust-call" fn - //~| found fn pointer `fn + //~| expected signature `extern "rust-call" fn + //~| found signature `fn println!("{:?}", self.x); } } diff --git a/src/test/ui/issues/issue-15094.stderr b/src/test/ui/issues/issue-15094.stderr index 2dcdaba170a..b7c950892dc 100644 --- a/src/test/ui/issues/issue-15094.stderr +++ b/src/test/ui/issues/issue-15094.stderr @@ -4,8 +4,8 @@ error[E0053]: method `call_once` has an incompatible type for trait LL | fn call_once(self, _args: ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn | - = note: expected fn pointer `extern "rust-call" fn(Debuger<_>, ())` - found fn pointer `fn(Debuger<_>, ())` + = note: expected signature `extern "rust-call" fn(Debuger<_>, ())` + found signature `fn(Debuger<_>, ())` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr index 6f4813ca623..5822160107c 100644 --- a/src/test/ui/issues/issue-20225.stderr +++ b/src/test/ui/issues/issue-20225.stderr @@ -9,8 +9,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} | expected `&T`, found type parameter `T` | help: change the parameter type to match the trait: `(&'a T,)` | - = note: expected fn pointer `extern "rust-call" fn(&Foo, (&'a T,))` - found fn pointer `extern "rust-call" fn(&Foo, (T,))` + = note: expected signature `extern "rust-call" fn(&Foo, (&'a T,))` + found signature `extern "rust-call" fn(&Foo, (T,))` error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/issue-20225.rs:11:51 @@ -23,8 +23,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} | expected `&T`, found type parameter `T` | help: change the parameter type to match the trait: `(&'a T,)` | - = note: expected fn pointer `extern "rust-call" fn(&mut Foo, (&'a T,))` - found fn pointer `extern "rust-call" fn(&mut Foo, (T,))` + = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a T,))` + found signature `extern "rust-call" fn(&mut Foo, (T,))` error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/issue-20225.rs:18:47 @@ -38,8 +38,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} | expected `&T`, found type parameter `T` | help: change the parameter type to match the trait: `(&'a T,)` | - = note: expected fn pointer `extern "rust-call" fn(Foo, (&'a T,))` - found fn pointer `extern "rust-call" fn(Foo, (T,))` + = note: expected signature `extern "rust-call" fn(Foo, (&'a T,))` + found signature `extern "rust-call" fn(Foo, (T,))` error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-21332.stderr b/src/test/ui/issues/issue-21332.stderr index d92966da17c..0e1beebf293 100644 --- a/src/test/ui/issues/issue-21332.stderr +++ b/src/test/ui/issues/issue-21332.stderr @@ -7,8 +7,8 @@ LL | fn next(&mut self) -> Result { Ok(7) } | expected enum `Option`, found enum `Result` | help: change the output type to match the trait: `Option` | - = note: expected fn pointer `fn(&mut S) -> Option` - found fn pointer `fn(&mut S) -> Result` + = note: expected signature `fn(&mut S) -> Option` + found signature `fn(&mut S) -> Result` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-37884.stderr b/src/test/ui/issues/issue-37884.stderr index e9f50b41f6a..7ddb36c8e6f 100644 --- a/src/test/ui/issues/issue-37884.stderr +++ b/src/test/ui/issues/issue-37884.stderr @@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait LL | fn next(&'a mut self) -> Option | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected fn pointer `fn(&mut RepeatMut<'a, T>) -> Option<_>` - found fn pointer `fn(&'a mut RepeatMut<'a, T>) -> Option<_>` + = note: expected signature `fn(&mut RepeatMut<'a, T>) -> Option<_>` + found signature `fn(&'a mut RepeatMut<'a, T>) -> Option<_>` note: the anonymous lifetime as defined here... --> $DIR/issue-37884.rs:6:5 | diff --git a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr index 3040a8512ce..9c61d5a0c25 100644 --- a/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr +++ b/src/test/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr @@ -7,8 +7,8 @@ LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'1 i32) -> &'1 i32` | - = note: expected `fn(&'1 i32, &'a i32) -> &'a i32` - found `fn(&'1 i32, &'1 i32) -> &'1 i32` + = note: expected signature `fn(&'1 i32, &'a i32) -> &'a i32` + found signature `fn(&'1 i32, &'1 i32) -> &'1 i32` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr index 54b41926451..154f2fcbee0 100644 --- a/src/test/ui/mismatched_types/E0053.stderr +++ b/src/test/ui/mismatched_types/E0053.stderr @@ -12,8 +12,8 @@ note: type in trait | LL | fn foo(x: u16); | ^^^ - = note: expected fn pointer `fn(u16)` - found fn pointer `fn(i16)` + = note: expected signature `fn(u16)` + found signature `fn(i16)` error[E0053]: method `bar` has an incompatible type for trait --> $DIR/E0053.rs:11:12 @@ -29,8 +29,8 @@ note: type in trait | LL | fn bar(&self); | ^^^^^ - = note: expected fn pointer `fn(&Bar)` - found fn pointer `fn(&mut Bar)` + = note: expected signature `fn(&Bar)` + found signature `fn(&mut Bar)` error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr index b75c7a99fdd..9ddea162944 100644 --- a/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr +++ b/src/test/ui/mismatched_types/issue-74918-missing-lifetime.stderr @@ -18,8 +18,8 @@ LL | fn next(&mut self) -> Option> { | = note: expected `fn(&'1 mut ChunkingIterator) -> Option>` | - = note: expected `fn(&'1 mut ChunkingIterator) -> Option>` - found `fn(&'1 mut ChunkingIterator) -> Option>` + = note: expected signature `fn(&'1 mut ChunkingIterator) -> Option>` + found signature `fn(&'1 mut ChunkingIterator) -> Option>` = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output diff --git a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr index 2a2c23c9421..88416ba4bb6 100644 --- a/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr +++ b/src/test/ui/mismatched_types/issue-75361-mismatched-impl.stderr @@ -7,8 +7,8 @@ LL | fn adjacent_edges(&self) -> Box>; LL | fn adjacent_edges(&self) -> Box + '_> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 T) -> Box<(dyn MyTrait + '1)>` | - = note: expected `fn(&'1 T) -> Box<(dyn MyTrait + 'static)>` - found `fn(&'1 T) -> Box<(dyn MyTrait + '1)>` + = note: expected signature `fn(&'1 T) -> Box<(dyn MyTrait + 'static)>` + found signature `fn(&'1 T) -> Box<(dyn MyTrait + '1)>` help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` --> $DIR/issue-75361-mismatched-impl.rs:12:55 | diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 6b2ba53daa0..6e7bf5eb46d 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -12,8 +12,8 @@ note: type in trait | LL | fn foo(x: u16); | ^^^ - = note: expected fn pointer `fn(u16)` - found fn pointer `fn(i16)` + = note: expected signature `fn(u16)` + found signature `fn(i16)` error[E0053]: method `bar` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:10:28 @@ -29,8 +29,8 @@ note: type in trait | LL | fn bar(&mut self, bar: &mut Bar); | ^^^^^^^^ - = note: expected fn pointer `fn(&mut Bar, &mut Bar)` - found fn pointer `fn(&mut Bar, &Bar)` + = note: expected signature `fn(&mut Bar, &mut Bar)` + found signature `fn(&mut Bar, &Bar)` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/impl-method-mismatch.rs b/src/test/ui/traits/impl-method-mismatch.rs index 683b1c1aa43..62580755c81 100644 --- a/src/test/ui/traits/impl-method-mismatch.rs +++ b/src/test/ui/traits/impl-method-mismatch.rs @@ -6,8 +6,8 @@ impl Mumbo for usize { // Cannot have a larger effect than the trait: unsafe fn jumbo(&self, x: &usize) { *self + *x; } //~^ ERROR method `jumbo` has an incompatible type for trait - //~| expected fn pointer `fn - //~| found fn pointer `unsafe fn + //~| expected signature `fn + //~| found signature `unsafe fn } fn main() {} diff --git a/src/test/ui/traits/impl-method-mismatch.stderr b/src/test/ui/traits/impl-method-mismatch.stderr index 30aa97d2934..252b5aff96a 100644 --- a/src/test/ui/traits/impl-method-mismatch.stderr +++ b/src/test/ui/traits/impl-method-mismatch.stderr @@ -9,8 +9,8 @@ note: type in trait | LL | fn jumbo(&self, x: &usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected fn pointer `fn(&usize, &usize) -> usize` - found fn pointer `unsafe fn(&usize, &usize)` + = note: expected signature `fn(&usize, &usize) -> usize` + found signature `unsafe fn(&usize, &usize)` error: aborting due to previous error diff --git a/src/test/ui/traits/issue-35869.stderr b/src/test/ui/traits/issue-35869.stderr index 0780109b843..6d985bdeaf8 100644 --- a/src/test/ui/traits/issue-35869.stderr +++ b/src/test/ui/traits/issue-35869.stderr @@ -12,8 +12,8 @@ note: type in trait | LL | fn foo(_: fn(u8) -> ()); | ^^^^^^^^^^^^ - = note: expected fn pointer `fn(fn(u8))` - found fn pointer `fn(fn(u16))` + = note: expected signature `fn(fn(u8))` + found signature `fn(fn(u16))` error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-35869.rs:13:15 @@ -29,8 +29,8 @@ note: type in trait | LL | fn bar(_: Option); | ^^^^^^^^^^ - = note: expected fn pointer `fn(Option)` - found fn pointer `fn(Option)` + = note: expected signature `fn(Option)` + found signature `fn(Option)` error[E0053]: method `baz` has an incompatible type for trait --> $DIR/issue-35869.rs:15:15 @@ -46,8 +46,8 @@ note: type in trait | LL | fn baz(_: (u8, u16)); | ^^^^^^^^^ - = note: expected fn pointer `fn((u8, _))` - found fn pointer `fn((u16, _))` + = note: expected signature `fn((u8, _))` + found signature `fn((u16, _))` error[E0053]: method `qux` has an incompatible type for trait --> $DIR/issue-35869.rs:17:17 @@ -63,8 +63,8 @@ note: type in trait | LL | fn qux() -> u8; | ^^ - = note: expected fn pointer `fn() -> u8` - found fn pointer `fn() -> u16` + = note: expected signature `fn() -> u8` + found signature `fn() -> u16` error: aborting due to 4 previous errors diff --git a/src/test/ui/traits/matching-lifetimes.stderr b/src/test/ui/traits/matching-lifetimes.stderr index de1c878a513..f8119ed415d 100644 --- a/src/test/ui/traits/matching-lifetimes.stderr +++ b/src/test/ui/traits/matching-lifetimes.stderr @@ -4,8 +4,8 @@ error[E0308]: method not compatible with trait LL | fn foo(x: Foo<'b,'a>) { | ^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected fn pointer `fn(Foo<'a, 'b>)` - found fn pointer `fn(Foo<'b, 'a>)` + = note: expected signature `fn(Foo<'a, 'b>)` + found signature `fn(Foo<'b, 'a>)` note: the lifetime `'b` as defined here... --> $DIR/matching-lifetimes.rs:13:9 | @@ -23,8 +23,8 @@ error[E0308]: method not compatible with trait LL | fn foo(x: Foo<'b,'a>) { | ^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected fn pointer `fn(Foo<'a, 'b>)` - found fn pointer `fn(Foo<'b, 'a>)` + = note: expected signature `fn(Foo<'a, 'b>)` + found signature `fn(Foo<'b, 'a>)` note: the lifetime `'a` as defined here... --> $DIR/matching-lifetimes.rs:13:6 | diff --git a/src/test/ui/traits/param-without-lifetime-constraint.stderr b/src/test/ui/traits/param-without-lifetime-constraint.stderr index 118b2cf3ecd..b128b6518ce 100644 --- a/src/test/ui/traits/param-without-lifetime-constraint.stderr +++ b/src/test/ui/traits/param-without-lifetime-constraint.stderr @@ -7,8 +7,8 @@ LL | fn get_relation(&self) -> To; LL | fn get_relation(&self) -> &ProofReader { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 Article) -> &'1 ProofReader` | - = note: expected `fn(&'1 Article) -> &'2 ProofReader` - found `fn(&'1 Article) -> &'1 ProofReader` + = note: expected signature `fn(&'1 Article) -> &'2 ProofReader` + found signature `fn(&'1 Article) -> &'1 ProofReader` help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` --> $DIR/param-without-lifetime-constraint.rs:10:31 | diff --git a/src/test/ui/traits/self-without-lifetime-constraint.stderr b/src/test/ui/traits/self-without-lifetime-constraint.stderr index 85fada3b87c..05a49820a82 100644 --- a/src/test/ui/traits/self-without-lifetime-constraint.stderr +++ b/src/test/ui/traits/self-without-lifetime-constraint.stderr @@ -7,8 +7,8 @@ LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult; LL | fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>` | - = note: expected `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>` - found `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>` + = note: expected signature `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>` + found signature `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>` help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` --> $DIR/self-without-lifetime-constraint.rs:41:60 | diff --git a/src/test/ui/unsafe/unsafe-trait-impl.rs b/src/test/ui/unsafe/unsafe-trait-impl.rs index 03a251be1a9..1fc84ca0256 100644 --- a/src/test/ui/unsafe/unsafe-trait-impl.rs +++ b/src/test/ui/unsafe/unsafe-trait-impl.rs @@ -7,8 +7,8 @@ trait Foo { impl Foo for u32 { fn len(&self) -> u32 { *self } //~^ ERROR method `len` has an incompatible type for trait - //~| expected fn pointer `unsafe fn(&u32) -> _` - //~| found fn pointer `fn(&u32) -> _` + //~| expected signature `unsafe fn(&u32) -> _` + //~| found signature `fn(&u32) -> _` } fn main() { } diff --git a/src/test/ui/unsafe/unsafe-trait-impl.stderr b/src/test/ui/unsafe/unsafe-trait-impl.stderr index 8a0cba1fac5..18ba79404b7 100644 --- a/src/test/ui/unsafe/unsafe-trait-impl.stderr +++ b/src/test/ui/unsafe/unsafe-trait-impl.stderr @@ -9,8 +9,8 @@ note: type in trait | LL | unsafe fn len(&self) -> u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected fn pointer `unsafe fn(&u32) -> _` - found fn pointer `fn(&u32) -> _` + = note: expected signature `unsafe fn(&u32) -> _` + found signature `fn(&u32) -> _` error: aborting due to previous error diff --git a/src/test/ui/wrong-mul-method-signature.stderr b/src/test/ui/wrong-mul-method-signature.stderr index 8338f61b22a..504a6032b01 100644 --- a/src/test/ui/wrong-mul-method-signature.stderr +++ b/src/test/ui/wrong-mul-method-signature.stderr @@ -7,8 +7,8 @@ LL | fn mul(self, s: &f64) -> Vec1 { | expected `f64`, found `&f64` | help: change the parameter type to match the trait: `f64` | - = note: expected fn pointer `fn(Vec1, f64) -> Vec1` - found fn pointer `fn(Vec1, &f64) -> Vec1` + = note: expected signature `fn(Vec1, f64) -> Vec1` + found signature `fn(Vec1, &f64) -> Vec1` error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:33:21 @@ -19,8 +19,8 @@ LL | fn mul(self, s: f64) -> Vec2 { | expected struct `Vec2`, found `f64` | help: change the parameter type to match the trait: `Vec2` | - = note: expected fn pointer `fn(Vec2, Vec2) -> f64` - found fn pointer `fn(Vec2, f64) -> Vec2` + = note: expected signature `fn(Vec2, Vec2) -> f64` + found signature `fn(Vec2, f64) -> Vec2` error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:52:29 @@ -31,8 +31,8 @@ LL | fn mul(self, s: f64) -> f64 { | expected `i32`, found `f64` | help: change the output type to match the trait: `i32` | - = note: expected fn pointer `fn(Vec3, _) -> i32` - found fn pointer `fn(Vec3, _) -> f64` + = note: expected signature `fn(Vec3, _) -> i32` + found signature `fn(Vec3, _) -> f64` error[E0308]: mismatched types --> $DIR/wrong-mul-method-signature.rs:63:45 -- cgit 1.4.1-3-g733a5 From 0e570e58f2cf465f254b7e6c56584ec732a77dbc Mon Sep 17 00:00:00 2001 From: Yukang Date: Sun, 8 Jan 2023 22:51:42 +0800 Subject: Remove extra space --- src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr index 22bafc6cc8b..8607917ede6 100644 --- a/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr +++ b/src/test/ui/suggestions/issue-106443-sugg-clone-for-bound.stderr @@ -6,7 +6,7 @@ LL | foo(s); | help: consider further restricting this bound | -LL | fn bar(s: &T) { +LL | fn bar(s: &T) { | +++++++ help: consider using clone here | -- cgit 1.4.1-3-g733a5 From ca554efaf78962f9dc9599663b29626269c69c8c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 02:40:59 +0000 Subject: Improve spans of non-WF implied bound types --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 58 +++++++------------ compiler/rustc_middle/src/query/mod.rs | 2 +- .../rustc_trait_selection/src/traits/engine.rs | 6 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 67 ++++++++++++++++++---- .../associated-types-for-unimpl-trait.stderr | 4 +- .../associated-types-no-suitable-bound.stderr | 4 +- ...ssociated-types-no-suitable-supertrait-2.stderr | 4 +- .../associated-types-no-suitable-supertrait.stderr | 8 +-- ...nrelated-trait-in-method-without-default.stderr | 4 +- src/test/ui/associated-types/issue-59324.rs | 2 +- src/test/ui/associated-types/issue-59324.stderr | 17 ++---- src/test/ui/issues/issue-18611.stderr | 8 +-- src/test/ui/issues/issue-20831-debruijn.stderr | 24 ++------ src/test/ui/issues/issue-35570.rs | 1 - src/test/ui/issues/issue-35570.stderr | 16 +----- src/test/ui/nll/normalization-bounds-error.stderr | 8 +-- .../regions-implied-bounds-projection-gap-hr-1.rs | 1 - ...gions-implied-bounds-projection-gap-hr-1.stderr | 21 +------ .../min_specialization/issue-79224.rs | 6 +- .../min_specialization/issue-79224.stderr | 18 ++---- src/test/ui/wf/issue-103573.stderr | 4 +- src/test/ui/wf/wf-foreign-fn-decl-ret.stderr | 4 +- 22 files changed, 134 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1afe6242403..b663f90cab7 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1489,54 +1489,38 @@ fn check_fn_or_method<'tcx>( def_id: LocalDefId, ) { let tcx = wfcx.tcx(); - let sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); + let mut sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), sig); // Normalize the input and output types one at a time, using a different // `WellFormedLoc` for each. We cannot call `normalize_associated_types` // on the entire `FnSig`, since this would use the same `WellFormedLoc` // for each type, preventing the HIR wf check from generating // a nice error message. - let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig; - inputs_and_output = tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| { - wfcx.normalize( - span, - Some(WellFormedLoc::Param { - function: def_id, - // Note that the `param_idx` of the output type is - // one greater than the index of the last input type. - param_idx: i.try_into().unwrap(), - }), - ty, - ) - })); - // Manually call `normalize_associated_types_in` on the other types - // in `FnSig`. This ensures that if the types of these fields - // ever change to include projections, we will start normalizing - // them automatically. - let sig = ty::FnSig { - inputs_and_output, - c_variadic: wfcx.normalize(span, None, c_variadic), - unsafety: wfcx.normalize(span, None, unsafety), - abi: wfcx.normalize(span, None, abi), - }; + let arg_span = + |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span); + + sig.inputs_and_output = + tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| { + wfcx.normalize( + arg_span(idx), + Some(WellFormedLoc::Param { + function: def_id, + // Note that the `param_idx` of the output type is + // one greater than the index of the last input type. + param_idx: idx.try_into().unwrap(), + }), + ty, + ) + })); - for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() { + for (idx, ty) in sig.inputs_and_output.iter().enumerate() { wfcx.register_wf_obligation( - ty.span, - Some(WellFormedLoc::Param { function: def_id, param_idx: i.try_into().unwrap() }), - input_ty.into(), + arg_span(idx), + Some(WellFormedLoc::Param { function: def_id, param_idx: idx.try_into().unwrap() }), + ty.into(), ); } - wfcx.register_wf_obligation( - hir_decl.output.span(), - Some(WellFormedLoc::Param { - function: def_id, - param_idx: sig.inputs().len().try_into().unwrap(), - }), - sig.output().into(), - ); - check_where_clauses(wfcx, span, def_id); check_return_position_impl_trait_in_trait_bounds( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 37db2274f67..7f794a926c0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -803,7 +803,7 @@ rustc_queries! { /// /// Note that we've liberated the late bound regions of function signatures, so /// this can not be used to check whether these types are well formed. - query assumed_wf_types(key: DefId) -> &'tcx ty::List> { + query assumed_wf_types(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] { desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index bc6d9d4b922..72ed3aa499d 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -191,8 +191,8 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { let assumed_wf_types = tcx.assumed_wf_types(def_id); let mut implied_bounds = FxIndexSet::default(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let cause = ObligationCause::misc(span, hir_id); - for ty in assumed_wf_types { + for &(ty, ty_span) in assumed_wf_types { + let span = if ty_span.is_dummy() { span } else { ty_span }; // FIXME(@lcnr): rustc currently does not check wf for types // pre-normalization, meaning that implied bounds are sometimes // incorrect. See #100910 for more details. @@ -205,7 +205,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // sound and then uncomment this line again. // implied_bounds.insert(ty); - let normalized = self.normalize(&cause, param_env, ty); + let normalized = self.normalize(&ObligationCause::misc(span, hir_id), param_env, ty); implied_bounds.insert(normalized); } implied_bounds diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index b7a24a22c53..e3f34373ccc 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,33 +1,80 @@ use crate::rustc_middle::ty::DefIdTree; -use rustc_hir::{def::DefKind, def_id::DefId}; +use rustc_hir::{self as hir, def::DefKind, def_id::DefId}; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::{Span, DUMMY_SP}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { match tcx.def_kind(def_id) { DefKind::Fn => { let sig = tcx.fn_sig(def_id); let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - liberated_sig.inputs_and_output + if let Some(node) = tcx.hir().get_if_local(def_id) + && let Some(decl) = node.fn_decl() + { + assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); + tcx.arena.alloc_from_iter(std::iter::zip( + liberated_sig.inputs_and_output, + decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), + )) + } else { + tcx.arena.alloc_from_iter( + liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), + ) + } } DefKind::AssocFn => { let sig = tcx.fn_sig(def_id); let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - let mut assumed_wf_types: Vec<_> = - tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); - assumed_wf_types.extend(liberated_sig.inputs_and_output); - tcx.intern_type_list(&assumed_wf_types) + let assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id)); + if let Some(node) = tcx.hir().get_if_local(def_id) + && let Some(decl) = node.fn_decl() + { + assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); + tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip( + liberated_sig.inputs_and_output, + decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), + ))) + } else { + tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain( + liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), + )) + } } DefKind::Impl => match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.substs.types().collect(); - tcx.intern_type_list(&types) + let self_span = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(impl_), + .. + })) = tcx.hir().get_if_local(def_id) + { + impl_.self_ty.span + } else { + DUMMY_SP + }; + tcx.arena.alloc_from_iter(std::iter::zip( + types, + // FIXME: reliable way of getting trait ref substs... + [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)), + )) } // Only the impl self type - None => tcx.intern_type_list(&[tcx.type_of(def_id)]), + None => { + let span = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(impl_), + .. + })) = tcx.hir().get_if_local(def_id) + { + impl_.self_ty.span + } else { + DUMMY_SP + }; + tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)]) + } }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), DefKind::Mod @@ -56,6 +103,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Generator => ty::List::empty(), + | DefKind::Generator => &[], } } diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr index 389cc7beddd..6552c8be780 100644 --- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr +++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-for-unimpl-trait.rs:10:5 + --> $DIR/associated-types-for-unimpl-trait.rs:10:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr index 1feaa612ee6..b2ee1b5e6d0 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `T: Get` is not satisfied - --> $DIR/associated-types-no-suitable-bound.rs:11:5 + --> $DIR/associated-types-no-suitable-bound.rs:11:21 | LL | fn uhoh(foo: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr index cc3ed556115..2e40dbd065d 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:5 + --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr index 18f2830d8b2..bd3ee2abd2c 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `(T, U): Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:22:5 + --> $DIR/associated-types-no-suitable-supertrait.rs:22:40 | LL | fn uhoh(&self, foo: U, bar: <(T, U) as Get>::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:17:5 + --> $DIR/associated-types-no-suitable-supertrait.rs:17:40 | LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr index 66d59bccdbb..2e67c21940f 100644 --- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:5 + --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40 | LL | fn okay(&self, foo: U, bar: ::Value); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs index 9e68e9e7751..551f13ee178 100644 --- a/src/test/ui/associated-types/issue-59324.rs +++ b/src/test/ui/associated-types/issue-59324.rs @@ -15,9 +15,9 @@ pub trait ThriftService: { fn get_service( //~^ ERROR the trait bound `Bug: Foo` is not satisfied - //~| ERROR the trait bound `Bug: Foo` is not satisfied &self, ) -> Self::AssocType; + //~^ ERROR the trait bound `Bug: Foo` is not satisfied } fn with_factory(factory: dyn ThriftService<()>) {} diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr index 62cf1f37a77..a84b599b52b 100644 --- a/src/test/ui/associated-types/issue-59324.stderr +++ b/src/test/ui/associated-types/issue-59324.stderr @@ -20,7 +20,7 @@ LL | | LL | | LL | | Service::OnlyFoo> ... | -LL | | ) -> Self::AssocType; +LL | | LL | | } | |_^ the trait `Foo` is not implemented for `Bug` | @@ -34,7 +34,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied | LL | / fn get_service( LL | | -LL | | LL | | &self, LL | | ) -> Self::AssocType; | |_________________________^ the trait `Foo` is not implemented for `Bug` @@ -45,20 +44,16 @@ LL | pub trait ThriftService: | +++++ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:23:1 + --> $DIR/issue-59324.rs:23:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:16:5 + --> $DIR/issue-59324.rs:19:10 | -LL | / fn get_service( -LL | | -LL | | -LL | | &self, -LL | | ) -> Self::AssocType; - | |_________________________^ the trait `Foo` is not implemented for `Bug` +LL | ) -> Self::AssocType; + | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` | help: consider further restricting this bound | diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr index 22c3470b61e..bd18d46223e 100644 --- a/src/test/ui/issues/issue-18611.stderr +++ b/src/test/ui/issues/issue-18611.stderr @@ -1,10 +1,8 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied - --> $DIR/issue-18611.rs:1:1 + --> $DIR/issue-18611.rs:1:18 | -LL | / fn add_state(op: ::State) { -LL | | -LL | | } - | |_^ the trait `HasState` is not implemented for `isize` +LL | fn add_state(op: ::State) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index ef62dece836..c3af1f6786b 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -1,14 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | // -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the anonymous lifetime defined here... --> $DIR/issue-20831-debruijn.rs:28:58 @@ -21,16 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he LL | impl<'a> Publisher<'a> for MyStruct<'a> { | ^^ note: ...so that the types are compatible - --> $DIR/issue-20831-debruijn.rs:28:5 + --> $DIR/issue-20831-debruijn.rs:28:33 | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | // -... | -LL | | self.sub = t; -LL | | } - | |_____^ +LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected ` as Publisher<'_>>` found ` as Publisher<'_>>` diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs index a2b0222d4f3..42bdb423f8f 100644 --- a/src/test/ui/issues/issue-35570.rs +++ b/src/test/ui/issues/issue-35570.rs @@ -7,7 +7,6 @@ trait Trait2<'a> { fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied - //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied let _e: (usize, usize) = unsafe{mem::transmute(param)}; } diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr index ebc40f6786f..b6c244241ed 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -1,19 +1,9 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:1 - | -LL | / fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { -LL | | -LL | | -LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)}; -LL | | } - | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()` - -error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:40 + --> $DIR/issue-35570.rs:8:16 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 6abe53127c3..0fc3670d6c5 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -1,8 +1,8 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements - --> $DIR/normalization-bounds-error.rs:12:1 + --> $DIR/normalization-bounds-error.rs:12:31 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'d` as defined here... --> $DIR/normalization-bounds-error.rs:12:14 @@ -15,10 +15,10 @@ note: ...but the lifetime must also be valid for the lifetime `'a` as defined he LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ note: ...so that the types are compatible - --> $DIR/normalization-bounds-error.rs:12:1 + --> $DIR/normalization-bounds-error.rs:12:31 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `Visitor<'d>` found `Visitor<'_>` diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs index 1106352037a..429548f119b 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs @@ -20,7 +20,6 @@ trait Trait2<'a, 'b> { // do not infer that. fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied { } diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index 66f592c34dd..43b7b9c16b1 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -1,29 +1,14 @@ error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1 - | -LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) -LL | | -LL | | -LL | | { -LL | | } - | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ++++++++++++++++++++++++ - -error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` | help: consider restricting type parameter `T` | LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) | ++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs index 408732fe944..d02c108ae6b 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.rs +++ b/src/test/ui/specialization/min_specialization/issue-79224.rs @@ -15,8 +15,10 @@ impl ToString for Cow<'_, str> { } } -impl Display for Cow<'_, B> { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR: the trait bound `B: Clone` is not satisfied [E0277] +impl Display for Cow<'_, B> { + //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] + //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "foo") } } diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr index fd34a59d2bd..d4d7daf4111 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.stderr +++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr @@ -1,12 +1,8 @@ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:1 + --> $DIR/issue-79224.rs:18:29 | -LL | / impl Display for Cow<'_, B> { -LL | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | write!(f, "foo") -LL | | } -LL | | } - | |_^ the trait `Clone` is not implemented for `B` +LL | impl Display for Cow<'_, B> { + | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound @@ -15,12 +11,10 @@ LL | impl Display for Cow<'_, B> { | +++++++++++++++++++ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:19:5 + --> $DIR/issue-79224.rs:18:29 | -LL | / fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -LL | | write!(f, "foo") -LL | | } - | |_____^ the trait `Clone` is not implemented for `B` +LL | impl Display for Cow<'_, B> { + | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound diff --git a/src/test/ui/wf/issue-103573.stderr b/src/test/ui/wf/issue-103573.stderr index fcf3f15e4d3..3b6ab332612 100644 --- a/src/test/ui/wf/issue-103573.stderr +++ b/src/test/ui/wf/issue-103573.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `<>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied - --> $DIR/issue-103573.rs:18:5 + --> $DIR/issue-103573.rs:18:17 | LL | fn g<'a>(_: &< as TraitB>::TypeB as TraitA>::TypeA); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` | help: consider further restricting the associated type | diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr index 78312a09105..b03023b5fd1 100644 --- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/wf-foreign-fn-decl-ret.rs:11:5 + --> $DIR/wf-foreign-fn-decl-ret.rs:11:25 | LL | pub fn lint_me() -> <() as Foo>::Assoc; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 -- cgit 1.4.1-3-g733a5 From 0bddce50903c463ff06cc05edc1b3aba6645f50f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 03:14:27 +0000 Subject: Normalize assumed_wf_types after wfchecking is complete, for better spans --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 7 ++++--- src/test/ui/issues/issue-35570.stderr | 4 ++-- .../regions/regions-implied-bounds-projection-gap-hr-1.stderr | 4 ++-- src/test/ui/specialization/min_specialization/issue-79224.rs | 2 +- .../ui/specialization/min_specialization/issue-79224.stderr | 10 +++++----- src/test/ui/traits/issue-91594.stderr | 4 ++-- src/test/ui/wf/issue-103573.stderr | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b663f90cab7..969f7de51ce 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -97,21 +97,22 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( let infcx = &tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(infcx); - let assumed_wf_types = ocx.assumed_wf_types(param_env, span, body_def_id); - let mut wfcx = WfCheckingCtxt { ocx, span, body_id, param_env }; if !tcx.features().trivial_bounds { wfcx.check_false_global_bounds() } f(&mut wfcx); + + let assumed_wf_types = wfcx.ocx.assumed_wf_types(param_env, span, body_def_id); + let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types); + let errors = wfcx.select_all_or_error(); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None); return; } - let implied_bounds = infcx.implied_bounds_tys(param_env, body_id, assumed_wf_types); let outlives_environment = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr index b6c244241ed..2697d46bdb2 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied - --> $DIR/issue-35570.rs:8:16 + --> $DIR/issue-35570.rs:8:40 | LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` error: aborting due to previous error diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index 43b7b9c16b1..6844e866532 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied - --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25 + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:49 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/specialization/min_specialization/issue-79224.rs b/src/test/ui/specialization/min_specialization/issue-79224.rs index d02c108ae6b..104bddd076e 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.rs +++ b/src/test/ui/specialization/min_specialization/issue-79224.rs @@ -17,8 +17,8 @@ impl ToString for Cow<'_, str> { impl Display for Cow<'_, B> { //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] - //~| ERROR: the trait bound `B: Clone` is not satisfied [E0277] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + //~^ ERROR: the trait bound `B: Clone` is not satisfied [E0277] write!(f, "foo") } } diff --git a/src/test/ui/specialization/min_specialization/issue-79224.stderr b/src/test/ui/specialization/min_specialization/issue-79224.stderr index d4d7daf4111..be6f04ae62a 100644 --- a/src/test/ui/specialization/min_specialization/issue-79224.stderr +++ b/src/test/ui/specialization/min_specialization/issue-79224.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:29 + --> $DIR/issue-79224.rs:18:17 | LL | impl Display for Cow<'_, B> { - | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` + | ^^^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound @@ -11,10 +11,10 @@ LL | impl Display for Cow<'_, B> { | +++++++++++++++++++ error[E0277]: the trait bound `B: Clone` is not satisfied - --> $DIR/issue-79224.rs:18:29 + --> $DIR/issue-79224.rs:20:12 | -LL | impl Display for Cow<'_, B> { - | ^^^^^^^^^^ the trait `Clone` is not implemented for `B` +LL | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + | ^^^^^ the trait `Clone` is not implemented for `B` | = note: required for `B` to implement `ToOwned` help: consider further restricting this bound diff --git a/src/test/ui/traits/issue-91594.stderr b/src/test/ui/traits/issue-91594.stderr index 5fcd090a834..9f9acf85113 100644 --- a/src/test/ui/traits/issue-91594.stderr +++ b/src/test/ui/traits/issue-91594.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `Foo: HasComponent<()>` is not satisfied - --> $DIR/issue-91594.rs:10:1 + --> $DIR/issue-91594.rs:10:6 | LL | impl HasComponent<>::Interface> for Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasComponent<()>` is not implemented for `Foo` | = help: the trait `HasComponent<>::Interface>` is implemented for `Foo` note: required for `Foo` to implement `Component` diff --git a/src/test/ui/wf/issue-103573.stderr b/src/test/ui/wf/issue-103573.stderr index 3b6ab332612..5227badb77d 100644 --- a/src/test/ui/wf/issue-103573.stderr +++ b/src/test/ui/wf/issue-103573.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `<>::TypeC<'a> as TraitB>::TypeB: TraitA` is not satisfied - --> $DIR/issue-103573.rs:18:17 + --> $DIR/issue-103573.rs:18:18 | LL | fn g<'a>(_: &< as TraitB>::TypeB as TraitA>::TypeA); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TraitA` is not implemented for `<>::TypeC<'a> as TraitB>::TypeB` | help: consider further restricting the associated type | -- cgit 1.4.1-3-g733a5 From e77e8eb9455264b70eb4344a404243b7c012db08 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 19:02:58 +0000 Subject: Don't store spans in assumed_wf_types actually --- compiler/rustc_middle/src/query/mod.rs | 2 +- .../rustc_trait_selection/src/traits/engine.rs | 6 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 67 ++++------------------ src/test/ui/issues/issue-35570.rs | 1 + src/test/ui/issues/issue-35570.stderr | 12 +++- .../regions-implied-bounds-projection-gap-hr-1.rs | 1 + ...gions-implied-bounds-projection-gap-hr-1.stderr | 17 +++++- 7 files changed, 43 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7f794a926c0..37db2274f67 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -803,7 +803,7 @@ rustc_queries! { /// /// Note that we've liberated the late bound regions of function signatures, so /// this can not be used to check whether these types are well formed. - query assumed_wf_types(key: DefId) -> &'tcx [(Ty<'tcx>, Span)] { + query assumed_wf_types(key: DefId) -> &'tcx ty::List> { desc { |tcx| "computing the implied bounds of `{}`", tcx.def_path_str(key) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 72ed3aa499d..bc6d9d4b922 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -191,8 +191,8 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { let assumed_wf_types = tcx.assumed_wf_types(def_id); let mut implied_bounds = FxIndexSet::default(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - for &(ty, ty_span) in assumed_wf_types { - let span = if ty_span.is_dummy() { span } else { ty_span }; + let cause = ObligationCause::misc(span, hir_id); + for ty in assumed_wf_types { // FIXME(@lcnr): rustc currently does not check wf for types // pre-normalization, meaning that implied bounds are sometimes // incorrect. See #100910 for more details. @@ -205,7 +205,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { // sound and then uncomment this line again. // implied_bounds.insert(ty); - let normalized = self.normalize(&ObligationCause::misc(span, hir_id), param_env, ty); + let normalized = self.normalize(&cause, param_env, ty); implied_bounds.insert(normalized); } implied_bounds diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index e3f34373ccc..b7a24a22c53 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -1,80 +1,33 @@ use crate::rustc_middle::ty::DefIdTree; -use rustc_hir::{self as hir, def::DefKind, def_id::DefId}; +use rustc_hir::{def::DefKind, def_id::DefId}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::{Span, DUMMY_SP}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { assumed_wf_types, ..*providers }; } -fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { +fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { match tcx.def_kind(def_id) { DefKind::Fn => { let sig = tcx.fn_sig(def_id); let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - if let Some(node) = tcx.hir().get_if_local(def_id) - && let Some(decl) = node.fn_decl() - { - assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); - tcx.arena.alloc_from_iter(std::iter::zip( - liberated_sig.inputs_and_output, - decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), - )) - } else { - tcx.arena.alloc_from_iter( - liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), - ) - } + liberated_sig.inputs_and_output } DefKind::AssocFn => { let sig = tcx.fn_sig(def_id); let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); - let assumed_wf_types = tcx.assumed_wf_types(tcx.parent(def_id)); - if let Some(node) = tcx.hir().get_if_local(def_id) - && let Some(decl) = node.fn_decl() - { - assert_eq!(decl.inputs.len(), liberated_sig.inputs().len()); - tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain(std::iter::zip( - liberated_sig.inputs_and_output, - decl.inputs.iter().map(|ty| ty.span).chain([decl.output.span()]), - ))) - } else { - tcx.arena.alloc_from_iter(assumed_wf_types.iter().copied().chain( - liberated_sig.inputs_and_output.iter().map(|ty| (ty, DUMMY_SP)), - )) - } + let mut assumed_wf_types: Vec<_> = + tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); + assumed_wf_types.extend(liberated_sig.inputs_and_output); + tcx.intern_type_list(&assumed_wf_types) } DefKind::Impl => match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.substs.types().collect(); - let self_span = if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(impl_), - .. - })) = tcx.hir().get_if_local(def_id) - { - impl_.self_ty.span - } else { - DUMMY_SP - }; - tcx.arena.alloc_from_iter(std::iter::zip( - types, - // FIXME: reliable way of getting trait ref substs... - [self_span].into_iter().chain(std::iter::repeat(DUMMY_SP)), - )) + tcx.intern_type_list(&types) } // Only the impl self type - None => { - let span = if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(impl_), - .. - })) = tcx.hir().get_if_local(def_id) - { - impl_.self_ty.span - } else { - DUMMY_SP - }; - tcx.arena.alloc_from_iter([(tcx.type_of(def_id), span)]) - } + None => tcx.intern_type_list(&[tcx.type_of(def_id)]), }, DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), DefKind::Mod @@ -103,6 +56,6 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &[(Ty<'_>, Span)] { | DefKind::LifetimeParam | DefKind::GlobalAsm | DefKind::Closure - | DefKind::Generator => &[], + | DefKind::Generator => ty::List::empty(), } } diff --git a/src/test/ui/issues/issue-35570.rs b/src/test/ui/issues/issue-35570.rs index 42bdb423f8f..a2b0222d4f3 100644 --- a/src/test/ui/issues/issue-35570.rs +++ b/src/test/ui/issues/issue-35570.rs @@ -7,6 +7,7 @@ trait Trait2<'a> { fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { //~^ ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied + //~| ERROR the trait bound `for<'a> (): Trait2<'a>` is not satisfied let _e: (usize, usize) = unsafe{mem::transmute(param)}; } diff --git a/src/test/ui/issues/issue-35570.stderr b/src/test/ui/issues/issue-35570.stderr index 2697d46bdb2..3dc33729d8f 100644 --- a/src/test/ui/issues/issue-35570.stderr +++ b/src/test/ui/issues/issue-35570.stderr @@ -4,6 +4,16 @@ error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied LL | fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()` -error: aborting due to previous error +error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied + --> $DIR/issue-35570.rs:8:1 + | +LL | / fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { +LL | | +LL | | +LL | | let _e: (usize, usize) = unsafe{mem::transmute(param)}; +LL | | } + | |_^ the trait `for<'a> Trait2<'a>` is not implemented for `()` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs index 429548f119b..1106352037a 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs @@ -20,6 +20,7 @@ trait Trait2<'a, 'b> { // do not infer that. fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) //~^ ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied + //~| ERROR the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied { } diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index 6844e866532..3fd39810d44 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -9,6 +9,21 @@ help: consider restricting type parameter `T` LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) | ++++++++++++++++++++++++ -error: aborting due to previous error +error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied + --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:1 + | +LL | / fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) +LL | | +LL | | +LL | | { +LL | | } + | |_^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< >::Foo >) + | ++++++++++++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. -- cgit 1.4.1-3-g733a5 From 59aa421f3518b28bba5ebc883714638e65b0a3c5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 8 Jan 2023 19:45:23 +0000 Subject: Suppress type errors that come from private fields --- compiler/rustc_hir_typeck/src/expr.rs | 6 +++--- src/test/ui/issues/issue-25386.rs | 1 - src/test/ui/issues/issue-25386.stderr | 8 +------- src/test/ui/privacy/private-field-ty-err.rs | 20 ++++++++++++++++++++ src/test/ui/privacy/private-field-ty-err.stderr | 14 ++++++++++++++ 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/privacy/private-field-ty-err.rs create mode 100644 src/test/ui/privacy/private-field-ty-err.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 6ed1bc051a5..b08b22108c8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2217,7 +2217,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); return field_ty; } - private_candidate = Some((adjustments, base_def.did(), field_ty)); + private_candidate = Some((adjustments, base_def.did())); } } ty::Tuple(tys) => { @@ -2240,12 +2240,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false)); - if let Some((adjustments, did, field_ty)) = private_candidate { + if let Some((adjustments, did)) = private_candidate { // (#90483) apply adjustments to avoid ExprUseVisitor from // creating erroneous projection. self.apply_adjustments(base, adjustments); self.ban_private_field_access(expr, base_ty, field, did); - return field_ty; + return self.tcx().ty_error(); } if field.name == kw::Empty { diff --git a/src/test/ui/issues/issue-25386.rs b/src/test/ui/issues/issue-25386.rs index a76d8a615f6..b26cc77680d 100644 --- a/src/test/ui/issues/issue-25386.rs +++ b/src/test/ui/issues/issue-25386.rs @@ -24,5 +24,4 @@ macro_rules! check_ptr_exist { fn main() { let item = stuff::Item::new(); println!("{}", check_ptr_exist!(item, name)); - //~^ ERROR field `name` of struct `CObj` is private } diff --git a/src/test/ui/issues/issue-25386.stderr b/src/test/ui/issues/issue-25386.stderr index bce269393ee..727b9690829 100644 --- a/src/test/ui/issues/issue-25386.stderr +++ b/src/test/ui/issues/issue-25386.stderr @@ -9,12 +9,6 @@ LL | println!("{}", check_ptr_exist!(item, name)); | = note: this error originates in the macro `check_ptr_exist` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0616]: field `name` of struct `CObj` is private - --> $DIR/issue-25386.rs:26:43 - | -LL | println!("{}", check_ptr_exist!(item, name)); - | ^^^^ private field - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0616`. diff --git a/src/test/ui/privacy/private-field-ty-err.rs b/src/test/ui/privacy/private-field-ty-err.rs new file mode 100644 index 00000000000..10db6069567 --- /dev/null +++ b/src/test/ui/privacy/private-field-ty-err.rs @@ -0,0 +1,20 @@ +fn main() { + let x = foo::Foo::default(); + if x.len { + //~^ ERROR field `len` of struct `Foo` is private + println!("foo"); + } +} + +mod foo { + #[derive(Default)] + pub struct Foo { + len: String, + } + + impl Foo { + pub fn len(&self) -> usize { + 42 + } + } +} diff --git a/src/test/ui/privacy/private-field-ty-err.stderr b/src/test/ui/privacy/private-field-ty-err.stderr new file mode 100644 index 00000000000..e583a25fd8f --- /dev/null +++ b/src/test/ui/privacy/private-field-ty-err.stderr @@ -0,0 +1,14 @@ +error[E0616]: field `len` of struct `Foo` is private + --> $DIR/private-field-ty-err.rs:3:10 + | +LL | if x.len { + | ^^^ private field + | +help: a method `len` also exists, call it with parentheses + | +LL | if x.len() { + | ++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0616`. -- cgit 1.4.1-3-g733a5 From 65fae266eb62bc6af00b71c898b69344e25d8cd6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 8 Jan 2023 21:29:45 +0100 Subject: Add goml scripts to tidy checks --- src/tools/tidy/src/style.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index f409a86db26..723a52c4c68 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -25,6 +25,7 @@ use std::path::Path; /// displayed on the console with --example. const ERROR_CODE_COLS: usize = 80; const COLS: usize = 100; +const GOML_COLS: usize = 120; const LINES: usize = 3000; @@ -230,7 +231,8 @@ pub fn check(path: &Path, bad: &mut bool) { walk(path, &mut skip, &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); - let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl"]; + let extensions = + [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md", ".css", ".ftl", ".goml"]; if extensions.iter().all(|e| !filename.ends_with(e)) || filename.starts_with(".#") { return; } @@ -255,8 +257,15 @@ pub fn check(path: &Path, bad: &mut bool) { let extension = file.extension().unwrap().to_string_lossy(); let is_error_code = extension == "md" && is_in(file, "src", "error_codes"); + let is_goml_code = extension == "goml"; - let max_columns = if is_error_code { ERROR_CODE_COLS } else { COLS }; + let max_columns = if is_error_code { + ERROR_CODE_COLS + } else if is_goml_code { + GOML_COLS + } else { + COLS + }; let can_contain = contents.contains("// ignore-tidy-") || contents.contains("# ignore-tidy-") -- cgit 1.4.1-3-g733a5 From 31b39be9cef4f028b0a1cde5abff2f8acc426bfd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 8 Jan 2023 21:29:57 +0100 Subject: Fix tidy issues in goml scripts --- src/test/rustdoc-gui/escape-key.goml | 2 +- src/test/rustdoc-gui/impl-doc.goml | 6 +++--- src/test/rustdoc-gui/mobile.goml | 6 +++++- src/test/rustdoc-gui/rust-logo.goml | 21 ++++++++++++++++++--- .../rustdoc-gui/scrape-examples-button-focus.goml | 10 +++++----- src/test/rustdoc-gui/sidebar.goml | 2 +- src/test/rustdoc-gui/type-declation-overflow.goml | 1 + 7 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml index 78e9f23093e..5d80d24969d 100644 --- a/src/test/rustdoc-gui/escape-key.goml +++ b/src/test/rustdoc-gui/escape-key.goml @@ -5,7 +5,7 @@ goto: "file://" + |DOC_PATH| + "/test_docs/index.html" write: (".search-input", "test") // To be SURE that the search will be run. press-key: 'Enter' -wait-for: "#search h1" // The search element is empty before the first search +wait-for: "#search h1" // The search element is empty before the first search // Check that the currently displayed element is search. wait-for: "#alternative-display #search" assert-attribute: ("#main-content", {"class": "content hidden"}) diff --git a/src/test/rustdoc-gui/impl-doc.goml b/src/test/rustdoc-gui/impl-doc.goml index 7322032b3f5..6caffb9c39f 100644 --- a/src/test/rustdoc-gui/impl-doc.goml +++ b/src/test/rustdoc-gui/impl-doc.goml @@ -3,7 +3,7 @@ goto: "file://" + |DOC_PATH| + "/test_docs/struct.TypeWithImplDoc.html" // The text is about 24px tall, so if there's a margin, then their position will be >24px apart compare-elements-position-near-false: ( - "#implementations-list > .implementors-toggle > .docblock > p", - "#implementations-list > .implementors-toggle > .impl-items", - {"y": 24} + "#implementations-list > .implementors-toggle > .docblock > p", + "#implementations-list > .implementors-toggle > .impl-items", + {"y": 24} ) diff --git a/src/test/rustdoc-gui/mobile.goml b/src/test/rustdoc-gui/mobile.goml index 704542a39d2..895864d8944 100644 --- a/src/test/rustdoc-gui/mobile.goml +++ b/src/test/rustdoc-gui/mobile.goml @@ -27,4 +27,8 @@ assert-css-false: (".content .out-of-band .since::before", { "content": "\"Since goto: "file://" + |DOC_PATH| + "/settings.html" size: (400, 600) // Ignored for now https://github.com/rust-lang/rust/issues/93784. -// compare-elements-position-near-false: ("#preferred-light-theme .setting-name", "#preferred-light-theme .choice", {"y": 16}) +// compare-elements-position-near-false: ( +// "#preferred-light-theme .setting-name", +// "#preferred-light-theme .choice", +// {"y": 16}, +// ) diff --git a/src/test/rustdoc-gui/rust-logo.goml b/src/test/rustdoc-gui/rust-logo.goml index e94dc9a964d..2d15e8b9699 100644 --- a/src/test/rustdoc-gui/rust-logo.goml +++ b/src/test/rustdoc-gui/rust-logo.goml @@ -31,13 +31,28 @@ define-function: ( call-function: ( "check-logo", - ("ayu", "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"), + { + "theme": "ayu", + "filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) " + + "drop-shadow(rgb(255, 255, 255) 0px 1px 0px) " + + "drop-shadow(rgb(255, 255, 255) -1px 0px 0px) " + + "drop-shadow(rgb(255, 255, 255) 0px -1px 0px)", + }, ) call-function: ( "check-logo", - ("dark", "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px 1px 0px) drop-shadow(rgb(255, 255, 255) -1px 0px 0px) drop-shadow(rgb(255, 255, 255) 0px -1px 0px)"), + { + "theme": "dark", + "filter": "drop-shadow(rgb(255, 255, 255) 1px 0px 0px) " + + "drop-shadow(rgb(255, 255, 255) 0px 1px 0px) " + + "drop-shadow(rgb(255, 255, 255) -1px 0px 0px) " + + "drop-shadow(rgb(255, 255, 255) 0px -1px 0px)", + }, ) call-function: ( "check-logo", - ("light", "none"), + { + "theme": "light", + "filter": "none", + }, ) diff --git a/src/test/rustdoc-gui/scrape-examples-button-focus.goml b/src/test/rustdoc-gui/scrape-examples-button-focus.goml index bba518db099..10651a3f669 100644 --- a/src/test/rustdoc-gui/scrape-examples-button-focus.goml +++ b/src/test/rustdoc-gui/scrape-examples-button-focus.goml @@ -5,25 +5,25 @@ store-property: (initialScrollTop, ".scraped-example-list > .scraped-example pre focus: ".scraped-example-list > .scraped-example .next" press-key: "Enter" assert-property-false: (".scraped-example-list > .scraped-example pre", { - "scrollTop": |initialScrollTop| + "scrollTop": |initialScrollTop| }) focus: ".scraped-example-list > .scraped-example .prev" press-key: "Enter" assert-property: (".scraped-example-list > .scraped-example pre", { - "scrollTop": |initialScrollTop| + "scrollTop": |initialScrollTop| }) // The expand button increases the scrollHeight of the minimized code viewport store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") assert-property-false: (".scraped-example-list > .scraped-example pre", { - "scrollHeight": |smallOffsetHeight| + "scrollHeight": |smallOffsetHeight| }) focus: ".scraped-example-list > .scraped-example .expand" press-key: "Enter" assert-property-false: (".scraped-example-list > .scraped-example pre", { - "offsetHeight": |smallOffsetHeight| + "offsetHeight": |smallOffsetHeight| }) store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight") assert-property: (".scraped-example-list > .scraped-example pre", { - "scrollHeight": |fullOffsetHeight| + "scrollHeight": |fullOffsetHeight| }) diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml index 9db7f59695b..9c742be0587 100644 --- a/src/test/rustdoc-gui/sidebar.goml +++ b/src/test/rustdoc-gui/sidebar.goml @@ -148,4 +148,4 @@ assert-text: ("#toggle-all-docs", "[+]") assert-property: (".sidebar", {"clientWidth": "200"}) click: "#toggle-all-docs" assert-text: ("#toggle-all-docs", "[−]") -assert-property: (".sidebar", {"clientWidth": "200"}) \ No newline at end of file +assert-property: (".sidebar", {"clientWidth": "200"}) diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index c014eb52e71..9b60bc04738 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -1,3 +1,4 @@ +// ignore-tidy-linelength // This test ensures that the items declaration content overflow is handled inside the
 directly.
 
 // We need to disable this check because
-- 
cgit 1.4.1-3-g733a5


From 6fdb54d2f103dc21197037e6b1ad0b51073b9627 Mon Sep 17 00:00:00 2001
From: Esteban Küber 
Date: Sun, 8 Jan 2023 22:27:13 +0000
Subject: Do not emit structured suggestion for turbofish with wrong span

Fix #79161.
---
 compiler/rustc_parse/src/parser/diagnostics.rs | 12 ++++++++++--
 src/test/ui/parser/nested-bad-turbofish.rs     |  3 +++
 src/test/ui/parser/nested-bad-turbofish.stderr | 11 +++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/parser/nested-bad-turbofish.rs
 create mode 100644 src/test/ui/parser/nested-bad-turbofish.stderr

diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index b3231f55bc6..d9fa3e31db9 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1104,7 +1104,11 @@ impl<'a> Parser<'a> {
                     return if token::ModSep == self.token.kind {
                         // We have some certainty that this was a bad turbofish at this point.
                         // `foo< bar >::`
-                        err.suggest_turbofish = Some(op.span.shrink_to_lo());
+                        if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt {
+                            err.suggest_turbofish = Some(op.span.shrink_to_lo());
+                        } else {
+                            err.help_turbofish = Some(());
+                        }
 
                         let snapshot = self.create_snapshot_for_diagnostic();
                         self.bump(); // `::`
@@ -1130,7 +1134,11 @@ impl<'a> Parser<'a> {
                     } else if token::OpenDelim(Delimiter::Parenthesis) == self.token.kind {
                         // We have high certainty that this was a bad turbofish at this point.
                         // `foo< bar >(`
-                        err.suggest_turbofish = Some(op.span.shrink_to_lo());
+                        if let ExprKind::Binary(o, ..) = inner_op.kind && o.node == BinOpKind::Lt {
+                            err.suggest_turbofish = Some(op.span.shrink_to_lo());
+                        } else {
+                            err.help_turbofish = Some(());
+                        }
                         // Consume the fn call arguments.
                         match self.consume_fn_args() {
                             Err(()) => Err(err.into_diagnostic(&self.sess.span_diagnostic)),
diff --git a/src/test/ui/parser/nested-bad-turbofish.rs b/src/test/ui/parser/nested-bad-turbofish.rs
new file mode 100644
index 00000000000..02099fde212
--- /dev/null
+++ b/src/test/ui/parser/nested-bad-turbofish.rs
@@ -0,0 +1,3 @@
+fn main() {
+    foo<::V>(); //~ ERROR
+}
diff --git a/src/test/ui/parser/nested-bad-turbofish.stderr b/src/test/ui/parser/nested-bad-turbofish.stderr
new file mode 100644
index 00000000000..d82fa80e594
--- /dev/null
+++ b/src/test/ui/parser/nested-bad-turbofish.stderr
@@ -0,0 +1,11 @@
+error: comparison operators cannot be chained
+  --> $DIR/nested-bad-turbofish.rs:2:16
+   |
+LL |     foo<::V>();
+   |                ^   ^
+   |
+   = help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
+   = help: or use `(...)` if you meant to specify fn arguments
+
+error: aborting due to previous error
+
-- 
cgit 1.4.1-3-g733a5


From 8740443c354ee1510a16017fae2104fcc39933cb Mon Sep 17 00:00:00 2001
From: Ralf Jung 
Date: Mon, 9 Jan 2023 13:48:31 +0100
Subject: Preparing for merge from rustc

---
 src/tools/miri/rust-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 29f34da77eb..cf6d9c28080 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-3b1c8a94a4e8a6ba8bc7b39cc3580db9e5b72295
+c54c8cbac882e149e04a9e1f2d146fd548ae30ae
-- 
cgit 1.4.1-3-g733a5