From 7ebbdc6e3b8c8cec8dc78c20f961c4fae415a5a0 Mon Sep 17 00:00:00 2001 From: Vincent Thiberville Date: Wed, 6 Jul 2022 15:29:17 +0200 Subject: [PATCH 001/103] add FromOwnedFd/FromOwnedHandle for ChildStdin/out/err --- library/std/src/os/unix/process.rs | 30 +++++++++++++++++++++++++++ library/std/src/os/windows/process.rs | 27 ++++++++++++++++++++++++ library/std/src/sys/unix/pipe.rs | 8 ++++++- library/std/src/sys/windows/pipe.rs | 8 ++++++- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 729c63d184f2c..5c1841016f41f 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -434,6 +434,16 @@ impl From for OwnedFd { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStdin { + #[inline] + fn from(fd: OwnedFd) -> process::ChildStdin { + let fd = sys::fd::FileDesc::from_inner(fd); + let pipe = sys::pipe::AnonPipe::from_inner(fd); + process::ChildStdin::from_inner(pipe) + } +} + #[stable(feature = "io_safety", since = "1.63.0")] impl AsFd for crate::process::ChildStdout { #[inline] @@ -450,6 +460,16 @@ impl From for OwnedFd { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStdout { + #[inline] + fn from(fd: OwnedFd) -> process::ChildStdout { + let fd = sys::fd::FileDesc::from_inner(fd); + let pipe = sys::pipe::AnonPipe::from_inner(fd); + process::ChildStdout::from_inner(pipe) + } +} + #[stable(feature = "io_safety", since = "1.63.0")] impl AsFd for crate::process::ChildStderr { #[inline] @@ -466,6 +486,16 @@ impl From for OwnedFd { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStderr { + #[inline] + fn from(fd: OwnedFd) -> process::ChildStderr { + let fd = sys::fd::FileDesc::from_inner(fd); + let pipe = sys::pipe::AnonPipe::from_inner(fd); + process::ChildStderr::from_inner(pipe) + } +} + /// Returns the OS-assigned process identifier associated with this process's parent. #[must_use] #[stable(feature = "unix_ppid", since = "1.27.0")] diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 073168cf2d209..719b804ac199b 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -106,6 +106,33 @@ impl IntoRawHandle for process::ChildStderr { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStdin { + fn from(handle: OwnedHandle) -> process::ChildStdin { + let handle = sys::handle::Handle::from_inner(handle); + let pipe = sys::pipe::AnonPipe::from_inner(handle); + process::ChildStdin::from_inner(pipe) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStdout { + fn from(handle: OwnedHandle) -> process::ChildStdout { + let handle = sys::handle::Handle::from_inner(handle); + let pipe = sys::pipe::AnonPipe::from_inner(handle); + process::ChildStdout::from_inner(pipe) + } +} + +#[stable(feature = "io_safety", since = "1.63.0")] +impl From for process::ChildStderr { + fn from(handle: OwnedHandle) -> process::ChildStderr { + let handle = sys::handle::Handle::from_inner(handle); + let pipe = sys::pipe::AnonPipe::from_inner(handle); + process::ChildStderr::from_inner(pipe) + } +} + /// Windows-specific extensions to [`process::ExitStatus`]. /// /// This trait is sealed: it cannot be implemented outside the standard library. diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs index 938a46bfdd833..a9c783b46237e 100644 --- a/library/std/src/sys/unix/pipe.rs +++ b/library/std/src/sys/unix/pipe.rs @@ -3,7 +3,7 @@ use crate::mem; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; use crate::sys::{cvt, cvt_r}; -use crate::sys_common::IntoInner; +use crate::sys_common::{FromInner, IntoInner}; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes @@ -158,3 +158,9 @@ impl FromRawFd for AnonPipe { Self(FromRawFd::from_raw_fd(raw_fd)) } } + +impl FromInner for AnonPipe { + fn from_inner(fd: FileDesc) -> Self { + Self(fd) + } +} diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index d07147eccc1d3..7624e746f5c89 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -12,7 +12,7 @@ use crate::sys::c; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::hashmap_random_keys; -use crate::sys_common::IntoInner; +use crate::sys_common::{FromInner, IntoInner}; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes @@ -28,6 +28,12 @@ impl IntoInner for AnonPipe { } } +impl FromInner for AnonPipe { + fn from_inner(inner: Handle) -> AnonPipe { + Self { inner } + } +} + pub struct Pipes { pub ours: AnonPipe, pub theirs: AnonPipe, From 9de32a7a3b7928b3679118cf423fd69246de8784 Mon Sep 17 00:00:00 2001 From: Vincent Thiberville Date: Thu, 9 Mar 2023 10:46:38 +0100 Subject: [PATCH 002/103] add doc on From impl for ChildStd* --- library/std/src/os/unix/process.rs | 12 ++++++++++++ library/std/src/os/windows/process.rs | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 5c1841016f41f..95f10bcb04e3f 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -434,6 +434,10 @@ impl From for OwnedFd { } } +/// Create a `ChildStdin` from the provided `OwnedFd`. +/// +/// The provided file descriptor must point to a pipe +/// with the `CLOEXEC` flag set. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStdin { #[inline] @@ -460,6 +464,10 @@ impl From for OwnedFd { } } +/// Create a `ChildStdout` from the provided `OwnedFd`. +/// +/// The provided file descriptor must point to a pipe +/// with the `CLOEXEC` flag set. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStdout { #[inline] @@ -486,6 +494,10 @@ impl From for OwnedFd { } } +/// Create a `ChildStderr` from the provided `OwnedFd`. +/// +/// The provided file descriptor must point to a pipe +/// with the `CLOEXEC` flag set. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStderr { #[inline] diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 719b804ac199b..2f989a77f14ec 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -106,6 +106,10 @@ impl IntoRawHandle for process::ChildStderr { } } +/// Create a `ChildStdin` from the provided `OwnedHandle`. +/// +/// The provided handle must be asynchronous, as reading and +/// writing from and to it is implemented using asynchronous APIs. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStdin { fn from(handle: OwnedHandle) -> process::ChildStdin { @@ -115,6 +119,10 @@ impl From for process::ChildStdin { } } +/// Create a `ChildStdout` from the provided `OwnedHandle`. +/// +/// The provided handle must be asynchronous, as reading and +/// writing from and to it is implemented using asynchronous APIs. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStdout { fn from(handle: OwnedHandle) -> process::ChildStdout { @@ -124,6 +132,10 @@ impl From for process::ChildStdout { } } +/// Create a `ChildStderr` from the provided `OwnedHandle`. +/// +/// The provided handle must be asynchronous, as reading and +/// writing from and to it is implemented using asynchronous APIs. #[stable(feature = "io_safety", since = "1.63.0")] impl From for process::ChildStderr { fn from(handle: OwnedHandle) -> process::ChildStderr { From 659c17a6760ca03d3d69e2f44cef8fb3932cec95 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 23 Jun 2023 14:38:30 +0200 Subject: [PATCH 003/103] Change the wording in `std::fmt::Write::write_str` Refer to the error instead of expanding its name. --- library/core/src/fmt/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 1786b309c5bd3..5c6359a9025e3 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -112,9 +112,9 @@ pub trait Write { /// /// # Errors /// - /// This function will return an instance of [`Error`] on error. + /// This function will return an instance of [`std::fmt::Error`] on error. /// - /// The purpose of std::fmt::Error is to abort the formatting operation when the underlying + /// The purpose of that error is to abort the formatting operation when the underlying /// destination encounters some error preventing it from accepting more text; it should /// generally be propagated rather than handled, at least when implementing formatting traits. /// From 27e10e2b5e2a589196c3d72f5da58f480ad14374 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Sat, 15 Jul 2023 19:20:41 +0800 Subject: [PATCH 004/103] Implement `From<{&,&mut} [T; N]>` for `Vec` --- library/alloc/src/vec/mod.rs | 30 ++++++++++++++++++++++++++++++ library/alloc/tests/vec.rs | 10 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 598ecf05e8246..d42c8720e6bda 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3101,6 +3101,36 @@ impl From<&mut [T]> for Vec { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")] +impl From<&[T; N]> for Vec { + /// Allocate a `Vec` and fill it by cloning `s`'s items. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]); + /// ``` + fn from(s: &[T; N]) -> Vec { + Self::from(s.as_slice()) + } +} + +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")] +impl From<&mut [T; N]> for Vec { + /// Allocate a `Vec` and fill it by cloning `s`'s items. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); + /// ``` + fn from(s: &mut [T; N]) -> Vec { + Self::from(s.as_mut_slice()) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_from_array", since = "1.44.0")] impl From<[T; N]> for Vec { diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 183dd8e6e5932..a3799a7be05d1 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -2563,3 +2563,13 @@ fn test_box_zero_allocator() { // Ensure all ZSTs have been freed. assert!(alloc.state.borrow().0.is_empty()); } + +#[test] +fn test_vec_from_array_ref() { + assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]); +} + +#[test] +fn test_vec_from_array_mut_ref() { + assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); +} From b2d35e1f4bc2aa6f2b9745ea515d5d69298b2e52 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Mon, 24 Jul 2023 21:33:16 -0400 Subject: [PATCH 005/103] Implement `From<[T; N]>` for `Rc<[T]>` and `Arc<[T]>` --- library/alloc/src/rc.rs | 21 +++++++++++++++++++++ library/alloc/src/sync.rs | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index bf01b2082eda2..be9832267810c 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2406,6 +2406,27 @@ impl From for Rc { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")] +impl From<[T; N]> for Rc<[T]> { + /// Converts a [`[T; N]`](prim@array) into an `Rc<[T]>`. + /// + /// The conversion moves the array into a newly allocated `Rc`. + /// + /// # Example + /// + /// ``` + /// # use std::rc::Rc; + /// let original: [i32; 3] = [1, 2, 3]; + /// let shared: Rc<[i32]> = Rc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: [T; N]) -> Rc<[T]> { + Rc::<[T; N]>::from(v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From<&[T]> for Rc<[T]> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index c2202f2fce553..26fd715c31be0 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3269,6 +3269,27 @@ impl From for Arc { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")] +impl From<[T; N]> for Arc<[T]> { + /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`. + /// + /// The conversion moves the array into a newly allocated `Arc`. + /// + /// # Example + /// + /// ``` + /// # use std::sync::Arc; + /// let original: [i32; 3] = [1, 2, 3]; + /// let shared: Arc<[i32]> = Arc::from(original); + /// assert_eq!(&[1, 2, 3], &shared[..]); + /// ``` + #[inline] + fn from(v: [T; N]) -> Arc<[T]> { + Arc::<[T; N]>::from(v) + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "shared_from_slice", since = "1.21.0")] impl From<&[T]> for Arc<[T]> { From 6acb415e7c7671c078177a95412987374b30a3c3 Mon Sep 17 00:00:00 2001 From: "Chai T. Rex" Date: Thu, 3 Aug 2023 13:25:52 -0400 Subject: [PATCH 006/103] Convert `Into for ExitStatusError` to `From for ExitStatus` in `std::process` --- library/std/src/process.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index f9cb755b01a3a..4f20bb4c16672 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1738,9 +1738,9 @@ impl ExitStatusError { } #[unstable(feature = "exit_status_error", issue = "84908")] -impl Into for ExitStatusError { - fn into(self) -> ExitStatus { - ExitStatus(self.0.into()) +impl From for ExitStatus { + fn from(error: ExitStatusError) -> Self { + Self(error.0.into()) } } From 72e29da3eccd3e4c1fb2c581fa33216db50fcc93 Mon Sep 17 00:00:00 2001 From: Be Wilson Date: Mon, 3 Jul 2023 14:26:05 -0500 Subject: [PATCH 007/103] stabilize combining +bundle and +whole-archive link modifiers Currently, combining +bundle and +whole-archive works only with #![feature(packed_bundled_libs)] This crate feature is independent of the -Zpacked-bundled-libs command line option. This commit stabilizes the #![feature(packed_bundled_libs)] crate feature and implicitly enables it only when the +bundle and +whole-archive link modifiers are combined. This allows rlib crates to use the +whole-archive link modifier with native libraries and have all symbols included in the linked library to be included in downstream staticlib crates that use the rlib as a dependency. Other cases requiring the packed_bundled_libs behavior still require the -Zpacked-bundled-libs command line option, which can be stabilized independently in the future. Per discussion on https://github.com/rust-lang/rust/issues/108081 there is no risk of regression stabilizing the crate feature in this way because the combination of +bundle,+whole-archive link modifiers was previously not allowed. --- compiler/rustc_codegen_ssa/messages.ftl | 2 -- compiler/rustc_codegen_ssa/src/back/link.rs | 8 +------- compiler/rustc_codegen_ssa/src/base.rs | 1 - compiler/rustc_codegen_ssa/src/errors.rs | 4 ---- compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/active.rs | 2 -- .../rlib-format-packed-bundled-libs-3/Makefile | 4 ++-- .../rlib-format-packed-bundled-libs-3/rust_dep.rs | 2 -- .../mix-bundle-and-whole-archive-link-attr.rs | 11 ----------- .../mix-bundle-and-whole-archive-link-attr.stderr | 4 ---- .../mix-bundle-and-whole-archive.rs | 8 -------- .../mix-bundle-and-whole-archive.stderr | 4 ---- 13 files changed, 5 insertions(+), 48 deletions(-) delete mode 100644 tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs delete mode 100644 tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr delete mode 100644 tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs delete mode 100644 tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index b6c70c6224977..326c359411d86 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -44,8 +44,6 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal` .note = an unsuffixed integer value, e.g., `1`, is expected -codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index a7ac728c59b02..c4a0f6291e7f4 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -365,15 +365,9 @@ fn link_rlib<'a>( // loaded from the libraries found here and then encode that into the // metadata of the rlib we're generating somehow. for lib in codegen_results.crate_info.used_libraries.iter() { - let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else { + let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else { continue; }; - if whole_archive == Some(true) - && flavor == RlibFlavor::Normal - && !codegen_results.crate_info.feature_packed_bundled_libs - { - sess.emit_err(errors::IncompatibleLinkingModifiers); - } if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename { let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess); let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?; diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index aa003e4e89811..6627d7d81e97a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -839,7 +839,6 @@ impl CrateInfo { dependency_formats: tcx.dependency_formats(()).clone(), windows_subsystem, natvis_debugger_visualizers: Default::default(), - feature_packed_bundled_libs: tcx.features().packed_bundled_libs, }; let crates = tcx.crates(()); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index b7d8b9b45bf16..c3b5e6c9bf365 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -106,10 +106,6 @@ pub struct CreateTempDir { pub error: Error, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_incompatible_linking_modifiers)] -pub struct IncompatibleLinkingModifiers; - #[derive(Diagnostic)] #[diag(codegen_ssa_add_native_library)] pub struct AddNativeLibrary { diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 7bed3fa615034..34a331ed02b52 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -164,7 +164,6 @@ pub struct CrateInfo { pub dependency_formats: Lrc, pub windows_subsystem: Option, pub natvis_debugger_visualizers: BTreeSet, - pub feature_packed_bundled_libs: bool, // unstable feature flag. } #[derive(Encodable, Decodable)] diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index b1f74643b69c7..7ee78c28b26e2 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -267,6 +267,8 @@ declare_features! ( (accepted, non_modrs_mods, "1.30.0", Some(44660), None), /// Allows the use of or-patterns (e.g., `0 | 1`). (accepted, or_patterns, "1.53.0", Some(54883), None), + /// Allows using `+bundle,+whole-archive` link modifiers with native libs. + (accepted, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None), /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. /// This defines the behavior of panics. (accepted, panic_handler, "1.30.0", Some(44489), None), diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 953ea1bf523d1..25b71023b4589 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -241,8 +241,6 @@ declare_features! ( (active, linkage, "1.0.0", Some(29603), None), /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. (internal, needs_panic_runtime, "1.10.0", Some(32837), None), - /// Allows using `+bundled,+whole-archive` native libs. - (active, packed_bundled_libs, "1.69.0", Some(108081), None), /// Allows using the `#![panic_runtime]` attribute. (internal, panic_runtime, "1.10.0", Some(32837), None), /// Allows using `#[rustc_allow_const_fn_unstable]`. diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile index 1f2812cb08792..9ba077b18547e 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -3,7 +3,7 @@ include ../tools.mk # ignore-cross-compile # only-linux -# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive. +# Make sure -Zpacked_bundled_libs-like behavior activates with +bundle,+whole-archive. # We're using the llvm-nm instead of the system nm to ensure it is compatible # with the LLVM bitcode generated by rustc. @@ -11,7 +11,7 @@ NM = "$(LLVM_BIN_DIR)"/llvm-nm all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4) # test cfg with packed bundle - $(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs + $(RUSTC) rust_dep_cfg.rs --crate-type=rlib $(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a" $(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a" diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs index abd846b6862d1..bde9b739de6a3 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs @@ -1,5 +1,3 @@ -#![feature(packed_bundled_libs)] - #[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")] extern "C" {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs deleted file mode 100644 index 0ccd441cc6489..0000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs +++ /dev/null @@ -1,11 +0,0 @@ -// gate-test-packed_bundled_libs - -// ignore-wasm32-bare -// compile-flags: --crate-type rlib -// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -// build-fail - -#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")] -extern "C" {} - -fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr deleted file mode 100644 index 8a9fed740b04e..0000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - -error: aborting due to previous error - diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs deleted file mode 100644 index 18d4b52a34c3d..0000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs +++ /dev/null @@ -1,8 +0,0 @@ -// gate-test-packed_bundled_libs - -// ignore-wasm32-bare -// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib -// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs -// build-fail - -fn main() {} diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr deleted file mode 100644 index 8a9fed740b04e..0000000000000 --- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs - -error: aborting due to previous error - From d9c85daa51bb131696a62a9653debf8ab8d1de07 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 16 Aug 2023 09:18:34 +0100 Subject: [PATCH 008/103] Update windows ffi bindings --- Cargo.lock | 18 +- library/std/src/sys/windows/c.rs | 6 +- library/std/src/sys/windows/c/windows_sys.lst | 8 +- library/std/src/sys/windows/c/windows_sys.rs | 157 +++++++++--------- library/std/src/sys/windows/handle.rs | 9 +- src/tools/generate-windows-sys/Cargo.toml | 2 +- src/tools/generate-windows-sys/src/main.rs | 31 ++-- 7 files changed, 104 insertions(+), 127 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7337901bc3a59..0f2cfba2925ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5851,19 +5851,21 @@ dependencies = [ [[package]] name = "windows-bindgen" -version = "0.49.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6935fb09b84ee57929ae92518b475f5dfdfbeb87c5334756acc28ee8e202b60" +checksum = "bc1f16b778125675feee0d15d6dd9f6af0e3ac52b3233d63a10aa39230c1cd75" dependencies = [ + "proc-macro2", + "rayon", + "syn 2.0.27", "windows-metadata", - "windows-tokens", ] [[package]] name = "windows-metadata" -version = "0.49.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5bca94a32bf1e6a376522b6601275a3b611ee885ec0f1b6a05f17e8cfd3385" +checksum = "753135d996f9da437c0b31dbde3032489a61708361929bcc07d4fba0b161000e" [[package]] name = "windows-sys" @@ -5889,12 +5891,6 @@ dependencies = [ "windows_x86_64_msvc", ] -[[package]] -name = "windows-tokens" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b34c9a3b28cb41db7385546f7f9a8179348dffc89923dde66857b1ba5312f6b4" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index d9ccba0e9da76..f3637cbb981dc 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -46,10 +46,6 @@ pub use FD_SET as fd_set; pub use LINGER as linger; pub use TIMEVAL as timeval; -pub type CONDITION_VARIABLE = RTL_CONDITION_VARIABLE; -pub type SRWLOCK = RTL_SRWLOCK; -pub type INIT_ONCE = RTL_RUN_ONCE; - pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() }; pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() }; pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() }; @@ -224,7 +220,7 @@ pub unsafe extern "system" fn ReadFileEx( ) -> BOOL { windows_sys::ReadFileEx( hFile.as_raw_handle(), - lpBuffer, + lpBuffer.cast::(), nNumberOfBytesToRead, lpOverlapped, lpCompletionRoutine, diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 5469ba42eb11a..3e5a9b7451012 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -1,3 +1,6 @@ +--out windows_sys.rs +--config flatten std +--filter // tidy-alphabetical-start Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION @@ -2108,7 +2111,6 @@ Windows.Win32.Networking.WinSock.WSABASEERR Windows.Win32.Networking.WinSock.WSABUF Windows.Win32.Networking.WinSock.WSACleanup Windows.Win32.Networking.WinSock.WSADATA -Windows.Win32.Networking.WinSock.WSADATA Windows.Win32.Networking.WinSock.WSADuplicateSocketW Windows.Win32.Networking.WinSock.WSAEACCES Windows.Win32.Networking.WinSock.WSAEADDRINUSE @@ -2420,8 +2422,6 @@ Windows.Win32.System.Console.STD_OUTPUT_HANDLE Windows.Win32.System.Console.WriteConsoleW Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128 Windows.Win32.System.Diagnostics.Debug.CONTEXT -Windows.Win32.System.Diagnostics.Debug.CONTEXT -Windows.Win32.System.Diagnostics.Debug.CONTEXT Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD Windows.Win32.System.Diagnostics.Debug.FACILITY_CODE Windows.Win32.System.Diagnostics.Debug.FACILITY_NT_BIT @@ -2435,7 +2435,6 @@ Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_OPTIONS Windows.Win32.System.Diagnostics.Debug.FormatMessageW Windows.Win32.System.Diagnostics.Debug.M128A Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT -Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT Windows.Win32.System.Environment.FreeEnvironmentStringsW Windows.Win32.System.Environment.GetCommandLineW Windows.Win32.System.Environment.GetCurrentDirectoryW @@ -2456,7 +2455,6 @@ Windows.Win32.System.Kernel.ExceptionContinueExecution Windows.Win32.System.Kernel.ExceptionContinueSearch Windows.Win32.System.Kernel.ExceptionNestedException Windows.Win32.System.Kernel.FLOATING_SAVE_AREA -Windows.Win32.System.Kernel.FLOATING_SAVE_AREA Windows.Win32.System.Kernel.OBJ_DONT_REPARSE Windows.Win32.System.LibraryLoader.GetModuleFileNameW Windows.Win32.System.LibraryLoader.GetModuleHandleA diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index b24f6dc900fc5..c7fba5bd30bed 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -32,11 +32,11 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { - pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> (); + pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> (); } #[link(name = "kernel32")] extern "system" { - pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> (); + pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK) -> (); } #[link(name = "kernel32")] extern "system" { @@ -189,18 +189,15 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { - pub fn FindClose(hfindfile: FindFileHandle) -> BOOL; + pub fn FindClose(hfindfile: HANDLE) -> BOOL; } #[link(name = "kernel32")] extern "system" { - pub fn FindFirstFileW( - lpfilename: PCWSTR, - lpfindfiledata: *mut WIN32_FIND_DATAW, - ) -> FindFileHandle; + pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE; } #[link(name = "kernel32")] extern "system" { - pub fn FindNextFileW(hfindfile: FindFileHandle, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL; + pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL; } #[link(name = "kernel32")] extern "system" { @@ -360,7 +357,7 @@ extern "system" { #[link(name = "kernel32")] extern "system" { pub fn InitOnceBeginInitialize( - lpinitonce: *mut RTL_RUN_ONCE, + lpinitonce: *mut INIT_ONCE, dwflags: u32, fpending: *mut BOOL, lpcontext: *mut *mut ::core::ffi::c_void, @@ -369,7 +366,7 @@ extern "system" { #[link(name = "kernel32")] extern "system" { pub fn InitOnceComplete( - lpinitonce: *mut RTL_RUN_ONCE, + lpinitonce: *mut INIT_ONCE, dwflags: u32, lpcontext: *const ::core::ffi::c_void, ) -> BOOL; @@ -424,7 +421,7 @@ extern "system" { extern "system" { pub fn ReadFile( hfile: HANDLE, - lpbuffer: *mut ::core::ffi::c_void, + lpbuffer: *mut u8, nnumberofbytestoread: u32, lpnumberofbytesread: *mut u32, lpoverlapped: *mut OVERLAPPED, @@ -434,7 +431,7 @@ extern "system" { extern "system" { pub fn ReadFileEx( hfile: HANDLE, - lpbuffer: *mut ::core::ffi::c_void, + lpbuffer: *mut u8, nnumberofbytestoread: u32, lpoverlapped: *mut OVERLAPPED, lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE, @@ -442,11 +439,11 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { - pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> (); + pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK) -> (); } #[link(name = "kernel32")] extern "system" { - pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> (); + pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK) -> (); } #[link(name = "kernel32")] extern "system" { @@ -513,8 +510,8 @@ extern "system" { #[link(name = "kernel32")] extern "system" { pub fn SleepConditionVariableSRW( - conditionvariable: *mut RTL_CONDITION_VARIABLE, - srwlock: *mut RTL_SRWLOCK, + conditionvariable: *mut CONDITION_VARIABLE, + srwlock: *mut SRWLOCK, dwmilliseconds: u32, flags: u32, ) -> BOOL; @@ -549,11 +546,11 @@ extern "system" { } #[link(name = "kernel32")] extern "system" { - pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN; + pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN; } #[link(name = "kernel32")] extern "system" { - pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN; + pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN; } #[link(name = "kernel32")] extern "system" { @@ -574,19 +571,19 @@ extern "system" { lphandles: *const HANDLE, bwaitall: BOOL, dwmilliseconds: u32, - ) -> WIN32_ERROR; + ) -> WAIT_EVENT; } #[link(name = "kernel32")] extern "system" { - pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR; + pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT; } #[link(name = "kernel32")] extern "system" { - pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> (); + pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> (); } #[link(name = "kernel32")] extern "system" { - pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> (); + pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> (); } #[link(name = "kernel32")] extern "system" { @@ -899,7 +896,17 @@ impl ::core::clone::Clone for BY_HANDLE_FILE_INFORMATION { } pub const CALLBACK_CHUNK_FINISHED: LPPROGRESS_ROUTINE_CALLBACK_REASON = 0u32; pub const CALLBACK_STREAM_SWITCH: LPPROGRESS_ROUTINE_CALLBACK_REASON = 1u32; -pub type COMPARESTRING_RESULT = u32; +pub type COMPARESTRING_RESULT = i32; +#[repr(C)] +pub struct CONDITION_VARIABLE { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for CONDITION_VARIABLE {} +impl ::core::clone::Clone for CONDITION_VARIABLE { + fn clone(&self) -> Self { + *self + } +} pub type CONSOLE_MODE = u32; #[repr(C)] pub struct CONSOLE_READCONSOLE_CONTROL { @@ -917,7 +924,7 @@ impl ::core::clone::Clone for CONSOLE_READCONSOLE_CONTROL { #[repr(C)] #[cfg(target_arch = "aarch64")] pub struct CONTEXT { - pub ContextFlags: u32, + pub ContextFlags: CONTEXT_FLAGS, pub Cpsr: u32, pub Anonymous: CONTEXT_0, pub Sp: u64, @@ -1004,7 +1011,7 @@ pub struct CONTEXT { pub P4Home: u64, pub P5Home: u64, pub P6Home: u64, - pub ContextFlags: u32, + pub ContextFlags: CONTEXT_FLAGS, pub MxCsr: u32, pub SegCs: u16, pub SegDs: u16, @@ -1100,7 +1107,7 @@ impl ::core::clone::Clone for CONTEXT_0_0 { #[repr(C)] #[cfg(target_arch = "x86")] pub struct CONTEXT { - pub ContextFlags: u32, + pub ContextFlags: CONTEXT_FLAGS, pub Dr0: u32, pub Dr1: u32, pub Dr2: u32, @@ -1134,6 +1141,7 @@ impl ::core::clone::Clone for CONTEXT { *self } } +pub type CONTEXT_FLAGS = u32; pub const CP_UTF8: u32 = 65001u32; pub const CREATE_ALWAYS: FILE_CREATION_DISPOSITION = 2u32; pub const CREATE_BREAKAWAY_FROM_JOB: PROCESS_CREATION_FLAGS = 16777216u32; @@ -1151,9 +1159,9 @@ pub const CREATE_SEPARATE_WOW_VDM: PROCESS_CREATION_FLAGS = 2048u32; pub const CREATE_SHARED_WOW_VDM: PROCESS_CREATION_FLAGS = 4096u32; pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32; pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32; -pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2u32; -pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3u32; -pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1u32; +pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2i32; +pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3i32; +pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1i32; pub const DEBUG_ONLY_THIS_PROCESS: PROCESS_CREATION_FLAGS = 2u32; pub const DEBUG_PROCESS: PROCESS_CREATION_FLAGS = 1u32; pub const DELETE: FILE_ACCESS_RIGHTS = 65536u32; @@ -3369,7 +3377,6 @@ pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32; pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32; pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32; pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32; -pub type FindFileHandle = *mut ::core::ffi::c_void; pub type GENERIC_ACCESS_RIGHTS = u32; pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32; pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32; @@ -3383,6 +3390,12 @@ pub struct GUID { pub data3: u16, pub data4: [u8; 8], } +impl ::core::marker::Copy for GUID {} +impl ::core::clone::Clone for GUID { + fn clone(&self) -> Self { + *self + } +} impl GUID { pub const fn from_u128(uuid: u128) -> Self { Self { @@ -3393,12 +3406,6 @@ impl GUID { } } } -impl ::core::marker::Copy for GUID {} -impl ::core::clone::Clone for GUID { - fn clone(&self) -> Self { - *self - } -} pub type HANDLE = *mut ::core::ffi::c_void; pub type HANDLE_FLAGS = u32; pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32; @@ -3431,6 +3438,16 @@ impl ::core::clone::Clone for IN6_ADDR_0 { pub const INFINITE: u32 = 4294967295u32; pub const INHERIT_CALLER_PRIORITY: PROCESS_CREATION_FLAGS = 131072u32; pub const INHERIT_PARENT_AFFINITY: PROCESS_CREATION_FLAGS = 65536u32; +#[repr(C)] +pub union INIT_ONCE { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for INIT_ONCE {} +impl ::core::clone::Clone for INIT_ONCE { + fn clone(&self) -> Self { + *self + } +} pub const INIT_ONCE_INIT_FAILED: u32 = 4u32; pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32; pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _); @@ -3659,10 +3676,10 @@ pub type NTSTATUS = i32; pub struct OBJECT_ATTRIBUTES { pub Length: u32, pub RootDirectory: HANDLE, - pub ObjectName: *mut UNICODE_STRING, + pub ObjectName: *const UNICODE_STRING, pub Attributes: u32, - pub SecurityDescriptor: *mut ::core::ffi::c_void, - pub SecurityQualityOfService: *mut ::core::ffi::c_void, + pub SecurityDescriptor: *const ::core::ffi::c_void, + pub SecurityQualityOfService: *const ::core::ffi::c_void, } impl ::core::marker::Copy for OBJECT_ATTRIBUTES {} impl ::core::clone::Clone for OBJECT_ATTRIBUTES { @@ -3712,8 +3729,8 @@ pub type PCSTR = *const u8; pub type PCWSTR = *const u16; pub type PIO_APC_ROUTINE = ::core::option::Option< unsafe extern "system" fn( - apccontext: *const ::core::ffi::c_void, - iostatusblock: *const IO_STATUS_BLOCK, + apccontext: *mut ::core::ffi::c_void, + iostatusblock: *mut IO_STATUS_BLOCK, reserved: u32, ) -> (), >; @@ -3755,36 +3772,6 @@ pub type PSTR = *mut u8; pub type PWSTR = *mut u16; pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32; pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32; -#[repr(C)] -pub struct RTL_CONDITION_VARIABLE { - pub Ptr: *mut ::core::ffi::c_void, -} -impl ::core::marker::Copy for RTL_CONDITION_VARIABLE {} -impl ::core::clone::Clone for RTL_CONDITION_VARIABLE { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -pub union RTL_RUN_ONCE { - pub Ptr: *mut ::core::ffi::c_void, -} -impl ::core::marker::Copy for RTL_RUN_ONCE {} -impl ::core::clone::Clone for RTL_RUN_ONCE { - fn clone(&self) -> Self { - *self - } -} -#[repr(C)] -pub struct RTL_SRWLOCK { - pub Ptr: *mut ::core::ffi::c_void, -} -impl ::core::marker::Copy for RTL_SRWLOCK {} -impl ::core::clone::Clone for RTL_SRWLOCK { - fn clone(&self) -> Self { - *self - } -} pub const SD_BOTH: WINSOCK_SHUTDOWN_HOW = 2i32; pub const SD_RECEIVE: WINSOCK_SHUTDOWN_HOW = 0i32; pub const SD_SEND: WINSOCK_SHUTDOWN_HOW = 1i32; @@ -3821,10 +3808,7 @@ impl ::core::clone::Clone for SOCKADDR { *self } } -#[cfg(target_pointer_width = "32")] -pub type SOCKET = u32; -#[cfg(target_pointer_width = "64")] -pub type SOCKET = u64; +pub type SOCKET = usize; pub const SOCKET_ERROR: i32 = -1i32; pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32; pub const SOCK_RAW: WINSOCK_SOCKET_TYPE = 3i32; @@ -3838,6 +3822,16 @@ pub const SO_LINGER: i32 = 128i32; pub const SO_RCVTIMEO: i32 = 4102i32; pub const SO_SNDTIMEO: i32 = 4101i32; pub const SPECIFIC_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 65535u32; +#[repr(C)] +pub struct SRWLOCK { + pub Ptr: *mut ::core::ffi::c_void, +} +impl ::core::marker::Copy for SRWLOCK {} +impl ::core::clone::Clone for SRWLOCK { + fn clone(&self) -> Self { + *self + } +} pub const STACK_SIZE_PARAM_IS_A_RESERVATION: THREAD_CREATION_FLAGS = 65536u32; pub const STANDARD_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 2031616u32; pub const STANDARD_RIGHTS_EXECUTE: FILE_ACCESS_RIGHTS = 131072u32; @@ -4008,12 +4002,13 @@ impl ::core::clone::Clone for UNICODE_STRING { pub const VOLUME_NAME_DOS: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32; pub const VOLUME_NAME_GUID: GETFINALPATHNAMEBYHANDLE_FLAGS = 1u32; pub const VOLUME_NAME_NONE: GETFINALPATHNAMEBYHANDLE_FLAGS = 4u32; -pub const WAIT_ABANDONED: WIN32_ERROR = 128u32; -pub const WAIT_ABANDONED_0: WIN32_ERROR = 128u32; -pub const WAIT_FAILED: WIN32_ERROR = 4294967295u32; -pub const WAIT_IO_COMPLETION: WIN32_ERROR = 192u32; -pub const WAIT_OBJECT_0: WIN32_ERROR = 0u32; -pub const WAIT_TIMEOUT: WIN32_ERROR = 258u32; +pub const WAIT_ABANDONED: WAIT_EVENT = 128u32; +pub const WAIT_ABANDONED_0: WAIT_EVENT = 128u32; +pub type WAIT_EVENT = u32; +pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32; +pub const WAIT_IO_COMPLETION: WAIT_EVENT = 192u32; +pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32; +pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32; pub const WC_ERR_INVALID_CHARS: u32 = 128u32; pub type WIN32_ERROR = u32; #[repr(C)] diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index 84c1fbde32d2f..56d0d6c088737 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -143,13 +143,8 @@ impl Handle { ) -> io::Result> { let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let mut amt = 0; - let res = cvt(c::ReadFile( - self.as_raw_handle(), - buf.as_ptr() as c::LPVOID, - len, - &mut amt, - overlapped, - )); + let res = + cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped)); match res { Ok(_) => Ok(Some(amt as usize)), Err(e) => { diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml index 23e88844bd0b8..9821677a1226e 100644 --- a/src/tools/generate-windows-sys/Cargo.toml +++ b/src/tools/generate-windows-sys/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies.windows-bindgen] -version = "0.49" +version = "0.51.1" diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs index 91d981462e816..dff2c5e467afa 100644 --- a/src/tools/generate-windows-sys/src/main.rs +++ b/src/tools/generate-windows-sys/src/main.rs @@ -1,5 +1,7 @@ +use std::env; +use std::error::Error; use std::fs; -use std::io::{self, Write}; +use std::io::{self, Read, Seek, Write}; use std::path::PathBuf; /// This is printed to the file before the rest of the contents. @@ -11,25 +13,20 @@ const PRELUDE: &str = r#"// This file is autogenerated. // ignore-tidy-filelength "#; -fn main() -> io::Result<()> { +fn main() -> Result<(), Box> { let mut path: PathBuf = - std::env::args_os().nth(1).expect("a path to the rust repository is required").into(); - path.push("library/std/src/sys/windows/c/windows_sys.lst"); + env::args_os().nth(1).expect("a path to the rust repository is required").into(); + path.push("library/std/src/sys/windows/c"); + env::set_current_dir(&path)?; - // Load the list of APIs - let buffer = fs::read_to_string(&path)?; - let names: Vec<&str> = buffer - .lines() - .filter_map(|line| { - let line = line.trim(); - if line.is_empty() || line.starts_with("//") { None } else { Some(line) } - }) - .collect(); + let info = windows_bindgen::bindgen(["--etc", "windows_sys.lst"])?; + println!("{info}"); - // Write the bindings to windows-sys.rs - let bindings = windows_bindgen::standalone_std(&names); - path.set_extension("rs"); - let mut f = std::fs::File::create(&path)?; + // add some gunk to the output file. + let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?; + let mut bindings = String::new(); + f.read_to_string(&mut bindings)?; + f.seek(io::SeekFrom::Start(0))?; f.write_all(PRELUDE.as_bytes())?; f.write_all(bindings.as_bytes())?; From eb19bd33bac3f1e5f8cec2ddcb4ad7188baaba1c Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 16 Aug 2023 15:18:53 +0100 Subject: [PATCH 009/103] Abstract over internal `SOCKET` type This allows `SOCKET` to be `usize` internally --- library/std/src/os/windows/io/socket.rs | 8 +++--- library/std/src/sys/windows/net.rs | 38 ++++++++++++++----------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index 6359835cad5d9..c80b9e28499bc 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -116,7 +116,7 @@ impl BorrowedSocket<'_> { let mut info = unsafe { mem::zeroed::() }; let result = unsafe { sys::c::WSADuplicateSocketW( - self.as_raw_socket(), + self.as_raw_socket() as sys::c::SOCKET, sys::c::GetCurrentProcessId(), &mut info, ) @@ -134,7 +134,7 @@ impl BorrowedSocket<'_> { }; if socket != sys::c::INVALID_SOCKET { - unsafe { Ok(OwnedSocket::from_raw_socket(socket)) } + unsafe { Ok(OwnedSocket::from_raw_socket(socket as RawSocket)) } } else { let error = unsafe { sys::c::WSAGetLastError() }; @@ -158,7 +158,7 @@ impl BorrowedSocket<'_> { } unsafe { - let socket = OwnedSocket::from_raw_socket(socket); + let socket = OwnedSocket::from_raw_socket(socket as RawSocket); socket.set_no_inherit()?; Ok(socket) } @@ -211,7 +211,7 @@ impl Drop for OwnedSocket { #[inline] fn drop(&mut self) { unsafe { - let _ = sys::c::closesocket(self.socket); + let _ = sys::c::closesocket(self.socket as sys::c::SOCKET); } } } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 1ae42cb7eae63..abdcab4247fac 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -117,7 +117,7 @@ impl Socket { }; if socket != c::INVALID_SOCKET { - unsafe { Ok(Self::from_raw_socket(socket)) } + unsafe { Ok(Self::from_raw(socket)) } } else { let error = unsafe { c::WSAGetLastError() }; @@ -133,7 +133,7 @@ impl Socket { } unsafe { - let socket = Self::from_raw_socket(socket); + let socket = Self::from_raw(socket); socket.0.set_no_inherit()?; Ok(socket) } @@ -144,7 +144,7 @@ impl Socket { self.set_nonblocking(true)?; let result = { let (addr, len) = addr.into_inner(); - let result = unsafe { c::connect(self.as_raw_socket(), addr.as_ptr(), len) }; + let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) }; cvt(result).map(drop) }; self.set_nonblocking(false)?; @@ -170,7 +170,7 @@ impl Socket { let fds = { let mut fds = unsafe { mem::zeroed::() }; fds.fd_count = 1; - fds.fd_array[0] = self.as_raw_socket(); + fds.fd_array[0] = self.as_raw(); fds }; @@ -202,11 +202,11 @@ impl Socket { } pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result { - let socket = unsafe { c::accept(self.as_raw_socket(), storage, len) }; + let socket = unsafe { c::accept(self.as_raw(), storage, len) }; match socket { c::INVALID_SOCKET => Err(last_error()), - _ => unsafe { Ok(Self::from_raw_socket(socket)) }, + _ => unsafe { Ok(Self::from_raw(socket)) }, } } @@ -218,9 +218,8 @@ impl Socket { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32; - let result = unsafe { - c::recv(self.as_raw_socket(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) - }; + let result = + unsafe { c::recv(self.as_raw(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) }; match result { c::SOCKET_ERROR => { @@ -257,7 +256,7 @@ impl Socket { let mut flags = 0; let result = unsafe { c::WSARecv( - self.as_raw_socket(), + self.as_raw(), bufs.as_mut_ptr() as *mut c::WSABUF, length, &mut nread, @@ -305,7 +304,7 @@ impl Socket { // do the same on windows to map a shut down socket to returning EOF. let result = unsafe { c::recvfrom( - self.as_raw_socket(), + self.as_raw(), buf.as_mut_ptr() as *mut _, length, flags, @@ -341,7 +340,7 @@ impl Socket { let mut nwritten = 0; let result = unsafe { c::WSASend( - self.as_raw_socket(), + self.as_raw(), bufs.as_ptr() as *const c::WSABUF as *mut _, length, &mut nwritten, @@ -392,14 +391,14 @@ impl Socket { Shutdown::Read => c::SD_RECEIVE, Shutdown::Both => c::SD_BOTH, }; - let result = unsafe { c::shutdown(self.as_raw_socket(), how) }; + let result = unsafe { c::shutdown(self.as_raw(), how) }; cvt(result).map(drop) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as c_ulong; let result = - unsafe { c::ioctlsocket(self.as_raw_socket(), c::FIONBIO as c_int, &mut nonblocking) }; + unsafe { c::ioctlsocket(self.as_raw(), c::FIONBIO as c_int, &mut nonblocking) }; cvt(result).map(drop) } @@ -433,8 +432,15 @@ impl Socket { } // This is used by sys_common code to abstract over Windows and Unix. - pub fn as_raw(&self) -> RawSocket { - self.as_inner().as_raw_socket() + pub fn as_raw(&self) -> c::SOCKET { + debug_assert_eq!(mem::size_of::(), mem::size_of::()); + debug_assert_eq!(mem::align_of::(), mem::align_of::()); + self.as_inner().as_raw_socket() as c::SOCKET + } + pub unsafe fn from_raw(raw: c::SOCKET) -> Self { + debug_assert_eq!(mem::size_of::(), mem::size_of::()); + debug_assert_eq!(mem::align_of::(), mem::align_of::()); + Self::from_raw_socket(raw as RawSocket) } } From de3726c9b32c251b3c5181e1dab64f00e68a88c1 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 17 Aug 2023 15:29:29 +0100 Subject: [PATCH 010/103] Add GetActiveProcessorCount and process attributes --- library/std/src/sys/windows/c/windows_sys.lst | 2 ++ library/std/src/sys/windows/c/windows_sys.rs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index 3e5a9b7451012..aabb68c5c1067 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -2480,6 +2480,7 @@ Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime Windows.Win32.System.SystemInformation.GetWindowsDirectoryW Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE Windows.Win32.System.SystemInformation.SYSTEM_INFO +Windows.Win32.System.SystemServices.ALL_PROCESSOR_GROUPS Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH Windows.Win32.System.SystemServices.DLL_THREAD_DETACH Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS @@ -2512,6 +2513,7 @@ Windows.Win32.System.Threading.DeleteProcThreadAttributeList Windows.Win32.System.Threading.DETACHED_PROCESS Windows.Win32.System.Threading.ExitProcess Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT +Windows.Win32.System.Threading.GetActiveProcessorCount Windows.Win32.System.Threading.GetCurrentProcess Windows.Win32.System.Threading.GetCurrentProcessId Windows.Win32.System.Threading.GetCurrentThread diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index c7fba5bd30bed..96c7d17c3ce60 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -220,6 +220,10 @@ extern "system" { pub fn FreeEnvironmentStringsW(penv: PCWSTR) -> BOOL; } #[link(name = "kernel32")] +extern "system" { + pub fn GetActiveProcessorCount(groupnumber: u16) -> u32; +} +#[link(name = "kernel32")] extern "system" { pub fn GetCommandLineW() -> PCWSTR; } @@ -844,6 +848,7 @@ impl ::core::clone::Clone for ADDRINFOA { pub const AF_INET: ADDRESS_FAMILY = 2u16; pub const AF_INET6: ADDRESS_FAMILY = 23u16; pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16; +pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32; #[repr(C)] pub union ARM64_NT_NEON128 { pub Anonymous: ARM64_NT_NEON128_0, From e7908608d9d11a77b3c73eb1aaac47492575efe9 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 28 Aug 2023 20:02:40 +0100 Subject: [PATCH 011/103] Remove old bindings that have been moved --- Cargo.lock | 2 +- library/std/src/sys/windows/c/windows_sys.lst | 6 ------ library/std/src/sys/windows/c/windows_sys.rs | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f2cfba2925ed..9356d46dc8928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5857,7 +5857,7 @@ checksum = "bc1f16b778125675feee0d15d6dd9f6af0e3ac52b3233d63a10aa39230c1cd75" dependencies = [ "proc-macro2", "rayon", - "syn 2.0.27", + "syn 2.0.29", "windows-metadata", ] diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst index aabb68c5c1067..0aca37e2d454e 100644 --- a/library/std/src/sys/windows/c/windows_sys.lst +++ b/library/std/src/sys/windows/c/windows_sys.lst @@ -2330,7 +2330,6 @@ Windows.Win32.Storage.FileSystem.FileStandardInfo Windows.Win32.Storage.FileSystem.FileStorageInfo Windows.Win32.Storage.FileSystem.FileStreamInfo Windows.Win32.Storage.FileSystem.FindClose -Windows.Win32.Storage.FileSystem.FindFileHandle Windows.Win32.Storage.FileSystem.FindFirstFileW Windows.Win32.Storage.FileSystem.FindNextFileW Windows.Win32.Storage.FileSystem.FlushFileBuffers @@ -2542,9 +2541,6 @@ Windows.Win32.System.Threading.PROFILE_USER Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS Windows.Win32.System.Threading.ReleaseSRWLockExclusive Windows.Win32.System.Threading.ReleaseSRWLockShared -Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE -Windows.Win32.System.Threading.RTL_RUN_ONCE -Windows.Win32.System.Threading.RTL_SRWLOCK Windows.Win32.System.Threading.SetThreadStackGuarantee Windows.Win32.System.Threading.Sleep Windows.Win32.System.Threading.SleepConditionVariableSRW @@ -2584,8 +2580,6 @@ Windows.Win32.System.Threading.WaitForMultipleObjects Windows.Win32.System.Threading.WaitForSingleObject Windows.Win32.System.Threading.WakeAllConditionVariable Windows.Win32.System.Threading.WakeConditionVariable -Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK -Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE Windows.Win32.UI.Shell.GetUserProfileDirectoryW // tidy-alphabetical-end diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs index 96c7d17c3ce60..851d15915c7d1 100644 --- a/library/std/src/sys/windows/c/windows_sys.rs +++ b/library/std/src/sys/windows/c/windows_sys.rs @@ -4,7 +4,7 @@ // regenerate the bindings. // // ignore-tidy-filelength -// Bindings generated by `windows-bindgen` 0.49.0 +// Bindings generated by `windows-bindgen` 0.51.1 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)] #[link(name = "advapi32")] From d8c1533252e3bab1791a5fffed9dab1cec23c3b9 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 4 Sep 2023 17:46:26 +0200 Subject: [PATCH 012/103] "what would rustfmt do" --- library/std/src/process.rs | 140 ++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 71 deletions(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 7380b45b00fea..88f39e28fa121 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -12,9 +12,9 @@ //! use std::process::Command; //! //! let output = Command::new("echo") -//! .arg("Hello world") -//! .output() -//! .expect("Failed to execute command"); +//! .arg("Hello world") +//! .output() +//! .expect("Failed to execute command"); //! //! assert_eq!(b"Hello world\n", output.stdout.as_slice()); //! ``` @@ -154,12 +154,11 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; /// use std::process::Command; /// /// let mut child = Command::new("/bin/cat") -/// .arg("file.txt") -/// .spawn() -/// .expect("failed to execute child"); +/// .arg("file.txt") +/// .spawn() +/// .expect("failed to execute child"); /// -/// let ecode = child.wait() -/// .expect("failed to wait on child"); +/// let ecode = child.wait().expect("failed to wait on child"); /// /// assert!(ecode.success()); /// ``` @@ -481,15 +480,15 @@ impl fmt::Debug for ChildStderr { /// /// let output = if cfg!(target_os = "windows") { /// Command::new("cmd") -/// .args(["/C", "echo hello"]) -/// .output() -/// .expect("failed to execute process") +/// .args(["/C", "echo hello"]) +/// .output() +/// .expect("failed to execute process") /// } else { /// Command::new("sh") -/// .arg("-c") -/// .arg("echo hello") -/// .output() -/// .expect("failed to execute process") +/// .arg("-c") +/// .arg("echo hello") +/// .output() +/// .expect("failed to execute process") /// }; /// /// let hello = output.stdout; @@ -502,8 +501,7 @@ impl fmt::Debug for ChildStderr { /// use std::process::Command; /// /// let mut echo_hello = Command::new("sh"); -/// echo_hello.arg("-c") -/// .arg("echo hello"); +/// echo_hello.arg("-c").arg("echo hello"); /// let hello_1 = echo_hello.output().expect("failed to execute process"); /// let hello_2 = echo_hello.output().expect("failed to execute process"); /// ``` @@ -576,8 +574,8 @@ impl Command { /// use std::process::Command; /// /// Command::new("sh") - /// .spawn() - /// .expect("sh command failed to start"); + /// .spawn() + /// .expect("sh command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn new>(program: S) -> Command { @@ -620,10 +618,10 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .arg("-l") - /// .arg("-a") - /// .spawn() - /// .expect("ls command failed to start"); + /// .arg("-l") + /// .arg("-a") + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn arg>(&mut self, arg: S) -> &mut Command { @@ -650,9 +648,9 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .args(["-l", "-a"]) - /// .spawn() - /// .expect("ls command failed to start"); + /// .args(["-l", "-a"]) + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn args(&mut self, args: I) -> &mut Command @@ -688,9 +686,9 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .env("PATH", "/bin") - /// .spawn() - /// .expect("ls command failed to start"); + /// .env("PATH", "/bin") + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn env(&mut self, key: K, val: V) -> &mut Command @@ -731,12 +729,12 @@ impl Command { /// ).collect(); /// /// Command::new("printenv") - /// .stdin(Stdio::null()) - /// .stdout(Stdio::inherit()) - /// .env_clear() - /// .envs(&filtered_env) - /// .spawn() - /// .expect("printenv failed to start"); + /// .stdin(Stdio::null()) + /// .stdout(Stdio::inherit()) + /// .env_clear() + /// .envs(&filtered_env) + /// .spawn() + /// .expect("printenv failed to start"); /// ``` #[stable(feature = "command_envs", since = "1.19.0")] pub fn envs(&mut self, vars: I) -> &mut Command @@ -772,9 +770,9 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .env_remove("PATH") - /// .spawn() - /// .expect("ls command failed to start"); + /// .env_remove("PATH") + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn env_remove>(&mut self, key: K) -> &mut Command { @@ -802,9 +800,9 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .env_clear() - /// .spawn() - /// .expect("ls command failed to start"); + /// .env_clear() + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn env_clear(&mut self) -> &mut Command { @@ -830,9 +828,9 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .current_dir("/bin") - /// .spawn() - /// .expect("ls command failed to start"); + /// .current_dir("/bin") + /// .spawn() + /// .expect("ls command failed to start"); /// ``` /// /// [`canonicalize`]: crate::fs::canonicalize @@ -861,9 +859,9 @@ impl Command { /// use std::process::{Command, Stdio}; /// /// Command::new("ls") - /// .stdin(Stdio::null()) - /// .spawn() - /// .expect("ls command failed to start"); + /// .stdin(Stdio::null()) + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn stdin>(&mut self, cfg: T) -> &mut Command { @@ -890,9 +888,9 @@ impl Command { /// use std::process::{Command, Stdio}; /// /// Command::new("ls") - /// .stdout(Stdio::null()) - /// .spawn() - /// .expect("ls command failed to start"); + /// .stdout(Stdio::null()) + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn stdout>(&mut self, cfg: T) -> &mut Command { @@ -919,9 +917,9 @@ impl Command { /// use std::process::{Command, Stdio}; /// /// Command::new("ls") - /// .stderr(Stdio::null()) - /// .spawn() - /// .expect("ls command failed to start"); + /// .stderr(Stdio::null()) + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn stderr>(&mut self, cfg: T) -> &mut Command { @@ -941,8 +939,8 @@ impl Command { /// use std::process::Command; /// /// Command::new("ls") - /// .spawn() - /// .expect("ls command failed to start"); + /// .spawn() + /// .expect("ls command failed to start"); /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn spawn(&mut self) -> io::Result { @@ -963,9 +961,9 @@ impl Command { /// use std::process::Command; /// use std::io::{self, Write}; /// let output = Command::new("/bin/cat") - /// .arg("file.txt") - /// .output() - /// .expect("failed to execute process"); + /// .arg("file.txt") + /// .output() + /// .expect("failed to execute process"); /// /// println!("status: {}", output.status); /// io::stdout().write_all(&output.stdout).unwrap(); @@ -990,9 +988,9 @@ impl Command { /// use std::process::Command; /// /// let status = Command::new("/bin/cat") - /// .arg("file.txt") - /// .status() - /// .expect("failed to execute process"); + /// .arg("file.txt") + /// .status() + /// .expect("failed to execute process"); /// /// println!("process finished with: {status}"); /// @@ -1558,9 +1556,9 @@ impl ExitStatus { /// use std::process::Command; /// /// let status = Command::new("ls") - /// .arg("/dev/nonexistent") - /// .status() - /// .expect("ls could not be executed"); + /// .arg("/dev/nonexistent") + /// .status() + /// .expect("ls could not be executed"); /// /// println!("ls: {status}"); /// status.exit_ok().expect_err("/dev/nonexistent could be listed!"); @@ -1580,9 +1578,9 @@ impl ExitStatus { /// use std::process::Command; /// /// let status = Command::new("mkdir") - /// .arg("projects") - /// .status() - /// .expect("failed to execute mkdir"); + /// .arg("projects") + /// .status() + /// .expect("failed to execute mkdir"); /// /// if status.success() { /// println!("'projects/' directory created"); @@ -1613,13 +1611,13 @@ impl ExitStatus { /// use std::process::Command; /// /// let status = Command::new("mkdir") - /// .arg("projects") - /// .status() - /// .expect("failed to execute mkdir"); + /// .arg("projects") + /// .status() + /// .expect("failed to execute mkdir"); /// /// match status.code() { /// Some(code) => println!("Exited with status code: {code}"), - /// None => println!("Process terminated by signal") + /// None => println!("Process terminated by signal") /// } /// ``` #[must_use] From 4c2f1c615b976fcd21f6cc2078b09d10c9d72507 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Mon, 4 Sep 2023 21:43:21 +0100 Subject: [PATCH 013/103] Weaken needlessly restrictive orderings on Arc::*_count Signed-off-by: Alex Saveau --- library/alloc/src/sync.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index d3b7558440c67..fd313a58e27cf 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1616,7 +1616,7 @@ impl Arc { #[must_use] #[stable(feature = "arc_counts", since = "1.15.0")] pub fn weak_count(this: &Self) -> usize { - let cnt = this.inner().weak.load(Acquire); + let cnt = this.inner().weak.load(Relaxed); // If the weak count is currently locked, the value of the // count was 0 just before taking the lock. if cnt == usize::MAX { 0 } else { cnt - 1 } @@ -1646,7 +1646,7 @@ impl Arc { #[must_use] #[stable(feature = "arc_counts", since = "1.15.0")] pub fn strong_count(this: &Self) -> usize { - this.inner().strong.load(Acquire) + this.inner().strong.load(Relaxed) } /// Increments the strong reference count on the `Arc` associated with the @@ -2801,7 +2801,7 @@ impl Weak { #[must_use] #[stable(feature = "weak_counts", since = "1.41.0")] pub fn strong_count(&self) -> usize { - if let Some(inner) = self.inner() { inner.strong.load(Acquire) } else { 0 } + if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 } } /// Gets an approximation of the number of `Weak` pointers pointing to this @@ -2820,7 +2820,7 @@ impl Weak { pub fn weak_count(&self) -> usize { if let Some(inner) = self.inner() { let weak = inner.weak.load(Acquire); - let strong = inner.strong.load(Acquire); + let strong = inner.strong.load(Relaxed); if strong == 0 { 0 } else { From e4af4e50831a23485e3e05646097bea26ff97a79 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 8 Sep 2023 03:00:59 +0000 Subject: [PATCH 014/103] Stabilize impl_trait_projections --- .../src/error_codes/E0760.md | 2 +- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/active.rs | 2 - .../rustc_hir_analysis/src/check/check.rs | 135 +----------------- .../async-await/feature-self-return-type.rs | 1 - .../feature-self-return-type.stderr | 2 +- .../in-trait/async-associated-types.rs | 1 - .../issue-61949-self-return-type.rs | 28 ---- .../issue-61949-self-return-type.stderr | 26 ---- tests/ui/async-await/issues/issue-78600.rs | 2 +- .../ui/async-await/issues/issue-78600.stderr | 14 -- .../ui/impl-trait/bound-normalization-fail.rs | 3 +- .../bound-normalization-fail.stderr | 16 +-- .../impl-trait/capture-lifetime-not-in-hir.rs | 21 +++ .../capture-lifetime-not-in-hir.stderr | 14 ++ .../ui/impl-trait/feature-self-return-type.rs | 1 - .../feature-self-return-type.stderr | 6 +- 17 files changed, 50 insertions(+), 226 deletions(-) delete mode 100644 tests/ui/async-await/issue-61949-self-return-type.rs delete mode 100644 tests/ui/async-await/issue-61949-self-return-type.stderr delete mode 100644 tests/ui/async-await/issues/issue-78600.stderr create mode 100644 tests/ui/impl-trait/capture-lifetime-not-in-hir.rs create mode 100644 tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr diff --git a/compiler/rustc_error_codes/src/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md index 85e5faada224e..9c4739f0df084 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0760.md +++ b/compiler/rustc_error_codes/src/error_codes/E0760.md @@ -5,7 +5,7 @@ or `Self` that references lifetimes from a parent scope. Erroneous code example: -```compile_fail,edition2018 +```ignore,edition2018 struct S<'a>(&'a i32); impl<'a> S<'a> { diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index afcf30d0b293e..6aa1e0c3e006b 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -197,6 +197,8 @@ declare_features! ( /// + `impl Iterator for &mut Iterator` /// + `impl Debug for Foo<'_>` (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), + /// Allows referencing `Self` and projections in impl-trait. + (accepted, impl_trait_projections, "CURRENT_RUSTC_VERSION", Some(103532), None), /// Allows using `a..=b` and `..=b` as inclusive range syntaxes. (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), /// Allows inferring outlives requirements (RFC 2093). diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 1941390dc4a1c..92615cc6d2a80 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -465,8 +465,6 @@ declare_features! ( (active, impl_trait_in_assoc_type, "1.70.0", Some(63063), None), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None), - /// Allows referencing `Self` and projections in impl-trait. - (active, impl_trait_projections, "1.67.0", Some(103532), None), /// Allows using imported `main` function (active, imported_main, "1.53.0", Some(28937), None), /// Allows associated types in inherent impls. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index c0cf1ea34cf2d..99cfba6788756 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -5,18 +5,15 @@ use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; -use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind, Res}; +use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; -use rustc_hir::intravisit::Visitor; -use rustc_hir::{ItemKind, Node, PathSegment}; -use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; +use rustc_hir::Node; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; -use rustc_middle::hir::nested_filter; use rustc_middle::middle::stability::EvalResult; use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::fold::BottomUpFolder; @@ -218,9 +215,6 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { let args = GenericArgs::identity_for_item(tcx, item.owner_id); let span = tcx.def_span(item.owner_id.def_id); - if !tcx.features().impl_trait_projections { - check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span); - } if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() { return; } @@ -231,129 +225,6 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) { let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin); } -/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result -/// in "inheriting lifetimes". -#[instrument(level = "debug", skip(tcx, span))] -pub(super) fn check_opaque_for_inheriting_lifetimes( - tcx: TyCtxt<'_>, - def_id: LocalDefId, - span: Span, -) { - let item = tcx.hir().expect_item(def_id); - debug!(?item, ?span); - - struct ProhibitOpaqueVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - opaque_identity_ty: Ty<'tcx>, - parent_count: u32, - references_parent_regions: bool, - selftys: Vec<(Span, Option)>, - } - - impl<'tcx> ty::visit::TypeVisitor> for ProhibitOpaqueVisitor<'tcx> { - type BreakTy = Ty<'tcx>; - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - debug!(?t, "root_visit_ty"); - if t == self.opaque_identity_ty { - ControlFlow::Continue(()) - } else { - t.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { - tcx: self.tcx, - op: |region| { - if let ty::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = *region - && index < self.parent_count - { - self.references_parent_regions= true; - } - }, - }); - if self.references_parent_regions { - ControlFlow::Break(t) - } else { - ControlFlow::Continue(()) - } - } - } - } - - impl<'tcx> Visitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { - type NestedFilter = nested_filter::OnlyBodies; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { - match arg.kind { - hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { - [PathSegment { res: Res::SelfTyParam { .. }, .. }] => { - let impl_ty_name = None; - self.selftys.push((path.span, impl_ty_name)); - } - [PathSegment { res: Res::SelfTyAlias { alias_to: def_id, .. }, .. }] => { - let impl_ty_name = Some(self.tcx.def_path_str(*def_id)); - self.selftys.push((path.span, impl_ty_name)); - } - _ => {} - }, - _ => {} - } - hir::intravisit::walk_ty(self, arg); - } - } - - if let ItemKind::OpaqueTy(&hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), - .. - }) = item.kind - { - let args = GenericArgs::identity_for_item(tcx, def_id); - let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); - let mut visitor = ProhibitOpaqueVisitor { - opaque_identity_ty, - parent_count: tcx.generics_of(def_id).parent_count as u32, - references_parent_regions: false, - tcx, - selftys: vec![], - }; - let prohibit_opaque = tcx - .explicit_item_bounds(def_id) - .instantiate_identity_iter_copied() - .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); - - if let Some(ty) = prohibit_opaque.break_value() { - visitor.visit_item(&item); - let is_async = match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => { - matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..)) - } - _ => unreachable!(), - }; - - let mut err = feature_err( - &tcx.sess.parse_sess, - sym::impl_trait_projections, - span, - format!( - "`{}` return type cannot contain a projection or `Self` that references \ - lifetimes from a parent scope", - if is_async { "async fn" } else { "impl Trait" }, - ), - ); - for (span, name) in visitor.selftys { - err.span_suggestion( - span, - "consider spelling out the type instead", - name.unwrap_or_else(|| format!("{ty:?}")), - Applicability::MaybeIncorrect, - ); - } - err.emit(); - } - } -} - /// Checks that an opaque type does not contain cycles. pub(super) fn check_opaque_for_cycles<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/tests/ui/async-await/feature-self-return-type.rs b/tests/ui/async-await/feature-self-return-type.rs index 41f887430c1cb..ae6f766d247e6 100644 --- a/tests/ui/async-await/feature-self-return-type.rs +++ b/tests/ui/async-await/feature-self-return-type.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(impl_trait_projections)] // This test checks that we emit the correct borrowck error when `Self` is used as a return type. // See #61949 for context. diff --git a/tests/ui/async-await/feature-self-return-type.stderr b/tests/ui/async-await/feature-self-return-type.stderr index 747c54b669440..dc160bfbf6179 100644 --- a/tests/ui/async-await/feature-self-return-type.stderr +++ b/tests/ui/async-await/feature-self-return-type.stderr @@ -1,5 +1,5 @@ error[E0597]: `bar` does not live long enough - --> $DIR/feature-self-return-type.rs:22:18 + --> $DIR/feature-self-return-type.rs:21:18 | LL | let x = { | - borrow later stored here diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs index 974f5aaff83c3..3e2739a164f17 100644 --- a/tests/ui/async-await/in-trait/async-associated-types.rs +++ b/tests/ui/async-await/in-trait/async-associated-types.rs @@ -2,7 +2,6 @@ // edition: 2021 #![feature(async_fn_in_trait)] -#![feature(impl_trait_projections)] #![allow(incomplete_features)] use std::fmt::Debug; diff --git a/tests/ui/async-await/issue-61949-self-return-type.rs b/tests/ui/async-await/issue-61949-self-return-type.rs deleted file mode 100644 index d73dbc6e828f3..0000000000000 --- a/tests/ui/async-await/issue-61949-self-return-type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// edition:2018 -// gate-test-impl_trait_projections - -// This test checks that `Self` is prohibited as a return type. See #61949 for context. - -pub struct Foo<'a> { - pub bar: &'a i32, -} - -impl<'a> Foo<'a> { - pub async fn new(_bar: &'a i32) -> Self { - //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - Foo { - bar: &22 - } - } -} - -async fn foo() { - let x = { - let bar = 22; - Foo::new(&bar).await - //~^ ERROR `bar` does not live long enough - }; - drop(x); -} - -fn main() { } diff --git a/tests/ui/async-await/issue-61949-self-return-type.stderr b/tests/ui/async-await/issue-61949-self-return-type.stderr deleted file mode 100644 index ac85ed2887abc..0000000000000 --- a/tests/ui/async-await/issue-61949-self-return-type.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-61949-self-return-type.rs:11:40 - | -LL | pub async fn new(_bar: &'a i32) -> Self { - | ^^^^ help: consider spelling out the type instead: `Foo<'a>` - | - = note: see issue #103532 for more information - = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable - -error[E0597]: `bar` does not live long enough - --> $DIR/issue-61949-self-return-type.rs:22:18 - | -LL | let x = { - | - borrow later stored here -LL | let bar = 22; - | --- binding `bar` declared here -LL | Foo::new(&bar).await - | ^^^^ borrowed value does not live long enough -LL | -LL | }; - | - `bar` dropped here while still borrowed - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0597, E0658. -For more information about an error, try `rustc --explain E0597`. diff --git a/tests/ui/async-await/issues/issue-78600.rs b/tests/ui/async-await/issues/issue-78600.rs index 8aaeaecf3e1da..4303fc7952f2b 100644 --- a/tests/ui/async-await/issues/issue-78600.rs +++ b/tests/ui/async-await/issues/issue-78600.rs @@ -1,10 +1,10 @@ +// check-pass // edition:2018 struct S<'a>(&'a i32); impl<'a> S<'a> { async fn new(i: &'a i32) -> Result { - //~^ ERROR: `async fn` Ok(S(&22)) } } diff --git a/tests/ui/async-await/issues/issue-78600.stderr b/tests/ui/async-await/issues/issue-78600.stderr deleted file mode 100644 index 37eafa996c535..0000000000000 --- a/tests/ui/async-await/issues/issue-78600.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-78600.rs:6:33 - | -LL | async fn new(i: &'a i32) -> Result { - | ^^^^^^^----^^^^^ - | | - | help: consider spelling out the type instead: `S<'a>` - | - = note: see issue #103532 for more information - = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/bound-normalization-fail.rs b/tests/ui/impl-trait/bound-normalization-fail.rs index 3329592478d6f..566a4a7adccb9 100644 --- a/tests/ui/impl-trait/bound-normalization-fail.rs +++ b/tests/ui/impl-trait/bound-normalization-fail.rs @@ -39,8 +39,7 @@ mod lifetimes { /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - //~| ERROR: type mismatch + //~^ ERROR: type mismatch Foo(()) } } diff --git a/tests/ui/impl-trait/bound-normalization-fail.stderr b/tests/ui/impl-trait/bound-normalization-fail.stderr index f04a753a0e8bd..fcac9ac34dbc3 100644 --- a/tests/ui/impl-trait/bound-normalization-fail.stderr +++ b/tests/ui/impl-trait/bound-normalization-fail.stderr @@ -19,21 +19,12 @@ help: consider constraining the associated type `::Assoc LL | fn foo_fail>() -> impl FooLike { | ++++++++++++ -error[E0658]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:41:41 - | -LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #103532 for more information - = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable - error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` --> $DIR/bound-normalization-fail.rs:41:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == >::Assoc` -... +LL | LL | Foo(()) | ------- return type was inferred to be `Foo<()>` here | @@ -49,7 +40,6 @@ help: consider constraining the associated type `>::As LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike { | ++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0658. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs new file mode 100644 index 0000000000000..9c067cb693444 --- /dev/null +++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs @@ -0,0 +1,21 @@ +#![feature(rustc_attrs)] +#![rustc_variance_of_opaques] + +trait Bar<'a> { + type Assoc: From<()>; +} + +fn foo<'a, T: Bar<'a>>() -> impl Into { + //~^ ERROR [o, o] + // captures both T and 'a invariantly + () +} + +fn foo2<'a, T: Bar<'a>>() -> impl Into + 'a { + //~^ ERROR [o, o, o] + // captures both T and 'a invariantly, and also duplicates `'a` + // i.e. the opaque looks like `impl Into<>::Assoc> + 'a_duplicated` + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr new file mode 100644 index 0000000000000..9d52001b02460 --- /dev/null +++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr @@ -0,0 +1,14 @@ +error: [o, o] + --> $DIR/capture-lifetime-not-in-hir.rs:8:29 + | +LL | fn foo<'a, T: Bar<'a>>() -> impl Into { + | ^^^^^^^^^^^^^^^^^^^ + +error: [o, o, o] + --> $DIR/capture-lifetime-not-in-hir.rs:14:30 + | +LL | fn foo2<'a, T: Bar<'a>>() -> impl Into + 'a { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/impl-trait/feature-self-return-type.rs b/tests/ui/impl-trait/feature-self-return-type.rs index 51877e9cc3c43..7555df1b2c709 100644 --- a/tests/ui/impl-trait/feature-self-return-type.rs +++ b/tests/ui/impl-trait/feature-self-return-type.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(impl_trait_projections)] // This test checks that we emit the correct borrowck error when `Self` or a projection is used as // a return type. See #61949 for context. diff --git a/tests/ui/impl-trait/feature-self-return-type.stderr b/tests/ui/impl-trait/feature-self-return-type.stderr index b9b8d00ce308b..e7113a9dfb1b9 100644 --- a/tests/ui/impl-trait/feature-self-return-type.stderr +++ b/tests/ui/impl-trait/feature-self-return-type.stderr @@ -1,5 +1,5 @@ error[E0597]: `bar` does not live long enough - --> $DIR/feature-self-return-type.rs:23:22 + --> $DIR/feature-self-return-type.rs:22:22 | LL | let x = { | - borrow later stored here @@ -12,7 +12,7 @@ LL | }; | - `bar` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/feature-self-return-type.rs:63:17 + --> $DIR/feature-self-return-type.rs:62:17 | LL | let x = { | - borrow later stored here @@ -25,7 +25,7 @@ LL | }; | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/feature-self-return-type.rs:95:17 + --> $DIR/feature-self-return-type.rs:94:17 | LL | let x = { | - borrow later stored here From d49123ddc9ccd18282527d90abb17b73f6b41d13 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 16 Sep 2023 11:43:34 +0200 Subject: [PATCH 015/103] fix a comment about assert_receiver_is_total_eq --- library/core/src/cmp.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 6d5133646b58e..122f9e773afa7 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -281,9 +281,9 @@ pub macro PartialEq($item:item) { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Eq"] pub trait Eq: PartialEq { - // this method is used solely by #[deriving] to assert - // that every component of a type implements #[deriving] - // itself, the current deriving infrastructure means doing this + // this method is used solely by #[derive(Eq)] to assert + // that every component of a type implements `Eq` + // itself. The current deriving infrastructure means doing this // assertion without using a method on this trait is nearly // impossible. // From e8b8ddd17e93875b6536224c598790117d4c929e Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 14 Sep 2023 16:21:54 +0200 Subject: [PATCH 016/103] remove provisional cache --- .../src/solve/search_graph/cache.rs | 102 ------------ .../src/solve/search_graph/mod.rs | 148 ++++++++---------- .../cycles/fixpoint-rerun-all-cycle-heads.rs | 53 +++++++ .../fixpoint-rerun-all-cycle-heads.stderr | 10 ++ .../cycles/inductive-not-on-stack.rs | 2 +- .../cycles/inductive-not-on-stack.stderr | 15 +- 6 files changed, 142 insertions(+), 188 deletions(-) delete mode 100644 compiler/rustc_trait_selection/src/solve/search_graph/cache.rs create mode 100644 tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs create mode 100644 tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs deleted file mode 100644 index be48447e27c24..0000000000000 --- a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! This module both handles the global cache which stores "finished" goals, -//! and the provisional cache which contains partially computed goals. -//! -//! The provisional cache is necessary when dealing with coinductive cycles. -//! -//! For more information about the provisional cache and coinduction in general, -//! check out the relevant section of the rustc-dev-guide. -//! -//! FIXME(@lcnr): Write that section, feel free to ping me if you need help here -//! before then or if I still haven't done that before January 2023. -use super::StackDepth; -use rustc_data_structures::fx::FxHashMap; -use rustc_index::IndexVec; -use rustc_middle::traits::solve::{CanonicalInput, QueryResult}; - -rustc_index::newtype_index! { - pub struct EntryIndex {} -} - -#[derive(Debug, Clone)] -pub(super) struct ProvisionalEntry<'tcx> { - /// In case we have a coinductive cycle, this is the - /// the current provisional result of this goal. - /// - /// This starts out as `None` for all goals and gets to some - /// when the goal gets popped from the stack or we rerun evaluation - /// for this goal to reach a fixpoint. - pub(super) response: Option>, - /// In case of a cycle, the position of deepest stack entry involved - /// in that cycle. This is monotonically decreasing in the stack as all - /// elements between the current stack element in the deepest stack entry - /// involved have to also be involved in that cycle. - /// - /// We can only move entries to the global cache once we're complete done - /// with the cycle. If this entry has not been involved in a cycle, - /// this is just its own depth. - pub(super) depth: StackDepth, - - /// The goal for this entry. Should always be equal to the corresponding goal - /// in the lookup table. - pub(super) input: CanonicalInput<'tcx>, -} - -pub(super) struct ProvisionalCache<'tcx> { - pub(super) entries: IndexVec>, - // FIXME: This is only used to quickly check whether a given goal - // is in the cache. We should experiment with using something like - // `SsoHashSet` here because in most cases there are only a few entries. - pub(super) lookup_table: FxHashMap, EntryIndex>, -} - -impl<'tcx> ProvisionalCache<'tcx> { - pub(super) fn empty() -> ProvisionalCache<'tcx> { - ProvisionalCache { entries: Default::default(), lookup_table: Default::default() } - } - - pub(super) fn is_empty(&self) -> bool { - self.entries.is_empty() && self.lookup_table.is_empty() - } - - /// Adds a dependency from the current leaf to `target` in the cache - /// to prevent us from moving any goals which depend on the current leaf - /// to the global cache while we're still computing `target`. - /// - /// Its important to note that `target` may already be part of a different cycle. - /// In this case we have to ensure that we also depend on all other goals - /// in the existing cycle in addition to the potentially direct cycle with `target`. - pub(super) fn add_dependency_of_leaf_on(&mut self, target: EntryIndex) { - let depth = self.entries[target].depth; - for provisional_entry in &mut self.entries.raw[target.index()..] { - // The depth of `target` is the position of the deepest goal in the stack - // on which `target` depends. That goal is the `root` of this cycle. - // - // Any entry which was added after `target` is either on the stack itself - // at which point its depth is definitely at least as high as the depth of - // `root`. If it's not on the stack itself it has to depend on a goal - // between `root` and `leaf`. If it were to depend on a goal deeper in the - // stack than `root`, then `root` would also depend on that goal, at which - // point `root` wouldn't be the root anymore. - debug_assert!(provisional_entry.depth >= depth); - provisional_entry.depth = depth; - } - - // We only update entries which were added after `target` as no other - // entry should have a higher depth. - // - // Any entry which previously had a higher depth than target has to - // be between `target` and `root`. Because of this we would have updated - // its depth when calling `add_dependency_of_leaf_on(root)` for `target`. - if cfg!(debug_assertions) { - self.entries.iter().all(|e| e.depth <= depth); - } - } - - pub(super) fn depth(&self, entry_index: EntryIndex) -> StackDepth { - self.entries[entry_index].depth - } - - pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> Option> { - self.entries[entry_index].response - } -} diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 16de518e8e0b0..449c7456f7079 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -1,10 +1,7 @@ -mod cache; - -use self::cache::ProvisionalEntry; use super::inspect; use super::inspect::ProofTreeBuilder; use super::SolverMode; -use cache::ProvisionalCache; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashSet; use rustc_index::Idx; use rustc_index::IndexVec; @@ -27,8 +24,14 @@ struct StackEntry<'tcx> { // The maximum depth reached by this stack entry, only up-to date // for the top of the stack and lazily updated for the rest. reached_depth: StackDepth, + // In case of a cycle, the depth of the root. + cycle_root_depth: StackDepth, + encountered_overflow: bool, has_been_used: bool, + /// Starts out as `None` and gets set when rerunning this + /// goal in case we encounter a cycle. + provisional_result: Option>, /// We put only the root goal of a coinductive cycle into the global cache. /// @@ -47,7 +50,7 @@ pub(super) struct SearchGraph<'tcx> { /// /// An element is *deeper* in the stack if its index is *lower*. stack: IndexVec>, - provisional_cache: ProvisionalCache<'tcx>, + stack_entries: FxHashMap, StackDepth>, } impl<'tcx> SearchGraph<'tcx> { @@ -56,7 +59,7 @@ impl<'tcx> SearchGraph<'tcx> { mode, local_overflow_limit: tcx.recursion_limit().0.checked_ilog2().unwrap_or(0) as usize, stack: Default::default(), - provisional_cache: ProvisionalCache::empty(), + stack_entries: Default::default(), } } @@ -85,6 +88,7 @@ impl<'tcx> SearchGraph<'tcx> { /// would cause us to not track overflow and recursion depth correctly. fn pop_stack(&mut self) -> StackEntry<'tcx> { let elem = self.stack.pop().unwrap(); + assert!(self.stack_entries.remove(&elem.input).is_some()); if let Some(last) = self.stack.raw.last_mut() { last.reached_depth = last.reached_depth.max(elem.reached_depth); last.encountered_overflow |= elem.encountered_overflow; @@ -104,22 +108,17 @@ impl<'tcx> SearchGraph<'tcx> { } pub(super) fn is_empty(&self) -> bool { - self.stack.is_empty() && self.provisional_cache.is_empty() + self.stack.is_empty() } /// Whether we're currently in a cycle. This should only be used /// for debug assertions. pub(super) fn in_cycle(&self) -> bool { if let Some(stack_depth) = self.stack.last_index() { - // Either the current goal on the stack is the root of a cycle... - if self.stack[stack_depth].has_been_used { - return true; - } - - // ...or it depends on a goal with a lower depth. - let current_goal = self.stack[stack_depth].input; - let entry_index = self.provisional_cache.lookup_table[¤t_goal]; - self.provisional_cache.entries[entry_index].depth != stack_depth + // Either the current goal on the stack is the root of a cycle + // or it depends on a goal with a lower depth. + self.stack[stack_depth].has_been_used + || self.stack[stack_depth].cycle_root_depth != stack_depth } else { false } @@ -211,9 +210,8 @@ impl<'tcx> SearchGraph<'tcx> { } } - // Look at the provisional cache to detect cycles. - let cache = &mut self.provisional_cache; - match cache.lookup_table.entry(input) { + // Check whether we're in a cycle. + match self.stack_entries.entry(input) { // No entry, we push this goal on the stack and try to prove it. Entry::Vacant(v) => { let depth = self.stack.next_index(); @@ -221,14 +219,14 @@ impl<'tcx> SearchGraph<'tcx> { input, available_depth, reached_depth: depth, + cycle_root_depth: depth, encountered_overflow: false, has_been_used: false, + provisional_result: None, cycle_participants: Default::default(), }; assert_eq!(self.stack.push(entry), depth); - let entry_index = - cache.entries.push(ProvisionalEntry { response: None, depth, input }); - v.insert(entry_index); + v.insert(depth); } // We have a nested goal which relies on a goal `root` deeper in the stack. // @@ -239,41 +237,50 @@ impl<'tcx> SearchGraph<'tcx> { // // Finally we can return either the provisional response for that goal if we have a // coinductive cycle or an ambiguous result if the cycle is inductive. - Entry::Occupied(entry_index) => { + Entry::Occupied(entry) => { inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CacheHit( CacheHit::Provisional, )); - let entry_index = *entry_index.get(); - let stack_depth = cache.depth(entry_index); + let stack_depth = *entry.get(); debug!("encountered cycle with depth {stack_depth:?}"); - - cache.add_dependency_of_leaf_on(entry_index); - let mut iter = self.stack.iter_mut(); - let root = iter.nth(stack_depth.as_usize()).unwrap(); - for e in iter { - root.cycle_participants.insert(e.input); + // We start by updating the root depth of all cycle participants, and + // add all cycle participants to the root. + let root_depth = self.stack[stack_depth].cycle_root_depth; + let (prev, participants) = self.stack.raw.split_at_mut(stack_depth.as_usize() + 1); + let root = &mut prev[root_depth.as_usize()]; + for entry in participants { + debug_assert!(entry.cycle_root_depth >= root_depth); + entry.cycle_root_depth = root_depth; + root.cycle_participants.insert(entry.input); + // FIXME(@lcnr): I believe that this line is needed as we could + // otherwise access a cache entry for the root of a cycle while + // computing the result for a cycle participant. This can result + // in unstable results due to incompleteness. + // + // However, a test for this would be an even more complex version of + // tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs. + // I did not bother to write such a test and we have no regression test + // for this. It would be good to have such a test :) + #[allow(rustc::potential_query_instability)] + root.cycle_participants.extend(entry.cycle_participants.drain()); } - // If we're in a cycle, we have to retry proving the current goal - // until we reach a fixpoint. + // If we're in a cycle, we have to retry proving the cycle head + // until we reach a fixpoint. It is not enough to simply retry the + // `root` goal of this cycle. + // + // See tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs + // for an example. self.stack[stack_depth].has_been_used = true; - return if let Some(result) = cache.provisional_result(entry_index) { + return if let Some(result) = self.stack[stack_depth].provisional_result { result } else { - // If we don't have a provisional result yet, the goal has to - // still be on the stack. - let mut goal_on_stack = false; - let mut is_coinductive = true; - for entry in self.stack.raw[stack_depth.index()..] + // If we don't have a provisional result yet we're in the first iteration, + // so we start with no constraints. + let is_coinductive = self.stack.raw[stack_depth.index()..] .iter() - .skip_while(|entry| entry.input != input) - { - goal_on_stack = true; - is_coinductive &= entry.input.value.goal.predicate.is_coinductive(tcx); - } - debug_assert!(goal_on_stack); - + .all(|entry| entry.input.value.goal.predicate.is_coinductive(tcx)); if is_coinductive { Self::response_no_constraints(tcx, input, Certainty::Yes) } else { @@ -294,40 +301,25 @@ impl<'tcx> SearchGraph<'tcx> { // of the previous iteration is equal to the final result, at which // point we are done. for _ in 0..self.local_overflow_limit() { - let response = prove_goal(self, inspect); + let result = prove_goal(self, inspect); // Check whether the current goal is the root of a cycle and whether // we have to rerun because its provisional result differed from the // final result. - // - // Also update the response for this goal stored in the provisional - // cache. let stack_entry = self.pop_stack(); debug_assert_eq!(stack_entry.input, input); - let cache = &mut self.provisional_cache; - let provisional_entry_index = - *cache.lookup_table.get(&stack_entry.input).unwrap(); - let provisional_entry = &mut cache.entries[provisional_entry_index]; if stack_entry.has_been_used - && provisional_entry.response.map_or(true, |r| r != response) + && stack_entry.provisional_result.map_or(true, |r| r != result) { - // If so, update the provisional result for this goal and remove - // all entries whose result depends on this goal from the provisional - // cache... - // - // That's not completely correct, as a nested goal can also only - // depend on a goal which is lower in the stack so it doesn't - // actually depend on the current goal. This should be fairly - // rare and is hopefully not relevant for performance. - provisional_entry.response = Some(response); - #[allow(rustc::potential_query_instability)] - cache.lookup_table.retain(|_key, index| *index <= provisional_entry_index); - cache.entries.truncate(provisional_entry_index.index() + 1); - - // ...and finally push our goal back on the stack and reevaluate it. - self.stack.push(StackEntry { has_been_used: false, ..stack_entry }); + // If so, update its provisional result and reevaluate it. + let depth = self.stack.push(StackEntry { + has_been_used: false, + provisional_result: Some(result), + ..stack_entry + }); + assert_eq!(self.stack_entries.insert(input, depth), None); } else { - return (stack_entry, response); + return (stack_entry, result); } } @@ -343,17 +335,7 @@ impl<'tcx> SearchGraph<'tcx> { // // It is not possible for any nested goal to depend on something deeper on the // stack, as this would have also updated the depth of the current goal. - let cache = &mut self.provisional_cache; - let provisional_entry_index = *cache.lookup_table.get(&input).unwrap(); - let provisional_entry = &mut cache.entries[provisional_entry_index]; - let depth = provisional_entry.depth; - if depth == self.stack.next_index() { - for (i, entry) in cache.entries.drain_enumerated(provisional_entry_index.index()..) { - let actual_index = cache.lookup_table.remove(&entry.input); - debug_assert_eq!(Some(i), actual_index); - debug_assert!(entry.depth == depth); - } - + if final_entry.cycle_root_depth == self.stack.next_index() { // When encountering a cycle, both inductive and coinductive, we only // move the root into the global cache. We also store all other cycle // participants involved. @@ -371,8 +353,6 @@ impl<'tcx> SearchGraph<'tcx> { dep_node, result, ) - } else { - provisional_entry.response = Some(result); } result diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs new file mode 100644 index 0000000000000..2790639234060 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs @@ -0,0 +1,53 @@ +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs)] + +// Check that we correctly rerun the trait solver for heads of cycles, +// even if they are not the root. + +struct A(*const T); +struct B(*const T); +struct C(*const T); + +#[rustc_coinductive] +trait Trait<'a, 'b> {} +trait NotImplemented {} + +impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A where B: Trait<'a, 'b> {} + +// With this the root of `B` is `A`, even if the other impl does +// not have a cycle with `A`. This candidate never applies because of +// the `A: NotImplemented` bound. +impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B +where + A: Trait<'a, 'b>, + A: NotImplemented, +{ +} + +// This impl directly requires 'b to be equal to 'static. +// +// Because of the coinductive cycle through `C` it also requires +// 'a to be 'static. +impl<'a, T: ?Sized> Trait<'a, 'static> for B +where + C: Trait<'a, 'a>, +{} + +// In the first iteration of `B: Trait<'a, 'b>` we don't add any +// constraints here, only after setting the provisional result to require +// `'b == 'static` do we also add that constraint for `'a`. +impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C +where + B: Trait<'a, 'b>, +{} + +fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {} + +fn check<'a, T: ?Sized>() { + impls_trait::<'a, 'static, A>(); + //~^ ERROR lifetime may not live long enough +} + +fn main() { + check::<()>(); +} diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr new file mode 100644 index 0000000000000..4cbd0898148a5 --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/fixpoint-rerun-all-cycle-heads.rs:47:5 + | +LL | fn check<'a, T: ?Sized>() { + | -- lifetime `'a` defined here +LL | impls_trait::<'a, 'static, A>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to previous error + diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs index 3cfe7ab87f60a..f06b98a79cfe3 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs @@ -39,7 +39,7 @@ fn impls_ar() {} fn main() { impls_a::<()>(); - // FIXME(-Ztrait-solver=next): This is broken and should error. + //~^ ERROR overflow evaluating the requirement `(): A` impls_ar::<()>(); //~^ ERROR overflow evaluating the requirement `(): AR` diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr index 341153340635e..859b3f3f1c7d7 100644 --- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr @@ -1,3 +1,16 @@ +error[E0275]: overflow evaluating the requirement `(): A` + --> $DIR/inductive-not-on-stack.rs:41:15 + | +LL | impls_a::<()>(); + | ^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) +note: required by a bound in `impls_a` + --> $DIR/inductive-not-on-stack.rs:25:15 + | +LL | fn impls_a() {} + | ^ required by this bound in `impls_a` + error[E0275]: overflow evaluating the requirement `(): AR` --> $DIR/inductive-not-on-stack.rs:44:16 | @@ -11,6 +24,6 @@ note: required by a bound in `impls_ar` LL | fn impls_ar() {} | ^^ required by this bound in `impls_ar` -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. From 1a01e57d277e3b2668c9c18fd44ae48399a4cf48 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 18 Sep 2023 14:37:19 +0000 Subject: [PATCH 017/103] Prototype using const generic for simd_shuffle IDX array --- .../src/intrinsics/simd.rs | 50 +++++++++++- compiler/rustc_codegen_llvm/src/intrinsic.rs | 57 ++++++++++++- .../rustc_hir_analysis/src/check/intrinsic.rs | 44 +++++----- compiler/rustc_span/src/symbol.rs | 1 + src/tools/miri/src/shims/intrinsics/mod.rs | 5 +- src/tools/miri/src/shims/intrinsics/simd.rs | 33 ++++++++ tests/ui/simd/intrinsic/generic-elements.rs | 28 ++++++- .../ui/simd/intrinsic/generic-elements.stderr | 80 ++++++++++++++++--- .../monomorphize-shuffle-index.generic.stderr | 12 +++ tests/ui/simd/monomorphize-shuffle-index.rs | 28 +++++-- 10 files changed, 293 insertions(+), 45 deletions(-) create mode 100644 tests/ui/simd/monomorphize-shuffle-index.generic.stderr diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index c64a4008996d5..6efbe14986354 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -21,7 +21,7 @@ fn report_simd_type_validation_error( pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, intrinsic: Symbol, - _args: GenericArgsRef<'tcx>, + generic_args: GenericArgsRef<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, target: BasicBlock, @@ -117,6 +117,54 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }); } + // simd_shuffle_generic(x: T, y: T) -> U + sym::simd_shuffle_generic => { + let [x, y] = args else { + bug!("wrong number of args for intrinsic {intrinsic}"); + }; + let x = codegen_operand(fx, x); + let y = codegen_operand(fx, y); + + if !x.layout().ty.is_simd() { + report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty); + return; + } + + let idx = generic_args[2] + .expect_const() + .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span)) + .unwrap() + .unwrap_branch(); + + assert_eq!(x.layout(), y.layout()); + let layout = x.layout(); + + let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx); + let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); + + assert_eq!(lane_ty, ret_lane_ty); + assert_eq!(idx.len() as u64, ret_lane_count); + + let total_len = lane_count * 2; + + let indexes = + idx.iter().map(|idx| idx.unwrap_leaf().try_to_u16().unwrap()).collect::>(); + + for &idx in &indexes { + assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); + } + + for (out_idx, in_idx) in indexes.into_iter().enumerate() { + let in_lane = if u64::from(in_idx) < lane_count { + x.value_lane(fx, in_idx.into()) + } else { + y.value_lane(fx, u64::from(in_idx) - lane_count) + }; + let out_lane = ret.place_lane(fx, u64::try_from(out_idx).unwrap()); + out_lane.write_cvalue(fx, in_lane); + } + } + // simd_shuffle(x: T, y: T, idx: I) -> U sym::simd_shuffle => { let (x, y, idx) = match args { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 9289c37d76352..a97b803fc645b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -15,7 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; use rustc_hir as hir; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{sym, symbol::kw, Span, Symbol}; use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; @@ -376,7 +376,9 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { } _ if name.as_str().starts_with("simd_") => { - match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) { + match generic_simd_intrinsic( + self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span, + ) { Ok(llval) => llval, Err(()) => return, } @@ -911,6 +913,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, + fn_args: GenericArgsRef<'tcx>, args: &[OperandRef<'tcx, &'ll Value>], ret_ty: Ty<'tcx>, llret_ty: &'ll Type, @@ -1030,6 +1033,56 @@ fn generic_simd_intrinsic<'ll, 'tcx>( )); } + if name == sym::simd_shuffle_generic { + let idx = fn_args[2] + .expect_const() + .eval(tcx, ty::ParamEnv::reveal_all(), Some(span)) + .unwrap() + .unwrap_branch(); + let n = idx.len() as u64; + + 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, + InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len } + ); + require!( + in_elem == out_ty, + InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } + ); + + let total_len = in_len * 2; + + let indices: Option> = idx + .iter() + .enumerate() + .map(|(arg_idx, val)| { + let idx = val.unwrap_leaf().try_to_i32().unwrap(); + if idx >= i32::try_from(total_len).unwrap() { + bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds { + span, + name, + arg_idx: arg_idx as u64, + total_len: total_len.into(), + }); + None + } else { + Some(bx.const_i32(idx)) + } + }) + .collect(); + let Some(indices) = indices else { + return Ok(bx.const_null(llret_ty)); + }; + + return Ok(bx.shuffle_vector( + args[0].immediate(), + args[1].immediate(), + bx.const_vector(&indices), + )); + } + if name == sym::simd_shuffle { // Make sure this is actually an array, since typeck only checks the length-suffixed // version of this intrinsic. diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index f89e2e5c25bf2..a5856f0ca17eb 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -20,6 +20,7 @@ fn equate_intrinsic_type<'tcx>( it: &hir::ForeignItem<'_>, n_tps: usize, n_lts: usize, + n_cts: usize, sig: ty::PolyFnSig<'tcx>, ) { let (own_counts, span) = match &it.kind { @@ -51,7 +52,7 @@ fn equate_intrinsic_type<'tcx>( if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime") && gen_count_ok(own_counts.types, n_tps, "type") - && gen_count_ok(own_counts.consts, 0, "const") + && gen_count_ok(own_counts.consts, n_cts, "const") { let fty = Ty::new_fn_ptr(tcx, sig); let it_def_id = it.owner_id.def_id; @@ -492,7 +493,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic); let sig = ty::Binder::bind_with_vars(sig, bound_vars); - equate_intrinsic_type(tcx, it, n_tps, n_lts, sig) + equate_intrinsic_type(tcx, it, n_tps, n_lts, 0, sig) } /// Type-check `extern "platform-intrinsic" { ... }` functions. @@ -504,9 +505,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) let name = it.ident.name; - let (n_tps, inputs, output) = match name { + let (n_tps, n_cts, inputs, output) = match name { sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => { - (2, vec![param(0), param(0)], param(1)) + (2, 0, vec![param(0), param(0)], param(1)) } sym::simd_add | sym::simd_sub @@ -522,8 +523,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_fmax | sym::simd_fpow | sym::simd_saturating_add - | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)), - sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)), + | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)), + sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)), sym::simd_neg | sym::simd_bswap | sym::simd_bitreverse @@ -541,25 +542,25 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_ceil | sym::simd_floor | sym::simd_round - | sym::simd_trunc => (1, vec![param(0)], param(0)), - sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)), - sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)), - sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)), - sym::simd_scatter => (3, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), - sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), - sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)), + | sym::simd_trunc => (1, 0, vec![param(0)], param(0)), + sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)), + sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)), + sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)), + sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)), + sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)), + sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)), sym::simd_cast | sym::simd_as | sym::simd_cast_ptr | sym::simd_expose_addr - | sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)), - sym::simd_bitmask => (2, vec![param(0)], param(1)), + | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)), + sym::simd_bitmask => (2, 0, vec![param(0)], param(1)), sym::simd_select | sym::simd_select_bitmask => { - (2, vec![param(0), param(1), param(1)], param(1)) + (2, 0, vec![param(0), param(1), param(1)], param(1)) } - sym::simd_reduce_all | sym::simd_reduce_any => (1, vec![param(0)], tcx.types.bool), + sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool), sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => { - (2, vec![param(0), param(1)], param(1)) + (2, 0, vec![param(0), param(1)], param(1)) } sym::simd_reduce_add_unordered | sym::simd_reduce_mul_unordered @@ -569,8 +570,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_reduce_min | sym::simd_reduce_max | sym::simd_reduce_min_nanless - | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)), - sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)), + | sym::simd_reduce_max_nanless => (2, 0, vec![param(0)], param(1)), + sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)), + sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)), _ => { let msg = format!("unrecognized platform-specific intrinsic function: `{name}`"); tcx.sess.struct_span_err(it.span, msg).emit(); @@ -580,5 +582,5 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic); let sig = ty::Binder::dummy(sig); - equate_intrinsic_type(tcx, it, n_tps, 0, sig) + equate_intrinsic_type(tcx, it, n_tps, 0, n_cts, sig) } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 382754be2ca83..4f46256626f5e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1465,6 +1465,7 @@ symbols! { simd_shl, simd_shr, simd_shuffle, + simd_shuffle_generic, simd_sub, simd_trunc, simd_xor, diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs index ef9d071044818..fad76cbb64b2f 100644 --- a/src/tools/miri/src/shims/intrinsics/mod.rs +++ b/src/tools/miri/src/shims/intrinsics/mod.rs @@ -60,7 +60,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { } // The rest jumps to `ret` immediately. - this.emulate_intrinsic_by_name(intrinsic_name, args, dest)?; + this.emulate_intrinsic_by_name(intrinsic_name, instance.args, args, dest)?; trace!("{:?}", this.dump_place(dest)); this.go_to_block(ret); @@ -71,6 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn emulate_intrinsic_by_name( &mut self, intrinsic_name: &str, + generic_args: ty::GenericArgsRef<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -80,7 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { return this.emulate_atomic_intrinsic(name, args, dest); } if let Some(name) = intrinsic_name.strip_prefix("simd_") { - return this.emulate_simd_intrinsic(name, args, dest); + return this.emulate_simd_intrinsic(name, generic_args, args, dest); } match intrinsic_name { diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index dd8c4a4f6ecab..59d6fe53448ac 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -12,6 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn emulate_simd_intrinsic( &mut self, intrinsic_name: &str, + generic_args: ty::GenericArgsRef<'tcx>, args: &[OpTy<'tcx, Provenance>], dest: &PlaceTy<'tcx, Provenance>, ) -> InterpResult<'tcx> { @@ -490,6 +491,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.write_immediate(val, &dest)?; } } + "shuffle_generic" => { + let [left, right] = check_arg_count(args)?; + let (left, left_len) = this.operand_to_simd(left)?; + let (right, right_len) = this.operand_to_simd(right)?; + let (dest, dest_len) = this.place_to_simd(dest)?; + + let index = generic_args[2].expect_const().eval(*this.tcx, this.param_env(), Some(this.tcx.span)).unwrap().unwrap_branch(); + let index_len = index.len(); + + assert_eq!(left_len, right_len); + assert_eq!(index_len as u64, dest_len); + + for i in 0..dest_len { + let src_index: u64 = index[i as usize].unwrap_leaf() + .try_to_u32().unwrap() + .into(); + let dest = this.project_index(&dest, i)?; + + let val = if src_index < left_len { + this.read_immediate(&this.project_index(&left, src_index)?)? + } else if src_index < left_len.checked_add(right_len).unwrap() { + let right_idx = src_index.checked_sub(left_len).unwrap(); + this.read_immediate(&this.project_index(&right, right_idx)?)? + } else { + span_bug!( + this.cur_span(), + "simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}", + ); + }; + this.write_immediate(*val, &dest)?; + } + } "shuffle" => { let [left, right, index] = check_arg_count(args)?; let (left, left_len) = this.operand_to_simd(left)?; diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs index 0ff2203ec722e..6ba93e46f75e6 100644 --- a/tests/ui/simd/intrinsic/generic-elements.rs +++ b/tests/ui/simd/intrinsic/generic-elements.rs @@ -1,6 +1,7 @@ // build-fail -#![feature(repr_simd, platform_intrinsics, rustc_attrs)] +#![feature(repr_simd, platform_intrinsics, rustc_attrs, adt_const_params)] +#![allow(incomplete_features)] #[repr(simd)] #[derive(Copy, Clone)] @@ -35,6 +36,7 @@ extern "platform-intrinsic" { fn simd_extract(x: T, idx: u32) -> E; fn simd_shuffle(x: T, y: T, idx: I) -> U; + fn simd_shuffle_generic(x: T, y: T) -> U; } fn main() { @@ -71,5 +73,29 @@ fn main() { //~^ ERROR expected return type of length 4, found `i32x8` with length 8 simd_shuffle::<_, _, i32x2>(x, x, IDX8); //~^ ERROR expected return type of length 8, found `i32x2` with length 2 + + const I2: &[u32] = &[0; 2]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + const I4: &[u32] = &[0; 4]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + const I8: &[u32] = &[0; 8]; + simd_shuffle_generic::(0, 0); + //~^ ERROR expected SIMD input type, found non-SIMD `i32` + + simd_shuffle_generic::<_, f32x2, I2>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` + simd_shuffle_generic::<_, f32x4, I4>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` + simd_shuffle_generic::<_, f32x8, I8>(x, x); +//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` + + simd_shuffle_generic::<_, i32x8, I2>(x, x); + //~^ ERROR expected return type of length 2, found `i32x8` with length 8 + simd_shuffle_generic::<_, i32x8, I4>(x, x); + //~^ ERROR expected return type of length 4, found `i32x8` with length 8 + simd_shuffle_generic::<_, i32x2, I8>(x, x); + //~^ ERROR expected return type of length 8, found `i32x2` with length 2 } } diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr index 115d9d4b3f3ac..26e01344939cc 100644 --- a/tests/ui/simd/intrinsic/generic-elements.stderr +++ b/tests/ui/simd/intrinsic/generic-elements.stderr @@ -1,75 +1,129 @@ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:44:9 + --> $DIR/generic-elements.rs:46:9 | LL | simd_insert(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64` - --> $DIR/generic-elements.rs:46:9 + --> $DIR/generic-elements.rs:48:9 | LL | simd_insert(x, 0, 1.0); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32` - --> $DIR/generic-elements.rs:48:9 + --> $DIR/generic-elements.rs:50:9 | LL | simd_extract::<_, f32>(x, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:52:9 + --> $DIR/generic-elements.rs:54:9 | LL | simd_shuffle::(0, 0, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:55:9 + --> $DIR/generic-elements.rs:57:9 | LL | simd_shuffle::(0, 0, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:58:9 + --> $DIR/generic-elements.rs:60:9 | LL | simd_shuffle::(0, 0, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:61:9 + --> $DIR/generic-elements.rs:63:9 | LL | simd_shuffle::<_, _, f32x2>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:63:9 + --> $DIR/generic-elements.rs:65:9 | LL | simd_shuffle::<_, _, f32x4>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:65:9 + --> $DIR/generic-elements.rs:67:9 | LL | simd_shuffle::<_, _, f32x8>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:68:9 + --> $DIR/generic-elements.rs:70:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:70:9 + --> $DIR/generic-elements.rs:72:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:72:9 + --> $DIR/generic-elements.rs:74:9 | LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:78:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:81:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` + --> $DIR/generic-elements.rs:84:9 + | +LL | simd_shuffle_generic::(0, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` + --> $DIR/generic-elements.rs:87:9 + | +LL | simd_shuffle_generic::<_, f32x2, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` + --> $DIR/generic-elements.rs:89:9 + | +LL | simd_shuffle_generic::<_, f32x4, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` + --> $DIR/generic-elements.rs:91:9 + | +LL | simd_shuffle_generic::<_, f32x8, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 + --> $DIR/generic-elements.rs:94:9 + | +LL | simd_shuffle_generic::<_, i32x8, I2>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 + --> $DIR/generic-elements.rs:96:9 + | +LL | simd_shuffle_generic::<_, i32x8, I4>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 + --> $DIR/generic-elements.rs:98:9 + | +LL | simd_shuffle_generic::<_, i32x2, I8>(x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 21 previous errors For more information about this error, try `rustc --explain E0511`. diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr new file mode 100644 index 0000000000000..fc66b195674c6 --- /dev/null +++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr @@ -0,0 +1,12 @@ +error: overly complex generic constant + --> $DIR/monomorphize-shuffle-index.rs:29:45 + | +LL | return simd_shuffle_generic::<_, _, { &Self::I }>(a, b); + | ^^--------^^ + | | + | pointer casts are not allowed in generic constants + | + = help: consider moving this anonymous constant into a `const` function + +error: aborting due to previous error + diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index 2467baa08b0a7..db7953f06dd46 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -1,8 +1,14 @@ -//run-pass -#![feature(repr_simd, platform_intrinsics)] +//[old]run-pass +//[generic_with_fn]run-pass +// revisions: old generic generic_with_fn +#![feature(repr_simd, platform_intrinsics, adt_const_params, generic_const_exprs)] +#![allow(incomplete_features)] extern "platform-intrinsic" { + #[cfg(old)] fn simd_shuffle(a: T, b: T, i: I) -> U; + #[cfg(any(generic, generic_with_fn))] + fn simd_shuffle_generic(a: T, b: T) -> U; } #[derive(Copy, Clone)] @@ -11,12 +17,24 @@ struct Simd([T; N]); trait Shuffle { const I: [u32; N]; - - unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd { - simd_shuffle(a, b, Self::I) + const J: &'static [u32] = &Self::I; + + unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd + where + Thing<{ Self::J }>:, + { + #[cfg(old)] + return simd_shuffle(a, b, Self::I); + #[cfg(generic)] + return simd_shuffle_generic::<_, _, { &Self::I }>(a, b); + //[generic]~^ overly complex generic constant + #[cfg(generic_with_fn)] + return simd_shuffle_generic::<_, _, { Self::J }>(a, b); } } +struct Thing; + fn main() { struct I1; impl Shuffle<4> for I1 { From 77e205a113e4843d1b84467afe8ea74a36ed9424 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Wed, 13 Sep 2023 20:42:56 +0300 Subject: [PATCH 018/103] Migrate `rustc_hir_analysis` to session diagnostic Part 5: Finishing `coherence/builtin.rs` file --- compiler/rustc_hir_analysis/messages.ftl | 25 +++ .../src/coherence/builtin.rs | 200 +++++++----------- compiler/rustc_hir_analysis/src/errors.rs | 124 +++++++++++ tests/ui/error-codes/E0374.stderr | 4 +- tests/ui/error-codes/E0377.stderr | 4 +- .../ui/invalid_dispatch_from_dyn_impls.stderr | 4 +- 6 files changed, 236 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 18f7a18625edb..a2452a19d462e 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -34,6 +34,17 @@ hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present .label = `for<...>` is here +hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures + +hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions + .note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced + .coercions_note = currently, {$number} fields need coercions: {$coercions} + .label = requires multiple coercions + +hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}` + +hir_analysis_coercion_between_struct_single_note = expected a single field to be coerced, none found + hir_analysis_const_bound_for_non_const_trait = ~const can only be applied to `#[const_trait]` traits @@ -57,6 +68,15 @@ hir_analysis_copy_impl_on_type_with_dtor = the trait `Copy` cannot be implemented for this type; the type has a destructor .label = `Copy` not allowed on types with destructors +hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions + .note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced + .coercions_note = currently, {$number} fields need coercions: {$coercions} + +hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` + +hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else + .note = extra field `{$name}` of type `{$ty}` is not allowed + hir_analysis_drop_impl_negative = negative `Drop` impls are not supported hir_analysis_drop_impl_on_wrong_item = @@ -228,6 +248,8 @@ hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind} .label = not allowed in type signatures +hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}` + hir_analysis_return_type_notation_conflicting_bound = ambiguous associated function `{$assoc_name}` for `{$ty_name}` .note = `{$assoc_name}` is declared in two supertraits: `{$first_bound}` and `{$second_bound}` @@ -295,6 +317,9 @@ hir_analysis_too_large_static = extern static is too large for the current archi hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]` .suggestion = remove this annotation +hir_analysis_trait_cannot_impl_for_ty = the trait `{$trait_name}` cannot be implemented for this type + .label = this field does not implement `{$trait_name}` + hir_analysis_trait_object_declared_with_no_traits = at least one trait is required for an object type .alias_span = this alias does not contain a trait diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 94f3e8706fce3..be70acfc35de9 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -1,11 +1,10 @@ //! Check properties that are required by built-in traits and set //! up data structures required by type-checking/codegen. -use crate::errors::{ - ConstParamTyImplOnNonAdt, CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem, -}; +use crate::errors; + use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; @@ -65,7 +64,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { let impl_ = tcx.hir().expect_item(impl_did).expect_impl(); - tcx.sess.emit_err(DropImplOnWrongItem { span: impl_.self_ty.span }); + tcx.sess.emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span }); } fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { @@ -91,10 +90,10 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span); } Err(CopyImplementationError::NotAnAdt) => { - tcx.sess.emit_err(CopyImplOnNonAdt { span }); + tcx.sess.emit_err(errors::CopyImplOnNonAdt { span }); } Err(CopyImplementationError::HasDestructor) => { - tcx.sess.emit_err(CopyImplOnTypeWithDtor { span }); + tcx.sess.emit_err(errors::CopyImplOnTypeWithDtor { span }); } } } @@ -117,7 +116,7 @@ fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span); } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { - tcx.sess.emit_err(ConstParamTyImplOnNonAdt { span }); + tcx.sess.emit_err(errors::ConstParamTyImplOnNonAdt { span }); } } } @@ -152,8 +151,6 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef let param_env = tcx.param_env(impl_did); - let create_err = |msg: &str| struct_span_err!(tcx.sess, span, E0378, "{}", msg); - let infcx = tcx.infer_ctxt().build(); let cause = ObligationCause::misc(span, impl_did); @@ -176,22 +173,19 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef let source_path = tcx.def_path_str(def_a.did()); let target_path = tcx.def_path_str(def_b.did()); - create_err(&format!( - "the trait `DispatchFromDyn` may only be implemented \ - for a coercion between structures with the same \ - definition; expected `{source_path}`, found `{target_path}`", - )) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynCoercion { + span, + trait_name: "DispatchFromDyn", + note: true, + source_path, + target_path, + }); return; } if def_a.repr().c() || def_a.repr().packed() { - create_err( - "structs implementing `DispatchFromDyn` may not have \ - `#[repr(packed)]` or `#[repr(C)]`", - ) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynRepr { span }); } let fields = &def_a.non_enum_variant().fields; @@ -213,16 +207,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b) { if ok.obligations.is_empty() { - create_err( - "the trait `DispatchFromDyn` may only be implemented \ - for structs containing the field being coerced, \ - ZST fields with 1 byte alignment, and nothing else", - ) - .note(format!( - "extra field `{}` of type `{}` is not allowed", - field.name, ty_a, - )) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynZST { + span, + name: field.name, + ty: ty_a, + }); return false; } @@ -233,36 +222,29 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef .collect::>(); if coerced_fields.is_empty() { - create_err( - "the trait `DispatchFromDyn` may only be implemented \ - for a coercion between structures with a single field \ - being coerced, none found", - ) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynSingle { + span, + trait_name: "DispatchFromDyn", + note: true, + }); } else if coerced_fields.len() > 1 { - create_err("implementing the `DispatchFromDyn` trait requires multiple coercions") - .note( - "the trait `DispatchFromDyn` may only be implemented \ - for a coercion between structures with a single field \ - being coerced", - ) - .note(format!( - "currently, {} fields need coercions: {}", - coerced_fields.len(), - coerced_fields - .iter() - .map(|field| { - format!( - "`{}` (`{}` to `{}`)", - field.name, - field.ty(tcx, args_a), - field.ty(tcx, args_b), - ) - }) - .collect::>() - .join(", ") - )) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynMulti { + span, + coercions_note: true, + number: coerced_fields.len(), + coercions: coerced_fields + .iter() + .map(|field| { + format!( + "`{}` (`{}` to `{}`)", + field.name, + field.ty(tcx, args_a), + field.ty(tcx, args_b), + ) + }) + .collect::>() + .join(", "), + }); } else { let ocx = ObligationCtxt::new(&infcx); for field in coerced_fields { @@ -288,11 +270,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef } } _ => { - create_err( - "the trait `DispatchFromDyn` may only be implemented \ - for a coercion between structures", - ) - .emit(); + tcx.sess.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" }); } } } @@ -359,17 +337,13 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe if def_a != def_b { let source_path = tcx.def_path_str(def_a.did()); let target_path = tcx.def_path_str(def_b.did()); - struct_span_err!( - tcx.sess, + tcx.sess.emit_err(errors::DispatchFromDynSame { span, - E0377, - "the trait `CoerceUnsized` may only be implemented \ - for a coercion between structures with the same \ - definition; expected `{}`, found `{}`", + trait_name: "CoerceUnsized", + note: true, source_path, - target_path - ) - .emit(); + target_path, + }); return err_info; } @@ -445,15 +419,11 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe .collect::>(); if diff_fields.is_empty() { - struct_span_err!( - tcx.sess, + tcx.sess.emit_err(errors::CoerceUnsizedOneField { span, - E0374, - "the trait `CoerceUnsized` may only be implemented \ - for a coercion between structures with one field \ - being coerced, none found" - ) - .emit(); + trait_name: "CoerceUnsized", + note: true, + }); return err_info; } else if diff_fields.len() > 1 { let item = tcx.hir().expect_item(impl_did); @@ -463,29 +433,17 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe tcx.def_span(impl_did) }; - struct_span_err!( - tcx.sess, + tcx.sess.emit_err(errors::CoerceUnsizedMulti { span, - E0375, - "implementing the trait \ - `CoerceUnsized` requires multiple \ - coercions" - ) - .note( - "`CoerceUnsized` may only be implemented for \ - a coercion between structures with one field being coerced", - ) - .note(format!( - "currently, {} fields need coercions: {}", - diff_fields.len(), - diff_fields + coercions_note: true, + number: diff_fields.len(), + coercions: diff_fields .iter() - .map(|&(i, a, b)| { format!("`{}` (`{}` to `{}`)", fields[i].name, a, b) }) + .map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)) .collect::>() - .join(", ") - )) - .span_label(span, "requires multiple coercions") - .emit(); + .join(", "), + }); + return err_info; } @@ -495,14 +453,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe } _ => { - struct_span_err!( - tcx.sess, - span, - E0376, - "the trait `CoerceUnsized` may only be implemented \ - for a coercion between structures" - ) - .emit(); + tcx.sess.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }); return err_info; } }; @@ -540,13 +491,6 @@ fn infringing_fields_error( let trait_name = tcx.def_path_str(trait_did); - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0204, - "the trait `{trait_name}` cannot be implemented for this type" - ); - // We'll try to suggest constraining type parameters to fulfill the requirements of // their `Copy` implementation. let mut errors: BTreeMap<_, Vec<_>> = Default::default(); @@ -554,14 +498,15 @@ fn infringing_fields_error( let mut seen_tys = FxHashSet::default(); + let mut label_spans = Vec::new(); + for (field, ty, reason) in fields { // Only report an error once per type. if !seen_tys.insert(ty) { continue; } - let field_span = tcx.def_span(field.did); - err.span_label(field_span, format!("this field does not implement `{trait_name}`")); + label_spans.push(tcx.def_span(field.did)); match reason { InfringingFieldsReason::Fulfill(fulfillment_errors) => { @@ -625,13 +570,24 @@ fn infringing_fields_error( } } } + let mut notes = Vec::new(); for ((ty, error_predicate), spans) in errors { let span: MultiSpan = spans.into(); - err.span_note( + notes.push(errors::ImplForTyRequires { span, - format!("the `{trait_name}` impl for `{ty}` requires that `{error_predicate}`"), - ); + error_predicate, + trait_name: trait_name.clone(), + ty, + }); } + + let mut err = tcx.sess.create_err(errors::TraitCannotImplForTy { + span: impl_span, + trait_name, + label_spans, + notes, + }); + suggest_constraining_type_params( tcx, tcx.hir().get_generics(impl_did).expect("impls always have generics"), diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index b83ef8d07db4d..968e3358fd402 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -953,6 +953,25 @@ pub struct InherentTyOutside { pub span: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0378")] +pub struct DispatchFromDynCoercion<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, + #[note(hir_analysis_coercion_between_struct_same_note)] + pub note: bool, + pub source_path: String, + pub target_path: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_dispatch_from_dyn_repr, code = "E0378")] +pub struct DispatchFromDynRepr { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_analysis_inherent_ty_outside_relevant, code = "E0390")] #[help] @@ -1015,3 +1034,108 @@ pub struct InherentNominal { #[label] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_dispatch_from_dyn_zst, code = "E0378")] +#[note] +pub struct DispatchFromDynZST<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0378")] +pub struct DispatchFromDynSingle<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, + #[note(hir_analysis_coercion_between_struct_single_note)] + pub note: bool, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_dispatch_from_dyn_multi, code = "E0378")] +#[note] +pub struct DispatchFromDynMulti { + #[primary_span] + pub span: Span, + #[note(hir_analysis_coercions_note)] + pub coercions_note: bool, + pub number: usize, + pub coercions: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0376")] +pub struct DispatchFromDynStruct<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0377")] +pub struct DispatchFromDynSame<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, + #[note(hir_analysis_coercion_between_struct_same_note)] + pub note: bool, + pub source_path: String, + pub target_path: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0374")] +pub struct CoerceUnsizedOneField<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, + #[note(hir_analysis_coercion_between_struct_single_note)] + pub note: bool, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_multi, code = "E0375")] +#[note] +pub struct CoerceUnsizedMulti { + #[primary_span] + #[label] + pub span: Span, + #[note(hir_analysis_coercions_note)] + pub coercions_note: bool, + pub number: usize, + pub coercions: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_coerce_unsized_may, code = "E0378")] +pub struct CoerceUnsizedMay<'a> { + #[primary_span] + pub span: Span, + pub trait_name: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_trait_cannot_impl_for_ty, code = "E0204")] +pub struct TraitCannotImplForTy { + #[primary_span] + pub span: Span, + pub trait_name: String, + #[label] + pub label_spans: Vec, + #[subdiagnostic] + pub notes: Vec, +} + +#[derive(Subdiagnostic)] +#[note(hir_analysis_requires_note)] +pub struct ImplForTyRequires { + #[primary_span] + pub span: MultiSpan, + pub error_predicate: String, + pub trait_name: String, + pub ty: String, +} diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr index 68e15e6f8fe81..a77920430672e 100644 --- a/tests/ui/error-codes/E0374.stderr +++ b/tests/ui/error-codes/E0374.stderr @@ -1,8 +1,10 @@ -error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced, none found +error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures --> $DIR/E0374.rs:8:1 | LL | impl CoerceUnsized> for Foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected a single field to be coerced, none found error: aborting due to previous error diff --git a/tests/ui/error-codes/E0377.stderr b/tests/ui/error-codes/E0377.stderr index bf7d8c8d39d2a..664e499ec23a0 100644 --- a/tests/ui/error-codes/E0377.stderr +++ b/tests/ui/error-codes/E0377.stderr @@ -1,8 +1,10 @@ -error[E0377]: the trait `CoerceUnsized` may only be implemented for a coercion between structures with the same definition; expected `Foo`, found `Bar` +error[E0377]: the trait `CoerceUnsized` may only be implemented for a coercion between structures --> $DIR/E0377.rs:12:1 | LL | impl CoerceUnsized> for Foo where T: CoerceUnsized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected coercion between the same definition; expected `Foo`, found `Bar` error: aborting due to previous error diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr index b5b32d2f0bd36..172ee7ade4903 100644 --- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr +++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr @@ -15,11 +15,13 @@ LL | impl DispatchFromDyn> for Multipl = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced = note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`) -error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced, none found +error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures --> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1 | LL | impl DispatchFromDyn> for NothingToCoerce {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected a single field to be coerced, none found error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]` --> $DIR/invalid_dispatch_from_dyn_impls.rs:37:1 From 62bdb1a6e0011d6dbbcc552afebaffbd8fd26104 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 17 Jul 2023 17:45:31 +0200 Subject: [PATCH 019/103] offset_from: docs improvements --- library/core/src/ptr/const_ptr.rs | 12 ++++++++++-- library/core/src/ptr/mut_ptr.rs | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index ee69d89a4b720..b89e9e260e739 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -607,7 +607,9 @@ impl *const T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]. + /// This function is the inverse of [`offset`]: it is valid to call if and only if + /// `self` could have been computed as `origin.offset(n)` for some `n`, and it will + /// then return that `n`. /// /// [`offset`]: #method.offset /// @@ -646,6 +648,12 @@ impl *const T { /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on /// such large allocations either.) /// + /// The requirement for pointers to be derived from the same allocated object is primarily + /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated + /// object do not have a known distance to each other. However, the requirement also exists at + /// runtime, and may be exploited by optimizations. You can use `(self as usize).sub(origin as + /// usize) / mem::size_of::()` to avoid this requirement. + /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -703,7 +711,7 @@ impl *const T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset_from][pointer::offset_from] on it. See that method for + /// using [`offset_from`][pointer::offset_from] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 6d623b82c1cfe..e7611c90344bf 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -781,7 +781,9 @@ impl *mut T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]. + /// This function is the inverse of [`offset`]: it is valid to call if and only if + /// `self` could have been computed as `origin.offset(n)` for some `n`, and it will + /// then return that `n`. /// /// [`offset`]: pointer#method.offset-1 /// @@ -820,6 +822,12 @@ impl *mut T { /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on /// such large allocations either.) /// + /// The requirement for pointers to be derived from the same allocated object is primarily + /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated + /// object do not have a known distance to each other. However, the requirement also exists at + /// runtime, and may be exploited by optimizations. You can use `(self as usize).sub(origin as + /// usize) / mem::size_of::()` to avoid this requirement. + /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object /// @@ -875,7 +883,7 @@ impl *mut T { /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and - /// using [offset_from][pointer::offset_from] on it. See that method for + /// using [`offset_from`][pointer::offset_from] on it. See that method for /// documentation and safety requirements. /// /// For non-`Sized` pointees this operation considers only the data pointers, From 39b53dc204e944e37fef621d4799a561f423cfd3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 31 Jul 2023 14:24:11 +0200 Subject: [PATCH 020/103] documentation tweaks --- library/core/src/ptr/const_ptr.rs | 12 ++++++------ library/core/src/ptr/mut_ptr.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index b89e9e260e739..97aa3015bf1fc 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -607,9 +607,8 @@ impl *const T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]: it is valid to call if and only if - /// `self` could have been computed as `origin.offset(n)` for some `n`, and it will - /// then return that `n`. + /// This function is the inverse of [`offset`]: it is valid to call and will return + /// `n` if and only if `origin.offset(n)` is valid to call and will return `self`. /// /// [`offset`]: #method.offset /// @@ -650,9 +649,10 @@ impl *const T { /// /// The requirement for pointers to be derived from the same allocated object is primarily /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated - /// object do not have a known distance to each other. However, the requirement also exists at - /// runtime, and may be exploited by optimizations. You can use `(self as usize).sub(origin as - /// usize) / mem::size_of::()` to avoid this requirement. + /// objects do not have a known distance to each other. However, the requirement also exists at + /// runtime and may be exploited by optimizations. If you wish to compute the difference between + /// pointers that are not guaranteed to be from the same allocation, use `(self as + /// usize).sub(origin as usize) / mem::size_of::()`. /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e7611c90344bf..2f21319d559dc 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -781,9 +781,8 @@ impl *mut T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]: it is valid to call if and only if - /// `self` could have been computed as `origin.offset(n)` for some `n`, and it will - /// then return that `n`. + /// This function is the inverse of [`offset`]: it is valid to call and will return + /// `n` if and only if `origin.offset(n)` is valid to call and will return `self`. /// /// [`offset`]: pointer#method.offset-1 /// @@ -824,9 +823,10 @@ impl *mut T { /// /// The requirement for pointers to be derived from the same allocated object is primarily /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated - /// object do not have a known distance to each other. However, the requirement also exists at - /// runtime, and may be exploited by optimizations. You can use `(self as usize).sub(origin as - /// usize) / mem::size_of::()` to avoid this requirement. + /// objects do not have a known distance to each other. However, the requirement also exists at + /// runtime and may be exploited by optimizations. If you wish to compute the difference between + /// pointers that are not guaranteed to be from the same allocation, use `(self as + /// usize).sub(origin as usize) / mem::size_of::()`. /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object From 14625f5b3ec9730bef12c63f7d4fb4c43d118d7a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 19 Aug 2023 16:44:54 +0200 Subject: [PATCH 021/103] consistent wording --- library/core/src/ptr/const_ptr.rs | 4 ++-- library/core/src/ptr/mut_ptr.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 97aa3015bf1fc..0f589647a47fe 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -648,8 +648,8 @@ impl *const T { /// such large allocations either.) /// /// The requirement for pointers to be derived from the same allocated object is primarily - /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated - /// objects do not have a known distance to each other. However, the requirement also exists at + /// needed for `const`-compatibility: the distance between pointers into *different* allocated + /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between /// pointers that are not guaranteed to be from the same allocation, use `(self as /// usize).sub(origin as usize) / mem::size_of::()`. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 2f21319d559dc..d395319b6f39d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -822,8 +822,8 @@ impl *mut T { /// such large allocations either.) /// /// The requirement for pointers to be derived from the same allocated object is primarily - /// needed for `const`-compatibility: at compile-time, pointers into *different* allocated - /// objects do not have a known distance to each other. However, the requirement also exists at + /// needed for `const`-compatibility: the distance between pointers into *different* allocated + /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between /// pointers that are not guaranteed to be from the same allocation, use `(self as /// usize).sub(origin as usize) / mem::size_of::()`. From 6c73f254b977574a2e155dc18c4f96746071f4e0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Sep 2023 08:31:16 +0200 Subject: [PATCH 022/103] avoid talking about inverses --- library/core/src/ptr/const_ptr.rs | 12 +++++++----- library/core/src/ptr/mut_ptr.rs | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 0f589647a47fe..3e68216e40eda 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -607,8 +607,9 @@ impl *const T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]: it is valid to call and will return - /// `n` if and only if `origin.offset(n)` is valid to call and will return `self`. + /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// except that it has a lot more opportunities for UB, in exchange for the compiler + /// better understanding what you are doing. /// /// [`offset`]: #method.offset /// @@ -617,7 +618,7 @@ impl *const T { /// If any of the following conditions are violated, the result is Undefined /// Behavior: /// - /// * Both the starting and other pointer must be either in bounds or one + /// * Both `self` and `origin` must be either in bounds or one /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. @@ -651,8 +652,9 @@ impl *const T { /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between - /// pointers that are not guaranteed to be from the same allocation, use `(self as - /// usize).sub(origin as usize) / mem::size_of::()`. + /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - + /// origin as isize) / mem::size_of::()`. + // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index d395319b6f39d..c89ce52292a3d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -781,8 +781,9 @@ impl *mut T { /// Calculates the distance between two pointers. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// - /// This function is the inverse of [`offset`]: it is valid to call and will return - /// `n` if and only if `origin.offset(n)` is valid to call and will return `self`. + /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, + /// except that it has a lot more opportunities for UB, in exchange for the compiler + /// better understanding what you are doing. /// /// [`offset`]: pointer#method.offset-1 /// @@ -791,7 +792,7 @@ impl *mut T { /// If any of the following conditions are violated, the result is Undefined /// Behavior: /// - /// * Both the starting and other pointer must be either in bounds or one + /// * Both `self` and `origin` must be either in bounds or one /// byte past the end of the same [allocated object]. /// /// * Both pointers must be *derived from* a pointer to the same object. @@ -825,8 +826,9 @@ impl *mut T { /// needed for `const`-compatibility: the distance between pointers into *different* allocated /// objects is not known at compile-time. However, the requirement also exists at /// runtime and may be exploited by optimizations. If you wish to compute the difference between - /// pointers that are not guaranteed to be from the same allocation, use `(self as - /// usize).sub(origin as usize) / mem::size_of::()`. + /// pointers that are not guaranteed to be from the same allocation, use `(self as isize - + /// origin as isize) / mem::size_of::()`. + // FIXME: recommend `addr()` instead of `as usize` once that is stable. /// /// [`add`]: #method.add /// [allocated object]: crate::ptr#allocated-object From ec188115578db5207ba84977d7314a58e7d117e1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 21 Sep 2023 13:58:24 +0200 Subject: [PATCH 023/103] run abi/compatibility test against a whole bunch of targets --- tests/ui/abi/compatibility.rs | 183 ++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 10 deletions(-) diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 249e817628303..1f049b1785a62 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -1,16 +1,174 @@ // check-pass +// revisions: host +// revisions: arm +//[arm] compile-flags: --target arm-unknown-linux-gnueabi +//[arm] needs-llvm-components: arm +// revisions: aarch64 +//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//[aarch64] needs-llvm-components: aarch64 +// revisions: s390x +//[s390x] compile-flags: --target s390x-unknown-linux-gnu +//[s390x] needs-llvm-components: systemz +// revisions: mips +//[mips] compile-flags: --target mips-unknown-linux-gnu +//[mips] needs-llvm-components: mips +// revisions: mips64 +//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64 +//[mips64] needs-llvm-components: mips +// revisions: sparc +//[sparc] compile-flags: --target sparc-unknown-linux-gnu +//[sparc] needs-llvm-components: sparc +// revisions: sparc64 +//[sparc64] compile-flags: --target sparc64-unknown-linux-gnu +//[sparc64] needs-llvm-components: sparc +// revisions: powerpc64 +//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//[powerpc64] needs-llvm-components: powerpc +// revisions: riscv +//[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu +//[riscv] needs-llvm-components: riscv +// revisions: loongarch64 +//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu +//[loongarch64] needs-llvm-components: loongarch +// revisions: wasm +//[wasm] compile-flags: --target wasm32-unknown-unknown +//[wasm] needs-llvm-components: webassembly +// revisions: wasi +//[wasi] compile-flags: --target wasm32-wasi +//[wasi] needs-llvm-components: webassembly +// revisions: nvptx64 +//[nvptx64] compile-flags: --target nvptx64-nvidia-cuda +//[nvptx64] needs-llvm-components: nvptx #![feature(rustc_attrs, unsized_fn_params, transparent_unions)] +#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)] #![allow(unused, improper_ctypes_definitions, internal_features)] -use std::marker::PhantomData; -use std::mem::ManuallyDrop; -use std::num::NonZeroI32; -use std::ptr::NonNull; -// FIXME: a bunch of targets are broken in various ways. +// FIXME: some targets are broken in various ways. // Hence there are `cfg` throughout this test to disable parts of it on those targets. // sparc64: https://github.com/rust-lang/rust/issues/115336 // mips64: https://github.com/rust-lang/rust/issues/115404 +#[cfg(host)] +use std::{ + any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZeroI32, ptr::NonNull, rc::Rc, + sync::Arc, +}; + +/// To work cross-target this test must be no_core. +/// This little prelude supplies what we need. +#[cfg(not(host))] +mod prelude { + #[lang = "sized"] + pub trait Sized {} + + #[lang = "receiver"] + pub trait Receiver {} + impl Receiver for &T {} + impl Receiver for &mut T {} + + #[lang = "copy"] + pub trait Copy: Sized {} + impl Copy for i32 {} + impl Copy for f32 {} + impl Copy for &T {} + impl Copy for *const T {} + impl Copy for *mut T {} + + #[lang = "clone"] + pub trait Clone: Sized { + fn clone(&self) -> Self; + } + + #[lang = "phantom_data"] + pub struct PhantomData; + impl Copy for PhantomData {} + + #[lang = "unsafe_cell"] + #[repr(transparent)] + pub struct UnsafeCell { + value: T, + } + + pub trait Any: 'static {} + + pub enum Option { + None, + Some(T), + } + impl Copy for Option {} + + pub enum Result { + Ok(T), + Err(E), + } + impl Copy for Result {} + + #[lang = "manually_drop"] + #[repr(transparent)] + pub struct ManuallyDrop { + value: T, + } + impl Copy for ManuallyDrop {} + + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start(1)] + #[rustc_nonnull_optimization_guaranteed] + pub struct NonNull { + pointer: *const T, + } + impl Copy for NonNull {} + + #[repr(transparent)] + #[rustc_layout_scalar_valid_range_start(1)] + #[rustc_nonnull_optimization_guaranteed] + pub struct NonZeroI32(i32); + + // This just stands in for a non-trivial type. + pub struct Vec { + ptr: NonNull, + cap: usize, + len: usize, + } + + pub struct Unique { + pub pointer: NonNull, + pub _marker: PhantomData, + } + + pub struct Global; + + #[lang = "owned_box"] + pub struct Box(Unique, A); + + #[repr(C)] + struct RcBox { + strong: UnsafeCell, + weak: UnsafeCell, + value: T, + } + pub struct Rc { + ptr: NonNull>, + phantom: PhantomData>, + alloc: A, + } + + #[repr(C, align(8))] + struct AtomicUsize(usize); + #[repr(C)] + struct ArcInner { + strong: AtomicUsize, + weak: AtomicUsize, + data: T, + } + pub struct Arc { + ptr: NonNull>, + phantom: PhantomData>, + alloc: A, + } +} +#[cfg(not(host))] +use prelude::*; + macro_rules! assert_abi_compatible { ($name:ident, $t1:ty, $t2:ty) => { mod $name { @@ -26,8 +184,13 @@ macro_rules! assert_abi_compatible { }; } -#[derive(Copy, Clone)] struct Zst; +impl Copy for Zst {} +impl Clone for Zst { + fn clone(&self) -> Self { + Zst + } +} #[repr(C)] struct ReprC1(T); @@ -85,8 +248,8 @@ test_abi_compatible!(nonzero_int, NonZeroI32, i32); // `DispatchFromDyn` relies on ABI compatibility. // This is interesting since these types are not `repr(transparent)`. -test_abi_compatible!(rc, std::rc::Rc, *mut i32); -test_abi_compatible!(arc, std::sync::Arc, *mut i32); +test_abi_compatible!(rc, Rc, *mut i32); +test_abi_compatible!(arc, Arc, *mut i32); // `repr(transparent)` compatibility. #[repr(transparent)] @@ -160,7 +323,7 @@ mod unsized_ { use super::*; test_transparent_unsized!(str_, str); test_transparent_unsized!(slice, [u8]); - test_transparent_unsized!(dyn_trait, dyn std::any::Any); + test_transparent_unsized!(dyn_trait, dyn Any); } // RFC 3391 . @@ -185,7 +348,7 @@ test_nonnull!(ref_unsized, &[i32]); test_nonnull!(mut_unsized, &mut [i32]); test_nonnull!(fn_, fn()); test_nonnull!(nonnull, NonNull); -test_nonnull!(nonnull_unsized, NonNull); +test_nonnull!(nonnull_unsized, NonNull); test_nonnull!(non_zero, NonZeroI32); fn main() {} From 3e8676c327086e4761674060793dcfd2f03d0c48 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Mon, 18 Sep 2023 18:34:44 +0200 Subject: [PATCH 024/103] isqrt: initial implementation --- library/core/src/num/int_macros.rs | 80 +++++++++++++++++++++++++++++ library/core/src/num/uint_macros.rs | 35 +++++++++++++ 2 files changed, 115 insertions(+) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 1f43520e1b30a..66bd800135342 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -898,6 +898,45 @@ macro_rules! int_impl { acc.checked_mul(base) } + /// Returns the square root of the number, rounded down. + /// + /// Returns `None` if `self` is negative. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] + /// ``` + #[stable(feature = "isqrt", since = "1.73.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn checked_isqrt(self) -> Option { + if self < 0 { + return None; + } else if self < 2 { + return Some(self); + } + + let mut x: Self = self; + let mut c: Self = 0; + let mut d: Self = 1 << (self.ilog2() & !1); + + while (d != 0) { + if x >= c + d { + x -= c + d; + c = (c >> 1) + d; + } else { + c >>= 1; + } + d >>= 2; + } + + return Some(c); + } + /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric /// bounds instead of overflowing. /// @@ -2061,6 +2100,47 @@ macro_rules! int_impl { acc * base } + /// Returns the square root of the number, rounded down. + /// + /// # Panics + /// + /// This function will panic if `self` is negative. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] + /// ``` + #[stable(feature = "isqrt", since = "1.73.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn isqrt(self) -> Self { + if self < 0 { + panic!("argument of integer square root must be non-negative") + } else if self < 2 { + return self; + } + + let mut x: Self = self; + let mut c: Self = 0; + let mut d: Self = 1 << (self.ilog2() & !1); + + while (d != 0) { + if x >= c + d { + x -= c + d; + c = (c >> 1) + d; + } else { + c >>= 1; + } + d >>= 2; + } + + return c; + } + /// Calculates the quotient of Euclidean division of `self` by `rhs`. /// /// This computes the integer `q` such that `self = q * rhs + r`, with diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 23ca37817d4fd..4c093ab822076 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1979,6 +1979,41 @@ macro_rules! uint_impl { acc * base } + /// Returns the square root of the number, rounded down. + /// + /// # Examples + /// + /// Basic usage: + /// ``` + #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] + /// ``` + #[stable(feature = "isqrt", since = "1.73.0")] + #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const fn isqrt(self) -> Self { + if self < 2 { + return self; + } + + let mut x: Self = self; + let mut c: Self = 0; + let mut d: Self = 1 << (self.ilog2() & !1); + + while (d != 0) { + if x >= c + d { + x -= c + d; + c = (c >> 1) + d; + } else { + c >>= 1; + } + d >>= 2; + } + + return c; + } + /// Performs Euclidean division. /// /// Since, for the positive integers, all common From 1b34f1c6b2b407c286f0e0bac084114c7475c61e Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Mon, 18 Sep 2023 19:27:26 +0200 Subject: [PATCH 025/103] isqrt: add tests --- library/core/tests/num/int_macros.rs | 11 +++++++++++ library/core/tests/num/uint_macros.rs | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index 439bbe6699781..a9ce843386433 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -290,6 +290,17 @@ macro_rules! int_module { assert_eq!(r.saturating_pow(0), 1 as $T); } + #[test] + fn test_isqrt() { + assert_eq!($T::MIN.checked_isqrt(), None); + assert_eq!((-1 as $T).checked_isqrt(), None); + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + } + #[test] fn test_div_floor() { let a: $T = 8; diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 7d6203db0b940..9a8421c7b95c8 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -206,6 +206,16 @@ macro_rules! uint_module { assert_eq!(r.saturating_pow(2), MAX); } + #[test] + fn test_isqrt() { + assert_eq!((0 as $T).isqrt(), 0 as $T); + assert_eq!((1 as $T).isqrt(), 1 as $T); + assert_eq!((2 as $T).isqrt(), 1 as $T); + assert_eq!((99 as $T).isqrt(), 9 as $T); + assert_eq!((100 as $T).isqrt(), 10 as $T); + assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); + } + #[test] fn test_div_floor() { assert_eq!((8 as $T).div_floor(3), 2); From bdd66b3f98e8c3907aad82f16726f0a233ea4ba8 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sat, 23 Sep 2023 17:08:43 +0300 Subject: [PATCH 026/103] allow LTO on `proc-macro` crates with `-Zdylib-lto` Signed-off-by: onur-ozkan --- compiler/rustc_codegen_llvm/messages.ftl | 2 ++ compiler/rustc_codegen_llvm/src/back/lto.rs | 15 ++++++++++++--- compiler/rustc_codegen_llvm/src/errors.rs | 4 ++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index ddaff36f24b1d..c0cfe39f1e0a4 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -37,6 +37,8 @@ codegen_llvm_lto_disallowed = lto can only be run for executables, cdylibs and s codegen_llvm_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto` +codegen_llvm_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto` + codegen_llvm_missing_features = add the missing features in a `target_feature` attribute diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index ba263296bb454..cb5acf79135cc 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -2,7 +2,7 @@ use crate::back::write::{ self, bitcode_section_name, save_temp_bitcode, CodegenDiagnosticsStage, DiagnosticHandlers, }; use crate::errors::{ - DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, + DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, LtoProcMacro, }; use crate::llvm::{self, build_string}; use crate::{LlvmCodegenBackend, ModuleLlvm}; @@ -36,8 +36,12 @@ pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; pub fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { - CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true, - CrateType::Rlib | CrateType::ProcMacro => false, + CrateType::Executable + | CrateType::Dylib + | CrateType::Staticlib + | CrateType::Cdylib + | CrateType::ProcMacro => true, + CrateType::Rlib => false, } } @@ -87,6 +91,11 @@ fn prepare_lto( diag_handler.emit_err(LtoDylib); return Err(FatalError); } + } else if *crate_type == CrateType::ProcMacro { + if !cgcx.opts.unstable_opts.dylib_lto { + diag_handler.emit_err(LtoProcMacro); + return Err(FatalError); + } } } diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 264c273ba3072..665d195790c2d 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -138,6 +138,10 @@ pub(crate) struct LtoDisallowed; #[diag(codegen_llvm_lto_dylib)] pub(crate) struct LtoDylib; +#[derive(Diagnostic)] +#[diag(codegen_llvm_lto_proc_macro)] +pub(crate) struct LtoProcMacro; + #[derive(Diagnostic)] #[diag(codegen_llvm_lto_bitcode_from_rlib)] pub(crate) struct LtoBitcodeFromRlib { From 350ead872058a8be5fc45d27dad59f3bd7e00b6f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Mon, 25 Sep 2023 01:55:12 +0300 Subject: [PATCH 027/103] add sanity checks for user write access on `x install` Signed-off-by: onur-ozkan --- src/bootstrap/install.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index b62aa9992469b..85cd8abb99550 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -45,6 +45,23 @@ fn sanitize_sh(path: &Path) -> String { } } +fn is_dir_writable_for_user(dir: &PathBuf) -> bool { + let tmp_file = dir.join(".tmp"); + match fs::File::create(&tmp_file) { + Ok(_) => { + fs::remove_file(tmp_file).unwrap(); + true + } + Err(e) => { + if e.kind() == std::io::ErrorKind::PermissionDenied { + false + } else { + panic!("Failed the write access check for the current user. {}", e); + } + } + } +} + fn install_sh( builder: &Builder<'_>, package: &str, @@ -56,6 +73,17 @@ fn install_sh( let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); + + // Sanity check for the user write access on prefix and sysconfdir + assert!( + is_dir_writable_for_user(&prefix), + "User doesn't have write access on `install.prefix` path in the `config.toml`.", + ); + assert!( + is_dir_writable_for_user(&sysconfdir), + "User doesn't have write access on `install.sysconfdir` path in `config.toml`." + ); + let datadir = prefix.join(default_path(&builder.config.datadir, "share")); let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust")); let mandir = prefix.join(default_path(&builder.config.mandir, "share/man")); @@ -92,6 +120,9 @@ fn prepare_dir(mut path: PathBuf) -> String { // More information on the environment variable is available here: // https://www.gnu.org/prep/standards/html_node/DESTDIR.html if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) { + // Sanity check for the user write access on DESTDIR + assert!(is_dir_writable_for_user(&destdir), "User doesn't have write access on DESTDIR."); + let without_destdir = path.clone(); path = destdir; // Custom .join() which ignores disk roots. From 598f11a1eebbb35f47907519dd59bd7a3d6c2e9e Mon Sep 17 00:00:00 2001 From: Pouriya Jahanbakhsh Date: Mon, 25 Sep 2023 06:57:13 +0330 Subject: [PATCH 028/103] ref(bootstrap.py): add `eprint` function just like `print` but for `stderr` --- src/bootstrap/bootstrap.py | 90 +++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d58f0d54d3aec..fac0cdf203846 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -41,6 +41,10 @@ def get_cpus(): return 1 +def eprint(*args, **kwargs): + kwargs["file"] = sys.stderr + print(*args, **kwargs) + def get(base, url, path, checksums, verbose=False): with tempfile.NamedTemporaryFile(delete=False) as temp_file: @@ -57,23 +61,23 @@ def get(base, url, path, checksums, verbose=False): if os.path.exists(path): if verify(path, sha256, False): if verbose: - print("using already-download file", path, file=sys.stderr) + eprint("using already-download file", path) return else: if verbose: - print("ignoring already-download file", - path, "due to failed verification", file=sys.stderr) + eprint("ignoring already-download file", + path, "due to failed verification") os.unlink(path) download(temp_path, "{}/{}".format(base, url), True, verbose) if not verify(temp_path, sha256, verbose): raise RuntimeError("failed verification") if verbose: - print("moving {} to {}".format(temp_path, path), file=sys.stderr) + eprint("moving {} to {}".format(temp_path, path)) shutil.move(temp_path, path) finally: if os.path.isfile(temp_path): if verbose: - print("removing", temp_path, file=sys.stderr) + eprint("removing", temp_path) os.unlink(temp_path) @@ -83,7 +87,7 @@ def download(path, url, probably_big, verbose): _download(path, url, probably_big, verbose, True) return except RuntimeError: - print("\nspurious failure, trying again", file=sys.stderr) + eprint("\nspurious failure, trying again") _download(path, url, probably_big, verbose, False) @@ -94,7 +98,7 @@ def _download(path, url, probably_big, verbose, exception): # - If we are on win32 fallback to powershell # - Otherwise raise the error if appropriate if probably_big or verbose: - print("downloading {}".format(url), file=sys.stderr) + eprint("downloading {}".format(url)) try: if (probably_big or verbose) and "GITHUB_ACTIONS" not in os.environ: @@ -129,20 +133,20 @@ def _download(path, url, probably_big, verbose, exception): def verify(path, expected, verbose): """Check if the sha256 sum of the given path is valid""" if verbose: - print("verifying", path, file=sys.stderr) + eprint("verifying", path) with open(path, "rb") as source: found = hashlib.sha256(source.read()).hexdigest() verified = found == expected if not verified: - print("invalid checksum:\n" + eprint("invalid checksum:\n" " found: {}\n" - " expected: {}".format(found, expected), file=sys.stderr) + " expected: {}".format(found, expected)) return verified def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): """Unpack the given tarball file""" - print("extracting", tarball, file=sys.stderr) + eprint("extracting", tarball) fname = os.path.basename(tarball).replace(tarball_suffix, "") with contextlib.closing(tarfile.open(tarball)) as tar: for member in tar.getnames(): @@ -155,7 +159,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): dst_path = os.path.join(dst, name) if verbose: - print(" extracting", member, file=sys.stderr) + eprint(" extracting", member) tar.extract(member, dst) src_path = os.path.join(dst, member) if os.path.isdir(src_path) and os.path.exists(dst_path): @@ -167,7 +171,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None): def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs): """Run a child program in a new process""" if verbose: - print("running: " + ' '.join(args), file=sys.stderr) + eprint("running: " + ' '.join(args)) sys.stdout.flush() # Ensure that the .exe is used on Windows just in case a Linux ELF has been # compiled in the same directory. @@ -207,8 +211,8 @@ def require(cmd, exit=True, exception=False): if exception: raise elif exit: - print("error: unable to run `{}`: {}".format(' '.join(cmd), exc), file=sys.stderr) - print("Please make sure it's installed and in the path.", file=sys.stderr) + eprint("error: unable to run `{}`: {}".format(' '.join(cmd), exc)) + eprint("Please make sure it's installed and in the path.") sys.exit(1) return None @@ -239,14 +243,12 @@ def default_build_triple(verbose): host = next(x for x in version.split('\n') if x.startswith("host: ")) triple = host.split("host: ")[1] if verbose: - print("detected default triple {} from pre-installed rustc".format(triple), - file=sys.stderr) + eprint("detected default triple {} from pre-installed rustc".format(triple)) return triple except Exception as e: if verbose: - print("pre-installed rustc not detected: {}".format(e), - file=sys.stderr) - print("falling back to auto-detect", file=sys.stderr) + eprint("pre-installed rustc not detected: {}".format(e)) + eprint("falling back to auto-detect") required = not platform_is_win32() uname = require(["uname", "-smp"], exit=required) @@ -672,15 +674,14 @@ def get_answer(): if not is_nixos: in_nix_shell = os.getenv('IN_NIX_SHELL') if in_nix_shell: - print("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell), - "you may need to set `patch-binaries-for-nix=true` in config.toml", - file=sys.stderr) + eprint("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell), + "you may need to set `patch-binaries-for-nix=true` in config.toml") return is_nixos answer = self._should_fix_bins_and_dylibs = get_answer() if answer: - print("info: You seem to be using Nix.", file=sys.stderr) + eprint("info: You seem to be using Nix.") return answer def fix_bin_or_dylib(self, fname): @@ -693,7 +694,7 @@ def fix_bin_or_dylib(self, fname): Please see https://nixos.org/patchelf.html for more information """ assert self._should_fix_bins_and_dylibs is True - print("attempting to patch", fname, file=sys.stderr) + eprint("attempting to patch", fname) # Only build `.nix-deps` once. nix_deps_dir = self.nix_deps_dir @@ -726,7 +727,7 @@ def fix_bin_or_dylib(self, fname): "nix-build", "-E", nix_expr, "-o", nix_deps_dir, ]) except subprocess.CalledProcessError as reason: - print("warning: failed to call nix-build:", reason, file=sys.stderr) + eprint("warning: failed to call nix-build:", reason) return self.nix_deps_dir = nix_deps_dir @@ -746,7 +747,7 @@ def fix_bin_or_dylib(self, fname): try: subprocess.check_output([patchelf] + patchelf_args + [fname]) except subprocess.CalledProcessError as reason: - print("warning: failed to call patchelf:", reason, file=sys.stderr) + eprint("warning: failed to call patchelf:", reason) return def rustc_stamp(self): @@ -888,7 +889,7 @@ def build_bootstrap(self): if "GITHUB_ACTIONS" in env: print("::group::Building bootstrap") else: - print("Building bootstrap", file=sys.stderr) + eprint("Building bootstrap") args = self.build_bootstrap_cmd(env) # Run this from the source directory so cargo finds .cargo/config @@ -997,12 +998,9 @@ def check_vendored_status(self): if 'SUDO_USER' in os.environ and not self.use_vendored_sources: if os.getuid() == 0: self.use_vendored_sources = True - print('info: looks like you\'re trying to run this command as root', - file=sys.stderr) - print(' and so in order to preserve your $HOME this will now', - file=sys.stderr) - print(' use vendored sources by default.', - file=sys.stderr) + eprint('info: looks like you\'re trying to run this command as root') + eprint(' and so in order to preserve your $HOME this will now') + eprint(' use vendored sources by default.') cargo_dir = os.path.join(self.rust_root, '.cargo') if self.use_vendored_sources: @@ -1012,18 +1010,14 @@ def check_vendored_status(self): "--sync ./src/tools/rust-analyzer/Cargo.toml " \ "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \ "--sync ./src/bootstrap/Cargo.toml " - print('error: vendoring required, but vendor directory does not exist.', - file=sys.stderr) - print(' Run `cargo vendor {}` to initialize the ' - 'vendor directory.'.format(sync_dirs), - file=sys.stderr) - print('Alternatively, use the pre-vendored `rustc-src` dist component.', - file=sys.stderr) + eprint('error: vendoring required, but vendor directory does not exist.') + eprint(' Run `cargo vendor {}` to initialize the ' + 'vendor directory.'.format(sync_dirs)) + eprint('Alternatively, use the pre-vendored `rustc-src` dist component.') raise Exception("{} not found".format(vendor_dir)) if not os.path.exists(cargo_dir): - print('error: vendoring required, but .cargo/config does not exist.', - file=sys.stderr) + eprint('error: vendoring required, but .cargo/config does not exist.') raise Exception("{} not found".format(cargo_dir)) else: if os.path.exists(cargo_dir): @@ -1117,10 +1111,9 @@ def main(): # If the user is asking for help, let them know that the whole download-and-build # process has to happen before anything is printed out. if help_triggered: - print( + eprint( "info: Downloading and building bootstrap before processing --help command.\n" - " See src/bootstrap/README.md for help with common commands." - , file=sys.stderr) + " See src/bootstrap/README.md for help with common commands.") exit_code = 0 success_word = "successfully" @@ -1131,12 +1124,11 @@ def main(): exit_code = error.code else: exit_code = 1 - print(error, file=sys.stderr) + eprint(error) success_word = "unsuccessfully" if not help_triggered: - print("Build completed", success_word, "in", format_build_time(time() - start_time), - file=sys.stderr) + eprint("Build completed", success_word, "in", format_build_time(time() - start_time)) sys.exit(exit_code) From 81bca5f5cf2741c6f23c4e116ad3d38088701681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 04:45:17 +0000 Subject: [PATCH 029/103] When suggesting `self.x` for `S { x }`, use `S { x: self.x }` Tweak output. Fix #115992. --- compiler/rustc_resolve/src/late.rs | 20 +++- .../rustc_resolve/src/late/diagnostics.rs | 76 +++++++++++--- .../resolve/associated-fn-called-as-fn.stderr | 14 ++- ...ethod-in-self-not-available-in-assoc-fn.rs | 3 + ...d-in-self-not-available-in-assoc-fn.stderr | 16 ++- tests/ui/resolve/issue-14254.stderr | 98 +++++++++++++++---- tests/ui/resolve/issue-2356.stderr | 28 +++++- tests/ui/resolve/issue-60057.stderr | 7 +- .../resolve/resolve-assoc-suggestions.stderr | 21 +++- .../resolve-speculative-adjustment.stderr | 14 ++- ...e-with-name-similar-to-struct-field.stderr | 10 +- tests/ui/self/class-missing-self.stderr | 7 +- .../assoc-type-in-method-return.stderr | 7 +- 13 files changed, 267 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 01f9f06059426..f8c00a72b3e22 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4140,6 +4140,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { }); } + fn resolve_expr_field(&mut self, f: &'ast ExprField, e: &'ast Expr) { + self.resolve_expr(&f.expr, Some(e)); + self.visit_ident(f.ident); + walk_list!(self, visit_attribute, f.attrs.iter()); + } + fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -4155,7 +4161,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { ExprKind::Struct(ref se) => { self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct); - visit::walk_expr(self, expr); + // This is the same as `visit::walk_expr(self, expr);`, but we want to pass the + // parent in for accurate suggestions when encountering `Foo { bar }` that should + // have been `Foo { bar: self.bar }`. + if let Some(qself) = &se.qself { + self.visit_ty(&qself.ty); + } + self.visit_path(&se.path, expr.id); + walk_list!(self, resolve_expr_field, &se.fields, expr); + match &se.rest { + StructRest::Base(expr) => self.visit_expr(expr), + StructRest::Rest(_span) => {} + StructRest::None => {} + } } ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 06a08f29a1ee8..3ff022b0e21b6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -215,7 +215,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } } else { let mut span_label = None; - let item_span = path.last().unwrap().ident.span; + let item_ident = path.last().unwrap().ident; + let item_span = item_ident.span; let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 { debug!(?self.diagnostic_metadata.current_impl_items); debug!(?self.diagnostic_metadata.current_function); @@ -231,9 +232,35 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }) { let sp = item_span.shrink_to_lo(); + + // Account for `Foo { field }` when suggesting `self.field` so we result on + // `Foo { field: self.field }`. + let field = match source { + PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. })) => { + expr.fields.iter().find(|f| f.ident == item_ident) + } + _ => None, + }; + let pre = if let Some(field) = field && field.is_shorthand { + format!("{item_ident}: ") + } else { + String::new() + }; + // Ensure we provide a structured suggestion for an assoc fn only for + // expressions that are actually a fn call. + let is_call = match field { + Some(ast::ExprField { expr, .. }) => { + matches!(expr.kind, ExprKind::Call(..)) + } + _ => matches!( + source, + PathSource::Expr(Some(Expr { kind: ExprKind::Call(..), ..})), + ), + }; + match &item.kind { AssocItemKind::Fn(fn_) - if !sig.decl.has_self() && fn_.sig.decl.has_self() => { + if (!sig.decl.has_self() || !is_call) && fn_.sig.decl.has_self() => { // Ensure that we only suggest `self.` if `self` is available, // you can't call `fn foo(&self)` from `fn bar()` (#115992). // We also want to mention that the method exists. @@ -243,20 +270,28 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { )); None } + AssocItemKind::Fn(fn_) + if !fn_.sig.decl.has_self() && !is_call => { + span_label = Some(( + item.ident.span, + "an associated function by that name is available on `Self` here", + )); + None + } AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some(( sp, "consider using the method on `Self`", - "self.".to_string(), + format!("{pre}self."), )), AssocItemKind::Fn(_) => Some(( sp, "consider using the associated function on `Self`", - "Self::".to_string(), + format!("{pre}Self::"), )), AssocItemKind::Const(..) => Some(( sp, "consider using the associated constant on `Self`", - "Self::".to_string(), + format!("{pre}Self::"), )), _ => None } @@ -621,13 +656,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { self.lookup_assoc_candidate(ident, ns, is_expected, source.is_call()) { let self_is_available = self.self_value_is_available(path[0].ident.span); + // Account for `Foo { field }` when suggesting `self.field` so we result on + // `Foo { field: self.field }`. + let pre = match source { + PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. })) + if expr + .fields + .iter() + .any(|f| f.ident == path[0].ident && f.is_shorthand) => + { + format!("{path_str}: ") + } + _ => String::new(), + }; match candidate { AssocSuggestion::Field => { if self_is_available { - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), "you might have meant to use the available field", - format!("self.{path_str}"), + format!("{pre}self."), Applicability::MachineApplicable, ); } else { @@ -640,10 +688,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } else { "you might have meant to refer to the method" }; - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), msg, - format!("self.{path_str}"), + "self.".to_string(), Applicability::MachineApplicable, ); } @@ -651,10 +699,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { | AssocSuggestion::AssocFn { .. } | AssocSuggestion::AssocConst | AssocSuggestion::AssocType => { - err.span_suggestion( - span, + err.span_suggestion_verbose( + span.shrink_to_lo(), format!("you might have meant to {}", candidate.action()), - format!("Self::{path_str}"), + "Self::".to_string(), Applicability::MachineApplicable, ); } diff --git a/tests/ui/resolve/associated-fn-called-as-fn.stderr b/tests/ui/resolve/associated-fn-called-as-fn.stderr index fbdea30d551fd..7d28b959a1a48 100644 --- a/tests/ui/resolve/associated-fn-called-as-fn.stderr +++ b/tests/ui/resolve/associated-fn-called-as-fn.stderr @@ -2,13 +2,23 @@ error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:6:30 | LL | '0'..='9' => collect_primary(&c), - | ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary` + | ^^^^^^^^^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | '0'..='9' => Self::collect_primary(&c), + | ++++++ error[E0425]: cannot find function `collect_primary` in this scope --> $DIR/associated-fn-called-as-fn.rs:23:30 | LL | '0'..='9' => collect_primary(&c), - | ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary` + | ^^^^^^^^^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | '0'..='9' => Self::collect_primary(&c), + | ++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs index 9e72c36151e5d..b5f13959081b8 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs @@ -11,5 +11,8 @@ impl Foo { field; //~ ERROR cannot find value `field` in this scope Foo { field } //~ ERROR cannot find value `field` in this scope } + fn clone(&self) -> Foo { + Foo { field } //~ ERROR cannot find value `field` in this scope + } } fn main() {} diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 2eb3861e5f11b..4ced51c6f944c 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -16,6 +16,20 @@ LL | fn field(&self) -> u32 { LL | Foo { field } | ^^^^^ a field by this name exists in `Self` -error: aborting due to 2 previous errors +error[E0425]: cannot find value `field` in this scope + --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 + | +LL | fn field(&self) -> u32 { + | ----- a method by that name is available on `Self` here +... +LL | Foo { field } + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | Foo { field: self.field } + | ++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/issue-14254.stderr b/tests/ui/resolve/issue-14254.stderr index 690a40f7edd77..9284b4babc50f 100644 --- a/tests/ui/resolve/issue-14254.stderr +++ b/tests/ui/resolve/issue-14254.stderr @@ -8,13 +8,23 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:30:9 | LL | x; - | ^ help: you might have meant to use the available field: `self.x` + | ^ + | +help: you might have meant to use the available field + | +LL | self.x; + | +++++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:32:9 | LL | y; - | ^ help: you might have meant to use the available field: `self.y` + | ^ + | +help: you might have meant to use the available field + | +LL | self.y; + | +++++ error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:34:9 @@ -31,7 +41,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:38:9 @@ -43,13 +53,23 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/issue-14254.rs:47:9 | LL | x; - | ^ help: you might have meant to use the available field: `self.x` + | ^ + | +help: you might have meant to use the available field + | +LL | self.x; + | +++++ error[E0425]: cannot find value `y` in this scope --> $DIR/issue-14254.rs:49:9 | LL | y; - | ^ help: you might have meant to use the available field: `self.y` + | ^ + | +help: you might have meant to use the available field + | +LL | self.y; + | +++++ error[E0425]: cannot find value `a` in this scope --> $DIR/issue-14254.rs:51:9 @@ -66,7 +86,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `b` in this scope --> $DIR/issue-14254.rs:55:9 @@ -83,7 +103,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:73:9 @@ -94,7 +114,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:82:9 @@ -105,7 +125,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:91:9 @@ -116,7 +136,7 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find value `bah` in this scope --> $DIR/issue-14254.rs:100:9 @@ -127,55 +147,95 @@ LL | bah; help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:19:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:28:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:45:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:62:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:71:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:80:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:89:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error[E0425]: cannot find function `baz` in this scope --> $DIR/issue-14254.rs:98:9 | LL | baz(); - | ^^^ help: you might have meant to call the method: `self.baz` + | ^^^ + | +help: you might have meant to call the method + | +LL | self.baz(); + | +++++ error: aborting due to 24 previous errors diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 273e8b2a661fb..191754c5dc4dc 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -21,7 +21,12 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:79:5 | LL | whiskers = 0; - | ^^^^^^^^ help: you might have meant to use the available field: `self.whiskers` + | ^^^^^^^^ + | +help: you might have meant to use the available field + | +LL | self.whiskers = 0; + | +++++ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 @@ -47,19 +52,34 @@ error[E0425]: cannot find function `clone` in this scope --> $DIR/issue-2356.rs:24:5 | LL | clone(); - | ^^^^^ help: you might have meant to call the method: `self.clone` + | ^^^^^ + | +help: you might have meant to call the method + | +LL | self.clone(); + | +++++ error[E0425]: cannot find function `default` in this scope --> $DIR/issue-2356.rs:31:5 | LL | default(); - | ^^^^^^^ help: you might have meant to call the associated function: `Self::default` + | ^^^^^^^ + | +help: you might have meant to call the associated function + | +LL | Self::default(); + | ++++++ error[E0425]: cannot find function `shave` in this scope --> $DIR/issue-2356.rs:41:5 | LL | shave(4); - | ^^^^^ help: you might have meant to call the associated function: `Self::shave` + | ^^^^^ + | +help: you might have meant to call the associated function + | +LL | Self::shave(4); + | ++++++ error[E0425]: cannot find function `purr` in this scope --> $DIR/issue-2356.rs:43:5 diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index 4d915fcd9fe3d..88117ec96d21d 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -8,7 +8,12 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:14:21 | LL | banana: banana - | ^^^^^^ help: you might have meant to use the available field: `self.banana` + | ^^^^^^ + | +help: you might have meant to use the available field + | +LL | banana: self.banana + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index 8def9aa20253b..3d9d4ffaa10c8 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -14,13 +14,23 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-assoc-suggestions.rs:20:9 | LL | field; - | ^^^^^ help: you might have meant to use the available field: `self.field` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.field; + | +++++ error[E0412]: cannot find type `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:23:16 | LL | let _: Type; - | ^^^^ help: you might have meant to use the associated type: `Self::Type` + | ^^^^ + | +help: you might have meant to use the associated type + | +LL | let _: Self::Type; + | ++++++ error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:25:13 @@ -50,7 +60,12 @@ error[E0425]: cannot find value `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:34:9 | LL | method; - | ^^^^^^ help: you might have meant to refer to the method: `self.method` + | ^^^^^^ + | +help: you might have meant to refer to the method + | +LL | self.method; + | +++++ error: aborting due to 9 previous errors diff --git a/tests/ui/resolve/resolve-speculative-adjustment.stderr b/tests/ui/resolve/resolve-speculative-adjustment.stderr index be11a7ebeca00..fb15472bdae8d 100644 --- a/tests/ui/resolve/resolve-speculative-adjustment.stderr +++ b/tests/ui/resolve/resolve-speculative-adjustment.stderr @@ -8,13 +8,23 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/resolve-speculative-adjustment.rs:23:9 | LL | field; - | ^^^^^ help: you might have meant to use the available field: `self.field` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.field; + | +++++ error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:25:9 | LL | method(); - | ^^^^^^ help: you might have meant to call the method: `self.method` + | ^^^^^^ + | +help: you might have meant to call the method + | +LL | self.method(); + | +++++ error[E0425]: cannot find function `method` in this scope --> $DIR/resolve-speculative-adjustment.rs:19:13 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index f32e0404e46cb..a77675a1b038b 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -25,7 +25,7 @@ LL | println!("{config}"); help: you might have meant to use the available field | LL | println!("{self.config}"); - | ~~~~~~~~~~~ + | +++++ help: a local variable with a similar name exists | LL | println!("{cofig}"); @@ -43,7 +43,7 @@ LL | fn ba() {} help: you might have meant to refer to the associated function | LL | Self::bah; - | ~~~~~~~~~ + | ++++++ help: a function with a similar name exists | LL | ba; @@ -61,7 +61,7 @@ LL | const BARR: u32 = 3; help: you might have meant to use the associated `const` | LL | Self::BAR; - | ~~~~~~~~~ + | ++++++ help: a constant with a similar name exists | LL | BARR; @@ -79,7 +79,7 @@ LL | type Bar = String; help: you might have meant to use the associated type | LL | let foo: Self::Baz = "".to_string(); - | ~~~~~~~~~ + | ++++++ help: a type alias with a similar name exists | LL | let foo: Bar = "".to_string(); @@ -97,7 +97,7 @@ LL | fn ba() {} help: you might have meant to call the method | LL | self.baz(); - | ~~~~~~~~ + | +++++ help: a function with a similar name exists | LL | ba(); diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr index 08493b4f9a2da..ca7a896200fc3 100644 --- a/tests/ui/self/class-missing-self.stderr +++ b/tests/ui/self/class-missing-self.stderr @@ -2,7 +2,12 @@ error[E0425]: cannot find value `meows` in this scope --> $DIR/class-missing-self.rs:9:7 | LL | meows += 1; - | ^^^^^ help: you might have meant to use the available field: `self.meows` + | ^^^^^ + | +help: you might have meant to use the available field + | +LL | self.meows += 1; + | +++++ error[E0425]: cannot find function `sleep` in this scope --> $DIR/class-missing-self.rs:10:7 diff --git a/tests/ui/suggestions/assoc-type-in-method-return.stderr b/tests/ui/suggestions/assoc-type-in-method-return.stderr index 202e4a16eada7..df3828ad411e1 100644 --- a/tests/ui/suggestions/assoc-type-in-method-return.stderr +++ b/tests/ui/suggestions/assoc-type-in-method-return.stderr @@ -2,7 +2,12 @@ error[E0412]: cannot find type `Bla` in this scope --> $DIR/assoc-type-in-method-return.rs:3:25 | LL | fn to_bla(&self) -> Bla; - | ^^^ help: you might have meant to use the associated type: `Self::Bla` + | ^^^ + | +help: you might have meant to use the associated type + | +LL | fn to_bla(&self) -> Self::Bla; + | ++++++ error: aborting due to previous error From d00c7e78ea9e887e7e7d04dbe6c233444f4e6295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 17:23:16 +0000 Subject: [PATCH 030/103] Point at field definition when unresolved name exists in `Self` --- compiler/rustc_resolve/src/late/diagnostics.rs | 14 +++++++------- ...thod-in-self-not-available-in-assoc-fn.stderr | 10 ++++++++-- tests/ui/resolve/issue-2356.stderr | 10 ++++++++-- tests/ui/resolve/issue-60057.stderr | 5 ++++- ...able-with-name-similar-to-struct-field.stderr | 16 ++++++++-------- .../resolve/unresolved_static_type_field.stderr | 5 ++++- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3ff022b0e21b6..4ac5d6d19aa7d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -41,7 +41,7 @@ type Res = def::Res; /// A field or associated item from self type suggested in case of resolution failure. enum AssocSuggestion { - Field, + Field(Span), MethodWithSelf { called: bool }, AssocFn { called: bool }, AssocType, @@ -51,7 +51,7 @@ enum AssocSuggestion { impl AssocSuggestion { fn action(&self) -> &'static str { match self { - AssocSuggestion::Field => "use the available field", + AssocSuggestion::Field(_) => "use the available field", AssocSuggestion::MethodWithSelf { called: true } => { "call the method with the fully-qualified path" } @@ -670,7 +670,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { _ => String::new(), }; match candidate { - AssocSuggestion::Field => { + AssocSuggestion::Field(field_span) => { if self_is_available { err.span_suggestion_verbose( span.shrink_to_lo(), @@ -679,7 +679,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { Applicability::MachineApplicable, ); } else { - err.span_label(span, "a field by this name exists in `Self`"); + err.span_label(field_span, "a field by that name exists in `Self`"); } } AssocSuggestion::MethodWithSelf { called } if self_is_available => { @@ -1715,11 +1715,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { resolution.full_res() { if let Some(field_ids) = self.r.field_def_ids(did) { - if field_ids + if let Some(field_id) = field_ids .iter() - .any(|&field_id| ident.name == self.r.tcx.item_name(field_id)) + .find(|&&field_id| ident.name == self.r.tcx.item_name(field_id)) { - return Some(AssocSuggestion::Field); + return Some(AssocSuggestion::Field(self.r.def_span(*field_id))); } } } diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 4ced51c6f944c..3c44c1c249ce2 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -1,20 +1,26 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | field; - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | Foo { field } - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 191754c5dc4dc..5f75ae988702f 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers -= other; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:65:8 @@ -31,8 +34,11 @@ LL | self.whiskers = 0; error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers = 4; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:92:5 diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index 88117ec96d21d..a2ab86443536c 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | +LL | banana: u8, + | ---------- a field by that name exists in `Self` +... LL | banana: banana - | ^^^^^^ a field by this name exists in `Self` + | ^^^^^^ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:14:21 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index a77675a1b038b..0306c8af87d85 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -1,20 +1,20 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | Self { config } - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | println!("{config}"); - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index 06926b53ddd35..035dc9b9656ad 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | +LL | cx: bool, + | -------- a field by that name exists in `Self` +... LL | f(cx); - | ^^ a field by this name exists in `Self` + | ^^ error: aborting due to previous error From d185e0d899272030fd137f7adcf269e60c14901e Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Tue, 29 Aug 2023 22:17:06 +0800 Subject: [PATCH 031/103] Promote loongarch64-unknown-none* to Tier 2 MCP: https://github.com/rust-lang/compiler-team/issues/664 --- src/ci/docker/host-x86_64/dist-various-2/Dockerfile | 2 ++ src/doc/rustc/src/platform-support.md | 4 ++-- src/doc/rustc/src/platform-support/loongarch-none.md | 2 +- src/tools/build-manifest/src/main.rs | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 670e37b9d01a7..01b46118b9c1e 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -128,6 +128,8 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none +ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 5701b002f2185..ff831a2050480 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -157,6 +157,8 @@ target | std | notes `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD `i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI +[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) +[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) `mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL @@ -274,8 +276,6 @@ target | std | host | notes `i686-uwp-windows-gnu` | ? | | `i686-uwp-windows-msvc` | ? | | `i686-wrs-vxworks` | ? | | -[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) -[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md index d0ae3425fa8eb..68d7c9d85e444 100644 --- a/src/doc/rustc/src/platform-support/loongarch-none.md +++ b/src/doc/rustc/src/platform-support/loongarch-none.md @@ -1,6 +1,6 @@ # `loongarch*-unknown-none*` -**Tier: 3** +**Tier: 2** Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 0f7a3c2f952ad..5153dd26f4ad4 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -98,6 +98,8 @@ static TARGETS: &[&str] = &[ "i686-unknown-linux-musl", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-none", + "loongarch64-unknown-none-softfloat", "m68k-unknown-linux-gnu", "csky-unknown-linux-gnuabiv2", "mips-unknown-linux-gnu", From a9030e668867dda6eb153f8b2518491b2c38d1d7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 26 Sep 2023 11:48:36 +0000 Subject: [PATCH 032/103] Add tests for simd_shuffle{_generic} --- src/tools/miri/tests/pass/portable-simd.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs index ee67a65a4f9a2..c1f5618c16346 100644 --- a/src/tools/miri/tests/pass/portable-simd.rs +++ b/src/tools/miri/tests/pass/portable-simd.rs @@ -1,5 +1,6 @@ //@compile-flags: -Zmiri-strict-provenance -#![feature(portable_simd, platform_intrinsics)] +#![feature(portable_simd, platform_intrinsics, adt_const_params, inline_const)] +#![allow(incomplete_features)] use std::simd::*; extern "platform-intrinsic" { @@ -390,6 +391,8 @@ fn simd_intrinsics() { fn simd_reduce_any(x: T) -> bool; fn simd_reduce_all(x: T) -> bool; fn simd_select(m: M, yes: T, no: T) -> T; + fn simd_shuffle_generic(x: T, y: T) -> U; + fn simd_shuffle(x: T, y: T, idx: IDX) -> U; } unsafe { // Make sure simd_eq returns all-1 for `true` @@ -413,6 +416,22 @@ fn simd_intrinsics() { simd_select(i8x4::from_array([0, -1, -1, 0]), b, a), i32x4::from_array([10, 2, 10, 10]) ); + assert_eq!( + simd_shuffle_generic::<_, i32x4, {&[3, 1, 0, 2]}>(a, b), + a, + ); + assert_eq!( + simd_shuffle::<_, _, i32x4>(a, b, const {[3, 1, 0, 2]}), + a, + ); + assert_eq!( + simd_shuffle_generic::<_, i32x4, {&[7, 5, 4, 6]}>(a, b), + i32x4::from_array([4, 2, 1, 10]), + ); + assert_eq!( + simd_shuffle::<_, _, i32x4>(a, b, const {[7, 5, 4, 6]}), + i32x4::from_array([4, 2, 1, 10]), + ); } } From 68f0b475c76de88fb5cb37c8cd0163703354415a Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Tue, 26 Sep 2023 15:44:28 +0200 Subject: [PATCH 033/103] isqrt: remove duplication by delegating to unsigned integers --- library/core/src/num/int_macros.rs | 50 +++++++---------------------- library/core/src/num/uint_macros.rs | 2 +- 2 files changed, 12 insertions(+), 40 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 66bd800135342..8bc82b5fc8898 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -915,26 +915,10 @@ macro_rules! int_impl { #[inline] pub const fn checked_isqrt(self) -> Option { if self < 0 { - return None; - } else if self < 2 { - return Some(self); - } - - let mut x: Self = self; - let mut c: Self = 0; - let mut d: Self = 1 << (self.ilog2() & !1); - - while (d != 0) { - if x >= c + d { - x -= c + d; - c = (c >> 1) + d; - } else { - c >>= 1; - } - d >>= 2; + None + } else { + Some((self as $UnsignedT).isqrt() as Self) } - - return Some(c); } /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric @@ -2118,27 +2102,15 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn isqrt(self) -> Self { - if self < 0 { - panic!("argument of integer square root must be non-negative") - } else if self < 2 { - return self; - } - - let mut x: Self = self; - let mut c: Self = 0; - let mut d: Self = 1 << (self.ilog2() & !1); - - while (d != 0) { - if x >= c + d { - x -= c + d; - c = (c >> 1) + d; - } else { - c >>= 1; - } - d >>= 2; + // I would like to implement it as + // ``` + // self.checked_isqrt().expect("argument of integer square root must be non-negative") + // ``` + // but `expect` is not yet stable as a `const fn`. + match self.checked_isqrt() { + Some(sqrt) => sqrt, + None => panic!("argument of integer square root must be non-negative"), } - - return c; } /// Calculates the quotient of Euclidean division of `self` by `rhs`. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 4c093ab822076..f8005694cebc1 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2011,7 +2011,7 @@ macro_rules! uint_impl { d >>= 2; } - return c; + c } /// Performs Euclidean division. From d49da0fe54251fbee190dc2adcdbffe787aecae7 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Tue, 26 Sep 2023 16:05:51 +0200 Subject: [PATCH 034/103] isqrt: add more tests --- library/core/tests/num/int_macros.rs | 17 +++++++++++++++++ library/core/tests/num/uint_macros.rs | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index a9ce843386433..dd0ea5e9238ce 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -299,6 +299,23 @@ macro_rules! int_module { assert_eq!((2 as $T).isqrt(), 1 as $T); assert_eq!((99 as $T).isqrt(), 9 as $T); assert_eq!((100 as $T).isqrt(), 10 as $T); + + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); + } + + for n in ($T::MAX - 127)..=$T::MAX { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + let (square, overflow) = (isqrt + 1).overflowing_pow(2); + assert!(overflow || square > n); + } } #[test] diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 9a8421c7b95c8..1ae7d04875709 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -214,6 +214,21 @@ macro_rules! uint_module { assert_eq!((99 as $T).isqrt(), 9 as $T); assert_eq!((100 as $T).isqrt(), 10 as $T); assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); + + let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; + for n in 0..=n_max { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); + } + + for n in ($T::MAX - 255)..=$T::MAX { + let isqrt: $T = n.isqrt(); + + assert!(isqrt.pow(2) <= n); + assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n); + } } #[test] From 9b7f9c4328dde77396f815dc929de6cdbc700531 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 26 Sep 2023 16:41:06 +0200 Subject: [PATCH 035/103] take more clarifying text from Gankra's PR original source: https://github.com/rust-lang/rust/pull/95851 --- library/core/src/ptr/const_ptr.rs | 7 +++++++ library/core/src/ptr/mut_ptr.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 3e68216e40eda..9af8f1228f0b6 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -611,6 +611,13 @@ impl *const T { /// except that it has a lot more opportunities for UB, in exchange for the compiler /// better understanding what you are doing. /// + /// The primary motivation of this method is for computing the `len` of an array/slice + /// of `T` that you are currently representing as a "start" and "end" pointer + /// (and "end" is "one past the end" of the array). + /// In that case, `end.offset_from(start)` gets you the length of the array. + /// + /// All of the following safety requirements are trivially satisfied for this usecase. + /// /// [`offset`]: #method.offset /// /// # Safety diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index c89ce52292a3d..109c286929b4e 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -785,6 +785,13 @@ impl *mut T { /// except that it has a lot more opportunities for UB, in exchange for the compiler /// better understanding what you are doing. /// + /// The primary motivation of this method is for computing the `len` of an array/slice + /// of `T` that you are currently representing as a "start" and "end" pointer + /// (and "end" is "one past the end" of the array). + /// In that case, `end.offset_from(start)` gets you the length of the array. + /// + /// All of the following safety requirements are trivially satisfied for this usecase. + /// /// [`offset`]: pointer#method.offset-1 /// /// # Safety From ac9707d25cb05b43a4466dbf18ca56f1b463ea78 Mon Sep 17 00:00:00 2001 From: apekros Date: Wed, 27 Sep 2023 18:05:14 +1000 Subject: [PATCH 036/103] Add regression test for rust-lang#56098 --- tests/ui/foreign/foreign-fn-linkname.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/ui/foreign/foreign-fn-linkname.rs b/tests/ui/foreign/foreign-fn-linkname.rs index f6d820594f966..d1d6e703e3dd4 100644 --- a/tests/ui/foreign/foreign-fn-linkname.rs +++ b/tests/ui/foreign/foreign-fn-linkname.rs @@ -2,6 +2,9 @@ // ignore-wasm32-bare no libc to test ffi with // ignore-sgx no libc +// Ensure no false positive on "unused extern crate" lint +#![deny(unused_extern_crates)] + #![feature(rustc_private)] extern crate libc; From e577dcdd4dd01c65921815cb9253a2fb96979a99 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 17 Sep 2023 16:24:22 +0200 Subject: [PATCH 037/103] Prefer expr_or_init over manual init detection --- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_lint/src/reference_casting.rs | 35 ++-------- tests/ui/lint/reference_casting.rs | 13 ++++ tests/ui/lint/reference_casting.stderr | 73 ++++++++++++++------ 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 84434d585d3d6..6dafa4ae01dd7 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -200,7 +200,7 @@ late_lint_methods!( BoxPointers: BoxPointers, PathStatements: PathStatements, LetUnderscore: LetUnderscore, - InvalidReferenceCasting: InvalidReferenceCasting::default(), + InvalidReferenceCasting: InvalidReferenceCasting, // Depends on referenced function signatures in expressions UnusedResults: UnusedResults, NonUpperCaseGlobals: NonUpperCaseGlobals, diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index d540f473ae8f1..717d44cea33df 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -1,8 +1,7 @@ use rustc_ast::Mutability; -use rustc_data_structures::fx::FxHashMap; -use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, QPath, StmtKind, UnOp}; +use rustc_hir::{Expr, ExprKind, UnOp}; use rustc_middle::ty::{self, TypeAndMut}; -use rustc_span::{sym, Span}; +use rustc_span::sym; use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext}; @@ -34,38 +33,18 @@ declare_lint! { "casts of `&T` to `&mut T` without interior mutability" } -#[derive(Default)] -pub struct InvalidReferenceCasting { - casted: FxHashMap, -} - -impl_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]); +declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]); impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting { - fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx rustc_hir::Stmt<'tcx>) { - let StmtKind::Local(local) = stmt.kind else { - return; - }; - let Local { init: Some(init), els: None, .. } = local else { - return; - }; - - if is_cast_from_const_to_mut(cx, init) { - self.casted.insert(local.pat.hir_id, init.span); - } - } - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else { return; }; - let orig_cast = if is_cast_from_const_to_mut(cx, e) { - None - } else if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind - && let Res::Local(hir_id) = &path.res - && let Some(orig_cast) = self.casted.get(hir_id) { - Some(*orig_cast) + let init = cx.expr_or_init(e); + + let orig_cast = if is_cast_from_const_to_mut(cx, init) { + if init.span != e.span { Some(init.span) } else { None } } else { return; }; diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 7745d4ef4c3a2..18c66b2a13e28 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -47,9 +47,19 @@ unsafe fn ref_to_mut() { let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; let _num = &mut *deferred; //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let deferred_rebind = deferred; + let _num = &mut *deferred_rebind; + //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *(num as *const _ as usize as *mut i32); //~^ ERROR casting `&T` to `&mut T` is undefined behavior + static NUM: &'static i32 = &2; + let num = NUM as *const i32 as *mut i32; + let num = num; + let num = num; + let _num = &mut *num; + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + unsafe fn generic_ref_cast_mut(this: &T) -> &mut T { &mut *((this as *const _) as *mut _) //~^ ERROR casting `&T` to `&mut T` is undefined behavior @@ -94,6 +104,9 @@ unsafe fn assign_to_ref() { let value = num as *const i32 as *mut i32; *value = 1; //~^ ERROR assigning to `&T` is undefined behavior + let value_rebind = value; + *value_rebind = 1; + //~^ ERROR assigning to `&T` is undefined behavior *(num as *const i32).cast::().cast_mut() = 2; //~^ ERROR assigning to `&T` is undefined behavior *(num as *const _ as usize as *mut i32) = 2; diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index 1189942c809dd..d4e56048a8ac6 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -112,7 +112,18 @@ LL | let _num = &mut *deferred; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:50:16 + --> $DIR/reference_casting.rs:51:16 + | +LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; + | ---------------------------------------------------------------------------- casting happend here +... +LL | let _num = &mut *deferred_rebind; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:53:16 | LL | let _num = &mut *(num as *const _ as usize as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +131,18 @@ LL | let _num = &mut *(num as *const _ as usize as *mut i32); = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:54:9 + --> $DIR/reference_casting.rs:60:16 + | +LL | let num = NUM as *const i32 as *mut i32; + | ----------------------------- casting happend here +... +LL | let _num = &mut *num; + | ^^^^^^^^^ + | + = note: for more information, visit + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:64:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -128,7 +150,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:59:18 + --> $DIR/reference_casting.rs:69:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +158,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:64:18 + --> $DIR/reference_casting.rs:74:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +166,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:74:5 + --> $DIR/reference_casting.rs:84:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -152,7 +174,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:76:5 + --> $DIR/reference_casting.rs:86:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -160,7 +182,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:78:5 + --> $DIR/reference_casting.rs:88:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -168,7 +190,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:80:5 + --> $DIR/reference_casting.rs:90:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -176,7 +198,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:82:5 + --> $DIR/reference_casting.rs:92:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -184,7 +206,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:84:5 + --> $DIR/reference_casting.rs:94:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -192,7 +214,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:86:5 + --> $DIR/reference_casting.rs:96:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -200,7 +222,7 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:88:5 + --> $DIR/reference_casting.rs:98:5 | LL | / std::ptr::write( LL | | @@ -212,7 +234,7 @@ LL | | ); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:95:5 + --> $DIR/reference_casting.rs:105:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -222,7 +244,18 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:97:5 + --> $DIR/reference_casting.rs:108:5 + | +LL | let value = num as *const i32 as *mut i32; + | ----------------------------- casting happend here +... +LL | *value_rebind = 1; + | ^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:110:5 | LL | *(num as *const i32).cast::().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +263,7 @@ LL | *(num as *const i32).cast::().cast_mut() = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:99:5 + --> $DIR/reference_casting.rs:112:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -238,7 +271,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:101:5 + --> $DIR/reference_casting.rs:114:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -249,7 +282,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:103:5 + --> $DIR/reference_casting.rs:116:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -260,7 +293,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:105:5 + --> $DIR/reference_casting.rs:118:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -271,12 +304,12 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:109:9 + --> $DIR/reference_casting.rs:122:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit -error: aborting due to 32 previous errors +error: aborting due to 35 previous errors From bd360472b13c3aaa642dd3d56945635612aaef73 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 27 Sep 2023 15:38:32 +0200 Subject: [PATCH 038/103] Simplify casting logic of the invalid_reference_casting lint --- compiler/rustc_lint/src/reference_casting.rs | 112 ++++++------------- tests/ui/lint/reference_casting.rs | 6 + tests/ui/lint/reference_casting.stderr | 74 +++++++----- 3 files changed, 87 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index 717d44cea33df..39def599be8d8 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -104,99 +104,51 @@ fn is_operation_we_care_about<'tcx>( deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e)) } -fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool { - let e = e.peel_blocks(); +fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>) -> bool { + let mut need_check_freeze = false; + let mut e = orig_expr; - fn from_casts<'tcx>( - cx: &LateContext<'tcx>, - e: &'tcx Expr<'tcx>, - need_check_freeze: &mut bool, - ) -> Option<&'tcx Expr<'tcx>> { - // as *mut ... - let mut e = if let ExprKind::Cast(e, t) = e.kind - && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() { - e - // .cast_mut() + let end_ty = cx.typeck_results().node_type(orig_expr.hir_id); + + // Bail out early if the end type is **not** a mutable pointer. + if !matches!(end_ty.kind(), ty::RawPtr(TypeAndMut { ty: _, mutbl: Mutability::Mut })) { + return false; + } + + loop { + e = e.peel_blocks(); + // as ... + e = if let ExprKind::Cast(expr, _) = e.kind { + expr + // .cast(), .cast_mut() or .cast_const() } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) { + && matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const) + ) + { expr - // UnsafeCell::raw_get() + // ptr::from_ref(), UnsafeCell::raw_get() or mem::transmute<_, _>() } else if let ExprKind::Call(path, [arg]) = e.kind && let ExprKind::Path(ref qpath) = path.kind && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) + && matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute) + ) { - *need_check_freeze = true; + if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) { + need_check_freeze = true; + } arg } else { - return None; + break; }; - - let mut had_at_least_one_cast = false; - loop { - e = e.peel_blocks(); - // as *mut/const ... or as - e = if let ExprKind::Cast(expr, t) = e.kind - && matches!(cx.typeck_results().node_type(t.hir_id).kind(), ty::RawPtr(_) | ty::Uint(_)) { - had_at_least_one_cast = true; - expr - // .cast(), .cast_mut() or .cast_const() - } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind - && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && matches!( - cx.tcx.get_diagnostic_name(def_id), - Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const) - ) - { - had_at_least_one_cast = true; - expr - // ptr::from_ref() or UnsafeCell::raw_get() - } else if let ExprKind::Call(path, [arg]) = e.kind - && let ExprKind::Path(ref qpath) = path.kind - && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && matches!( - cx.tcx.get_diagnostic_name(def_id), - Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get) - ) - { - if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) { - *need_check_freeze = true; - } - return Some(arg); - } else if had_at_least_one_cast { - return Some(e); - } else { - return None; - }; - } } - fn from_transmute<'tcx>( - cx: &LateContext<'tcx>, - e: &'tcx Expr<'tcx>, - ) -> Option<&'tcx Expr<'tcx>> { - // mem::transmute::<_, *mut _>() - if let ExprKind::Call(path, [arg]) = e.kind - && let ExprKind::Path(ref qpath) = path.kind - && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() - && cx.tcx.is_diagnostic_item(sym::transmute, def_id) - && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(e.hir_id).kind() { - Some(arg) - } else { - None - } - } - - let mut need_check_freeze = false; - let Some(e) = from_casts(cx, e, &mut need_check_freeze).or_else(|| from_transmute(cx, e)) - else { - return false; - }; - - let e = e.peel_blocks(); - let node_type = cx.typeck_results().node_type(e.hir_id); - if let ty::Ref(_, inner_ty, Mutability::Not) = node_type.kind() { + let start_ty = cx.typeck_results().node_type(e.hir_id); + if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() { // If an UnsafeCell method is involved we need to additionaly check the // inner type for the presence of the Freeze trait (ie does NOT contain // an UnsafeCell), since in that case we would incorrectly lint on valid casts. diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 18c66b2a13e28..3d73c261e5574 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -36,6 +36,8 @@ unsafe fn ref_to_mut() { //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *std::mem::transmute::<_, *mut i32>(num); //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *std::cell::UnsafeCell::raw_get( //~^ ERROR casting `&T` to `&mut T` is undefined behavior num as *const i32 as *const std::cell::UnsafeCell @@ -52,6 +54,8 @@ unsafe fn ref_to_mut() { //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *(num as *const _ as usize as *mut i32); //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior static NUM: &'static i32 = &2; let num = NUM as *const i32 as *mut i32; @@ -95,6 +99,8 @@ unsafe fn assign_to_ref() { //~^ ERROR assigning to `&T` is undefined behavior *std::mem::transmute::<_, *mut i32>(num) += 1; //~^ ERROR assigning to `&T` is undefined behavior + *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; + //~^ ERROR assigning to `&T` is undefined behavior std::ptr::write( //~^ ERROR assigning to `&T` is undefined behavior std::mem::transmute::<*const i32, *mut i32>(num), diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr index d4e56048a8ac6..8f89cf9805b04 100644 --- a/tests/ui/lint/reference_casting.stderr +++ b/tests/ui/lint/reference_casting.stderr @@ -82,6 +82,14 @@ LL | let _num = &mut *std::mem::transmute::<_, *mut i32>(num); error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` --> $DIR/reference_casting.rs:39:16 | +LL | let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:41:16 + | LL | let _num = &mut *std::cell::UnsafeCell::raw_get( | ________________^ LL | | @@ -92,7 +100,7 @@ LL | | ); = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:45:16 + --> $DIR/reference_casting.rs:47:16 | LL | let deferred = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -102,7 +110,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:48:16 + --> $DIR/reference_casting.rs:50:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -112,7 +120,7 @@ LL | let _num = &mut *deferred; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:51:16 + --> $DIR/reference_casting.rs:53:16 | LL | let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; | ---------------------------------------------------------------------------- casting happend here @@ -123,7 +131,7 @@ LL | let _num = &mut *deferred_rebind; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:53:16 + --> $DIR/reference_casting.rs:55:16 | LL | let _num = &mut *(num as *const _ as usize as *mut i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +139,15 @@ LL | let _num = &mut *(num as *const _ as usize as *mut i32); = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:60:16 + --> $DIR/reference_casting.rs:57:16 + | +LL | let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` + --> $DIR/reference_casting.rs:64:16 | LL | let num = NUM as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -142,7 +158,7 @@ LL | let _num = &mut *num; = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:64:9 + --> $DIR/reference_casting.rs:68:9 | LL | &mut *((this as *const _) as *mut _) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -150,7 +166,7 @@ LL | &mut *((this as *const _) as *mut _) = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:69:18 + --> $DIR/reference_casting.rs:73:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -158,7 +174,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell` - --> $DIR/reference_casting.rs:74:18 + --> $DIR/reference_casting.rs:78:18 | LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +182,7 @@ LL | unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:84:5 + --> $DIR/reference_casting.rs:88:5 | LL | *(a as *const _ as *mut _) = String::from("Replaced"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +190,7 @@ LL | *(a as *const _ as *mut _) = String::from("Replaced"); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:86:5 + --> $DIR/reference_casting.rs:90:5 | LL | *(a as *const _ as *mut String) += " world"; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +198,7 @@ LL | *(a as *const _ as *mut String) += " world"; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:88:5 + --> $DIR/reference_casting.rs:92:5 | LL | *std::ptr::from_ref(num).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -190,7 +206,7 @@ LL | *std::ptr::from_ref(num).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:90:5 + --> $DIR/reference_casting.rs:94:5 | LL | *std::ptr::from_ref({ num }).cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -198,7 +214,7 @@ LL | *std::ptr::from_ref({ num }).cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:92:5 + --> $DIR/reference_casting.rs:96:5 | LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -206,7 +222,7 @@ LL | *{ std::ptr::from_ref(num) }.cast_mut() += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:94:5 + --> $DIR/reference_casting.rs:98:5 | LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -214,7 +230,7 @@ LL | *(std::ptr::from_ref({ num }) as *mut i32) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:96:5 + --> $DIR/reference_casting.rs:100:5 | LL | *std::mem::transmute::<_, *mut i32>(num) += 1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,7 +238,15 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:98:5 + --> $DIR/reference_casting.rs:102:5 + | +LL | *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, visit + +error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` + --> $DIR/reference_casting.rs:104:5 | LL | / std::ptr::write( LL | | @@ -234,7 +258,7 @@ LL | | ); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:105:5 + --> $DIR/reference_casting.rs:111:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -244,7 +268,7 @@ LL | *value = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:108:5 + --> $DIR/reference_casting.rs:114:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -255,7 +279,7 @@ LL | *value_rebind = 1; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:110:5 + --> $DIR/reference_casting.rs:116:5 | LL | *(num as *const i32).cast::().cast_mut() = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -263,7 +287,7 @@ LL | *(num as *const i32).cast::().cast_mut() = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:112:5 + --> $DIR/reference_casting.rs:118:5 | LL | *(num as *const _ as usize as *mut i32) = 2; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -271,7 +295,7 @@ LL | *(num as *const _ as usize as *mut i32) = 2; = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:114:5 + --> $DIR/reference_casting.rs:120:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -282,7 +306,7 @@ LL | std::ptr::write(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:116:5 + --> $DIR/reference_casting.rs:122:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -293,7 +317,7 @@ LL | std::ptr::write_unaligned(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:118:5 + --> $DIR/reference_casting.rs:124:5 | LL | let value = num as *const i32 as *mut i32; | ----------------------------- casting happend here @@ -304,12 +328,12 @@ LL | std::ptr::write_volatile(value, 2); = note: for more information, visit error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell` - --> $DIR/reference_casting.rs:122:9 + --> $DIR/reference_casting.rs:128:9 | LL | *(this as *const _ as *mut _) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: for more information, visit -error: aborting due to 35 previous errors +error: aborting due to 38 previous errors From 1b2c1a85833ce2eb692054e0bbfe18c8911df216 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 27 Sep 2023 17:14:01 +0200 Subject: [PATCH 039/103] Fix ICE by introducing an expr_or_init variant for outside bodies --- compiler/rustc_lint/src/context.rs | 39 +++++++++++++++++++- compiler/rustc_lint/src/invalid_from_utf8.rs | 4 +- tests/ui/lint/reference_casting.rs | 4 ++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 460d54739a2e5..3c5cde4309b44 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1316,6 +1316,40 @@ impl<'tcx> LateContext<'tcx> { }) } + /// If the given expression is a local binding, find the initializer expression. + /// If that initializer expression is another local binding, find its initializer again. + /// + /// This process repeats as long as possible (but usually no more than once). + /// Type-check adjustments are not taken in account in this function. + /// + /// Examples: + /// ``` + /// let abc = 1; + /// let def = abc + 2; + /// // ^^^^^^^ output + /// let def = def; + /// dbg!(def); + /// // ^^^ input + /// ``` + pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> { + expr = expr.peel_blocks(); + + while let hir::ExprKind::Path(ref qpath) = expr.kind + && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) { + Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id), + _ => None, + } + && let Some(init) = match parent_node { + hir::Node::Expr(expr) => Some(expr), + hir::Node::Local(hir::Local { init, .. }) => *init, + _ => None + } + { + expr = init.peel_blocks(); + } + expr + } + /// If the given expression is a local binding, find the initializer expression. /// If that initializer expression is another local or **outside** (`const`/`static`) /// binding, find its initializer again. @@ -1338,7 +1372,10 @@ impl<'tcx> LateContext<'tcx> { /// dbg!(def); /// // ^^^ input /// ``` - pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> { + pub fn expr_or_init_with_outside_body<'a>( + &self, + mut expr: &'a hir::Expr<'tcx>, + ) -> &'a hir::Expr<'tcx> { expr = expr.peel_blocks(); while let hir::ExprKind::Path(ref qpath) = expr.kind diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs index 1841e7c85a817..e398059ade9fc 100644 --- a/compiler/rustc_lint/src/invalid_from_utf8.rs +++ b/compiler/rustc_lint/src/invalid_from_utf8.rs @@ -84,9 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 { ) }; - let mut init = cx.expr_or_init(arg); + let mut init = cx.expr_or_init_with_outside_body(arg); while let ExprKind::AddrOf(.., inner) = init.kind { - init = cx.expr_or_init(inner); + init = cx.expr_or_init_with_outside_body(inner); } match init.kind { ExprKind::Lit(Spanned { node: lit, .. }) => { diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 3d73c261e5574..fba8789e999ed 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -130,6 +130,7 @@ unsafe fn assign_to_ref() { } } +const RAW_PTR: *mut u8 = 1 as *mut u8; unsafe fn no_warn() { let num = &3i32; let mut_num = &mut 3i32; @@ -144,6 +145,9 @@ unsafe fn no_warn() { let mut value = 3; let value: *const i32 = &mut value; *(value as *const i16 as *mut i16) = 42; + *RAW_PTR = 42; // RAW_PTR is defined outside the function body, + // make sure we don't ICE on it when trying to + // determine if we should lint on it or not. fn safe_as_mut(x: &std::cell::UnsafeCell) -> &mut T { unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } From fd95627134e85f56f2e162790f56943b407f1a34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 27 Sep 2023 23:48:47 +0200 Subject: [PATCH 040/103] fix clippy::{redundant_guards, useless_format} --- compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 4 ++-- compiler/rustc_codegen_ssa/src/base.rs | 2 +- compiler/rustc_hir_typeck/src/demand.rs | 2 +- .../src/infer/error_reporting/note_and_explain.rs | 2 +- compiler/rustc_middle/src/mir/pretty.rs | 4 ++-- compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 4 +--- compiler/rustc_mir_transform/src/coverage/spans.rs | 2 +- compiler/rustc_mir_transform/src/large_enums.rs | 7 ++----- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_span/src/lib.rs | 4 ++-- .../src/traits/error_reporting/mod.rs | 2 +- src/librustdoc/doctest.rs | 2 +- 12 files changed, 16 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 2ea399789b9a3..27072a60f65f0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; }; diag.span_note( *trait_span, - format!("due to current limitations in the borrow checker, this implies a `'static` lifetime") + "due to current limitations in the borrow checker, this implies a `'static` lifetime" ); let Some(generics_fn) = hir.get_generics(self.body.source.def_id().expect_local()) else { return; }; let Def(_, trait_res_defid) = trait_ref.path.res else { return; }; @@ -277,7 +277,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if suggestions.len() > 0 { suggestions.dedup(); diag.multipart_suggestion_verbose( - format!("consider restricting the type parameter to the `'static` lifetime"), + "consider restricting the type parameter to the `'static` lifetime", suggestions, Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 6c51dffedbfad..3cca0eb7ae72e 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -181,7 +181,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( old_info } } - (_, &ty::Dynamic(ref data, _, _)) => meth::get_vtable(cx, source, data.principal()), + (_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()), _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 256a4bf944910..d97691369c958 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -644,7 +644,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.can_eq(self.param_env, ty, expected) { err.span_label( ex.span, - format!("expected because of this `break`"), + "expected because of this `break`", ); exit = true; } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b34900da83bb2..5c3beee284fca 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -621,7 +621,7 @@ fn foo(&self) -> Self::T { String::new() } { diag.span_label( item.span, - format!("associated type is `default` and may be overridden"), + "associated type is `default` and may be overridden", ); return true; } diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 349b32c10fb9e..76567c3f6b0a0 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1146,10 +1146,10 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) -> ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => { write!(fmt, "[-{offset:?} of {min_length:?}]")?; } - ProjectionElem::Subslice { from, to, from_end: true } if to == 0 => { + ProjectionElem::Subslice { from, to: 0, from_end: true } => { write!(fmt, "[{from:?}:]")?; } - ProjectionElem::Subslice { from, to, from_end: true } if from == 0 => { + ProjectionElem::Subslice { from: 0, to, from_end: true } => { write!(fmt, "[:-{to:?}]")?; } ProjectionElem::Subslice { from, to, from_end: true } => { 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 95dced644e161..d440ca319260c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -740,9 +740,7 @@ fn non_exhaustive_match<'p, 'tcx>( )); } } else if ty == cx.tcx.types.str_ { - err.note(format!( - "`&str` cannot be matched exhaustively, so a wildcard `_` is necessary", - )); + err.note("`&str` cannot be matched exhaustively, so a wildcard `_` is necessary"); } else if cx.is_foreign_non_exhaustive_enum(ty) { err.note(format!("`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively")); } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 5b24fa10beae8..767f8e9f4fa15 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -763,7 +763,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option // and `_1` is the `Place` for `somenum`. // // If and when the Issue is resolved, remove this special case match pattern: - StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None, + StatementKind::FakeRead(box (FakeReadCause::ForGuardBinding, _)) => None, // Retain spans from all other statements StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding` diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 4eee45f8d000b..886ff760481e0 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -54,11 +54,8 @@ impl EnumSizeOpt { let layout = tcx.layout_of(param_env.and(ty)).ok()?; let variants = match &layout.variants { Variants::Single { .. } => return None, - Variants::Multiple { tag_encoding, .. } - if matches!(tag_encoding, TagEncoding::Niche { .. }) => - { - return None; - } + Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => return None, + Variants::Multiple { variants, .. } if variants.len() <= 1 => return None, Variants::Multiple { variants, .. } => variants, }; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 64440a6c04e7a..adddc419dafb2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -186,7 +186,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { fallback_label: format!("not a {expected}"), span, span_label: match res { - Res::Def(kind, def_id) if kind == DefKind::TyParam => { + Res::Def(DefKind::TyParam, def_id) => { Some((self.r.def_span(def_id), "found this type parameter")) } _ => None, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c58fdbcb5e1b6..772e09291a139 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1753,7 +1753,7 @@ impl SourceFile { // is recorded. let diff = match self.normalized_pos.binary_search_by(|np| np.pos.cmp(&pos)) { Ok(i) => self.normalized_pos[i].diff, - Err(i) if i == 0 => 0, + Err(0) => 0, Err(i) => self.normalized_pos[i - 1].diff, }; @@ -1775,7 +1775,7 @@ impl SourceFile { .binary_search_by(|np| (np.pos.0 + np.diff).cmp(&(self.start_pos.0 + offset))) { Ok(i) => self.normalized_pos[i].diff, - Err(i) if i == 0 => 0, + Err(0) => 0, Err(i) => self.normalized_pos[i - 1].diff, }; 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 2a333a4f0e3ef..2a586f810d629 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3211,7 +3211,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let name = match self.tcx.opaque_type_origin(def_id.expect_local()) { hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => { - format!("opaque type") + "opaque type".to_string() } hir::OpaqueTyOrigin::TyAlias { .. } => { format!("`{}`", self.tcx.def_path_debug_str(def_id)) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 24597c3aca312..741d329fb1922 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -681,7 +681,7 @@ pub(crate) fn make_test( if s.contains(crate_name) { // rustdoc implicitly inserts an `extern crate` item for the own crate // which may be unused, so we need to allow the lint. - prog.push_str(&format!("#[allow(unused_extern_crates)]\n")); + prog.push_str("#[allow(unused_extern_crates)]\n"); prog.push_str(&format!("extern crate r#{crate_name};\n")); line_offset += 1; From e8a33847fd1d92a50d53287c737670d1a8f80df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 28 Sep 2023 00:20:32 +0200 Subject: [PATCH 041/103] don't clone copy types --- compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/stable_mir/src/fold.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index cd37221ae6f80..221df4e36b296 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1374,7 +1374,7 @@ fn impl_trait_ref( // make astconv happy. let mut path_segments = ast_trait_ref.path.segments.to_vec(); let last_segment = path_segments.len() - 1; - let mut args = path_segments[last_segment].args().clone(); + let mut args = *path_segments[last_segment].args(); let last_arg = args.args.len() - 1; assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host))); args.args = &args.args[..args.args.len() - 1]; diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index 16ae62311aaf0..1da123e922b3b 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -81,7 +81,7 @@ impl Foldable for UnevaluatedConst { impl Foldable for ConstDef { fn super_fold(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) + ControlFlow::Continue(*self) } } @@ -96,7 +96,7 @@ impl Foldable for Option { impl Foldable for Promoted { fn super_fold(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) + ControlFlow::Continue(*self) } } From 79195d5cbbf839ed6db8cda394b0a7b2ef447ba7 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 27 Sep 2023 16:51:21 -0700 Subject: [PATCH 042/103] Add `crate_name` to test so that it can be renamed --- tests/rustdoc/issue-12834.rs | 1 + tests/rustdoc/issue-13698.rs | 2 ++ tests/rustdoc/issue-15169.rs | 3 +++ tests/rustdoc/issue-15318-2.rs | 2 ++ tests/rustdoc/issue-15318-3.rs | 1 + tests/rustdoc/issue-15318.rs | 1 + tests/rustdoc/issue-15347.rs | 2 ++ tests/rustdoc/issue-16265-1.rs | 2 ++ tests/rustdoc/issue-16265-2.rs | 2 ++ tests/rustdoc/issue-17476.rs | 2 ++ tests/rustdoc/issue-19190-2.rs | 2 ++ tests/rustdoc/issue-19190-3.rs | 2 ++ tests/rustdoc/issue-19190.rs | 2 ++ tests/rustdoc/issue-20175.rs | 2 ++ tests/rustdoc/issue-20646.rs | 1 + tests/rustdoc/issue-20727-2.rs | 2 ++ tests/rustdoc/issue-20727-3.rs | 2 ++ tests/rustdoc/issue-20727-4.rs | 2 ++ tests/rustdoc/issue-20727.rs | 2 ++ 19 files changed, 35 insertions(+) diff --git a/tests/rustdoc/issue-12834.rs b/tests/rustdoc/issue-12834.rs index 9605a1e78c105..7bc5f682c5abf 100644 --- a/tests/rustdoc/issue-12834.rs +++ b/tests/rustdoc/issue-12834.rs @@ -1,6 +1,7 @@ // Tests that failing to syntax highlight a rust code-block doesn't cause // rustdoc to fail, while still rendering the code-block (without highlighting). +#![crate_name="issue_12834"] #![allow(rustdoc::invalid_rust_codeblocks)] // @has issue_12834/fn.foo.html diff --git a/tests/rustdoc/issue-13698.rs b/tests/rustdoc/issue-13698.rs index 3046a8a28627d..ead005301a97d 100644 --- a/tests/rustdoc/issue-13698.rs +++ b/tests/rustdoc/issue-13698.rs @@ -1,6 +1,8 @@ // aux-build:issue-13698.rs // ignore-cross-compile +#![crate_name="issue_13698"] + extern crate issue_13698; pub struct Foo; diff --git a/tests/rustdoc/issue-15169.rs b/tests/rustdoc/issue-15169.rs index e525d85e21ec0..6408f11e5c11c 100644 --- a/tests/rustdoc/issue-15169.rs +++ b/tests/rustdoc/issue-15169.rs @@ -1,3 +1,6 @@ // @has issue_15169/struct.Foo.html '//*[@id="method.eq"]' 'fn eq' + +#![crate_name="issue_15169"] + #[derive(PartialEq)] pub struct Foo; diff --git a/tests/rustdoc/issue-15318-2.rs b/tests/rustdoc/issue-15318-2.rs index 614f2c1c08e87..5c31a0694a5a5 100644 --- a/tests/rustdoc/issue-15318-2.rs +++ b/tests/rustdoc/issue-15318-2.rs @@ -1,5 +1,7 @@ // aux-build:issue-15318.rs // ignore-cross-compile + +#![crate_name="issue_15318_2"] #![no_std] extern crate issue_15318; diff --git a/tests/rustdoc/issue-15318-3.rs b/tests/rustdoc/issue-15318-3.rs index 2dab8f9488391..6395edd897d4c 100644 --- a/tests/rustdoc/issue-15318-3.rs +++ b/tests/rustdoc/issue-15318-3.rs @@ -1,3 +1,4 @@ +#![crate_name="issue_15318_3"] #![feature(rustc_attrs)] // @has issue_15318_3/primitive.pointer.html diff --git a/tests/rustdoc/issue-15318.rs b/tests/rustdoc/issue-15318.rs index 0349fe2854c8a..dbefc9c3b9291 100644 --- a/tests/rustdoc/issue-15318.rs +++ b/tests/rustdoc/issue-15318.rs @@ -1,6 +1,7 @@ // aux-build:issue-15318.rs // ignore-cross-compile +#![crate_name="issue_15318"] #![no_std] extern crate issue_15318; diff --git a/tests/rustdoc/issue-15347.rs b/tests/rustdoc/issue-15347.rs index e93d74011681b..8ceda315cc4d3 100644 --- a/tests/rustdoc/issue-15347.rs +++ b/tests/rustdoc/issue-15347.rs @@ -1,5 +1,7 @@ // compile-flags: -Z unstable-options --document-hidden-items +#![crate_name="issue_15347"] + // @has issue_15347/fn.foo.html #[doc(hidden)] pub fn foo() {} diff --git a/tests/rustdoc/issue-16265-1.rs b/tests/rustdoc/issue-16265-1.rs index 2fda637a64131..e13822127b47d 100644 --- a/tests/rustdoc/issue-16265-1.rs +++ b/tests/rustdoc/issue-16265-1.rs @@ -1,3 +1,5 @@ +#![crate_name="issue_16265_1"] + pub struct Foo; // @hasraw issue_16265_1/traits/index.html 'source' diff --git a/tests/rustdoc/issue-16265-2.rs b/tests/rustdoc/issue-16265-2.rs index c3eb356171e85..adb5a67ce6c8b 100644 --- a/tests/rustdoc/issue-16265-2.rs +++ b/tests/rustdoc/issue-16265-2.rs @@ -1,3 +1,5 @@ +#![crate_name="issue_16265_2"] + // @hasraw issue_16265_2/index.html 'source' trait Y {} diff --git a/tests/rustdoc/issue-17476.rs b/tests/rustdoc/issue-17476.rs index a5b484c985fff..de17af50ccd0f 100644 --- a/tests/rustdoc/issue-17476.rs +++ b/tests/rustdoc/issue-17476.rs @@ -1,6 +1,8 @@ // aux-build:issue-17476.rs // ignore-cross-compile +#![crate_name="issue_17476"] + extern crate issue_17476; pub struct Foo; diff --git a/tests/rustdoc/issue-19190-2.rs b/tests/rustdoc/issue-19190-2.rs index b6416e2e5b97e..17562c356e93d 100644 --- a/tests/rustdoc/issue-19190-2.rs +++ b/tests/rustdoc/issue-19190-2.rs @@ -1,3 +1,5 @@ +#![crate_name="issue_19190_2"] + use std::ops::Deref; pub struct Bar; diff --git a/tests/rustdoc/issue-19190-3.rs b/tests/rustdoc/issue-19190-3.rs index 4d34ce6509fe3..4aeb2ee08912c 100644 --- a/tests/rustdoc/issue-19190-3.rs +++ b/tests/rustdoc/issue-19190-3.rs @@ -1,6 +1,8 @@ // aux-build:issue-19190-3.rs // ignore-cross-compile +#![crate_name="issue_19190_3"] + extern crate issue_19190_3; use std::ops::Deref; diff --git a/tests/rustdoc/issue-19190.rs b/tests/rustdoc/issue-19190.rs index 2046273e2c1ba..9a68a2dec5245 100644 --- a/tests/rustdoc/issue-19190.rs +++ b/tests/rustdoc/issue-19190.rs @@ -1,3 +1,5 @@ +#![crate_name="issue_19190"] + use std::ops::Deref; pub struct Foo; diff --git a/tests/rustdoc/issue-20175.rs b/tests/rustdoc/issue-20175.rs index 6a42e2afbf43c..5b38ab91af9af 100644 --- a/tests/rustdoc/issue-20175.rs +++ b/tests/rustdoc/issue-20175.rs @@ -1,3 +1,5 @@ +#![crate_name="issue_20175"] + pub trait Foo { fn foo(&self) {} } diff --git a/tests/rustdoc/issue-20646.rs b/tests/rustdoc/issue-20646.rs index b2ee9c26014b3..e8447c61077a7 100644 --- a/tests/rustdoc/issue-20646.rs +++ b/tests/rustdoc/issue-20646.rs @@ -1,6 +1,7 @@ // aux-build:issue-20646.rs // ignore-cross-compile +#![crate_name="issue_20646"] #![feature(associated_types)] extern crate issue_20646; diff --git a/tests/rustdoc/issue-20727-2.rs b/tests/rustdoc/issue-20727-2.rs index c1aa9617b2e25..869ccac8d0944 100644 --- a/tests/rustdoc/issue-20727-2.rs +++ b/tests/rustdoc/issue-20727-2.rs @@ -1,6 +1,8 @@ // aux-build:issue-20727.rs // ignore-cross-compile +#![crate_name="issue_20727_2"] + extern crate issue_20727; // @has issue_20727_2/trait.Add.html diff --git a/tests/rustdoc/issue-20727-3.rs b/tests/rustdoc/issue-20727-3.rs index 2f9d91fc5f724..f7ba175c4b955 100644 --- a/tests/rustdoc/issue-20727-3.rs +++ b/tests/rustdoc/issue-20727-3.rs @@ -1,6 +1,8 @@ // aux-build:issue-20727.rs // ignore-cross-compile +#![crate_name="issue_20727_3"] + extern crate issue_20727; pub trait Bar {} diff --git a/tests/rustdoc/issue-20727-4.rs b/tests/rustdoc/issue-20727-4.rs index ec9f18fc3feb8..b3df0bb9fc28f 100644 --- a/tests/rustdoc/issue-20727-4.rs +++ b/tests/rustdoc/issue-20727-4.rs @@ -1,6 +1,8 @@ // aux-build:issue-20727.rs // ignore-cross-compile +#![crate_name="issue_20727_4"] + extern crate issue_20727; // @has issue_20727_4/trait.Index.html diff --git a/tests/rustdoc/issue-20727.rs b/tests/rustdoc/issue-20727.rs index 266848beef93d..ac7485233cc6b 100644 --- a/tests/rustdoc/issue-20727.rs +++ b/tests/rustdoc/issue-20727.rs @@ -1,6 +1,8 @@ // aux-build:issue-20727.rs // ignore-cross-compile +#![crate_name="issue_20727"] + extern crate issue_20727; // @has issue_20727/trait.Deref.html From 7cd8b2c9253e83c8101a45ccf6e401cd3160650c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 27 Sep 2023 17:15:37 -0700 Subject: [PATCH 043/103] Rename issue-\d+.rs tests to have meaningful names --- tests/rustdoc/{issue-15169.rs => anchor-id-trait-method-15169.rs} | 0 tests/rustdoc/{issue-20646.rs => assoc-type-bindings-20646.rs} | 0 .../{issue-19190-2.rs => deref-methods-19190-foreign-type.rs} | 0 tests/rustdoc/{issue-19190-3.rs => deref-methods-19190-inline.rs} | 0 tests/rustdoc/{issue-19190.rs => deref-methods-19190.rs} | 0 tests/rustdoc/{issue-13698.rs => doc-hidden-method-13698.rs} | 0 tests/rustdoc/{issue-18199.rs => doc-test-attr-18199.rs} | 0 tests/rustdoc/{issue-15347.rs => document-hidden-items-15347.rs} | 0 tests/rustdoc/{issue-12834.rs => highlight-invalid-rust-12834.rs} | 0 tests/rustdoc/{issue-19181.rs => ice-type-error-19181.rs} | 0 tests/rustdoc/{issue-20175.rs => impl-ref-20175.rs} | 0 .../rustdoc/{issue-16265-1.rs => infinite-redirection-16265-1.rs} | 0 .../rustdoc/{issue-16265-2.rs => infinite-redirection-16265-2.rs} | 0 .../{issue-20727-2.rs => inline-assoc-type-20727-bindings.rs} | 0 .../{issue-20727-3.rs => inline-assoc-type-20727-bounds-deref.rs} | 0 .../{issue-20727-4.rs => inline-assoc-type-20727-bounds-index.rs} | 0 .../rustdoc/{issue-20727.rs => inline-assoc-type-20727-bounds.rs} | 0 tests/rustdoc/{issue-16019.rs => macro-ice-16019.rs} | 0 .../{issue-17476.rs => method-link-foreign-trait-impl-17476.rs} | 0 .../{issue-15318-3.rs => primitive-raw-pointer-dox-15318-3.rs} | 0 .../{issue-15318.rs => primitive-raw-pointer-link-15318.rs} | 0 ...5318-2.rs => primitive-raw-pointer-link-no-inlined-15318-2.rs} | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{issue-15169.rs => anchor-id-trait-method-15169.rs} (100%) rename tests/rustdoc/{issue-20646.rs => assoc-type-bindings-20646.rs} (100%) rename tests/rustdoc/{issue-19190-2.rs => deref-methods-19190-foreign-type.rs} (100%) rename tests/rustdoc/{issue-19190-3.rs => deref-methods-19190-inline.rs} (100%) rename tests/rustdoc/{issue-19190.rs => deref-methods-19190.rs} (100%) rename tests/rustdoc/{issue-13698.rs => doc-hidden-method-13698.rs} (100%) rename tests/rustdoc/{issue-18199.rs => doc-test-attr-18199.rs} (100%) rename tests/rustdoc/{issue-15347.rs => document-hidden-items-15347.rs} (100%) rename tests/rustdoc/{issue-12834.rs => highlight-invalid-rust-12834.rs} (100%) rename tests/rustdoc/{issue-19181.rs => ice-type-error-19181.rs} (100%) rename tests/rustdoc/{issue-20175.rs => impl-ref-20175.rs} (100%) rename tests/rustdoc/{issue-16265-1.rs => infinite-redirection-16265-1.rs} (100%) rename tests/rustdoc/{issue-16265-2.rs => infinite-redirection-16265-2.rs} (100%) rename tests/rustdoc/{issue-20727-2.rs => inline-assoc-type-20727-bindings.rs} (100%) rename tests/rustdoc/{issue-20727-3.rs => inline-assoc-type-20727-bounds-deref.rs} (100%) rename tests/rustdoc/{issue-20727-4.rs => inline-assoc-type-20727-bounds-index.rs} (100%) rename tests/rustdoc/{issue-20727.rs => inline-assoc-type-20727-bounds.rs} (100%) rename tests/rustdoc/{issue-16019.rs => macro-ice-16019.rs} (100%) rename tests/rustdoc/{issue-17476.rs => method-link-foreign-trait-impl-17476.rs} (100%) rename tests/rustdoc/{issue-15318-3.rs => primitive-raw-pointer-dox-15318-3.rs} (100%) rename tests/rustdoc/{issue-15318.rs => primitive-raw-pointer-link-15318.rs} (100%) rename tests/rustdoc/{issue-15318-2.rs => primitive-raw-pointer-link-no-inlined-15318-2.rs} (100%) diff --git a/tests/rustdoc/issue-15169.rs b/tests/rustdoc/anchor-id-trait-method-15169.rs similarity index 100% rename from tests/rustdoc/issue-15169.rs rename to tests/rustdoc/anchor-id-trait-method-15169.rs diff --git a/tests/rustdoc/issue-20646.rs b/tests/rustdoc/assoc-type-bindings-20646.rs similarity index 100% rename from tests/rustdoc/issue-20646.rs rename to tests/rustdoc/assoc-type-bindings-20646.rs diff --git a/tests/rustdoc/issue-19190-2.rs b/tests/rustdoc/deref-methods-19190-foreign-type.rs similarity index 100% rename from tests/rustdoc/issue-19190-2.rs rename to tests/rustdoc/deref-methods-19190-foreign-type.rs diff --git a/tests/rustdoc/issue-19190-3.rs b/tests/rustdoc/deref-methods-19190-inline.rs similarity index 100% rename from tests/rustdoc/issue-19190-3.rs rename to tests/rustdoc/deref-methods-19190-inline.rs diff --git a/tests/rustdoc/issue-19190.rs b/tests/rustdoc/deref-methods-19190.rs similarity index 100% rename from tests/rustdoc/issue-19190.rs rename to tests/rustdoc/deref-methods-19190.rs diff --git a/tests/rustdoc/issue-13698.rs b/tests/rustdoc/doc-hidden-method-13698.rs similarity index 100% rename from tests/rustdoc/issue-13698.rs rename to tests/rustdoc/doc-hidden-method-13698.rs diff --git a/tests/rustdoc/issue-18199.rs b/tests/rustdoc/doc-test-attr-18199.rs similarity index 100% rename from tests/rustdoc/issue-18199.rs rename to tests/rustdoc/doc-test-attr-18199.rs diff --git a/tests/rustdoc/issue-15347.rs b/tests/rustdoc/document-hidden-items-15347.rs similarity index 100% rename from tests/rustdoc/issue-15347.rs rename to tests/rustdoc/document-hidden-items-15347.rs diff --git a/tests/rustdoc/issue-12834.rs b/tests/rustdoc/highlight-invalid-rust-12834.rs similarity index 100% rename from tests/rustdoc/issue-12834.rs rename to tests/rustdoc/highlight-invalid-rust-12834.rs diff --git a/tests/rustdoc/issue-19181.rs b/tests/rustdoc/ice-type-error-19181.rs similarity index 100% rename from tests/rustdoc/issue-19181.rs rename to tests/rustdoc/ice-type-error-19181.rs diff --git a/tests/rustdoc/issue-20175.rs b/tests/rustdoc/impl-ref-20175.rs similarity index 100% rename from tests/rustdoc/issue-20175.rs rename to tests/rustdoc/impl-ref-20175.rs diff --git a/tests/rustdoc/issue-16265-1.rs b/tests/rustdoc/infinite-redirection-16265-1.rs similarity index 100% rename from tests/rustdoc/issue-16265-1.rs rename to tests/rustdoc/infinite-redirection-16265-1.rs diff --git a/tests/rustdoc/issue-16265-2.rs b/tests/rustdoc/infinite-redirection-16265-2.rs similarity index 100% rename from tests/rustdoc/issue-16265-2.rs rename to tests/rustdoc/infinite-redirection-16265-2.rs diff --git a/tests/rustdoc/issue-20727-2.rs b/tests/rustdoc/inline-assoc-type-20727-bindings.rs similarity index 100% rename from tests/rustdoc/issue-20727-2.rs rename to tests/rustdoc/inline-assoc-type-20727-bindings.rs diff --git a/tests/rustdoc/issue-20727-3.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs similarity index 100% rename from tests/rustdoc/issue-20727-3.rs rename to tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs diff --git a/tests/rustdoc/issue-20727-4.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs similarity index 100% rename from tests/rustdoc/issue-20727-4.rs rename to tests/rustdoc/inline-assoc-type-20727-bounds-index.rs diff --git a/tests/rustdoc/issue-20727.rs b/tests/rustdoc/inline-assoc-type-20727-bounds.rs similarity index 100% rename from tests/rustdoc/issue-20727.rs rename to tests/rustdoc/inline-assoc-type-20727-bounds.rs diff --git a/tests/rustdoc/issue-16019.rs b/tests/rustdoc/macro-ice-16019.rs similarity index 100% rename from tests/rustdoc/issue-16019.rs rename to tests/rustdoc/macro-ice-16019.rs diff --git a/tests/rustdoc/issue-17476.rs b/tests/rustdoc/method-link-foreign-trait-impl-17476.rs similarity index 100% rename from tests/rustdoc/issue-17476.rs rename to tests/rustdoc/method-link-foreign-trait-impl-17476.rs diff --git a/tests/rustdoc/issue-15318-3.rs b/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs similarity index 100% rename from tests/rustdoc/issue-15318-3.rs rename to tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs diff --git a/tests/rustdoc/issue-15318.rs b/tests/rustdoc/primitive-raw-pointer-link-15318.rs similarity index 100% rename from tests/rustdoc/issue-15318.rs rename to tests/rustdoc/primitive-raw-pointer-link-15318.rs diff --git a/tests/rustdoc/issue-15318-2.rs b/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs similarity index 100% rename from tests/rustdoc/issue-15318-2.rs rename to tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs From f4ed73119ae6b9af4b6722954265ed617d066d2e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 27 Sep 2023 17:12:40 -0700 Subject: [PATCH 044/103] Document -Zlink-native-libraries Originally added in #70095. --- .../src/compiler-flags/link-native-libraries.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/doc/unstable-book/src/compiler-flags/link-native-libraries.md diff --git a/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md b/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md new file mode 100644 index 0000000000000..a1fcb631c6826 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md @@ -0,0 +1,8 @@ +# `link-native-libraries` + +This option allows ignoring libraries specified in `#[link]` attributes instead of passing them to the linker. +This can be useful in build systems that manage native libraries themselves and pass them manually, +e.g. with `-Clink-arg`. + +- `yes` - Pass native libraries to the linker. Default. +- `no` - Don't pass native libraries to the linker. From 0487237f1247d2395c50e52640ef547b88fd38be Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 27 Sep 2023 17:22:18 -0700 Subject: [PATCH 045/103] rustdoc: add URLs for test issues --- tests/rustdoc/anchor-id-trait-method-15169.rs | 1 + tests/rustdoc/assoc-type-bindings-20646.rs | 1 + tests/rustdoc/deref-methods-19190-foreign-type.rs | 2 ++ tests/rustdoc/deref-methods-19190-inline.rs | 1 + tests/rustdoc/deref-methods-19190.rs | 1 + tests/rustdoc/doc-hidden-method-13698.rs | 1 + tests/rustdoc/doc-test-attr-18199.rs | 1 + tests/rustdoc/document-hidden-items-15347.rs | 1 + tests/rustdoc/highlight-invalid-rust-12834.rs | 1 + tests/rustdoc/ice-type-error-19181.rs | 1 + tests/rustdoc/impl-ref-20175.rs | 2 ++ tests/rustdoc/infinite-redirection-16265-1.rs | 1 + tests/rustdoc/infinite-redirection-16265-2.rs | 1 + tests/rustdoc/inline-assoc-type-20727-bindings.rs | 1 + tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs | 1 + tests/rustdoc/inline-assoc-type-20727-bounds-index.rs | 1 + tests/rustdoc/inline-assoc-type-20727-bounds.rs | 1 + tests/rustdoc/macro-ice-16019.rs | 2 ++ tests/rustdoc/method-link-foreign-trait-impl-17476.rs | 1 + tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs | 1 + tests/rustdoc/primitive-raw-pointer-link-15318.rs | 1 + tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs | 1 + 22 files changed, 25 insertions(+) diff --git a/tests/rustdoc/anchor-id-trait-method-15169.rs b/tests/rustdoc/anchor-id-trait-method-15169.rs index 6408f11e5c11c..26bb59c1875fd 100644 --- a/tests/rustdoc/anchor-id-trait-method-15169.rs +++ b/tests/rustdoc/anchor-id-trait-method-15169.rs @@ -1,5 +1,6 @@ // @has issue_15169/struct.Foo.html '//*[@id="method.eq"]' 'fn eq' +// https://github.com/rust-lang/rust/issues/15169 #![crate_name="issue_15169"] #[derive(PartialEq)] diff --git a/tests/rustdoc/assoc-type-bindings-20646.rs b/tests/rustdoc/assoc-type-bindings-20646.rs index e8447c61077a7..375b5b5b23ea5 100644 --- a/tests/rustdoc/assoc-type-bindings-20646.rs +++ b/tests/rustdoc/assoc-type-bindings-20646.rs @@ -1,6 +1,7 @@ // aux-build:issue-20646.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/20646 #![crate_name="issue_20646"] #![feature(associated_types)] diff --git a/tests/rustdoc/deref-methods-19190-foreign-type.rs b/tests/rustdoc/deref-methods-19190-foreign-type.rs index 17562c356e93d..c8326992115c7 100644 --- a/tests/rustdoc/deref-methods-19190-foreign-type.rs +++ b/tests/rustdoc/deref-methods-19190-foreign-type.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/19190 + #![crate_name="issue_19190_2"] use std::ops::Deref; diff --git a/tests/rustdoc/deref-methods-19190-inline.rs b/tests/rustdoc/deref-methods-19190-inline.rs index 4aeb2ee08912c..619b268d68b39 100644 --- a/tests/rustdoc/deref-methods-19190-inline.rs +++ b/tests/rustdoc/deref-methods-19190-inline.rs @@ -1,6 +1,7 @@ // aux-build:issue-19190-3.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/19190 #![crate_name="issue_19190_3"] extern crate issue_19190_3; diff --git a/tests/rustdoc/deref-methods-19190.rs b/tests/rustdoc/deref-methods-19190.rs index 9a68a2dec5245..4c274d82ff785 100644 --- a/tests/rustdoc/deref-methods-19190.rs +++ b/tests/rustdoc/deref-methods-19190.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/19190 #![crate_name="issue_19190"] use std::ops::Deref; diff --git a/tests/rustdoc/doc-hidden-method-13698.rs b/tests/rustdoc/doc-hidden-method-13698.rs index ead005301a97d..f1bd6e73babdd 100644 --- a/tests/rustdoc/doc-hidden-method-13698.rs +++ b/tests/rustdoc/doc-hidden-method-13698.rs @@ -1,6 +1,7 @@ // aux-build:issue-13698.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/13698 #![crate_name="issue_13698"] extern crate issue_13698; diff --git a/tests/rustdoc/doc-test-attr-18199.rs b/tests/rustdoc/doc-test-attr-18199.rs index 9cc58b162f37e..c9d2235321c87 100644 --- a/tests/rustdoc/doc-test-attr-18199.rs +++ b/tests/rustdoc/doc-test-attr-18199.rs @@ -1,4 +1,5 @@ // compile-flags:--test +// https://github.com/rust-lang/rust/issues/18199 #![doc(test(attr(feature(staged_api))))] diff --git a/tests/rustdoc/document-hidden-items-15347.rs b/tests/rustdoc/document-hidden-items-15347.rs index 8ceda315cc4d3..d8a760e566602 100644 --- a/tests/rustdoc/document-hidden-items-15347.rs +++ b/tests/rustdoc/document-hidden-items-15347.rs @@ -1,4 +1,5 @@ // compile-flags: -Z unstable-options --document-hidden-items +// https://github.com/rust-lang/rust/issues/15347 #![crate_name="issue_15347"] diff --git a/tests/rustdoc/highlight-invalid-rust-12834.rs b/tests/rustdoc/highlight-invalid-rust-12834.rs index 7bc5f682c5abf..f8acc5002648f 100644 --- a/tests/rustdoc/highlight-invalid-rust-12834.rs +++ b/tests/rustdoc/highlight-invalid-rust-12834.rs @@ -1,5 +1,6 @@ // Tests that failing to syntax highlight a rust code-block doesn't cause // rustdoc to fail, while still rendering the code-block (without highlighting). +// https://github.com/rust-lang/rust/issues/12834 #![crate_name="issue_12834"] #![allow(rustdoc::invalid_rust_codeblocks)] diff --git a/tests/rustdoc/ice-type-error-19181.rs b/tests/rustdoc/ice-type-error-19181.rs index 3dea152fc6ecb..3ced613666406 100644 --- a/tests/rustdoc/ice-type-error-19181.rs +++ b/tests/rustdoc/ice-type-error-19181.rs @@ -1,4 +1,5 @@ // compile-flags:--test +// https://github.com/rust-lang/rust/issues/19181 // rustdoc should not panic when target crate has compilation errors diff --git a/tests/rustdoc/impl-ref-20175.rs b/tests/rustdoc/impl-ref-20175.rs index 5b38ab91af9af..a92db2d0a665b 100644 --- a/tests/rustdoc/impl-ref-20175.rs +++ b/tests/rustdoc/impl-ref-20175.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/20175 + #![crate_name="issue_20175"] pub trait Foo { diff --git a/tests/rustdoc/infinite-redirection-16265-1.rs b/tests/rustdoc/infinite-redirection-16265-1.rs index e13822127b47d..7d72469bd72c7 100644 --- a/tests/rustdoc/infinite-redirection-16265-1.rs +++ b/tests/rustdoc/infinite-redirection-16265-1.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/16265 #![crate_name="issue_16265_1"] pub struct Foo; diff --git a/tests/rustdoc/infinite-redirection-16265-2.rs b/tests/rustdoc/infinite-redirection-16265-2.rs index adb5a67ce6c8b..7a4791c5fd487 100644 --- a/tests/rustdoc/infinite-redirection-16265-2.rs +++ b/tests/rustdoc/infinite-redirection-16265-2.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/16265 #![crate_name="issue_16265_2"] // @hasraw issue_16265_2/index.html 'source' diff --git a/tests/rustdoc/inline-assoc-type-20727-bindings.rs b/tests/rustdoc/inline-assoc-type-20727-bindings.rs index 869ccac8d0944..e59dec29d030a 100644 --- a/tests/rustdoc/inline-assoc-type-20727-bindings.rs +++ b/tests/rustdoc/inline-assoc-type-20727-bindings.rs @@ -1,6 +1,7 @@ // aux-build:issue-20727.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/20727 #![crate_name="issue_20727_2"] extern crate issue_20727; diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs index f7ba175c4b955..005ee3e329416 100644 --- a/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs +++ b/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs @@ -1,6 +1,7 @@ // aux-build:issue-20727.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/20727 #![crate_name="issue_20727_3"] extern crate issue_20727; diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs index b3df0bb9fc28f..1a3f4cd20c1e2 100644 --- a/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs +++ b/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs @@ -1,6 +1,7 @@ // aux-build:issue-20727.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/20727 #![crate_name="issue_20727_4"] extern crate issue_20727; diff --git a/tests/rustdoc/inline-assoc-type-20727-bounds.rs b/tests/rustdoc/inline-assoc-type-20727-bounds.rs index ac7485233cc6b..7cbc8d38107db 100644 --- a/tests/rustdoc/inline-assoc-type-20727-bounds.rs +++ b/tests/rustdoc/inline-assoc-type-20727-bounds.rs @@ -1,6 +1,7 @@ // aux-build:issue-20727.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/20727 #![crate_name="issue_20727"] extern crate issue_20727; diff --git a/tests/rustdoc/macro-ice-16019.rs b/tests/rustdoc/macro-ice-16019.rs index 239d92378d9bb..d0f82e0a314ce 100644 --- a/tests/rustdoc/macro-ice-16019.rs +++ b/tests/rustdoc/macro-ice-16019.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/16019 + macro_rules! define_struct { ($rounds:expr) => ( struct Struct { diff --git a/tests/rustdoc/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc/method-link-foreign-trait-impl-17476.rs index de17af50ccd0f..e52ab6f38c2a5 100644 --- a/tests/rustdoc/method-link-foreign-trait-impl-17476.rs +++ b/tests/rustdoc/method-link-foreign-trait-impl-17476.rs @@ -1,5 +1,6 @@ // aux-build:issue-17476.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/17476 #![crate_name="issue_17476"] diff --git a/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs index 6395edd897d4c..80c559756870c 100644 --- a/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs +++ b/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/15318 #![crate_name="issue_15318_3"] #![feature(rustc_attrs)] diff --git a/tests/rustdoc/primitive-raw-pointer-link-15318.rs b/tests/rustdoc/primitive-raw-pointer-link-15318.rs index dbefc9c3b9291..77f25ff4cff08 100644 --- a/tests/rustdoc/primitive-raw-pointer-link-15318.rs +++ b/tests/rustdoc/primitive-raw-pointer-link-15318.rs @@ -1,5 +1,6 @@ // aux-build:issue-15318.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/15318 #![crate_name="issue_15318"] #![no_std] diff --git a/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs index 5c31a0694a5a5..1b35bb185ed48 100644 --- a/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs +++ b/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs @@ -1,5 +1,6 @@ // aux-build:issue-15318.rs // ignore-cross-compile +// https://github.com/rust-lang/rust/issues/15318 #![crate_name="issue_15318_2"] #![no_std] From 3848ffcee7ae74e15e4b68ad0f45a29f1fc170c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 28 Sep 2023 00:37:20 +0000 Subject: [PATCH 046/103] Tweak wording of missing angle backets in qualified path --- compiler/rustc_parse/messages.ftl | 2 +- compiler/rustc_parse/src/errors.rs | 13 +++- .../rustc_parse/src/parser/diagnostics.rs | 7 +-- tests/ui/did_you_mean/bad-assoc-expr.stderr | 62 ++++++++++++++++--- tests/ui/did_you_mean/bad-assoc-pat.stderr | 41 ++++++++++-- tests/ui/did_you_mean/bad-assoc-ty.stderr | 62 ++++++++++++++++--- tests/ui/parser/issues/issue-89388.stderr | 7 ++- 7 files changed, 162 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 2c4bc7bb5687f..05b6c40620651 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -509,7 +509,7 @@ parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of parse_maybe_recover_from_bad_qpath_stage_2 = missing angle brackets in associated item path - .suggestion = try: `{$ty}` + .suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths parse_maybe_recover_from_bad_type_plus = expected a path on the left-hand side of `+`, not `{$ty}` diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 5d3ec68355203..7c75e440aaabd 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -59,9 +59,18 @@ pub(crate) enum BadTypePlusSub { #[diag(parse_maybe_recover_from_bad_qpath_stage_2)] pub(crate) struct BadQPathStage2 { #[primary_span] - #[suggestion(code = "", applicability = "maybe-incorrect")] pub span: Span, - pub ty: String, + #[subdiagnostic] + pub wrap: WrapType, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +pub(crate) struct WrapType { + #[suggestion_part(code = "<")] + pub lo: Span, + #[suggestion_part(code = ">")] + pub hi: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 6c8ef34063f87..06b1b1523edbd 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -16,7 +16,7 @@ use crate::errors::{ StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, - UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, + UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType, }; use crate::fluent_generated as fluent; @@ -1589,10 +1589,9 @@ impl<'a> Parser<'a> { self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?; path.span = ty_span.to(self.prev_token.span); - let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty)); self.sess.emit_err(BadQPathStage2 { - span: path.span, - ty: format!("<{}>::{}", ty_str, pprust::path_to_string(&path)), + span: ty_span, + wrap: WrapType { lo: ty_span.shrink_to_lo(), hi: ty_span.shrink_to_hi() }, }); let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`. diff --git a/tests/ui/did_you_mean/bad-assoc-expr.stderr b/tests/ui/did_you_mean/bad-assoc-expr.stderr index c295cac9aa4b2..b83078e21b6a1 100644 --- a/tests/ui/did_you_mean/bad-assoc-expr.stderr +++ b/tests/ui/did_you_mean/bad-assoc-expr.stderr @@ -2,60 +2,104 @@ error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:3:5 | LL | [i32; 4]::clone(&a); - | ^^^^^^^^^^^^^^^ help: try: `<[i32; 4]>::clone` + | ^^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <[i32; 4]>::clone(&a); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:6:5 | LL | [i32]::as_ref(&a); - | ^^^^^^^^^^^^^ help: try: `<[i32]>::as_ref` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <[i32]>::as_ref(&a); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:9:5 | LL | (u8)::clone(&0); - | ^^^^^^^^^^^ help: try: `<(u8)>::clone` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <(u8)>::clone(&0); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:12:5 | LL | (u8, u8)::clone(&(0, 0)); - | ^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::clone` + | ^^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <(u8, u8)>::clone(&(0, 0)); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:15:6 | LL | &(u8)::clone(&0); - | ^^^^^^^^^^^ help: try: `<(u8)>::clone` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | &<(u8)>::clone(&0); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:18:10 | LL | 10 + (u8)::clone(&0); - | ^^^^^^^^^^^ help: try: `<(u8)>::clone` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | 10 + <(u8)>::clone(&0); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:32:13 | LL | let _ = ty!()::clone(&0); - | ^^^^^^^^^^^^ help: try: `::clone` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | let _ = ::clone(&0); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:34:5 | LL | ty!()::clone(&0); - | ^^^^^^^^^^^^ help: try: `::clone` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | ::clone(&0); + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-expr.rs:23:19 | LL | ($ty: ty) => ($ty::clone(&0)) - | ^^^^^^^^^^ help: try: `<$ty>::clone` + | ^^^ ... LL | expr!(u8); | --------- in this macro invocation | = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info) +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | ($ty: ty) => (<$ty>::clone(&0)) + | + + error: aborting due to 9 previous errors diff --git a/tests/ui/did_you_mean/bad-assoc-pat.stderr b/tests/ui/did_you_mean/bad-assoc-pat.stderr index 19d173f1b423c..8bdeb8ffdd0a8 100644 --- a/tests/ui/did_you_mean/bad-assoc-pat.stderr +++ b/tests/ui/did_you_mean/bad-assoc-pat.stderr @@ -2,42 +2,71 @@ error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:3:9 | LL | [u8]::AssocItem => {} - | ^^^^^^^^^^^^^^^ help: try: `<[u8]>::AssocItem` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <[u8]>::AssocItem => {} + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:6:9 | LL | (u8, u8)::AssocItem => {} - | ^^^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocItem` + | ^^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <(u8, u8)>::AssocItem => {} + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:9:9 | LL | _::AssocItem => {} - | ^^^^^^^^^^^^ help: try: `<_>::AssocItem` + | ^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | <_>::AssocItem => {} + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:14:10 | LL | &(u8,)::AssocItem => {} - | ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | &<(u8,)>::AssocItem => {} + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:32:9 | LL | ty!()::AssocItem => {} - | ^^^^^^^^^^^^^^^^ help: try: `::AssocItem` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | ::AssocItem => {} + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-pat.rs:21:19 | LL | ($ty: ty) => ($ty::AssocItem) - | ^^^^^^^^^^^^^^ help: try: `<$ty>::AssocItem` + | ^^^ ... LL | pat!(u8) => {} | -------- in this macro invocation | = note: this error originates in the macro `pat` (in Nightly builds, run with -Z macro-backtrace for more info) +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | ($ty: ty) => (<$ty>::AssocItem) + | + + error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope --> $DIR/bad-assoc-pat.rs:3:15 diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr index 55096e95df7e0..efa6bb6682407 100644 --- a/tests/ui/did_you_mean/bad-assoc-ty.stderr +++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr @@ -2,60 +2,104 @@ error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:1:10 | LL | type A = [u8; 4]::AssocTy; - | ^^^^^^^^^^^^^^^^ help: try: `<[u8; 4]>::AssocTy` + | ^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type A = <[u8; 4]>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:5:10 | LL | type B = [u8]::AssocTy; - | ^^^^^^^^^^^^^ help: try: `<[u8]>::AssocTy` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type B = <[u8]>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:9:10 | LL | type C = (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type C = <(u8)>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:13:10 | LL | type D = (u8, u8)::AssocTy; - | ^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocTy` + | ^^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type D = <(u8, u8)>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:17:10 | LL | type E = _::AssocTy; - | ^^^^^^^^^^ help: try: `<_>::AssocTy` + | ^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type E = <_>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:21:19 | LL | type F = &'static (u8)::AssocTy; - | ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy` + | ^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type F = &'static <(u8)>::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:27:10 | LL | type G = dyn 'static + (Send)::AssocTy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `::AssocTy` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type G = ::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:46:10 | LL | type I = ty!()::AssocTy; - | ^^^^^^^^^^^^^^ help: try: `::AssocTy` + | ^^^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | type I = ::AssocTy; + | + + error: missing angle brackets in associated item path --> $DIR/bad-assoc-ty.rs:39:19 | LL | ($ty: ty) => ($ty::AssocTy); - | ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy` + | ^^^ ... LL | type J = ty!(u8); | ------- in this macro invocation | = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | ($ty: ty) => (<$ty>::AssocTy); + | + + error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:1:10 diff --git a/tests/ui/parser/issues/issue-89388.stderr b/tests/ui/parser/issues/issue-89388.stderr index cf28bef0f4ab0..366d05c2d9480 100644 --- a/tests/ui/parser/issues/issue-89388.stderr +++ b/tests/ui/parser/issues/issue-89388.stderr @@ -2,7 +2,12 @@ error: missing angle brackets in associated item path --> $DIR/issue-89388.rs:5:24 | LL | let _ = option.map([_]::to_vec); - | ^^^^^^^^^^^ help: try: `<[_]>::to_vec` + | ^^^ + | +help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths + | +LL | let _ = option.map(<[_]>::to_vec); + | + + error: aborting due to previous error From f99fdac3df5f97287857786bcce9660250009cbf Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Thu, 28 Sep 2023 10:09:53 +0800 Subject: [PATCH 047/103] ci: upgrade to crosstool-ng 1.26.0 --- src/ci/docker/README.md | 4 ++-- .../dist-loongarch64-linux/Dockerfile | 5 ++--- src/ci/docker/scripts/crosstool-ng-git.sh | 17 ----------------- src/ci/docker/scripts/crosstool-ng.sh | 2 +- 4 files changed, 5 insertions(+), 23 deletions(-) delete mode 100644 src/ci/docker/scripts/crosstool-ng-git.sh diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index b83b198780ba7..2e64568371306 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -271,7 +271,7 @@ For targets: `loongarch64-unknown-linux-gnu` - Operating System > Linux kernel version = 5.19.16 - Binary utilities > Version of binutils = 2.40 - C-library > glibc version = 2.36 -- C compiler > gcc version = 13.1.0 +- C compiler > gcc version = 13.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM ### `mips-linux-gnu.defconfig` @@ -407,7 +407,7 @@ For targets: `riscv64-unknown-linux-gnu` - Target options > Bitness = 64-bit - Operating System > Target OS = linux - Operating System > Linux kernel version = 4.20.17 -- Binary utilities > Version of binutils = 2.32 +- Binary utilities > Version of binutils = 2.36.1 - C-library > glibc version = 2.29 - C compiler > gcc version = 8.5.0 - C compiler > C++ = ENABLE -- to cross compile LLVM diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 78689c429c2e3..55c737bd0aa31 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -3,9 +3,8 @@ FROM ubuntu:22.04 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh -# The latest released version does not support LoongArch. -COPY scripts/crosstool-ng-git.sh /scripts/ -RUN sh /scripts/crosstool-ng-git.sh +COPY scripts/crosstool-ng.sh /scripts/ +RUN sh /scripts/crosstool-ng.sh COPY scripts/rustbuild-setup.sh /scripts/ RUN sh /scripts/rustbuild-setup.sh diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh deleted file mode 100644 index b8d3991532717..0000000000000 --- a/src/ci/docker/scripts/crosstool-ng-git.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -ex - -URL=https://github.com/crosstool-ng/crosstool-ng -REV=227d99d7f3115f3a078595a580d2b307dcd23e93 - -mkdir crosstool-ng -cd crosstool-ng -git init -git fetch --depth=1 ${URL} ${REV} -git reset --hard FETCH_HEAD -./bootstrap -./configure --prefix=/usr/local -make -j$(nproc) -make install -cd .. -rm -rf crosstool-ng diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh index a28d7bde2accf..c3ee19b8d2c1f 100644 --- a/src/ci/docker/scripts/crosstool-ng.sh +++ b/src/ci/docker/scripts/crosstool-ng.sh @@ -1,7 +1,7 @@ #!/bin/sh set -ex -CT_NG=1.25.0 +CT_NG=1.26.0 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz" curl -Lf $url | tar xzf - From e2f70324089a2eb75d52552c058170e37d0064f0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 27 Sep 2023 22:55:34 -0700 Subject: [PATCH 048/103] Fix "unresolved link to std::fmt::Error" error: unresolved link to `std::fmt::Error` --> library/core/src/fmt/mod.rs:115:52 | 115 | /// This function will return an instance of [`std::fmt::Error`] on error. | | = note: `-D rustdoc::broken-intra-doc-links` implied by `-D warnings` --- library/core/src/fmt/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 5c6359a9025e3..d99d9dea87cf7 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -112,7 +112,7 @@ pub trait Write { /// /// # Errors /// - /// This function will return an instance of [`std::fmt::Error`] on error. + /// This function will return an instance of [`std::fmt::Error`][Error] on error. /// /// The purpose of that error is to abort the formatting operation when the underlying /// destination encounters some error preventing it from accepting more text; it should From 5e26e8c5bdd82c507f1ab4fdb29cad6f5861e4bd Mon Sep 17 00:00:00 2001 From: Anshul <83179501+ArchUsr64@users.noreply.github.com> Date: Thu, 28 Sep 2023 11:58:37 +0530 Subject: [PATCH 049/103] changed 'rotate' to 'rotating' --- library/core/src/slice/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0d635aced85bf..a19fcf93c4d90 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3410,7 +3410,7 @@ impl [T] { /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']); /// ``` /// - /// Rotate a subslice: + /// Rotating a subslice: /// /// ``` /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f']; From 9bdf9e754e82cadfacdb081ef2b0a0fe8df9be25 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 28 Sep 2023 00:13:02 -0700 Subject: [PATCH 050/103] Update stability attribute for child stream From impls --- library/std/src/os/unix/process.rs | 6 +++--- library/std/src/os/windows/process.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 95f10bcb04e3f..80eae4a63920a 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -438,7 +438,7 @@ impl From for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStdin { #[inline] fn from(fd: OwnedFd) -> process::ChildStdin { @@ -468,7 +468,7 @@ impl From for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStdout { #[inline] fn from(fd: OwnedFd) -> process::ChildStdout { @@ -498,7 +498,7 @@ impl From for OwnedFd { /// /// The provided file descriptor must point to a pipe /// with the `CLOEXEC` flag set. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStderr { #[inline] fn from(fd: OwnedFd) -> process::ChildStderr { diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 2f989a77f14ec..875b531c5cae2 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -110,7 +110,7 @@ impl IntoRawHandle for process::ChildStderr { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStdin { fn from(handle: OwnedHandle) -> process::ChildStdin { let handle = sys::handle::Handle::from_inner(handle); @@ -123,7 +123,7 @@ impl From for process::ChildStdin { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStdout { fn from(handle: OwnedHandle) -> process::ChildStdout { let handle = sys::handle::Handle::from_inner(handle); @@ -136,7 +136,7 @@ impl From for process::ChildStdout { /// /// The provided handle must be asynchronous, as reading and /// writing from and to it is implemented using asynchronous APIs. -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")] impl From for process::ChildStderr { fn from(handle: OwnedHandle) -> process::ChildStderr { let handle = sys::handle::Handle::from_inner(handle); From 02b01a46de62d26a2769b7546481a6ab08da82b8 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 21 Sep 2023 11:52:06 +0300 Subject: [PATCH 051/103] make region struct and add neccesasry types --- compiler/stable_mir/src/ty.rs | 49 +++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 82007e3068340..b7cd57f753aa2 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -1,7 +1,7 @@ use super::{ mir::Safety, mir::{Body, Mutability}, - with, AllocId, DefId, + with, AllocId, DefId, Symbol, }; use crate::Opaque; use std::fmt::{self, Debug, Formatter}; @@ -34,7 +34,52 @@ pub struct Const { } type Ident = Opaque; -pub type Region = Opaque; +pub(crate) struct Region { + kind: RegionKind, +} + +enum RegionKind { + ReEarlyBound(EarlyBoundRegion), + ReLateBound(DebruijnIndex, BoundRegion), + ReFree(FreeRegion), + ReStatic, + ReVar(RegionVid), + RePlaceholder(Placeholder), + ReErased, + ReError(ErrorGuaranteed), +} + +pub(crate) type DebruijnIndex = u32; + +pub struct EarlyBoundRegion { + pub def_id: DefId, + pub index: u32, + pub name: Symbol, +} + +pub(crate) type BoundVar = u32; + +pub struct BoundRegion { + pub var: BoundVar, + pub kind: BoundRegionKind, +} + +pub struct FreeRegion { + pub scope: DefId, + pub bound_region: BoundRegionKind, +} + +pub(crate) type RegionVid = u32; + +pub(crate) type UniverseIndex = u32; + +pub struct Placeholder { + pub universe: UniverseIndex, + pub bound: T, +} + +pub(crate) type ErrorGuaranteed = (); + #[derive(Clone, Copy, PartialEq, Eq)] pub struct Span(pub usize); From e49aa04000b3443a8cf1650ee0a75d48ddf115d0 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 21 Sep 2023 12:01:30 +0300 Subject: [PATCH 052/103] add RegionDef --- compiler/rustc_smir/src/rustc_internal/mod.rs | 4 +++ compiler/rustc_smir/src/rustc_smir/mod.rs | 28 ++++++++++++++++++- compiler/stable_mir/src/ty.rs | 9 ++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 441aafd1257ba..1a9dea99f643f 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -86,6 +86,10 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::ImplDef(self.create_def_id(did)) } + pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef { + stable_mir::ty::RegionDef(self.create_def_id(did)) + } + pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov { stable_mir::ty::Prov(self.create_alloc_id(aid)) } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 5ff17613b4e56..890faa4538e23 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,7 +7,12 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use hir::def::DefKind; +use crate::rustc_internal::{self, opaque}; +use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; +use crate::stable_mir::ty::{ + EarlyBoundRegion, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy, +}; +use crate::stable_mir::{self, CompilerError, Context}; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -1506,6 +1511,27 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { } } +impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { + type T = stable_mir::ty::RegionKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion { + def_id: tables.region_def(early_reg.def_id), + index: early_reg.index, + name: early_reg.name.to_string(), + }), + ty::ReLateBound(_, _) => todo!(), + ty::ReFree(_) => todo!(), + ty::ReStatic => todo!(), + ty::ReVar(_) => todo!(), + ty::RePlaceholder(_) => todo!(), + ty::ReErased => todo!(), + ty::ReError(_) => todo!(), + } + } +} + impl<'tcx> Stable<'tcx> for rustc_span::Span { type T = stable_mir::ty::Span; diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index b7cd57f753aa2..f6f433c2bad01 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -38,7 +38,7 @@ pub(crate) struct Region { kind: RegionKind, } -enum RegionKind { +pub enum RegionKind { ReEarlyBound(EarlyBoundRegion), ReLateBound(DebruijnIndex, BoundRegion), ReFree(FreeRegion), @@ -52,7 +52,7 @@ enum RegionKind { pub(crate) type DebruijnIndex = u32; pub struct EarlyBoundRegion { - pub def_id: DefId, + pub def_id: RegionDef, pub index: u32, pub name: Symbol, } @@ -65,7 +65,7 @@ pub struct BoundRegion { } pub struct FreeRegion { - pub scope: DefId, + pub scope: RegionDef, pub bound_region: BoundRegionKind, } @@ -197,6 +197,9 @@ pub struct ConstDef(pub DefId); #[derive(Clone, PartialEq, Eq, Debug)] pub struct ImplDef(pub DefId); +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct RegionDef(pub(crate) DefId); + #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec); From 5dc2214884483496ef8cf4a8fa7f1be189669974 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 21 Sep 2023 12:12:06 +0300 Subject: [PATCH 053/103] add stable for RegionKind --- compiler/rustc_smir/src/rustc_smir/mod.rs | 37 ++++++++++++++++------- compiler/stable_mir/src/ty.rs | 2 +- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 890faa4538e23..73a4798527d63 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -10,7 +10,8 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; use crate::stable_mir::ty::{ - EarlyBoundRegion, FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy, + BoundRegion, EarlyBoundRegion, FloatTy, FreeRegion, GenericParamDef, IntTy, Movability, Region, + RigidTy, Span, TyKind, UintTy, }; use crate::stable_mir::{self, CompilerError, Context}; use rustc_hir as hir; @@ -1505,9 +1506,8 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity { impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { type T = stable_mir::ty::Region; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - // FIXME: add a real implementation of stable regions - opaque(self) + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + Region { kind: self.kind().stable(tables) } } } @@ -1515,19 +1515,34 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { type T = stable_mir::ty::RegionKind; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use crate::stable_mir::ty::RegionKind; match self { ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion { def_id: tables.region_def(early_reg.def_id), index: early_reg.index, name: early_reg.name.to_string(), }), - ty::ReLateBound(_, _) => todo!(), - ty::ReFree(_) => todo!(), - ty::ReStatic => todo!(), - ty::ReVar(_) => todo!(), - ty::RePlaceholder(_) => todo!(), - ty::ReErased => todo!(), - ty::ReError(_) => todo!(), + ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound( + db_index.as_u32(), + BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, + ), + ty::ReFree(free_reg) => RegionKind::ReFree(FreeRegion { + scope: tables.region_def(free_reg.scope), + bound_region: free_reg.bound_region.stable(tables), + }), + ty::ReStatic => RegionKind::ReStatic, + ty::ReVar(vid_reg) => RegionKind::ReVar(vid_reg.as_u32()), + ty::RePlaceholder(place_holder) => { + RegionKind::RePlaceholder(stable_mir::ty::Placeholder { + universe: place_holder.universe.as_u32(), + bound: BoundRegion { + var: place_holder.bound.var.as_u32(), + kind: place_holder.bound.kind.stable(tables), + }, + }) + } + ty::ReErased => RegionKind::ReErased, + ty::ReError(_) => RegionKind::ReError(()), } } } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index f6f433c2bad01..a47621337f0f1 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -35,7 +35,7 @@ pub struct Const { type Ident = Opaque; pub(crate) struct Region { - kind: RegionKind, + pub kind: RegionKind, } pub enum RegionKind { From d83559939cf89f717d1fcd8266c5f457df6e37dd Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 21 Sep 2023 12:18:10 +0300 Subject: [PATCH 054/103] make reg public and add visit, fold --- compiler/stable_mir/src/fold.rs | 8 +++++++- compiler/stable_mir/src/ty.rs | 9 ++++++++- compiler/stable_mir/src/visitor.rs | 8 +++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index 16ae62311aaf0..edaf55f2aeb81 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -4,7 +4,7 @@ use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, - GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst, + GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst, }; pub trait Folder: Sized { @@ -106,6 +106,12 @@ impl Foldable for GenericArgs { } } +impl Foldable for Region { + fn super_fold(&self, _folder: &mut V) -> ControlFlow { + ControlFlow::Continue(self.clone()) + } +} + impl Foldable for GenericArgKind { fn super_fold(&self, folder: &mut V) -> ControlFlow { let mut this = self.clone(); diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index a47621337f0f1..d05fa4a2ed4bc 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -34,10 +34,13 @@ pub struct Const { } type Ident = Opaque; -pub(crate) struct Region { + +#[derive(Debug, Clone)] +pub struct Region { pub kind: RegionKind, } +#[derive(Debug, Clone)] pub enum RegionKind { ReEarlyBound(EarlyBoundRegion), ReLateBound(DebruijnIndex, BoundRegion), @@ -51,6 +54,7 @@ pub enum RegionKind { pub(crate) type DebruijnIndex = u32; +#[derive(Debug, Clone)] pub struct EarlyBoundRegion { pub def_id: RegionDef, pub index: u32, @@ -59,11 +63,13 @@ pub struct EarlyBoundRegion { pub(crate) type BoundVar = u32; +#[derive(Debug, Clone)] pub struct BoundRegion { pub var: BoundVar, pub kind: BoundRegionKind, } +#[derive(Debug, Clone)] pub struct FreeRegion { pub scope: RegionDef, pub bound_region: BoundRegionKind, @@ -73,6 +79,7 @@ pub(crate) type RegionVid = u32; pub(crate) type UniverseIndex = u32; +#[derive(Debug, Clone)] pub struct Placeholder { pub universe: UniverseIndex, pub bound: T, diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 9c3b4cd994a48..8d5a25008d78a 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -4,7 +4,7 @@ use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, - Promoted, RigidTy, TermKind, Ty, UnevaluatedConst, + Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, }; pub trait Visitor: Sized { @@ -101,6 +101,12 @@ impl Visitable for GenericArgs { } } +impl Visitable for Region { + fn super_visit(&self, _visitor: &mut V) -> ControlFlow { + ControlFlow::Continue(()) + } +} + impl Visitable for GenericArgKind { fn super_visit(&self, visitor: &mut V) -> ControlFlow { match self { From 2069e8c218fcc8428ae400fe91b245c977859036 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 11:36:53 +0300 Subject: [PATCH 055/103] fix imports --- compiler/rustc_smir/src/rustc_smir/mod.rs | 11 +++-------- compiler/stable_mir/src/ty.rs | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 73a4798527d63..2623ce8fd11f6 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,13 +7,8 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::rustc_internal::{self, opaque}; -use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{ - BoundRegion, EarlyBoundRegion, FloatTy, FreeRegion, GenericParamDef, IntTy, Movability, Region, - RigidTy, Span, TyKind, UintTy, -}; -use crate::stable_mir::{self, CompilerError, Context}; +use crate::rustc_smir::hir::def::DefKind; +use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -1515,7 +1510,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { type T = stable_mir::ty::RegionKind; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use crate::stable_mir::ty::RegionKind; + use stable_mir::ty::RegionKind; match self { ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion { def_id: tables.region_def(early_reg.def_id), diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index d05fa4a2ed4bc..20ef514e4ab03 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -205,7 +205,7 @@ pub struct ConstDef(pub DefId); pub struct ImplDef(pub DefId); #[derive(Clone, PartialEq, Eq, Debug)] -pub struct RegionDef(pub(crate) DefId); +pub struct RegionDef(pub DefId); #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec); From da2f897e590be03eb4acddfd9df804545b738b65 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 11:43:21 +0300 Subject: [PATCH 056/103] remove un-needed variants --- compiler/rustc_smir/src/rustc_smir/mod.rs | 9 ++------- compiler/stable_mir/src/ty.rs | 13 ------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 2623ce8fd11f6..3b6bacaa168ff 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,7 +8,7 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use crate::rustc_smir::hir::def::DefKind; -use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region}; +use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region}; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; @@ -1521,12 +1521,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { db_index.as_u32(), BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, ), - ty::ReFree(free_reg) => RegionKind::ReFree(FreeRegion { - scope: tables.region_def(free_reg.scope), - bound_region: free_reg.bound_region.stable(tables), - }), ty::ReStatic => RegionKind::ReStatic, - ty::ReVar(vid_reg) => RegionKind::ReVar(vid_reg.as_u32()), ty::RePlaceholder(place_holder) => { RegionKind::RePlaceholder(stable_mir::ty::Placeholder { universe: place_holder.universe.as_u32(), @@ -1537,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { }) } ty::ReErased => RegionKind::ReErased, - ty::ReError(_) => RegionKind::ReError(()), + _=> unimplemented!() } } } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 20ef514e4ab03..6029e3c11adef 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -44,12 +44,9 @@ pub struct Region { pub enum RegionKind { ReEarlyBound(EarlyBoundRegion), ReLateBound(DebruijnIndex, BoundRegion), - ReFree(FreeRegion), ReStatic, - ReVar(RegionVid), RePlaceholder(Placeholder), ReErased, - ReError(ErrorGuaranteed), } pub(crate) type DebruijnIndex = u32; @@ -69,14 +66,6 @@ pub struct BoundRegion { pub kind: BoundRegionKind, } -#[derive(Debug, Clone)] -pub struct FreeRegion { - pub scope: RegionDef, - pub bound_region: BoundRegionKind, -} - -pub(crate) type RegionVid = u32; - pub(crate) type UniverseIndex = u32; #[derive(Debug, Clone)] @@ -85,8 +74,6 @@ pub struct Placeholder { pub bound: T, } -pub(crate) type ErrorGuaranteed = (); - #[derive(Clone, Copy, PartialEq, Eq)] pub struct Span(pub usize); From bb17fe8bf5b32cd7fefbab95b6b1b7ee04628dbd Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 12:32:15 +0300 Subject: [PATCH 057/103] add real folder to Region --- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- compiler/stable_mir/src/fold.rs | 41 +++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 3b6bacaa168ff..128ba07654458 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -1532,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { }) } ty::ReErased => RegionKind::ReErased, - _=> unimplemented!() + _ => unimplemented!(), } } } diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index edaf55f2aeb81..bdc80bc8aa37c 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -1,6 +1,9 @@ use std::ops::ControlFlow; -use crate::Opaque; +use crate::{ + ty::{self, BoundRegion, BoundRegionKind}, + Opaque, +}; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, @@ -15,6 +18,9 @@ pub trait Folder: Sized { fn fold_const(&mut self, c: &Const) -> ControlFlow { c.super_fold(self) } + fn visit_reg(&mut self, reg: &Region) -> ControlFlow { + reg.super_fold(self) + } } pub trait Foldable: Sized + Clone { @@ -107,8 +113,39 @@ impl Foldable for GenericArgs { } impl Foldable for Region { + fn fold(&self, folder: &mut V) -> ControlFlow { + folder.visit_reg(self) + } + fn super_fold(&self, folder: &mut V) -> ControlFlow { + let mut kind = self.kind.clone(); + match &mut kind { + crate::ty::RegionKind::ReEarlyBound(_) => {} + crate::ty::RegionKind::ReLateBound(_, bound_reg) => { + *bound_reg = bound_reg.fold(folder)? + } + crate::ty::RegionKind::ReStatic => {} + crate::ty::RegionKind::RePlaceholder(bound_reg) => { + bound_reg.bound = bound_reg.bound.fold(folder)? + } + crate::ty::RegionKind::ReErased => {} + } + ControlFlow::Continue(ty::Region { kind: kind }.into()) + } +} + +impl Foldable for BoundRegion { + fn super_fold(&self, folder: &mut V) -> ControlFlow { + ControlFlow::Continue(BoundRegion { var: self.var, kind: self.kind.fold(folder)? }) + } +} + +impl Foldable for BoundRegionKind { fn super_fold(&self, _folder: &mut V) -> ControlFlow { - ControlFlow::Continue(self.clone()) + match self { + BoundRegionKind::BrAnon => ControlFlow::Continue(self.clone()), + BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(self.clone()), + BoundRegionKind::BrEnv => ControlFlow::Continue(self.clone()), + } } } From 17dfb18bd1ad15ce4437bb44ba30b0c82aad3e07 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 10:43:41 +0200 Subject: [PATCH 058/103] fixup! isqrt: initial implementation Fix C-ism and type inference. --- library/core/src/num/uint_macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f8005694cebc1..b232d5d50cb5c 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1997,11 +1997,11 @@ macro_rules! uint_impl { return self; } - let mut x: Self = self; - let mut c: Self = 0; - let mut d: Self = 1 << (self.ilog2() & !1); + let mut x = self; + let mut c = 0; + let mut d = 1 << (self.ilog2() & !1); - while (d != 0) { + while d != 0 { if x >= c + d { x -= c + d; c = (c >> 1) + d; From c97ab231415aa46cd1d35e8d00d601dec0d23e86 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 11:15:43 +0200 Subject: [PATCH 059/103] isqrt: fix stability --- library/core/src/lib.rs | 1 + library/core/src/num/int_macros.rs | 10 ++++++---- library/core/src/num/uint_macros.rs | 5 +++-- library/core/tests/lib.rs | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8b04bafcda54a..be734a9ba5298 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -178,6 +178,7 @@ #![feature(ip)] #![feature(ip_bits)] #![feature(is_ascii_octdigit)] +#![feature(isqrt)] #![feature(maybe_uninit_uninit_array)] #![feature(ptr_alignment_type)] #![feature(ptr_metadata)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 8bc82b5fc8898..d1fe8b55cc1b3 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -906,10 +906,11 @@ macro_rules! int_impl { /// /// Basic usage: /// ``` + /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] /// ``` - #[stable(feature = "isqrt", since = "1.73.0")] - #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[unstable(feature = "isqrt", issue = "none")] + #[rustc_const_unstable(feature = "isqrt", issue = "none")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2094,10 +2095,11 @@ macro_rules! int_impl { /// /// Basic usage: /// ``` + /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "1.73.0")] - #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[unstable(feature = "isqrt", issue = "none")] + #[rustc_const_unstable(feature = "isqrt", issue = "none")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index b232d5d50cb5c..5de672d5d7eca 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1985,10 +1985,11 @@ macro_rules! uint_impl { /// /// Basic usage: /// ``` + /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[stable(feature = "isqrt", since = "1.73.0")] - #[rustc_const_stable(feature = "isqrt", since = "1.73.0")] + #[unstable(feature = "isqrt", issue = "none")] + #[rustc_const_unstable(feature = "isqrt", issue = "none")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 17011b845cfb5..4d67f6f151185 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -56,6 +56,7 @@ #![feature(min_specialization)] #![feature(numfmt)] #![feature(num_midpoint)] +#![feature(isqrt)] #![feature(step_trait)] #![feature(str_internals)] #![feature(std_internals)] From fed72e06644db562c043f2f9cec99f2b2d9cba9d Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 12:47:21 +0300 Subject: [PATCH 060/103] add visitor for Region --- compiler/stable_mir/src/visitor.rs | 37 ++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 8d5a25008d78a..a26a1d8cfb9a4 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,6 +1,9 @@ use std::ops::ControlFlow; -use crate::Opaque; +use crate::{ + ty::{BoundRegion, BoundRegionKind}, + Opaque, +}; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, @@ -15,6 +18,9 @@ pub trait Visitor: Sized { fn visit_const(&mut self, c: &Const) -> ControlFlow { c.super_visit(self) } + fn visit_reg(&mut self, reg: &Region) -> ControlFlow { + reg.super_visit(self) + } } pub trait Visitable { @@ -102,11 +108,38 @@ impl Visitable for GenericArgs { } impl Visitable for Region { - fn super_visit(&self, _visitor: &mut V) -> ControlFlow { + fn visit(&self, visitor: &mut V) -> ControlFlow { + visitor.visit_reg(self) + } + + fn super_visit(&self, visitor: &mut V) -> ControlFlow { + match self.kind.clone() { + crate::ty::RegionKind::ReEarlyBound(_) => {} + crate::ty::RegionKind::ReLateBound(_, bound_reg) => bound_reg.visit(visitor)?, + crate::ty::RegionKind::ReStatic => {} + crate::ty::RegionKind::RePlaceholder(bound_reg) => bound_reg.bound.visit(visitor)?, + crate::ty::RegionKind::ReErased => {} + } ControlFlow::Continue(()) } } +impl Visitable for BoundRegion { + fn super_visit(&self, visitor: &mut V) -> ControlFlow { + self.kind.visit(visitor) + } +} + +impl Visitable for BoundRegionKind { + fn super_visit(&self, _visitor: &mut V) -> ControlFlow { + match self { + BoundRegionKind::BrAnon => ControlFlow::Continue(()), + BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(()), + BoundRegionKind::BrEnv => ControlFlow::Continue(()), + } + } +} + impl Visitable for GenericArgKind { fn super_visit(&self, visitor: &mut V) -> ControlFlow { match self { From 51463175a46599eb69375861bfe3626f68d643a4 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 12:12:18 +0200 Subject: [PATCH 061/103] isqrt: cite source and rename variables to match original C code --- library/core/src/num/uint_macros.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 5de672d5d7eca..371d6e180c2bf 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1998,21 +1998,26 @@ macro_rules! uint_impl { return self; } - let mut x = self; - let mut c = 0; - let mut d = 1 << (self.ilog2() & !1); - - while d != 0 { - if x >= c + d { - x -= c + d; - c = (c >> 1) + d; + // The algorithm is based on the one presented in + // + // which cites as source the following C code: + // . + + let mut op = self; + let mut res = 0; + let mut one = 1 << (self.ilog2() & !1); + + while one != 0 { + if op >= res + one { + op -= res + one; + res = (res >> 1) + one; } else { - c >>= 1; + res >>= 1; } - d >>= 2; + one >>= 2; } - c + res } /// Performs Euclidean division. From 77f9eae9956f6c7c23bdf81c2efdd47625382ea2 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 12:32:58 +0200 Subject: [PATCH 062/103] fixup! isqrt: fix stability --- library/core/src/num/int_macros.rs | 8 ++++---- library/core/src/num/uint_macros.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index d1fe8b55cc1b3..3cbb55af3bc66 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -909,8 +909,8 @@ macro_rules! int_impl { /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")] /// ``` - #[unstable(feature = "isqrt", issue = "none")] - #[rustc_const_unstable(feature = "isqrt", issue = "none")] + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -2098,8 +2098,8 @@ macro_rules! int_impl { /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[unstable(feature = "isqrt", issue = "none")] - #[rustc_const_unstable(feature = "isqrt", issue = "none")] + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 371d6e180c2bf..565fc1930ea4f 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1988,8 +1988,8 @@ macro_rules! uint_impl { /// #![feature(isqrt)] #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")] /// ``` - #[unstable(feature = "isqrt", issue = "none")] - #[rustc_const_unstable(feature = "isqrt", issue = "none")] + #[unstable(feature = "isqrt", issue = "116226")] + #[rustc_const_unstable(feature = "isqrt", issue = "116226")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From b325e9c60df758f1f1538c93e44b120a8fbf6d63 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 28 Sep 2023 13:41:02 +0200 Subject: [PATCH 063/103] Update LLVM submodule --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 42263494d29fe..d404cba4e39df 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 42263494d29febc26d3c1ebdaa7b63677573ec47 +Subproject commit d404cba4e39df595710869988ded7cbe1104b52f From fcdfd5b0b9efcf7797b0f1bf7e7ed47ff99de198 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 13:59:19 +0200 Subject: [PATCH 064/103] isqrt: `assume` that `isqrt` takes half as many bits https://github.com/rust-lang/rust/issues/89273#issuecomment-970581089 --- library/core/src/num/uint_macros.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 565fc1930ea4f..f2190efa4d3c9 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2017,6 +2017,13 @@ macro_rules! uint_impl { one >>= 2; } + // SAFETY: the result is positive and fits in an integer with half as many bits. + // Inform the optimizer about it. + unsafe { + intrinsics::assume(0 < res); + intrinsics::assume(res < 1 << (Self::BITS / 2)); + } + res } From 66bc682caba7d7c2ea68764e885b337e7610362e Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Wed, 27 Sep 2023 11:01:41 -0400 Subject: [PATCH 065/103] Fix `noop_method_call` detection for new diagnostic items --- compiler/rustc_lint/src/noop_method_call.rs | 6 ++++++ tests/ui/lint/noop-method-call.fixed | 13 +++++++++++++ tests/ui/lint/noop-method-call.rs | 13 +++++++++++++ tests/ui/lint/noop-method-call.stderr | 14 +++++++------- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index bc0b9d6d81871..cfbca6efbfa54 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -98,6 +98,12 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return }; // (Re)check that it implements the noop diagnostic. let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return }; + if !matches!( + name, + sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref + ) { + return; + } let receiver_ty = cx.typeck_results().expr_ty(receiver); let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); diff --git a/tests/ui/lint/noop-method-call.fixed b/tests/ui/lint/noop-method-call.fixed index eeb80279fd816..4d9834f7df625 100644 --- a/tests/ui/lint/noop-method-call.fixed +++ b/tests/ui/lint/noop-method-call.fixed @@ -1,6 +1,7 @@ // check-pass // run-rustfix +#![feature(rustc_attrs)] #![allow(unused)] use std::borrow::Borrow; @@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType) { non_clone_type; //~^ WARN call to `.clone()` on a reference in this situation does nothing } + +struct DiagnosticClone; +impl Clone for DiagnosticClone { + #[rustc_diagnostic_item = "other_clone"] + fn clone(&self) -> Self { + DiagnosticClone + } +} + +fn with_other_diagnostic_item(x: DiagnosticClone) { + x.clone(); +} diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs index 9569a0dfc617e..6242a00e03348 100644 --- a/tests/ui/lint/noop-method-call.rs +++ b/tests/ui/lint/noop-method-call.rs @@ -1,6 +1,7 @@ // check-pass // run-rustfix +#![feature(rustc_attrs)] #![allow(unused)] use std::borrow::Borrow; @@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType) { non_clone_type.clone(); //~^ WARN call to `.clone()` on a reference in this situation does nothing } + +struct DiagnosticClone; +impl Clone for DiagnosticClone { + #[rustc_diagnostic_item = "other_clone"] + fn clone(&self) -> Self { + DiagnosticClone + } +} + +fn with_other_diagnostic_item(x: DiagnosticClone) { + x.clone(); +} diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr index aefc2706fd529..d04f44022eefd 100644 --- a/tests/ui/lint/noop-method-call.stderr +++ b/tests/ui/lint/noop-method-call.stderr @@ -1,5 +1,5 @@ warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:15:25 + --> $DIR/noop-method-call.rs:16:25 | LL | let _ = &mut encoded.clone(); | ^^^^^^^^ help: remove this redundant call @@ -8,7 +8,7 @@ LL | let _ = &mut encoded.clone(); = note: `#[warn(noop_method_call)]` on by default warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:17:21 + --> $DIR/noop-method-call.rs:18:21 | LL | let _ = &encoded.clone(); | ^^^^^^^^ help: remove this redundant call @@ -16,7 +16,7 @@ LL | let _ = &encoded.clone(); = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:23:71 + --> $DIR/noop-method-call.rs:24:71 | LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clone(); | ^^^^^^^^ help: remove this redundant call @@ -24,7 +24,7 @@ LL | let non_clone_type_ref_clone: &PlainType = non_clone_type_ref.clon = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.deref()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:31:63 + --> $DIR/noop-method-call.rs:32:63 | LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); | ^^^^^^^^ help: remove this redundant call @@ -32,7 +32,7 @@ LL | let non_deref_type_deref: &PlainType = non_deref_type.deref(); = note: the type `PlainType` does not implement `Deref`, so calling `deref` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.borrow()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:35:66 + --> $DIR/noop-method-call.rs:36:66 | LL | let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); | ^^^^^^^^^ help: remove this redundant call @@ -40,7 +40,7 @@ LL | let non_borrow_type_borrow: &PlainType = non_borrow_type.borrow(); = note: the type `PlainType` does not implement `Borrow`, so calling `borrow` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:44:19 + --> $DIR/noop-method-call.rs:45:19 | LL | non_clone_type.clone(); | ^^^^^^^^ help: remove this redundant call @@ -48,7 +48,7 @@ LL | non_clone_type.clone(); = note: the type `PlainType` does not implement `Clone`, so calling `clone` on `&PlainType` copies the reference, which does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:49:19 + --> $DIR/noop-method-call.rs:50:19 | LL | non_clone_type.clone(); | ^^^^^^^^ help: remove this redundant call From 25648de28f10799fa6274f64fa12475292231c72 Mon Sep 17 00:00:00 2001 From: Federico Stra Date: Thu, 28 Sep 2023 17:43:01 +0200 Subject: [PATCH 066/103] isqrt: disable long running tests in Miri --- library/core/tests/num/int_macros.rs | 4 ++++ library/core/tests/num/uint_macros.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs index dd0ea5e9238ce..165d9a296176e 100644 --- a/library/core/tests/num/int_macros.rs +++ b/library/core/tests/num/int_macros.rs @@ -299,7 +299,11 @@ macro_rules! int_module { assert_eq!((2 as $T).isqrt(), 1 as $T); assert_eq!((99 as $T).isqrt(), 9 as $T); assert_eq!((100 as $T).isqrt(), 10 as $T); + } + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; for n in 0..=n_max { let isqrt: $T = n.isqrt(); diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs index 1ae7d04875709..955440647eb98 100644 --- a/library/core/tests/num/uint_macros.rs +++ b/library/core/tests/num/uint_macros.rs @@ -214,7 +214,11 @@ macro_rules! uint_module { assert_eq!((99 as $T).isqrt(), 9 as $T); assert_eq!((100 as $T).isqrt(), 10 as $T); assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1); + } + #[cfg(not(miri))] // Miri is too slow + #[test] + fn test_lots_of_isqrt() { let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T; for n in 0..=n_max { let isqrt: $T = n.isqrt(); From ec6f554536b1d3ef0185f93b2b7273a40760c6f6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 Sep 2023 14:24:55 +0000 Subject: [PATCH 067/103] Some tracing cleanups --- compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 7 +++---- compiler/rustc_mir_transform/src/elaborate_drops.rs | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index e24685cb90f73..c9991e499b32a 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -194,6 +194,7 @@ where D: DropElaborator<'b, 'tcx>, 'tcx: 'b, { + #[instrument(level = "trace", skip(self), ret)] fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> { place.ty(self.elaborator.body(), self.tcx()).ty } @@ -220,11 +221,9 @@ where // // FIXME: I think we should just control the flags externally, // and then we do not need this machinery. + #[instrument(level = "debug")] pub fn elaborate_drop(&mut self, bb: BasicBlock) { - debug!("elaborate_drop({:?}, {:?})", bb, self); - let style = self.elaborator.drop_style(self.path, DropFlagMode::Deep); - debug!("elaborate_drop({:?}, {:?}): live - {:?}", bb, self, style); - match style { + match self.elaborator.drop_style(self.path, DropFlagMode::Deep) { DropStyle::Dead => { self.elaborator .patch() diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 6a89d06727576..b62d7da2a4cca 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -170,6 +170,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { self.ctxt.param_env() } + #[instrument(level = "debug", skip(self), ret)] fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle { let ((maybe_live, maybe_dead), multipart) = match mode { DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false), From f5df26dbecf39dccd0833a3a82eb1aea3d127e17 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 Sep 2023 15:00:46 +0000 Subject: [PATCH 068/103] Unconditionally run `RevealAll` pass and run it earlier --- compiler/rustc_mir_transform/src/lib.rs | 2 +- .../rustc_mir_transform/src/reveal_all.rs | 4 --- .../incremental/hashes/function_interfaces.rs | 2 +- ...issue_78442.bar.RevealAll.panic-abort.diff | 26 +++++++++++++++---- ...ssue_78442.bar.RevealAll.panic-unwind.diff | 24 +++++++++++------ tests/ui/polymorphization/generators.rs | 2 ++ tests/ui/polymorphization/generators.stderr | 20 +++++++++++--- .../destructure_tait-ice-113594.rs | 18 +++++++++++++ 8 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9e4bc456d51a2..754f2ee837682 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -480,6 +480,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let passes: &[&dyn MirPass<'tcx>] = &[ // These next passes must be executed together &add_call_guards::CriticalCallEdges, + &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too. &elaborate_drops::ElaborateDrops, // This will remove extraneous landing pads which are no longer // necessary as well as well as forcing any call in a non-unwinding @@ -526,7 +527,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { body, &[ &check_alignment::CheckAlignment, - &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, &uninhabited_enum_branching::UninhabitedEnumBranching, diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 065793348e4c3..0c148837e2375 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -8,10 +8,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; pub struct RevealAll; impl<'tcx> MirPass<'tcx> for RevealAll { - fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 3 || super::inline::Inline.is_enabled(sess) - } - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Do not apply this transformation to generators. if body.generator.is_some() { diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 182ca7d926c6b..23b81705f9aa0 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs @@ -302,7 +302,7 @@ pub fn return_impl_trait() -> i32 { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] +#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")] #[rustc_clean(cfg = "cfail3")] #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")] #[rustc_clean(cfg = "cfail6")] diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff index c94dd2556956c..b532b133a83a5 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff +++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff @@ -15,28 +15,44 @@ StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = hide_foo() -> [return: bb1, unwind unreachable]; + _4 = hide_foo() -> [return: bb1, unwind: bb6]; } bb1: { _3 = &_4; StorageLive(_5); _5 = (); -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind unreachable]; +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; } bb2: { StorageDead(_5); StorageDead(_3); + drop(_4) -> [return: bb3, unwind: bb6]; + } + + bb3: { StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind unreachable]; + drop(_1) -> [return: bb4, unwind: bb7]; } - bb3: { + bb4: { return; } + + bb5 (cleanup): { + drop(_4) -> [return: bb6, unwind terminate(cleanup)]; + } + + bb6 (cleanup): { + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { + resume; + } } diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff index cbfb39115b370..bcebcf297c2b1 100644 --- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff @@ -15,35 +15,43 @@ StorageLive(_2); StorageLive(_3); StorageLive(_4); - _4 = hide_foo() -> [return: bb1, unwind: bb4]; + _4 = hide_foo() -> [return: bb1, unwind: bb6]; } bb1: { _3 = &_4; StorageLive(_5); _5 = (); -- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; -+ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; ++ _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb5]; } bb2: { StorageDead(_5); StorageDead(_3); + drop(_4) -> [return: bb3, unwind: bb6]; + } + + bb3: { StorageDead(_4); StorageDead(_2); _0 = const (); - drop(_1) -> [return: bb3, unwind: bb5]; + drop(_1) -> [return: bb4, unwind continue]; } - bb3: { + bb4: { return; } - bb4 (cleanup): { - drop(_1) -> [return: bb5, unwind terminate(cleanup)]; + bb5 (cleanup): { + drop(_4) -> [return: bb6, unwind terminate(cleanup)]; } - bb5 (cleanup): { + bb6 (cleanup): { + drop(_1) -> [return: bb7, unwind terminate(cleanup)]; + } + + bb7 (cleanup): { resume; } } diff --git a/tests/ui/polymorphization/generators.rs b/tests/ui/polymorphization/generators.rs index 779bac0ace29b..5f157bc3efb7e 100644 --- a/tests/ui/polymorphization/generators.rs +++ b/tests/ui/polymorphization/generators.rs @@ -32,6 +32,7 @@ where #[rustc_polymorphize_error] pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; @@ -57,6 +58,7 @@ pub fn used_type_in_return() -> impl Generator<(), Yield = u32, Retu #[rustc_polymorphize_error] pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr index 32d49d25f02ac..7461beb7b19a4 100644 --- a/tests/ui/polymorphization/generators.stderr +++ b/tests/ui/polymorphization/generators.stderr @@ -8,20 +8,34 @@ LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters - --> $DIR/generators.rs:35:5 + --> $DIR/generators.rs:36:5 | LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | - generic parameter `T` is unused +LL | LL | || { | ^^ error: item has unused generic parameters - --> $DIR/generators.rs:60:5 + --> $DIR/generators.rs:34:8 + | +LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | ^^^^^^^^^^^ - generic parameter `T` is unused + +error: item has unused generic parameters + --> $DIR/generators.rs:62:5 | LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | ------------ generic parameter `T` is unused +LL | LL | || { | ^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: item has unused generic parameters + --> $DIR/generators.rs:60:8 + | +LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { + | ^^^^^^^^^^^^ ------------ generic parameter `T` is unused + +error: aborting due to 4 previous errors; 1 warning emitted diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs new file mode 100644 index 0000000000000..67825e0568c74 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs @@ -0,0 +1,18 @@ +// build-pass + +#![feature(type_alias_impl_trait)] + +pub struct Foo { + /// This type must have nontrivial drop glue + field: String, +} + +pub type Tait = impl Sized; + +pub fn ice_cold(beverage: Tait) { + // Must destructure at least one field of `Foo` + let Foo { field } = beverage; + _ = field; +} + +fn main() {} From 9a40f1aa131e39b01981cd4f276a38a85205caad Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 11 Sep 2023 17:41:10 +0000 Subject: [PATCH 069/103] Remove unnecessary generator-check, which also fixes the issue within async functions --- compiler/rustc_mir_transform/src/reveal_all.rs | 5 ----- .../ui/type-alias-impl-trait/destructure_tait-ice-113594.rs | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 0c148837e2375..cdd208f5c9335 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -9,11 +9,6 @@ pub struct RevealAll; impl<'tcx> MirPass<'tcx> for RevealAll { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // Do not apply this transformation to generators. - if body.generator.is_some() { - return; - } - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body); } diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs index 67825e0568c74..7c2d68cceb8fc 100644 --- a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs +++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs @@ -1,4 +1,5 @@ // build-pass +// edition: 2021 #![feature(type_alias_impl_trait)] @@ -9,7 +10,7 @@ pub struct Foo { pub type Tait = impl Sized; -pub fn ice_cold(beverage: Tait) { +pub async fn ice_cold(beverage: Tait) { // Must destructure at least one field of `Foo` let Foo { field } = beverage; _ = field; From 479fa4a74d74b69c9bc5fc330519a92590f170e4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Sep 2023 10:31:53 +0000 Subject: [PATCH 070/103] Bless mir-opt tests --- ...await.b-{closure#0}.generator_resume.0.mir | 86 ++++++++++--------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir index 4d3baee7f117f..15330b13cc214 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir @@ -2,13 +2,16 @@ /* generator_layout = GeneratorLayout { field_tys: { _0: GeneratorSavedTy { - ty: Alias( - Opaque, - AliasTy { - args: [ - ], - def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}), - }, + ty: Generator( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [ + std::future::ResumeTy, + (), + (), + GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), + (), + ], + Static, ), source_info: SourceInfo { span: $DIR/async_await.rs:15:9: 15:14 (#8), @@ -17,13 +20,16 @@ ignore_for_traits: false, }, _1: GeneratorSavedTy { - ty: Alias( - Opaque, - AliasTy { - args: [ - ], - def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}), - }, + ty: Generator( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [ + std::future::ResumeTy, + (), + (), + GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), + (), + ], + Static, ), source_info: SourceInfo { span: $DIR/async_await.rs:16:9: 16:14 (#10), @@ -49,15 +55,15 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, debug _task_context => _38; let mut _0: std::task::Poll<()>; let _3: (); - let mut _4: impl std::future::Future; - let mut _5: impl std::future::Future; - let mut _6: impl std::future::Future; + let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _7: (); let _8: (); let mut _9: std::task::Poll<()>; - let mut _10: std::pin::Pin<&mut impl std::future::Future>; - let mut _11: &mut impl std::future::Future; - let mut _12: &mut impl std::future::Future; + let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>; + let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _13: &mut std::task::Context<'_>; let mut _14: &mut std::task::Context<'_>; let mut _15: &mut std::task::Context<'_>; @@ -65,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, let mut _18: !; let mut _19: &mut std::task::Context<'_>; let mut _20: (); - let mut _21: impl std::future::Future; - let mut _22: impl std::future::Future; - let mut _23: impl std::future::Future; + let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16}; let _24: (); let mut _25: std::task::Poll<()>; - let mut _26: std::pin::Pin<&mut impl std::future::Future>; - let mut _27: &mut impl std::future::Future; - let mut _28: &mut impl std::future::Future; + let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>; + let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; + let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}; let mut _29: &mut std::task::Context<'_>; let mut _30: &mut std::task::Context<'_>; let mut _31: &mut std::task::Context<'_>; @@ -84,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, let mut _38: &mut std::task::Context<'_>; let mut _39: u32; scope 1 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future); + debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); let _17: (); scope 2 { } @@ -93,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } } scope 4 { - debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future); + debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); let _33: (); scope 5 { } @@ -116,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } bb2: { - _4 = as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; + _4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable]; } bb3: { StorageDead(_5); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future) = move _4; + (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4; goto -> bb4; } @@ -132,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageLive(_10); StorageLive(_11); StorageLive(_12); - _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future); + _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); _11 = &mut (*_12); - _10 = Pin::<&mut impl Future>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; + _10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable]; } bb5: { @@ -150,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, bb6: { _13 = &mut (*_14); StorageDead(_15); - _9 = as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; + _9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable]; } bb7: { @@ -187,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageDead(_12); StorageDead(_9); StorageDead(_8); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future)) -> [return: bb12, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable]; } bb11: { @@ -212,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, } bb14: { - _21 = as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; + _21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable]; } bb15: { StorageDead(_22); nop; - (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future) = move _21; + (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21; goto -> bb16; } @@ -228,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageLive(_26); StorageLive(_27); StorageLive(_28); - _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future); + _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}); _27 = &mut (*_28); - _26 = Pin::<&mut impl Future>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; + _26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable]; } bb17: { @@ -246,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, bb18: { _29 = &mut (*_30); StorageDead(_31); - _25 = as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; + _25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable]; } bb19: { @@ -279,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>, StorageDead(_28); StorageDead(_25); StorageDead(_24); - drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future)) -> [return: bb23, unwind unreachable]; + drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable]; } bb22: { From 6ea2db7c2d78182fabf66a8c6ffc856446e1cf81 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Sep 2023 11:20:17 +0000 Subject: [PATCH 071/103] Strip `OpaqueCast` during `RevealAll`. --- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/place.rs | 4 +++- .../src/interpret/projection.rs | 2 +- .../rustc_mir_transform/src/reveal_all.rs | 19 +++++++++++++++ .../indirect-recursion-issue-112047.stderr | 2 +- tests/ui/polymorphization/generators.rs | 2 -- tests/ui/polymorphization/generators.stderr | 20 +++------------- .../cross_inference_pattern_bug.rs | 2 +- .../destructure_tait-layout_of-ice-113594.rs | 23 +++++++++++++++++++ .../indirect-recursion-issue-112047.stderr | 7 ++++-- 10 files changed, 57 insertions(+), 26 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 9b5a6b89191e1..6d55fdc307401 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -875,7 +875,7 @@ pub(crate) fn codegen_place<'tcx>( PlaceElem::Deref => { cplace = cplace.place_deref(fx); } - PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty), + PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), PlaceElem::Field(field, _ty) => { cplace = cplace.place_field(fx, field); } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index a9ecbdc5f35ed..f775711f87020 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -463,7 +463,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ProjectionElem::Field(ref field, _) => { cg_base.project_field(bx, field.index()) } - mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty), + mir::ProjectionElem::OpaqueCast(ty) => { + bug!("encountered OpaqueCast({ty}) in codegen") + } mir::ProjectionElem::Index(index) => { let index = &mir::Operand::Copy(mir::Place::from(index)); let index = self.codegen_operand(bx, index); diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 6c720ac4a574d..ca5e19ac1fafa 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -316,7 +316,7 @@ where { use rustc_middle::mir::ProjectionElem::*; Ok(match proj_elem { - OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?, + OpaqueCast(ty) => bug!("OpaqueCast({ty}) encountered after borrowck"), Field(field, _) => self.project_field(base, field.index())?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index cdd208f5c9335..6cc0d383119ca 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -25,6 +25,25 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { self.tcx } + #[inline] + fn visit_place( + &mut self, + place: &mut Place<'tcx>, + _context: PlaceContext, + _location: Location, + ) { + // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed. + // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these + // projections anymore. + place.projection = self.tcx.mk_place_elems( + &place + .projection + .into_iter() + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) + .collect::>(), + ); + } + #[inline] fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) { // We have to use `try_normalize_erasing_regions` here, since it's diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr index e0c1acfedfc36..41e84466a144e 100644 --- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr @@ -2,7 +2,7 @@ error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indir | = note: ...which requires computing layout of `<::Second as Second>::{opaque#0}`... = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle - = note: cycle used when computing layout of `::second::{opaque#0}` + = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error diff --git a/tests/ui/polymorphization/generators.rs b/tests/ui/polymorphization/generators.rs index 5f157bc3efb7e..779bac0ace29b 100644 --- a/tests/ui/polymorphization/generators.rs +++ b/tests/ui/polymorphization/generators.rs @@ -32,7 +32,6 @@ where #[rustc_polymorphize_error] pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { - //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; @@ -58,7 +57,6 @@ pub fn used_type_in_return() -> impl Generator<(), Yield = u32, Retu #[rustc_polymorphize_error] pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { - //~^ ERROR item has unused generic parameters || { //~^ ERROR item has unused generic parameters yield 1; diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr index 7461beb7b19a4..32d49d25f02ac 100644 --- a/tests/ui/polymorphization/generators.stderr +++ b/tests/ui/polymorphization/generators.stderr @@ -8,34 +8,20 @@ LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters - --> $DIR/generators.rs:36:5 + --> $DIR/generators.rs:35:5 | LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | - generic parameter `T` is unused -LL | LL | || { | ^^ error: item has unused generic parameters - --> $DIR/generators.rs:34:8 - | -LL | pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { - | ^^^^^^^^^^^ - generic parameter `T` is unused - -error: item has unused generic parameters - --> $DIR/generators.rs:62:5 + --> $DIR/generators.rs:60:5 | LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { | ------------ generic parameter `T` is unused -LL | LL | || { | ^^ -error: item has unused generic parameters - --> $DIR/generators.rs:60:8 - | -LL | pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { - | ^^^^^^^^^^^^ ------------ generic parameter `T` is unused - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs index 9a50c0f988a56..31fea42fa5d8a 100644 --- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs +++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs @@ -1,5 +1,5 @@ // compile-flags: --edition=2021 -// check-pass +// build-pass #![feature(type_alias_impl_trait)] fn main() { diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs new file mode 100644 index 0000000000000..8568b26bea2a3 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs @@ -0,0 +1,23 @@ +// build-pass +// edition: 2021 + +#![feature(type_alias_impl_trait)] + +fn foo(x: T) { + type Opaque = impl Sized; + let foo: Opaque = (x,); + let (a,): (T,) = foo; +} + +const fn bar(x: T) { + type Opaque = impl Copy; + let foo: Opaque = (x, 2u32); + let (a, b): (T, u32) = foo; +} + +fn main() { + foo::(1); + bar::(1); + const CONST: () = bar::(42u32); + CONST +} diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr index 3312230bc81df..2063becdb0838 100644 --- a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr +++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr @@ -1,6 +1,5 @@ error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}` | - = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit`... = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`... = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`... = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}`... @@ -8,7 +7,11 @@ error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirec = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`... = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`... = note: ...which again requires computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`, completing the cycle - = note: cycle used when computing layout of `::Recur` +note: cycle used when elaborating drops for `::recur` + --> $DIR/indirect-recursion-issue-112047.rs:22:5 + | +LL | fn recur(self) -> Self::Recur { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to previous error From 2d4201f7c65b223967bb12aed2a790f85e457969 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Sep 2023 11:23:39 +0000 Subject: [PATCH 072/103] Skip reinterning if nothing changed --- compiler/rustc_codegen_cranelift/src/value_and_place.rs | 8 -------- compiler/rustc_const_eval/src/interpret/projection.rs | 4 +++- compiler/rustc_mir_transform/src/reveal_all.rs | 4 ++++ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index ff95141ce90fb..d4273c0b593ac 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -674,14 +674,6 @@ impl<'tcx> CPlace<'tcx> { } } - pub(crate) fn place_opaque_cast( - self, - fx: &mut FunctionCx<'_, '_, 'tcx>, - ty: Ty<'tcx>, - ) -> CPlace<'tcx> { - CPlace { inner: self.inner, layout: fx.layout_of(ty) } - } - pub(crate) fn place_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index ca5e19ac1fafa..f462c13816ee8 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -316,7 +316,9 @@ where { use rustc_middle::mir::ProjectionElem::*; Ok(match proj_elem { - OpaqueCast(ty) => bug!("OpaqueCast({ty}) encountered after borrowck"), + OpaqueCast(ty) => { + span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck") + } Field(field, _) => self.project_field(base, field.index())?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index 6cc0d383119ca..55f1eac6f8468 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -32,6 +32,10 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { _context: PlaceContext, _location: Location, ) { + // Performance optimization: don't reintern if there is no `OpaqueCast` to remove. + if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) { + return; + } // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed. // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these // projections anymore. From 0031cf7c7e5bd255a504df19f44cc0eaf240fd57 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 Sep 2023 11:35:09 +0000 Subject: [PATCH 073/103] Add a mir validation check to prevent OpaqueCast after analysis passes finish --- compiler/rustc_const_eval/src/transform/validate.rs | 8 ++++++++ compiler/rustc_middle/src/mir/syntax.rs | 1 + 2 files changed, 9 insertions(+) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 0d8733070a446..18b22882e7d08 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -633,6 +633,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { location: Location, ) { match elem { + ProjectionElem::OpaqueCast(ty) + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) => + { + self.fail( + location, + format!("explicit opaque type cast to `{ty}` after `RevealAll`"), + ) + } ProjectionElem::Index(index) => { let index_ty = self.body.local_decls[index].ty; if index_ty != self.tcx.types.usize { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 201926fee3e02..55f895f73b48b 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -139,6 +139,7 @@ pub enum RuntimePhase { /// * [`TerminatorKind::Yield`] /// * [`TerminatorKind::GeneratorDrop`] /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` + /// * [`PlaceElem::OpaqueCast`] /// /// And the following variants are allowed: /// * [`StatementKind::Retag`] From 9f2e15d2328df0d32c5515c7b9a922b810403982 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 19:21:12 +0300 Subject: [PATCH 074/103] change visit to fold for ty and reg --- compiler/stable_mir/src/fold.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index bdc80bc8aa37c..90853c104bb5b 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -12,13 +12,13 @@ use super::ty::{ pub trait Folder: Sized { type Break; - fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { + fn fold_ty(&mut self, ty: &Ty) -> ControlFlow { ty.super_fold(self) } fn fold_const(&mut self, c: &Const) -> ControlFlow { c.super_fold(self) } - fn visit_reg(&mut self, reg: &Region) -> ControlFlow { + fn fold_reg(&mut self, reg: &Region) -> ControlFlow { reg.super_fold(self) } } @@ -32,7 +32,7 @@ pub trait Foldable: Sized + Clone { impl Foldable for Ty { fn fold(&self, folder: &mut V) -> ControlFlow { - folder.visit_ty(self) + folder.fold_ty(self) } fn super_fold(&self, folder: &mut V) -> ControlFlow { let mut kind = self.kind(); @@ -114,7 +114,7 @@ impl Foldable for GenericArgs { impl Foldable for Region { fn fold(&self, folder: &mut V) -> ControlFlow { - folder.visit_reg(self) + folder.fold_reg(self) } fn super_fold(&self, folder: &mut V) -> ControlFlow { let mut kind = self.kind.clone(); @@ -257,7 +257,7 @@ pub enum Never {} impl Folder for GenericArgs { type Break = Never; - fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { + fn fold_ty(&mut self, ty: &Ty) -> ControlFlow { ControlFlow::Continue(match ty.kind() { TyKind::Param(p) => self[p], _ => *ty, From 8c41cd0d78caed65ebd2f057d5209fc564f9cc10 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 19:43:28 +0300 Subject: [PATCH 075/103] simplify fold --- compiler/stable_mir/src/fold.rs | 37 +++------------------------------ 1 file changed, 3 insertions(+), 34 deletions(-) diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index 90853c104bb5b..65b743811ce52 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -1,9 +1,6 @@ use std::ops::ControlFlow; -use crate::{ - ty::{self, BoundRegion, BoundRegionKind}, - Opaque, -}; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, @@ -116,36 +113,8 @@ impl Foldable for Region { fn fold(&self, folder: &mut V) -> ControlFlow { folder.fold_reg(self) } - fn super_fold(&self, folder: &mut V) -> ControlFlow { - let mut kind = self.kind.clone(); - match &mut kind { - crate::ty::RegionKind::ReEarlyBound(_) => {} - crate::ty::RegionKind::ReLateBound(_, bound_reg) => { - *bound_reg = bound_reg.fold(folder)? - } - crate::ty::RegionKind::ReStatic => {} - crate::ty::RegionKind::RePlaceholder(bound_reg) => { - bound_reg.bound = bound_reg.bound.fold(folder)? - } - crate::ty::RegionKind::ReErased => {} - } - ControlFlow::Continue(ty::Region { kind: kind }.into()) - } -} - -impl Foldable for BoundRegion { - fn super_fold(&self, folder: &mut V) -> ControlFlow { - ControlFlow::Continue(BoundRegion { var: self.var, kind: self.kind.fold(folder)? }) - } -} - -impl Foldable for BoundRegionKind { - fn super_fold(&self, _folder: &mut V) -> ControlFlow { - match self { - BoundRegionKind::BrAnon => ControlFlow::Continue(self.clone()), - BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(self.clone()), - BoundRegionKind::BrEnv => ControlFlow::Continue(self.clone()), - } + fn super_fold(&self, _: &mut V) -> ControlFlow { + ControlFlow::Continue(self.clone()) } } From 0cca109473161c5c71de53d8ea0c9b7ff0a9b5c4 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 19:46:39 +0300 Subject: [PATCH 076/103] visit and fold ty::ref --- compiler/stable_mir/src/fold.rs | 5 ++++- compiler/stable_mir/src/visitor.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/stable_mir/src/fold.rs b/compiler/stable_mir/src/fold.rs index 65b743811ce52..4e0b4bc7a73a5 100644 --- a/compiler/stable_mir/src/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -148,7 +148,10 @@ impl Foldable for RigidTy { } RigidTy::Slice(inner) => *inner = inner.fold(folder)?, RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?, - RigidTy::Ref(_, ty, _) => *ty = ty.fold(folder)?, + RigidTy::Ref(reg, ty, _) => { + *reg = reg.fold(folder)?; + *ty = ty.fold(folder)? + } RigidTy::FnDef(_, args) => *args = args.fold(folder)?, RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?, RigidTy::Closure(_, args) => *args = args.fold(folder)?, diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index a26a1d8cfb9a4..848a3114b6b56 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -167,7 +167,10 @@ impl Visitable for RigidTy { } RigidTy::Slice(inner) => inner.visit(visitor), RigidTy::RawPtr(ty, _) => ty.visit(visitor), - RigidTy::Ref(_, ty, _) => ty.visit(visitor), + RigidTy::Ref(reg, ty, _) => { + reg.visit(visitor); + ty.visit(visitor) + } RigidTy::FnDef(_, args) => args.visit(visitor), RigidTy::FnPtr(sig) => sig.visit(visitor), RigidTy::Closure(_, args) => args.visit(visitor), From eb779038de59e028ebbd6533072acec7b5fc98af Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 19:51:49 +0300 Subject: [PATCH 077/103] simplify visit --- compiler/stable_mir/src/visitor.rs | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 848a3114b6b56..961009581388d 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,9 +1,6 @@ use std::ops::ControlFlow; -use crate::{ - ty::{BoundRegion, BoundRegionKind}, - Opaque, -}; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, @@ -112,34 +109,11 @@ impl Visitable for Region { visitor.visit_reg(self) } - fn super_visit(&self, visitor: &mut V) -> ControlFlow { - match self.kind.clone() { - crate::ty::RegionKind::ReEarlyBound(_) => {} - crate::ty::RegionKind::ReLateBound(_, bound_reg) => bound_reg.visit(visitor)?, - crate::ty::RegionKind::ReStatic => {} - crate::ty::RegionKind::RePlaceholder(bound_reg) => bound_reg.bound.visit(visitor)?, - crate::ty::RegionKind::ReErased => {} - } + fn super_visit(&self, _: &mut V) -> ControlFlow { ControlFlow::Continue(()) } } -impl Visitable for BoundRegion { - fn super_visit(&self, visitor: &mut V) -> ControlFlow { - self.kind.visit(visitor) - } -} - -impl Visitable for BoundRegionKind { - fn super_visit(&self, _visitor: &mut V) -> ControlFlow { - match self { - BoundRegionKind::BrAnon => ControlFlow::Continue(()), - BoundRegionKind::BrNamed(_, _) => ControlFlow::Continue(()), - BoundRegionKind::BrEnv => ControlFlow::Continue(()), - } - } -} - impl Visitable for GenericArgKind { fn super_visit(&self, visitor: &mut V) -> ControlFlow { match self { From 34f10e2ab98622e42c38c97530070aa69ad51d86 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 28 Sep 2023 19:52:41 +0300 Subject: [PATCH 078/103] remove unimplemented --- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 128ba07654458..c6c97ce35e8b9 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -1532,7 +1532,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { }) } ty::ReErased => RegionKind::ReErased, - _ => unimplemented!(), + _ => unreachable!("{self:?}"), } } } From 255ca184541d9f411cadfc3306ef4f6435ac4eb9 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 28 Sep 2023 17:05:52 +0000 Subject: [PATCH 079/103] Add test for 116212. --- tests/mir-opt/ssa_unreachable_116212.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/mir-opt/ssa_unreachable_116212.rs diff --git a/tests/mir-opt/ssa_unreachable_116212.rs b/tests/mir-opt/ssa_unreachable_116212.rs new file mode 100644 index 0000000000000..f588665876c87 --- /dev/null +++ b/tests/mir-opt/ssa_unreachable_116212.rs @@ -0,0 +1,14 @@ +// Regression test for issue #116212. + +#![feature(never_type)] + +use std::mem::MaybeUninit; + +struct Foo { + x: u8, + y: !, +} + +fn main() { + let foo = unsafe { MaybeUninit::::uninit().assume_init() }; +} From 3816c15b88651db3c1f1b56bbd78edec11045fb0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 28 May 2023 12:55:36 +0000 Subject: [PATCH 080/103] Only visit reachable nodes in SsaLocals. --- compiler/rustc_mir_transform/src/ssa.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 3a675752fba91..af9514ed6bb5b 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -78,14 +78,10 @@ impl SsaLocals { visitor.assignments[local] = Set1::One(LocationExtended::Arg); } - if body.basic_blocks.len() > 2 { - for (bb, data) in traversal::reverse_postorder(body) { - visitor.visit_basic_block_data(bb, data); - } - } else { - for (bb, data) in body.basic_blocks.iter_enumerated() { - visitor.visit_basic_block_data(bb, data); - } + // For SSA assignments, a RPO visit will see the assignment before it sees any use. + // We only visit reachable nodes: computing `dominates` on an unreachable node ICEs. + for (bb, data) in traversal::reverse_postorder(body) { + visitor.visit_basic_block_data(bb, data); } for var_debug_info in &body.var_debug_info { From a95f20c9adb45be65d579251b3f7e4401b8aa3b1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 28 Sep 2023 10:18:56 -0700 Subject: [PATCH 081/103] Add Exclusive forwarding impls (FnOnce, FnMut, Generator) --- library/core/src/sync/exclusive.rs | 46 +++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs index 3f3e19c55d4ba..ff538d55c6079 100644 --- a/library/core/src/sync/exclusive.rs +++ b/library/core/src/sync/exclusive.rs @@ -2,6 +2,8 @@ use core::fmt; use core::future::Future; +use core::marker::Tuple; +use core::ops::{Generator, GeneratorState}; use core::pin::Pin; use core::task::{Context, Poll}; @@ -168,10 +170,52 @@ impl From for Exclusive { } #[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Future for Exclusive { +impl FnOnce for Exclusive +where + F: FnOnce, + Args: Tuple, +{ + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + self.into_inner().call_once(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl FnMut for Exclusive +where + F: FnMut, + Args: Tuple, +{ + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + self.get_mut().call_mut(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Future for Exclusive +where + T: Future + ?Sized, +{ type Output = T::Output; + #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.get_pin_mut().poll(cx) } } + +#[unstable(feature = "generator_trait", issue = "43122")] // also #98407 +impl Generator for Exclusive +where + G: Generator + ?Sized, +{ + type Yield = G::Yield; + type Return = G::Return; + + #[inline] + fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState { + G::resume(self.get_pin_mut(), arg) + } +} From 07f81cd58aef7529f6cf457e4167d8ce0c2c89ae Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Sun, 27 Aug 2023 11:43:45 +0000 Subject: [PATCH 082/103] Move needless_raw_string_hashes to pedantic --- src/tools/clippy/clippy_lints/src/raw_strings.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs index 2895595e03908..8a7e487466610 100644 --- a/src/tools/clippy/clippy_lints/src/raw_strings.rs +++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs @@ -50,7 +50,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.72.0"] pub NEEDLESS_RAW_STRING_HASHES, - style, + pedantic, "suggests reducing the number of hashes around a raw string literal" } impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]); From f1b74841602617633a9f731f5a5b20ae7d3ed117 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:00:38 +0200 Subject: [PATCH 083/103] Remove `rustc_lint_defs::lint_array` --- compiler/rustc_lint/src/foreign_modules.rs | 7 +++---- compiler/rustc_lint/src/lib.rs | 2 +- compiler/rustc_lint/src/passes.rs | 4 ++-- compiler/rustc_lint_defs/src/lib.rs | 13 ++----------- .../unstable-book/src/language-features/plugin.md | 10 ++++------ .../utils/internal_lints/lint_without_lint_pass.rs | 4 ++-- .../internal-lints/lint_pass_impl_without_macro.rs | 2 +- tests/ui-fulldeps/lint-pass-macros.rs | 2 +- .../plugin/auxiliary/lint-group-plugin-test.rs | 3 +-- .../plugin/auxiliary/lint-plugin-test.rs | 6 +++--- .../ui-fulldeps/plugin/auxiliary/lint-tool-test.rs | 6 +++--- 11 files changed, 23 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 7b291d558e03b..e1df69bdaf252 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -5,19 +5,18 @@ use rustc_hir::def::DefKind; use rustc_middle::query::Providers; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; -use rustc_session::lint::{lint_array, LintArray}; use rustc_span::{sym, Span, Symbol}; use rustc_target::abi::FIRST_VARIANT; use crate::lints::{BuiltinClashingExtern, BuiltinClashingExternSub}; -use crate::types; +use crate::{types, LintVec}; pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { clashing_extern_declarations, ..*providers }; } -pub(crate) fn get_lints() -> LintArray { - lint_array!(CLASHING_EXTERN_DECLARATIONS) +pub(crate) fn get_lints() -> LintVec { + vec![CLASHING_EXTERN_DECLARATIONS] } fn clashing_extern_declarations(tcx: TyCtxt<'_>, (): ()) { diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 284560465d630..cda344d056d74 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -130,7 +130,7 @@ pub use late::{check_crate, late_lint_mod, unerased_lint_store}; pub use passes::{EarlyLintPass, LateLintPass}; pub use rustc_session::lint::Level::{self, *}; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId}; -pub use rustc_session::lint::{LintArray, LintPass}; +pub use rustc_session::lint::{LintPass, LintVec}; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 7d2a910264049..508f3e1ec3106 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -111,7 +111,7 @@ macro_rules! declare_combined_late_lint_pass { } } - $v fn get_lints() -> $crate::LintArray { + $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::get_lints());)* lints @@ -226,7 +226,7 @@ macro_rules! declare_combined_early_lint_pass { } } - $v fn get_lints() -> $crate::LintArray { + $v fn get_lints() -> $crate::LintVec { let mut lints = Vec::new(); $(lints.extend_from_slice(&$pass::get_lints());)* lints diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 84e7ecb0b881c..7ba589c3b5a39 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -785,16 +785,7 @@ macro_rules! declare_tool_lint { ); } -/// Declares a static `LintArray` and return it as an expression. -#[macro_export] -macro_rules! lint_array { - ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) }; - ($( $lint:expr ),*) => {{ - vec![$($lint),*] - }} -} - -pub type LintArray = Vec<&'static Lint>; +pub type LintVec = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; @@ -808,7 +799,7 @@ macro_rules! impl_lint_pass { fn name(&self) -> &'static str { stringify!($ty) } } impl $ty { - pub fn get_lints() -> $crate::LintArray { $crate::lint_array!($($lint),*) } + pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] } } }; } diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 1fade6ce95b89..189cc910a8d75 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -43,14 +43,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; -use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; use rustc_ast::ast; +use rustc_driver::plugin::Registry; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; + declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); declare_lint_pass!(Pass => [TEST_LINT]); @@ -58,9 +58,7 @@ declare_lint_pass!(Pass => [TEST_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { - cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() - }); + cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)); } } } diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs index 87380f14f9a4d..bbb5ade8b9f36 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs @@ -28,8 +28,8 @@ declare_clippy_lint! { /// know the name of the lint. /// /// ### Known problems - /// Only checks for lints associated using the - /// `declare_lint_pass!`, `impl_lint_pass!`, and `lint_array!` macros. + /// Only checks for lints associated using the `declare_lint_pass!` and + /// `impl_lint_pass!` macros. /// /// ### Example /// ```rust,ignore diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index f6f0c038536c8..fa6734b6c6c30 100644 --- a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc_middle; extern crate rustc_session; -use rustc_session::lint::{LintArray, LintPass}; +use rustc_session::lint::{LintPass, LintVec}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { diff --git a/tests/ui-fulldeps/lint-pass-macros.rs b/tests/ui-fulldeps/lint-pass-macros.rs index b3c2a542792f0..4c61783418fb0 100644 --- a/tests/ui-fulldeps/lint-pass-macros.rs +++ b/tests/ui-fulldeps/lint-pass-macros.rs @@ -5,7 +5,7 @@ extern crate rustc_session; -use rustc_session::lint::{LintArray, LintPass}; +use rustc_session::lint::{LintPass, LintVec}; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs index 4a41e7fbb72a1..150f0c6b9a2da 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs @@ -5,13 +5,12 @@ // Load rustc as a plugin to get macros. extern crate rustc_driver; extern crate rustc_hir; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; use rustc_driver::plugin::Registry; -use rustc_lint::{LateContext, LateLintPass, LintArray, LintContext, LintId, LintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext, LintId}; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs index 30956deb799ed..acc5fe76051b9 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs @@ -6,14 +6,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; +use rustc_ast::ast; use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; -use rustc_ast as ast; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; + declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); declare_lint_pass!(Pass => [TEST_LINT]); diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs index c2c024865e8a8..21de4aa7008fd 100644 --- a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs @@ -4,14 +4,14 @@ extern crate rustc_ast; // Load rustc as a plugin to get macros extern crate rustc_driver; -#[macro_use] extern crate rustc_lint; #[macro_use] extern crate rustc_session; -use rustc_driver::plugin::Registry; -use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass}; use rustc_ast as ast; +use rustc_driver::plugin::Registry; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext, LintId}; + declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); declare_tool_lint!( /// Some docs From f040210b31987e8fbe799fb1b7feeda3ab3ccc56 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 22:15:51 +0000 Subject: [PATCH 084/103] Remove outdated comment There is no `reset` anymore --- compiler/rustc_middle/src/mir/traversal.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index ec16a8470c412..fd11bd0c1ac4b 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -249,8 +249,7 @@ pub fn postorder<'a, 'tcx>( /// /// Construction of a `ReversePostorder` traversal requires doing a full /// postorder traversal of the graph, therefore this traversal should be -/// constructed as few times as possible. Use the `reset` method to be able -/// to re-use the traversal +/// constructed as few times as possible. #[derive(Clone)] pub struct ReversePostorder<'a, 'tcx> { body: &'a Body<'tcx>, From 82e251be7da92f9f7ddfcb511b11aa8a1c33f98e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 22:17:13 +0000 Subject: [PATCH 085/103] Remove `ReversePostorder` altogether It was not used anywhere, instead we directly reverse postorder. --- compiler/rustc_middle/src/mir/traversal.rs | 58 ---------------------- 1 file changed, 58 deletions(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index fd11bd0c1ac4b..ab7b3f26d5555 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -226,64 +226,6 @@ pub fn postorder<'a, 'tcx>( reverse_postorder(body).rev() } -/// Reverse postorder traversal of a graph -/// -/// Reverse postorder is the reverse order of a postorder traversal. -/// This is different to a preorder traversal and represents a natural -/// linearization of control-flow. -/// -/// ```text -/// -/// A -/// / \ -/// / \ -/// B C -/// \ / -/// \ / -/// D -/// ``` -/// -/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D` -/// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to -/// a topological sort. -/// -/// Construction of a `ReversePostorder` traversal requires doing a full -/// postorder traversal of the graph, therefore this traversal should be -/// constructed as few times as possible. -#[derive(Clone)] -pub struct ReversePostorder<'a, 'tcx> { - body: &'a Body<'tcx>, - blocks: Vec, - idx: usize, -} - -impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> { - let blocks: Vec<_> = Postorder::new(&body.basic_blocks, root).map(|(bb, _)| bb).collect(); - let len = blocks.len(); - ReversePostorder { body, blocks, idx: len } - } -} - -impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { - type Item = (BasicBlock, &'a BasicBlockData<'tcx>); - - fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - if self.idx == 0 { - return None; - } - self.idx -= 1; - - self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb])) - } - - fn size_hint(&self) -> (usize, Option) { - (self.idx, Some(self.idx)) - } -} - -impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {} - /// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular /// order. /// From fb0e58596f9c504466676b70d1c93c910d6ba9ae Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 22:28:09 +0000 Subject: [PATCH 086/103] Simplify `Postorder::next` --- compiler/rustc_middle/src/mir/traversal.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index ab7b3f26d5555..b2d0d83240b95 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -192,12 +192,10 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { type Item = (BasicBlock, &'a BasicBlockData<'tcx>); fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { - let next = self.visit_stack.pop(); - if next.is_some() { - self.traverse_successor(); - } - - next.map(|(bb, _)| (bb, &self.basic_blocks[bb])) + let (bb, _) = self.visit_stack.pop()?; + self.traverse_successor(); + + Some((bb, &self.basic_blocks[bb])) } fn size_hint(&self) -> (usize, Option) { From 0d8a45813c52c33790648b9401428087f0ecb5d2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 22:30:31 +0000 Subject: [PATCH 087/103] `(&mut iter)` -> `iter.by_ref()` --- compiler/rustc_middle/src/mir/traversal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index b2d0d83240b95..07baaa6f90c96 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -237,7 +237,7 @@ pub fn reachable<'a, 'tcx>( /// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`. pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet { let mut iter = preorder(body); - (&mut iter).for_each(drop); + iter.by_ref().for_each(drop); iter.visited } From a7f3c4e6086c70f1c617bae6c157d5dc5636670f Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 22:39:53 +0000 Subject: [PATCH 088/103] Don't resolve basic block data in `Postorder` The only usage immediately throws out the data, so. --- compiler/rustc_middle/src/mir/basic_blocks.rs | 3 +-- compiler/rustc_middle/src/mir/traversal.rs | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index cd770c395e4d3..c0f02c64bbf62 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -66,8 +66,7 @@ impl<'tcx> BasicBlocks<'tcx> { #[inline] pub fn reverse_postorder(&self) -> &[BasicBlock] { self.cache.reverse_postorder.get_or_init(|| { - let mut rpo: Vec<_> = - Postorder::new(&self.basic_blocks, START_BLOCK).map(|(bb, _)| bb).collect(); + let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK).collect(); rpo.reverse(); rpo }) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 07baaa6f90c96..a89dbf991f0c2 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -188,14 +188,14 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { } } -impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { - type Item = (BasicBlock, &'a BasicBlockData<'tcx>); +impl<'tcx> Iterator for Postorder<'_, 'tcx> { + type Item = BasicBlock; - fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> { + fn next(&mut self) -> Option { let (bb, _) = self.visit_stack.pop()?; self.traverse_successor(); - - Some((bb, &self.basic_blocks[bb])) + + Some(bb) } fn size_hint(&self) -> (usize, Option) { From b53a1b38089f30a34d932ad4030f3d529664c9df Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Thu, 28 Sep 2023 20:51:48 +0000 Subject: [PATCH 089/103] make adt_const_params feature suggestion more consistent with others and only suggest it when the type can probably work --- .../rustc_hir_analysis/src/check/wfcheck.rs | 89 ++++++++++++------- .../suggest_feature_only_when_possible.rs | 44 +++++++++ .../suggest_feature_only_when_possible.stderr | 80 +++++++++++++++++ .../const-param-elided-lifetime.min.stderr | 10 +-- ...ram-type-depends-on-const-param.min.stderr | 4 +- .../float-generic.simple.stderr | 1 - .../fn-const-param-call.min.stderr | 4 + .../fn-const-param-infer.min.stderr | 2 + ...ay-size-in-generic-struct-param.min.stderr | 2 +- ...ics-type_name-as-const-argument.min.stderr | 2 +- .../issues/issue-56445-1.min.stderr | 2 +- .../issues/issue-62878.min.stderr | 2 +- .../issues/issue-63322-forbid-dyn.min.stderr | 2 +- .../issues/issue-68615-adt.min.stderr | 2 +- .../issues/issue-68615-array.min.stderr | 2 +- .../issues/issue-71169.min.stderr | 2 +- .../issues/issue-71381.min.stderr | 4 + .../issues/issue-71382.min.stderr | 2 + .../issues/issue-71611.min.stderr | 2 + .../issues/issue-72352.min.stderr | 2 + .../issues/issue-73491.min.stderr | 2 +- ...tic-reference-array-const-param.min.stderr | 2 +- .../issues/issue-74101.min.stderr | 4 +- .../issues/issue-74255.min.stderr | 2 +- .../issues/issue-74950.min.stderr | 10 +-- .../issues/issue-75047.min.stderr | 2 +- .../lifetime-in-const-param.stderr | 2 +- .../min_const_generics/complex-types.stderr | 13 ++- .../ui/const-generics/nested-type.min.stderr | 2 +- .../projection-as-arg-const.stderr | 1 - .../raw-ptr-const-param-deref.min.stderr | 4 + .../raw-ptr-const-param.min.stderr | 2 + .../slice-const-param-mismatch.min.stderr | 4 +- .../std/const-generics-range.min.stderr | 12 +-- ...te-const-param-static-reference.min.stderr | 2 +- .../type-dependent/issue-71348.min.stderr | 4 +- .../type-dependent/issue-71382.stderr | 2 + .../feature-gate-adt_const_params.stderr | 2 +- .../elided-lifetimes.stderr | 2 +- .../lifetimes/unusual-rib-combinations.stderr | 4 +- 40 files changed, 254 insertions(+), 84 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs create mode 100644 tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b7b162ce27bc8..c4fdffb02618a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,6 +24,9 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::traits::misc::{ + type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError, +}; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::{ @@ -865,43 +868,65 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ); }); } else { - let err_ty_str; - let mut is_ptr = true; - - let err = match ty.kind() { + let diag = match ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, - ty::FnPtr(_) => Some("function pointers"), - ty::RawPtr(_) => Some("raw pointers"), - _ => { - is_ptr = false; - err_ty_str = format!("`{ty}`"); - Some(err_ty_str.as_str()) - } + ty::FnPtr(_) => Some(tcx.sess.struct_span_err( + hir_ty.span, + "using function pointers as const generic parameters is forbidden", + )), + ty::RawPtr(_) => Some(tcx.sess.struct_span_err( + hir_ty.span, + "using raw pointers as const generic parameters is forbidden", + )), + _ => Some(tcx.sess.struct_span_err( + hir_ty.span, + format!("`{}` is forbidden as the type of a const generic parameter", ty), + )), }; - if let Some(unsupported_type) = err { - if is_ptr { - tcx.sess.span_err( - hir_ty.span, - format!( - "using {unsupported_type} as const generic parameters is forbidden", - ), - ); - } else { - let mut err = tcx.sess.struct_span_err( - hir_ty.span, - format!( - "{unsupported_type} is forbidden as the type of a const generic parameter", - ), - ); - err.note("the only supported types are integers, `bool` and `char`"); - if tcx.sess.is_nightly_build() { - err.help( - "more complex types are supported with `#![feature(adt_const_params)]`", - ); + if let Some(mut diag) = diag { + diag.note("the only supported types are integers, `bool` and `char`"); + + let cause = ObligationCause::misc(hir_ty.span, param.def_id); + let may_suggest_feature = match type_allowed_to_implement_const_param_ty( + tcx, + tcx.param_env(param.def_id), + ty, + cause, + ) { + // Can never implement `ConstParamTy`, don't suggest anything. + Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false, + // May be able to implement `ConstParamTy`. Only emit the feature help + // if the type is local, since the user may be able to fix the local type. + Err(ConstParamTyImplementationError::InfrigingFields(..)) => { + fn ty_is_local(ty: Ty<'_>) -> bool { + match ty.kind() { + ty::Adt(adt_def, ..) => adt_def.did().is_local(), + // Arrays and slices use the inner type's `ConstParamTy`. + ty::Array(ty, ..) => ty_is_local(*ty), + ty::Slice(ty) => ty_is_local(*ty), + // `&` references use the inner type's `ConstParamTy`. + // `&mut` are not supported. + ty::Ref(_, ty, ast::Mutability::Not) => ty_is_local(*ty), + // Say that a tuple is local if any of its components are local. + // This is not strictly correct, but it's likely that the user can fix the local component. + ty::Tuple(tys) => tys.iter().any(|ty| ty_is_local(ty)), + _ => false, + } + } + + ty_is_local(ty) } - err.emit(); + // Implments `ConstParamTy`, suggest adding the feature to enable. + Ok(..) => true, + }; + if may_suggest_feature && tcx.sess.is_nightly_build() { + diag.help( + "add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types", + ); } + + diag.emit(); } } } diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs new file mode 100644 index 0000000000000..a83830178d40e --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs @@ -0,0 +1,44 @@ +// Test that when adt_const_params is not enabled, we suggest adding the feature only when +// it would be possible for the type to be used as a const generic or when it's likely +// possible for the user to fix their type to be used. + +// Can never be used as const generics. +fn uwu_0() {} +//~^ ERROR: forbidden as the type of a const generic + +// Needs the feature but can be used, so suggest adding the feature. +fn owo_0() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// Can only be used in const generics with changes. +struct Meow { + meow: u8, +} + +fn meow_0() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_1() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_2() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` +fn meow_3() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// This is suboptimal that it thinks it can be used +// but better to suggest the feature to the user. +fn meow_4() {} +//~^ ERROR: forbidden as the type of a const generic +//~^^ HELP: add `#![feature(adt_const_params)]` + +// Non-local ADT that does not impl `ConstParamTy` +fn nya_0() {} +//~^ ERROR: forbidden as the type of a const generic +fn nya_1>() {} +//~^ ERROR: forbidden as the type of a const generic + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr new file mode 100644 index 0000000000000..04527e3158ed1 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr @@ -0,0 +1,80 @@ +error: `&'static mut ()` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:6:19 + | +LL | fn uwu_0() {} + | ^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: `&'static u32` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:10:19 + | +LL | fn owo_0() {} + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `Meow` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:19:20 + | +LL | fn meow_0() {} + | ^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `&'static Meow` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:22:20 + | +LL | fn meow_1() {} + | ^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `[Meow; 100]` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:25:20 + | +LL | fn meow_2() {} + | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `(Meow, u8)` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:28:20 + | +LL | fn meow_3() {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `(Meow, String)` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:34:20 + | +LL | fn meow_4() {} + | ^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + +error: `String` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:39:19 + | +LL | fn nya_0() {} + | ^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: `Vec` is forbidden as the type of a const generic parameter + --> $DIR/suggest_feature_only_when_possible.rs:41:19 + | +LL | fn nya_1>() {} + | ^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr index 656bc29466f23..ffe4528598850 100644 --- a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr +++ b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr @@ -35,7 +35,7 @@ LL | struct A; | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:14:15 @@ -44,7 +44,7 @@ LL | impl A { | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:22:15 @@ -53,7 +53,7 @@ LL | impl B for A {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:26:17 @@ -62,7 +62,7 @@ LL | fn bar() {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&u8` is forbidden as the type of a const generic parameter --> $DIR/const-param-elided-lifetime.rs:17:21 @@ -71,7 +71,7 @@ LL | fn foo(&self) {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 10 previous errors diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr index f829526ca1dc8..daeeadeed7cfd 100644 --- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr +++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr @@ -21,7 +21,7 @@ LL | pub struct Dependent([(); N]); | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `[u8; N]` is forbidden as the type of a const generic parameter --> $DIR/const-param-type-depends-on-const-param.rs:15:35 @@ -30,7 +30,7 @@ LL | pub struct SelfDependent; | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/float-generic.simple.stderr b/tests/ui/const-generics/float-generic.simple.stderr index 89ca36b0f6314..aeb19dc75322d 100644 --- a/tests/ui/const-generics/float-generic.simple.stderr +++ b/tests/ui/const-generics/float-generic.simple.stderr @@ -5,7 +5,6 @@ LL | fn foo() {} | ^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: aborting due to previous error diff --git a/tests/ui/const-generics/fn-const-param-call.min.stderr b/tests/ui/const-generics/fn-const-param-call.min.stderr index d984449e6ca6e..2d316fba1e90a 100644 --- a/tests/ui/const-generics/fn-const-param-call.min.stderr +++ b/tests/ui/const-generics/fn-const-param-call.min.stderr @@ -3,12 +3,16 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Wrapper u32>; | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using function pointers as const generic parameters is forbidden --> $DIR/fn-const-param-call.rs:13:15 | LL | impl u32> Wrapper { | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr index f0767a10994a5..a7afa48427594 100644 --- a/tests/ui/const-generics/fn-const-param-infer.min.stderr +++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | struct Checked bool>; | ^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr index 956e9c9c988a4..64d1e0bcff4e0 100644 --- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr @@ -23,7 +23,7 @@ LL | struct B { | ^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr index b8a1027c9ebdb..4c45339b93b37 100644 --- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr +++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr @@ -14,7 +14,7 @@ LL | trait Trait {} | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr index 71a7051f25bfa..fc10aba0fecd0 100644 --- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr @@ -13,7 +13,7 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr index 9c0e5179cc4c2..eb8b9732f58c8 100644 --- a/tests/ui/const-generics/issues/issue-62878.min.stderr +++ b/tests/ui/const-generics/issues/issue-62878.min.stderr @@ -13,7 +13,7 @@ LL | fn foo() {} | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr index 9f6c7ccf3fe74..9d80f1cd01bc6 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr @@ -5,7 +5,7 @@ LL | fn test() { | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr index df04c4896b45a..c8b9f17196aca 100644 --- a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr @@ -5,7 +5,7 @@ LL | struct Const {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-68615-array.min.stderr b/tests/ui/const-generics/issues/issue-68615-array.min.stderr index 1b4517087e223..fc6cef9d44e55 100644 --- a/tests/ui/const-generics/issues/issue-68615-array.min.stderr +++ b/tests/ui/const-generics/issues/issue-68615-array.min.stderr @@ -5,7 +5,7 @@ LL | struct Foo {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr index ebfb24bec28df..bba92f32a7842 100644 --- a/tests/ui/const-generics/issues/issue-71169.min.stderr +++ b/tests/ui/const-generics/issues/issue-71169.min.stderr @@ -13,7 +13,7 @@ LL | fn foo() {} | ^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index e1e140071fc13..e16d3b7a8a469 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -19,12 +19,16 @@ error: using function pointers as const generic parameters is forbidden | LL | pub fn call_me(&self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using function pointers as const generic parameters is forbidden --> $DIR/issue-71381.rs:23:19 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/issues/issue-71382.min.stderr b/tests/ui/const-generics/issues/issue-71382.min.stderr index 715037bd5f1e8..217166d847937 100644 --- a/tests/ui/const-generics/issues/issue-71382.min.stderr +++ b/tests/ui/const-generics/issues/issue-71382.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn test(&self) { | ^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index b33d7cf9850fa..b01936f4d2513 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -11,6 +11,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn func(outer: A) { | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-72352.min.stderr b/tests/ui/const-generics/issues/issue-72352.min.stderr index eedd73c4dcc0a..b010996b89692 100644 --- a/tests/ui/const-generics/issues/issue-72352.min.stderr +++ b/tests/ui/const-generics/issues/issue-72352.min.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | unsafe fn unsafely_do_the_thing usize>(ptr: *const i8) -> usize { | ^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-73491.min.stderr b/tests/ui/const-generics/issues/issue-73491.min.stderr index f03354fc472c0..fdf057bdbe47d 100644 --- a/tests/ui/const-generics/issues/issue-73491.min.stderr +++ b/tests/ui/const-generics/issues/issue-73491.min.stderr @@ -5,7 +5,7 @@ LL | fn hoge() {} | ^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr index 0a7db62472a9f..bed0a02a72673 100644 --- a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr +++ b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr @@ -5,7 +5,7 @@ LL | fn a() {} | ^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-74101.min.stderr b/tests/ui/const-generics/issues/issue-74101.min.stderr index 134c248347d3c..7852ce5bcfcea 100644 --- a/tests/ui/const-generics/issues/issue-74101.min.stderr +++ b/tests/ui/const-generics/issues/issue-74101.min.stderr @@ -5,7 +5,7 @@ LL | fn test() {} | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `[u8; 1 + 2]` is forbidden as the type of a const generic parameter --> $DIR/issue-74101.rs:9:21 @@ -14,7 +14,7 @@ LL | struct Foo; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr index bbcf8682b7119..affeca167e970 100644 --- a/tests/ui/const-generics/issues/issue-74255.min.stderr +++ b/tests/ui/const-generics/issues/issue-74255.min.stderr @@ -5,7 +5,7 @@ LL | fn ice_struct_fn() {} | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr index c37ee93d420fd..a5dbe10b78a32 100644 --- a/tests/ui/const-generics/issues/issue-74950.min.stderr +++ b/tests/ui/const-generics/issues/issue-74950.min.stderr @@ -5,7 +5,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -14,7 +14,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -23,7 +23,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -32,7 +32,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `Inner` is forbidden as the type of a const generic parameter --> $DIR/issue-74950.rs:20:23 @@ -41,7 +41,7 @@ LL | struct Outer; | ^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 5 previous errors diff --git a/tests/ui/const-generics/issues/issue-75047.min.stderr b/tests/ui/const-generics/issues/issue-75047.min.stderr index 46af19ef39540..e316b4624a007 100644 --- a/tests/ui/const-generics/issues/issue-75047.min.stderr +++ b/tests/ui/const-generics/issues/issue-75047.min.stderr @@ -5,7 +5,7 @@ LL | struct Foo::value()]>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/lifetime-in-const-param.stderr b/tests/ui/const-generics/lifetime-in-const-param.stderr index 8fd9068e8efd2..c2fcdcf1a7128 100644 --- a/tests/ui/const-generics/lifetime-in-const-param.stderr +++ b/tests/ui/const-generics/lifetime-in-const-param.stderr @@ -11,7 +11,7 @@ LL | struct S<'a, const N: S2>(&'a ()); | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/min_const_generics/complex-types.stderr b/tests/ui/const-generics/min_const_generics/complex-types.stderr index 4ddbadb54661b..8cc75dbaff9c3 100644 --- a/tests/ui/const-generics/min_const_generics/complex-types.stderr +++ b/tests/ui/const-generics/min_const_generics/complex-types.stderr @@ -5,7 +5,7 @@ LL | struct Foo; | ^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:6:21 @@ -14,7 +14,7 @@ LL | struct Bar; | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `No` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:11:21 @@ -23,7 +23,7 @@ LL | struct Fez; | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static u8` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:14:21 @@ -32,7 +32,7 @@ LL | struct Faz; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `!` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:17:21 @@ -41,7 +41,6 @@ LL | struct Fiz; | ^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:20:19 @@ -50,7 +49,7 @@ LL | enum Goo { A, B } | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `()` is forbidden as the type of a const generic parameter --> $DIR/complex-types.rs:23:20 @@ -59,7 +58,7 @@ LL | union Boo { a: () } | ^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 7 previous errors diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr index 257a9e31e14b2..ca5af5f969f58 100644 --- a/tests/ui/const-generics/nested-type.min.stderr +++ b/tests/ui/const-generics/nested-type.min.stderr @@ -30,7 +30,7 @@ LL | | }]>; | |__^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/projection-as-arg-const.stderr b/tests/ui/const-generics/projection-as-arg-const.stderr index 803ed9c959752..9f727231edfbe 100644 --- a/tests/ui/const-generics/projection-as-arg-const.stderr +++ b/tests/ui/const-generics/projection-as-arg-const.stderr @@ -5,7 +5,6 @@ LL | pub fn foo::Identity>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` error: aborting due to previous error diff --git a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr index 04bc46cb4ab12..1eb238255abc2 100644 --- a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr @@ -3,12 +3,16 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: using raw pointers as const generic parameters is forbidden --> $DIR/raw-ptr-const-param-deref.rs:11:15 | LL | impl Const

{ | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/raw-ptr-const-param.min.stderr b/tests/ui/const-generics/raw-ptr-const-param.min.stderr index 310422aafcd35..13fbc34e51a0d 100644 --- a/tests/ui/const-generics/raw-ptr-const-param.min.stderr +++ b/tests/ui/const-generics/raw-ptr-const-param.min.stderr @@ -3,6 +3,8 @@ error: using raw pointers as const generic parameters is forbidden | LL | struct Const; | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr index fed802f6adc6b..3c086f59b2788 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr +++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr @@ -5,7 +5,7 @@ LL | struct ConstString; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static [u8]` is forbidden as the type of a const generic parameter --> $DIR/slice-const-param-mismatch.rs:9:28 @@ -14,7 +14,7 @@ LL | struct ConstBytes; | ^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr index 53fca6e884a9a..d45f749246c8e 100644 --- a/tests/ui/const-generics/std/const-generics-range.min.stderr +++ b/tests/ui/const-generics/std/const-generics-range.min.stderr @@ -5,7 +5,7 @@ LL | struct _Range>; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeFrom` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:13:28 @@ -14,7 +14,7 @@ LL | struct _RangeFrom>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeFull` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:18:28 @@ -23,7 +23,7 @@ LL | struct _RangeFull; | ^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:24:33 @@ -32,7 +32,7 @@ LL | struct _RangeInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeTo` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:29:26 @@ -41,7 +41,7 @@ LL | struct _RangeTo>; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `RangeToInclusive` is forbidden as the type of a const generic parameter --> $DIR/const-generics-range.rs:34:35 @@ -50,7 +50,7 @@ LL | struct _RangeToInclusive>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr index 039c4276c8b77..f18e149464d3d 100644 --- a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr +++ b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr @@ -5,7 +5,7 @@ LL | struct Const; | ^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr index b8fbb3979799d..6490592c1e1e6 100644 --- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr @@ -5,7 +5,7 @@ LL | trait Get<'a, const N: &'static str> { | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&'static str` is forbidden as the type of a const generic parameter --> $DIR/issue-71348.rs:18:25 @@ -14,7 +14,7 @@ LL | fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Ta | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/type-dependent/issue-71382.stderr b/tests/ui/const-generics/type-dependent/issue-71382.stderr index ad522aead9050..3f42feea562ab 100644 --- a/tests/ui/const-generics/type-dependent/issue-71382.stderr +++ b/tests/ui/const-generics/type-dependent/issue-71382.stderr @@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden | LL | fn test u8>(&self) -> u8 { | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` error: aborting due to previous error diff --git a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr index d8f089a28b7e1..13b9b84f0be4e 100644 --- a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr +++ b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr @@ -5,7 +5,7 @@ LL | struct Foo; | ^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to previous error diff --git a/tests/ui/generic-const-items/elided-lifetimes.stderr b/tests/ui/generic-const-items/elided-lifetimes.stderr index 8cd3f9ee7a918..e7df8ca5cfd99 100644 --- a/tests/ui/generic-const-items/elided-lifetimes.stderr +++ b/tests/ui/generic-const-items/elided-lifetimes.stderr @@ -28,7 +28,7 @@ LL | const I: &str = ""; | ^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 4 previous errors diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 01ec69a6110fa..92a2ef2f432f1 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -56,7 +56,7 @@ LL | fn d() {} | ^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter --> $DIR/unusual-rib-combinations.rs:29:21 @@ -65,7 +65,7 @@ LL | struct Bar Foo<'a>)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool` and `char` - = help: more complex types are supported with `#![feature(adt_const_params)]` + = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types error: aborting due to 9 previous errors From e0abb98e2120903fe3a1b787914e0092150d88da Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 23:11:15 +0000 Subject: [PATCH 090/103] Remove unnecessary `&mut/ref mut` pair --- compiler/rustc_middle/src/mir/traversal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index a89dbf991f0c2..cc189a2cd97d9 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { // When we yield `C` and call `traverse_successor`, we push `B` to the stack, but // since we've already visited `E`, that child isn't added to the stack. The last // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A] - while let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() { + while let Some((_, iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() { if self.visited.insert(bb) { if let Some(term) = &self.basic_blocks[bb].terminator { self.visit_stack.push((bb, term.successors())); From 0e0dc59acbdc4671c1fdcaf6c06fd9c4d1d8c9e2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 23:16:48 +0000 Subject: [PATCH 091/103] Use `and_then` instead of while let chain to clarify `iter` scope --- compiler/rustc_middle/src/mir/traversal.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index cc189a2cd97d9..28b05f2524f02 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -178,7 +178,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { // When we yield `C` and call `traverse_successor`, we push `B` to the stack, but // since we've already visited `E`, that child isn't added to the stack. The last // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A] - while let Some((_, iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() { + while let Some(bb) = self.visit_stack.last_mut().and_then(|(_, iter)| iter.next_back()) { if self.visited.insert(bb) { if let Some(term) = &self.basic_blocks[bb].terminator { self.visit_stack.push((bb, term.successors())); From 27242437c7315b8fd456e310fe767a152cb434cd Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 28 Sep 2023 23:50:56 +0000 Subject: [PATCH 092/103] Reverse postorder instead of using reversed postorder --- src/tools/clippy/clippy_utils/src/mir/mod.rs | 32 ++++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs index f04467dc19d37..9dbb4c68d13f8 100644 --- a/src/tools/clippy/clippy_utils/src/mir/mod.rs +++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs @@ -30,20 +30,26 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) - locals.len() ]; - traversal::ReversePostorder::new(mir, location.block).try_fold(init, |usage, (tbb, tdata)| { - // Give up on loops - if tdata.terminator().successors().any(|s| s == location.block) { - return None; - } + traversal::Postorder::new(&mir.basic_blocks, location.block) + .collect::>() + .into_iter() + .rev() + .try_fold(init, |usage, tbb| { + let tdata = &mir.basic_blocks[tbb]; + + // Give up on loops + if tdata.terminator().successors().any(|s| s == location.block) { + return None; + } - let mut v = V { - locals, - location, - results: usage, - }; - v.visit_basic_block_data(tbb, tdata); - Some(v.results) - }) + let mut v = V { + locals, + location, + results: usage, + }; + v.visit_basic_block_data(tbb, tdata); + Some(v.results) + }) } struct V<'a> { From b83dfb5c5a6e9c976200490c89ff00726c425ad2 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 31 May 2023 10:10:16 +0800 Subject: [PATCH 093/103] fix(suggestion): insert projection to associated types --- compiler/rustc_hir_analysis/src/check/mod.rs | 67 +++++++++++-------- .../auxiliary/extern-issue-98562.rs | 26 +++++++ tests/ui/suggestions/issue-98562.rs | 12 ++++ tests/ui/suggestions/issue-98562.stderr | 11 +++ tests/ui/suggestions/missing-assoc-fn.stderr | 2 +- 5 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 tests/ui/suggestions/auxiliary/extern-issue-98562.rs create mode 100644 tests/ui/suggestions/issue-98562.rs create mode 100644 tests/ui/suggestions/issue-98562.stderr diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 88c98fa979e1c..5fa65f33c763c 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -329,41 +329,52 @@ fn bounds_from_generic_predicates<'tcx>( _ => {} } } - let generics = if types.is_empty() { - "".to_string() - } else { - format!( - "<{}>", - types - .keys() - .filter_map(|t| match t.kind() { - ty::Param(_) => Some(t.to_string()), - // Avoid suggesting the following: - // fn foo::Bar>(_: T) where T: Trait, ::Bar: Other {} - _ => None, - }) - .collect::>() - .join(", ") - ) - }; + let mut where_clauses = vec![]; + let mut types_str = vec![]; for (ty, bounds) in types { - where_clauses - .extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound)))); - } - for projection in &projections { - let p = projection.skip_binder(); - // FIXME: this is not currently supported syntax, we should be looking at the `types` and - // insert the associated types where they correspond, but for now let's be "lazy" and - // propose this instead of the following valid resugaring: - // `T: Trait, Trait::Assoc = K` → `T: Trait` - where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term)); + if let ty::Param(_) = ty.kind() { + let mut bounds_str = vec![]; + for bound in bounds { + let mut projections_str = vec![]; + for projection in &projections { + let p = projection.skip_binder(); + let alias_ty = p.projection_ty; + if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty { + let name = tcx.item_name(alias_ty.def_id); + projections_str.push(format!("{} = {}", name, p.term)); + } + } + let bound_def_path = tcx.def_path_str(bound); + if projections_str.is_empty() { + where_clauses.push(format!("{}: {}", ty, bound_def_path)); + } else { + bounds_str.push(format!("{}<{}>", bound_def_path, projections_str.join(", "))); + } + } + if bounds_str.is_empty() { + types_str.push(ty.to_string()); + } else { + types_str.push(format!("{}: {}", ty, bounds_str.join(" + "))); + } + } else { + // Avoid suggesting the following: + // fn foo::Bar>(_: T) where T: Trait, ::Bar: Other {} + where_clauses.extend( + bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))), + ); + } } + + let generics = + if types_str.is_empty() { "".to_string() } else { format!("<{}>", types_str.join(", ")) }; + let where_clauses = if where_clauses.is_empty() { - String::new() + "".to_string() } else { format!(" where {}", where_clauses.join(", ")) }; + (generics, where_clauses) } diff --git a/tests/ui/suggestions/auxiliary/extern-issue-98562.rs b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs new file mode 100644 index 0000000000000..948e40549c6db --- /dev/null +++ b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs @@ -0,0 +1,26 @@ +pub trait TraitE { + type I3; +} + +pub trait TraitD { + type I3; +} + +pub trait TraitC { + type I1; + type I2; +} + +pub trait TraitB { + type Item; +} + +pub trait TraitA { + fn baz< + U: TraitC + TraitD + TraitE, + V: TraitD + >(_: U, _: V) -> Self + where + U: TraitB, + ::Item: Copy; +} diff --git a/tests/ui/suggestions/issue-98562.rs b/tests/ui/suggestions/issue-98562.rs new file mode 100644 index 0000000000000..de04050d59312 --- /dev/null +++ b/tests/ui/suggestions/issue-98562.rs @@ -0,0 +1,12 @@ +// aux-build:extern-issue-98562.rs + +extern crate extern_issue_98562; +use extern_issue_98562::TraitA; + +struct X; +impl TraitA for X { + //~^ ERROR not all trait items implemented +} +//~^ HELP implement the missing item: `fn baz + TraitD, V: TraitD>(_: U, _: V) -> Self where U: TraitE, U: TraitB, ::Item: Copy { todo!() }` + +fn main() {} diff --git a/tests/ui/suggestions/issue-98562.stderr b/tests/ui/suggestions/issue-98562.stderr new file mode 100644 index 0000000000000..7897fa441a24f --- /dev/null +++ b/tests/ui/suggestions/issue-98562.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `baz` + --> $DIR/issue-98562.rs:7:1 + | +LL | impl TraitA for X { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `baz` in implementation + | + = help: implement the missing item: `fn baz + TraitD, V: TraitD>(_: U, _: V) -> Self where U: TraitE, U: TraitB, ::Item: Copy { todo!() }` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr index 77fa956287816..84cb6e98553ee 100644 --- a/tests/ui/suggestions/missing-assoc-fn.stderr +++ b/tests/ui/suggestions/missing-assoc-fn.stderr @@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter` LL | impl FromIterator<()> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation | - = help: implement the missing item: `fn from_iter(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }` + = help: implement the missing item: `fn from_iter>(_: T) -> Self { todo!() }` error: aborting due to 3 previous errors From 90f317b2de742bcc986cd40c6736ffc3813d036c Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Fri, 29 Sep 2023 12:24:35 +0200 Subject: [PATCH 094/103] add needs-relocation-model-pic to compiletest --- src/tools/compiletest/src/common.rs | 6 ++++++ src/tools/compiletest/src/header/needs.rs | 5 +++++ tests/ui/abi/relocation_model_pic.rs | 3 +-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index ba273489eb8af..0e1bf0c6c2dce 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -580,6 +580,8 @@ pub struct TargetCfg { pub(crate) sanitizers: Vec, #[serde(rename = "supports-xray", default)] pub(crate) xray: bool, + #[serde(default = "default_reloc_model")] + pub(crate) relocation_model: String, } impl TargetCfg { @@ -592,6 +594,10 @@ fn default_os() -> String { "none".into() } +fn default_reloc_model() -> String { + "pic".into() +} + #[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)] #[serde(rename_all = "kebab-case")] pub enum Endian { diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 1113721fff612..2b7a4387cebc1 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -134,6 +134,11 @@ pub(super) fn handle_needs( condition: config.target_cfg().dynamic_linking, ignore_reason: "ignored on targets without dynamic linking", }, + Need { + name: "needs-relocation-model-pic", + condition: config.target_cfg().relocation_model == "pic", + ignore_reason: "ignored on targets without PIC relocation model", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { diff --git a/tests/ui/abi/relocation_model_pic.rs b/tests/ui/abi/relocation_model_pic.rs index 0cfc44cd09d80..cca2e8db74d75 100644 --- a/tests/ui/abi/relocation_model_pic.rs +++ b/tests/ui/abi/relocation_model_pic.rs @@ -1,7 +1,6 @@ // run-pass // compile-flags: -C relocation-model=pic -// ignore-emscripten no pic -// ignore-wasm +// needs-relocation-model-pic #![feature(cfg_relocation_model)] From 3853774df8d8217fb9788be3c0636b9a06da740f Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 14 Jun 2023 12:19:21 +0200 Subject: [PATCH 095/103] mark relevant tests as requiring unwinding --- tests/incremental/change_crate_dep_kind.rs | 1 + tests/ui/panics/short-ice-remove-middle-frames-2.rs | 1 + tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr | 2 +- tests/ui/panics/short-ice-remove-middle-frames.rs | 1 + tests/ui/panics/short-ice-remove-middle-frames.run.stderr | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs index f518266016e09..b9f74340472c0 100644 --- a/tests/incremental/change_crate_dep_kind.rs +++ b/tests/incremental/change_crate_dep_kind.rs @@ -5,6 +5,7 @@ // needs-unwind // revisions:cfail1 cfail2 // compile-flags: -Z query-dep-graph -Cpanic=unwind +// needs-unwind // build-pass (FIXME(62277): could be check-pass?) #![feature(panic_unwind)] diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs index 38a80f8b6703a..751959f55bb6e 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs @@ -2,6 +2,7 @@ // run-fail // check-run-results // exec-env:RUST_BACKTRACE=1 +// needs-unwind // ignore-android FIXME #17520 // ignore-wasm no panic support // ignore-openbsd no support for libbacktrace without filename diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr index 2b648a0cad2ea..664ebaa4c51a6 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:56:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:57:5: debug!!! stack backtrace: 0: std::panicking::begin_panic diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs index c872084f0333e..134e13233da51 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.rs +++ b/tests/ui/panics/short-ice-remove-middle-frames.rs @@ -2,6 +2,7 @@ // run-fail // check-run-results // exec-env:RUST_BACKTRACE=1 +// needs-unwind // ignore-android FIXME #17520 // ignore-wasm no panic support // ignore-openbsd no support for libbacktrace without filename diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr index 5b37268409679..bc252fde1f6ab 100644 --- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr +++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:52:5: +thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:53:5: debug!!! stack backtrace: 0: std::panicking::begin_panic From 814fbd89b69173a3f2189c739dd32921702c5eca Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 29 Sep 2023 09:58:53 +0000 Subject: [PATCH 096/103] Remove deleted docs + better link together MIR traversing docs --- compiler/rustc_middle/src/mir/basic_blocks.rs | 4 +++ compiler/rustc_middle/src/mir/traversal.rs | 35 +++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index c0f02c64bbf62..3ecd5b9cd3456 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -63,6 +63,10 @@ impl<'tcx> BasicBlocks<'tcx> { } /// Returns basic blocks in a reverse postorder. + /// + /// See [`traversal::reverse_postorder`]'s docs to learn what is preorder traversal. + /// + /// [`traversal::reverse_postorder`]: crate::mir::traversal::reverse_postorder #[inline] pub fn reverse_postorder(&self) -> &[BasicBlock] { self.cache.reverse_postorder.get_or_init(|| { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 28b05f2524f02..a1ff8410eac4a 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -41,6 +41,12 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> { } } +/// Preorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that +/// returns basic blocks in a preorder. +/// +/// See [`Preorder`]'s docs to learn what is preorder traversal. pub fn preorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Preorder<'a, 'tcx> { Preorder::new(body, START_BLOCK) } @@ -213,10 +219,14 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> { } } -/// Creates an iterator over the `Body`'s basic blocks, that: +/// Postorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that: /// - returns basic blocks in a postorder, /// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the /// postorder itself. +/// +/// See [`Postorder`]'s docs to learn what is postorder traversal. pub fn postorder<'a, 'tcx>( body: &'a Body<'tcx>, ) -> impl Iterator)> + ExactSizeIterator + DoubleEndedIterator @@ -241,9 +251,30 @@ pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet { iter.visited } -/// Creates an iterator over the `Body`'s basic blocks, that: +/// Reverse postorder traversal of a graph. +/// +/// This function creates an iterator over the `Body`'s basic blocks, that: /// - returns basic blocks in a reverse postorder, /// - makes use of the `BasicBlocks` CFG cache's reverse postorder. +/// +/// Reverse postorder is the reverse order of a postorder traversal. +/// This is different to a preorder traversal and represents a natural +/// linearization of control-flow. +/// +/// ```text +/// +/// A +/// / \ +/// / \ +/// B C +/// \ / +/// \ / +/// D +/// ``` +/// +/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D` +/// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to +/// a topological sort. pub fn reverse_postorder<'a, 'tcx>( body: &'a Body<'tcx>, ) -> impl Iterator)> + ExactSizeIterator + DoubleEndedIterator From 854cdff9722e275496d15d8a89aa55ee32e753cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 29 Sep 2023 19:17:55 +0200 Subject: [PATCH 097/103] rustdoc: simplify sugared_async_return_type --- src/librustdoc/clean/types.rs | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f5251f50b7a7b..1d8fa2e636edd 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1604,14 +1604,16 @@ impl Type { /// /// This function will panic if the return type does not match the expected sugaring for async /// functions. - pub(crate) fn sugared_async_return_type(&self) -> Type { - if let Type::ImplTrait(v) = self && - let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..] + pub(crate) fn sugared_async_return_type(self) -> Type { + if let Type::ImplTrait(mut v) = self + && let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _ )) = v.pop() + && let Some(segment) = trait_.segments.pop() + && let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args + && let Some(binding) = bindings.pop() + && let TypeBindingKind::Equality { term } = binding.kind + && let Term::Type(ty) = term { - let bindings = trait_.bindings().unwrap(); - let ret_ty = bindings[0].term(); - let ty = ret_ty.ty().expect("unexpected constant in async fn return term"); - ty.clone() + ty } else { panic!("unexpected async fn return type") } @@ -2189,16 +2191,6 @@ impl Path { } }) } - - pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> { - self.segments.last().and_then(|seg| { - if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args { - Some(&**bindings) - } else { - None - } - }) - } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -2478,15 +2470,6 @@ pub(crate) enum TypeBindingKind { Constraint { bounds: Vec }, } -impl TypeBinding { - pub(crate) fn term(&self) -> &Term { - match self.kind { - TypeBindingKind::Equality { ref term } => term, - _ => panic!("expected equality type binding for parenthesized generic args"), - } - } -} - /// The type, lifetime, or constant that a private type alias's parameter should be /// replaced with when expanding a use of that type alias. /// From 841bff2e29c13b755fbb8cb9e0fc9a1555f75706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 29 Sep 2023 23:04:53 +0200 Subject: [PATCH 098/103] rustdoc: reduce the amount of `asyncness` query executions --- src/librustdoc/clean/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 34d81f51f76e6..5a1612e76e306 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1183,7 +1183,13 @@ fn clean_fn_decl_from_did_and_sig<'tcx>( // but shouldn't change any code meaning. let mut output = clean_middle_ty(sig.output(), cx, None, None); - if let Some(did) = did && cx.tcx.asyncness(did).is_async() { + // If the return type isn't an `impl Trait`, we can safely assume that this + // function isn't async without needing to execute the query `asyncness` at + // all which gives us a noticeable performance boost. + if let Some(did) = did + && let Type::ImplTrait(_) = output + && cx.tcx.asyncness(did).is_async() + { output = output.sugared_async_return_type(); } From 1ad3bb971b3d47fe4cbf18ecd9d1f1963cc4676b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 30 Sep 2023 09:06:06 +0800 Subject: [PATCH 099/103] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index e6aabe8b3fcf6..59596f0f31a94 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit e6aabe8b3fcf639be3a5bf68e77853bd7b3fa27d +Subproject commit 59596f0f31a94fde48b5aa7e945cd0b7ceca9620 From 1008c984059b4b34df40a8dd3fd77c249b7df6b7 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Sat, 30 Sep 2023 14:08:52 +0300 Subject: [PATCH 100/103] =?UTF-8?q?Add=20O=C4=9Fuz=20A=C4=9Fcayaz=C4=B1=20?= =?UTF-8?q?to=20.mailmap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .mailmap | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mailmap b/.mailmap index 21e1adb43cff9..26d6be9f0c600 100644 --- a/.mailmap +++ b/.mailmap @@ -429,6 +429,8 @@ Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb Nif Ward Nika Layzell NODA Kai +Oğuz Ağcayazı +Oğuz Ağcayazı oliver <16816606+o752d@users.noreply.github.com> Oliver Middleton Oliver Scherer From d62833861500038cdceb3259fece79d9a9b67e9f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 30 Sep 2023 23:29:13 +0200 Subject: [PATCH 101/103] 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 07dd52ce94159..b60de8344d948 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -2ba4eb2d49e774b5fbc2a06258ac7b0f60b92b7e +bb6c66be3793ac5c738eeac91ecdc4b99388d0b4 From 45d5733ccbd6300ece6b7bf18111e4a5b4daf774 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 30 Sep 2023 23:30:51 +0200 Subject: [PATCH 102/103] fmt --- src/tools/miri/src/shims/intrinsics/simd.rs | 11 +++++++---- src/tools/miri/tests/pass/portable-simd.rs | 14 ++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index 5e488679b81d6..0dc669849fe0c 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -495,16 +495,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let (right, right_len) = this.operand_to_simd(right)?; let (dest, dest_len) = this.place_to_simd(dest)?; - let index = generic_args[2].expect_const().eval(*this.tcx, this.param_env(), Some(this.tcx.span)).unwrap().unwrap_branch(); + let index = generic_args[2] + .expect_const() + .eval(*this.tcx, this.param_env(), Some(this.tcx.span)) + .unwrap() + .unwrap_branch(); let index_len = index.len(); assert_eq!(left_len, right_len); assert_eq!(index_len as u64, dest_len); for i in 0..dest_len { - let src_index: u64 = index[i as usize].unwrap_leaf() - .try_to_u32().unwrap() - .into(); + let src_index: u64 = + index[i as usize].unwrap_leaf().try_to_u32().unwrap().into(); let dest = this.project_index(&dest, i)?; let val = if src_index < left_len { diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs index c1f5618c16346..969162e2c1e9e 100644 --- a/src/tools/miri/tests/pass/portable-simd.rs +++ b/src/tools/miri/tests/pass/portable-simd.rs @@ -416,20 +416,14 @@ fn simd_intrinsics() { simd_select(i8x4::from_array([0, -1, -1, 0]), b, a), i32x4::from_array([10, 2, 10, 10]) ); + assert_eq!(simd_shuffle_generic::<_, i32x4, { &[3, 1, 0, 2] }>(a, b), a,); + assert_eq!(simd_shuffle::<_, _, i32x4>(a, b, const { [3, 1, 0, 2] }), a,); assert_eq!( - simd_shuffle_generic::<_, i32x4, {&[3, 1, 0, 2]}>(a, b), - a, - ); - assert_eq!( - simd_shuffle::<_, _, i32x4>(a, b, const {[3, 1, 0, 2]}), - a, - ); - assert_eq!( - simd_shuffle_generic::<_, i32x4, {&[7, 5, 4, 6]}>(a, b), + simd_shuffle_generic::<_, i32x4, { &[7, 5, 4, 6] }>(a, b), i32x4::from_array([4, 2, 1, 10]), ); assert_eq!( - simd_shuffle::<_, _, i32x4>(a, b, const {[7, 5, 4, 6]}), + simd_shuffle::<_, _, i32x4>(a, b, const { [7, 5, 4, 6] }), i32x4::from_array([4, 2, 1, 10]), ); } From 119113114cfe77ccec1fd69d6b6fd42422181978 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 30 Sep 2023 23:32:13 +0200 Subject: [PATCH 103/103] clippy --- src/tools/miri/src/shims/intrinsics/simd.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs index 0dc669849fe0c..200f37efa27b1 100644 --- a/src/tools/miri/src/shims/intrinsics/simd.rs +++ b/src/tools/miri/src/shims/intrinsics/simd.rs @@ -506,8 +506,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { assert_eq!(index_len as u64, dest_len); for i in 0..dest_len { - let src_index: u64 = - index[i as usize].unwrap_leaf().try_to_u32().unwrap().into(); + let src_index: u64 = index[usize::try_from(i).unwrap()] + .unwrap_leaf() + .try_to_u32() + .unwrap() + .into(); let dest = this.project_index(&dest, i)?; let val = if src_index < left_len {