From 2f02a4e4a02fed8275f71f800899fadc488b18d9 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 24 May 2022 12:08:54 -0700 Subject: [PATCH 01/76] coverage: Don't underflow column number I noticed this when running coverage on a debug build of rustc. There may be other places that do this but I'm just fixing the one I hit. --- compiler/rustc_mir_transform/src/coverage/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 2bb9f48f9b7c8..a96b8efd481a4 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -515,7 +515,7 @@ fn make_code_region( // Extend an empty span by one character so the region will be counted. let CharPos(char_pos) = start_col; if span.hi() == body_span.hi() { - start_col = CharPos(char_pos - 1); + start_col = CharPos(char_pos.saturating_sub(1)); } else { end_col = CharPos(char_pos + 1); } From 6f7ca32ae7f5cd9159a986ca0c30b77420cce933 Mon Sep 17 00:00:00 2001 From: pat-nel87 Date: Thu, 23 Feb 2023 19:53:33 -0500 Subject: [PATCH 02/76] black_box doc corrections - Issue #107957 --- library/core/src/hint.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index ee13dae60b198..f90077eecd1d8 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -223,12 +223,12 @@ pub fn spin_loop() { /// /// # When is this useful? /// -/// First and foremost: `black_box` does _not_ guarantee any exact behavior and, in some cases, may -/// do nothing at all. As such, it **must not be relied upon to control critical program behavior.** +/// First and foremost: `black_box` does _not_ guarantee any exact behavior beyond behaving as the identity function +/// and, in some cases, does nothing at all. As such, it **must not be relied upon to control critical program behavior.** /// This _immediately_ precludes any direct use of this function for cryptographic or security /// purposes. /// -/// While not suitable in those mission-critical cases, `back_box`'s functionality can generally be +/// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be /// relied upon for benchmarking, and should be used there. It will try to ensure that the /// compiler doesn't optimize away part of the intended test code based on context. For /// example: From 21549dac539dc220f052d038ec643645cedbbd6d Mon Sep 17 00:00:00 2001 From: pat-nel87 <71235856+pat-nel87@users.noreply.github.com> Date: Tue, 7 Mar 2023 18:32:58 -0500 Subject: [PATCH 03/76] black_box hint - Adjust for improved readability --- library/core/src/hint.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index f90077eecd1d8..a35f4e029a204 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -217,17 +217,14 @@ pub fn spin_loop() { /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The /// extent to which it can block optimisations may vary depending upon the platform and code-gen /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the -/// identity function. +/// identity function. As such, it **must not be relied upon to control critical program behavior.** +/// This _immediately_ precludes any direct use of this function for cryptographic or security +/// purposes. /// /// [`std::convert::identity`]: crate::convert::identity /// /// # When is this useful? /// -/// First and foremost: `black_box` does _not_ guarantee any exact behavior beyond behaving as the identity function -/// and, in some cases, does nothing at all. As such, it **must not be relied upon to control critical program behavior.** -/// This _immediately_ precludes any direct use of this function for cryptographic or security -/// purposes. -/// /// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be /// relied upon for benchmarking, and should be used there. It will try to ensure that the /// compiler doesn't optimize away part of the intended test code based on context. For From 3970793579f39d7610df1936c4ca996062e99c92 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Mon, 20 Mar 2023 08:34:43 +0100 Subject: [PATCH 04/76] Replace `yes` command by `while-echo` The `yes` command is not available on all platforms. --- tests/ui/process/process-sigpipe.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 7ae14c6b84d2f..4f4db11911594 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -8,14 +8,14 @@ // libstd ignores SIGPIPE, and other libraries may set signal masks. // Make sure that these behaviors don't get inherited to children // spawned via std::process, since they're needed for traditional UNIX -// filter behavior. This test checks that `yes | head` terminates +// filter behavior. +// This test checks that `while echo y ; do : ; done | head` terminates // (instead of running forever), and that it does not print an error // message about a broken pipe. // ignore-emscripten no threads support // ignore-vxworks no 'sh' // ignore-fuchsia no 'sh' -// ignore-nto no 'yes' use std::process; use std::thread; @@ -27,7 +27,11 @@ fn main() { thread::sleep_ms(5000); process::exit(1); }); - let output = process::Command::new("sh").arg("-c").arg("yes | head").output().unwrap(); + let output = process::Command::new("sh") + .arg("-c") + .arg("while echo y ; do : ; done | head") + .output() + .unwrap(); assert!(output.status.success()); assert!(output.stderr.len() == 0); } From 9c567fdaee23a0000bf91d3d550b8da4bee44bd6 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Apr 2023 01:03:30 -0400 Subject: [PATCH 05/76] Update documentation wording on path 'try_exists' functions --- library/std/src/fs.rs | 7 ++++--- library/std/src/path.rs | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c550378e7d6b7..82c27312d0f44 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2511,9 +2511,10 @@ impl AsInnerMut for DirBuilder { /// This function will traverse symbolic links to query information about the /// destination file. In case of broken symbolic links this will return `Ok(false)`. /// -/// As opposed to the [`Path::exists`] method, this one doesn't silently ignore errors -/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission -/// denied on some of the parent directories.) +/// As opposed to the [`Path::exists`] method, this will only return `Ok(true)` or `Ok(false)` +/// if the path was _verified_ to exist or not exist. If its existence can neither be confirmed +/// nor denied, an `Err(_)` will be propagated instead. This can be the case if e.g. listing +/// permission is denied on one of the parent directories. /// /// Note that while this avoids some pitfalls of the `exists()` method, it still can not /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios diff --git a/library/std/src/path.rs b/library/std/src/path.rs index dbc18f7827e60..6aa7ae7ef9025 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2844,9 +2844,11 @@ impl Path { /// This function will traverse symbolic links to query information about the /// destination file. In case of broken symbolic links this will return `Ok(false)`. /// - /// As opposed to the [`exists()`] method, this one doesn't silently ignore errors - /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission - /// denied on some of the parent directories.) + /// [`Path::exists()`] only checks whether or not a path was both found and readable. By + /// contrast, `try_exists` will return `Ok(true)` or `Ok(false)`, respectively, if the path + /// was _verified_ to exist or not exist. If its existence can neither be confirmed nor + /// denied, it will propagate an `Err(_)` instead. This can be the case if e.g. listing + /// permission is denied on one of the parent directories. /// /// Note that while this avoids some pitfalls of the `exists()` method, it still can not /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios From e3de409aaa592a36548a9f453688c3e877b5caa1 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 14 Apr 2023 17:53:57 +0000 Subject: [PATCH 06/76] Move test from rustdoc-ui to rustdoc-json --- .../reexport/auxiliary/enum_with_discriminant.rs | 6 ++++++ .../rustdoc-json/reexport/doc_inline_external_crate.rs | 10 ++++++++++ tests/rustdoc-json/reexport/extern_crate_glob.rs | 10 ++++++++++ .../rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs | 3 --- tests/rustdoc-ui/intra-doc/inline-external-enum.rs | 8 -------- 5 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs create mode 100644 tests/rustdoc-json/reexport/doc_inline_external_crate.rs create mode 100644 tests/rustdoc-json/reexport/extern_crate_glob.rs delete mode 100644 tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs delete mode 100644 tests/rustdoc-ui/intra-doc/inline-external-enum.rs diff --git a/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs b/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs new file mode 100644 index 0000000000000..4fa26204be917 --- /dev/null +++ b/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs @@ -0,0 +1,6 @@ +//! Should not be inlined + +/// Should not be inlined +pub enum O { + L = -1, +} diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs new file mode 100644 index 0000000000000..40b681d7dbbef --- /dev/null +++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs @@ -0,0 +1,10 @@ +// Regression Test for https://github.com/rust-lang/rust/issues/110138 +// aux-build: enum_with_discriminant.rs + +#[doc(inline)] +pub extern crate enum_with_discriminant; + +// @!has '$.index[*][?(@.docs == "Should not be inlined")]' +// @is '$.index[*][?(@.name == "enum_with_discriminant")].kind' '"extern_crate"' +// @set enum_with_discriminant = '$.index[*][?(@.name == "enum_with_discriminant")].id' +// @is '$.index[*][?(@.name == "doc_inline_external_crate")].inner.items[*]' $enum_with_discriminant diff --git a/tests/rustdoc-json/reexport/extern_crate_glob.rs b/tests/rustdoc-json/reexport/extern_crate_glob.rs new file mode 100644 index 0000000000000..8efb94fd3f17a --- /dev/null +++ b/tests/rustdoc-json/reexport/extern_crate_glob.rs @@ -0,0 +1,10 @@ +// aux-build: enum_with_discriminant.rs + +extern crate enum_with_discriminant; + +#[doc(inline)] +pub use enum_with_discriminant::*; + +// @!has '$.index[*][?(@.docs == "Should not be inlined")]' +// @set use = '$.index[*][?(@.inner.name == "enum_with_discriminant")].id' +// @is '$.index[*][?(@.name == "extern_crate_glob")].inner.items[*]' $use diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs b/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs deleted file mode 100644 index 6c48f5aa01f98..0000000000000 --- a/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub enum O { - L = -1, -} diff --git a/tests/rustdoc-ui/intra-doc/inline-external-enum.rs b/tests/rustdoc-ui/intra-doc/inline-external-enum.rs deleted file mode 100644 index 363dd7f64c225..0000000000000 --- a/tests/rustdoc-ui/intra-doc/inline-external-enum.rs +++ /dev/null @@ -1,8 +0,0 @@ -// check-pass -// aux-build: inner-crate-enum.rs -// compile-flags:-Z unstable-options --output-format json - -#[doc(inline)] -pub extern crate inner_crate_enum; - -fn main() {} From b9f960407aa6c442a0d87bcbede431ca9347fe13 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Sun, 9 Apr 2023 10:33:13 -0400 Subject: [PATCH 07/76] spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- src/doc/rustdoc/src/references.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustdoc/src/references.md b/src/doc/rustdoc/src/references.md index 45cf4e88eef6b..2e0cb1c0af4cd 100644 --- a/src/doc/rustdoc/src/references.md +++ b/src/doc/rustdoc/src/references.md @@ -13,15 +13,15 @@ If you know of other great resources, please submit a pull request! ## Community - [API Guidelines] -- [Github tagged RFCs] -- [Github tagged issues] +- [GitHub tagged RFCs] +- [GitHub tagged issues] - [RFC (stalled) front page styleguide] - [Guide on how to write documentation for a Rust crate] [API Guidelines]: https://rust-lang.github.io/api-guidelines/documentation.html -[Github tagged RFCs]: https://github.com/rust-lang/rfcs/issues?q=label%3AT-rustdoc -[Github tagged issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AT-rustdoc +[GitHub tagged RFCs]: https://github.com/rust-lang/rfcs/issues?q=label%3AT-rustdoc +[GitHub tagged issues]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+label%3AT-rustdoc [Guide on how to write documentation for a Rust crate]: https://blog.guillaume-gomez.fr/articles/2020-03-12+Guide+on+how+to+write+documentation+for+a+Rust+crate [Learn Rust]: https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments [RFC 1574: More API Documentation Conventions]: https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html From b9b48e792e1ba74dcb8ed8a0621b140ca3fc8080 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Sun, 9 Apr 2023 23:19:02 -0400 Subject: [PATCH 08/76] spelling: typographical Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- src/doc/rustdoc/src/how-to-read-rustdoc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index 56342f65d9998..393192af01e98 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -43,7 +43,7 @@ including automatic and blanket implementations that `rustdoc` knows about. Subheadings, variants, fields, and many other things in this documentation are anchors and can be clicked on and deep-linked to, which is a great way to communicate exactly what you're talking about. -The typograpical character "§" appears next to lines with anchors on them +The typographical character "§" appears next to lines with anchors on them when hovered or given keyboard focus. ## The Navigation Bar From b0a7d6e4b7627be023625e62c529f659de56f8fe Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 16:47:06 +0000 Subject: [PATCH 09/76] Suggest deref on comparison binop RHS even if type is not Copy --- compiler/rustc_hir_typeck/src/demand.rs | 6 ++++++ tests/ui/inference/deref-suggestion.rs | 9 +++++++++ tests/ui/inference/deref-suggestion.stderr | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 525acfdaa8124..b8222820cf7a4 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1508,6 +1508,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(compiler-errors): We can actually do this if the checked_ty is // `steps` layers of boxes, not just one, but this is easier and most likely. || (checked_ty.is_box() && steps == 1) + // We can always deref a binop that takes its arguments by ref. + || matches!( + self.tcx.hir().get_parent(expr.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, ..), .. }) + if !op.node.is_by_value() + ) { let deref_kind = if checked_ty.is_box() { "unboxing the value" diff --git a/tests/ui/inference/deref-suggestion.rs b/tests/ui/inference/deref-suggestion.rs index 0d8e7289dc8a2..dc39cc9dbffb0 100644 --- a/tests/ui/inference/deref-suggestion.rs +++ b/tests/ui/inference/deref-suggestion.rs @@ -72,4 +72,13 @@ fn main() { } else { &0 }; + + #[derive(PartialEq, Eq)] + struct Foo; + let foo = Foo; + let bar = &Foo; + + if foo == bar { + //~^ ERROR mismatched types + } } diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 1626032ae997d..6f5aacacfc1f1 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -175,6 +175,19 @@ LL | || }; | |_____`if` and `else` have incompatible types | expected `i32`, found `&{integer}` -error: aborting due to 13 previous errors +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:81:15 + | +LL | if foo == bar { + | --- ^^^ expected `Foo`, found `&Foo` + | | + | expected because this is `Foo` + | +help: consider dereferencing the borrow + | +LL | if foo == *bar { + | + + +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0308`. From 01c4f319276da912dd2be768ae0ce9857ad6bb63 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 20 Apr 2023 10:19:42 +0200 Subject: [PATCH 10/76] Fix `std` compilation error for wasi+atomics --- library/std/src/sys/wasi/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index 1dc3f2b20266d..c468ae395fc8d 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -32,8 +32,6 @@ pub mod io; #[path = "../unsupported/locks/mod.rs"] pub mod locks; pub mod net; -#[path = "../unsupported/once.rs"] -pub mod once; pub mod os; #[path = "../unix/os_str.rs"] pub mod os_str; @@ -51,6 +49,13 @@ pub mod thread_local_dtor; pub mod thread_local_key; pub mod time; +cfg_if::cfg_if! { + if #[cfg(not(target_feature = "atomics"))] { + #[path = "../unsupported/once.rs"] + pub mod once; + } +} + #[path = "../unsupported/common.rs"] #[deny(unsafe_op_in_unsafe_fn)] #[allow(unused)] From 77c83c09653f5c4437717e2e8aa7f10c1ff94fe4 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 20 Apr 2023 16:23:13 +0000 Subject: [PATCH 11/76] Add `impl_tag!` macro to implement `Tag` for tagged pointer easily --- .../rustc_data_structures/src/tagged_ptr.rs | 41 ++++- .../src/tagged_ptr/impl_tag.rs | 170 ++++++++++++++++++ .../src/tagged_ptr/impl_tag/tests.rs | 33 ++++ compiler/rustc_middle/src/ty/mod.rs | 29 +-- 4 files changed, 244 insertions(+), 29 deletions(-) create mode 100644 compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs create mode 100644 compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index 8568aac67c08c..a25046986cc59 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs @@ -24,6 +24,7 @@ use crate::aligned::Aligned; mod copy; mod drop; +mod impl_tag; pub use copy::CopyTaggedPtr; pub use drop::TaggedPtr; @@ -141,6 +142,40 @@ pub unsafe trait Tag: Copy { unsafe fn from_usize(tag: usize) -> Self; } +/// Returns the number of bits available for use for tags in a pointer to `T` +/// (this is based on `T`'s alignment). +pub const fn bits_for() -> u32 { + crate::aligned::align_of::().as_nonzero().trailing_zeros() +} + +/// Returns the correct [`Tag::BITS`] constant for a set of tag values. +pub const fn bits_for_tags(mut tags: &[usize]) -> u32 { + let mut bits = 0; + + while let &[tag, ref rest @ ..] = tags { + tags = rest; + + let b = bits_for_tag(tag); + if b > bits { + bits = b; + } + } + + bits +} + +/// Returns `(size_of::() * 8) - tag.leading_zeros()` +const fn bits_for_tag(mut tag: usize) -> u32 { + let mut bits = 0; + + while tag > 0 { + bits += 1; + tag >>= 1; + } + + bits +} + unsafe impl Pointer for Box { const BITS: u32 = bits_for::(); @@ -221,12 +256,6 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T { } } -/// Returns the number of bits available for use for tags in a pointer to `T` -/// (this is based on `T`'s alignment). -pub const fn bits_for() -> u32 { - crate::aligned::align_of::().as_nonzero().trailing_zeros() -} - /// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs new file mode 100644 index 0000000000000..deaaee4cc1728 --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -0,0 +1,170 @@ +/// Implements [`Tag`] for a given type. +/// +/// You can use `impl_tag` on structs and enums. +/// You need to specify the type and all its possible values, +/// which can only be paths with optional fields. +/// +/// [`Tag`]: crate::tagged_ptr::Tag +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag}; +/// +/// #[derive(Copy, Clone, PartialEq, Debug)] +/// enum SomeTag { +/// A, +/// B, +/// X { v: bool }, +/// Y(bool, bool), +/// } +/// +/// impl_tag! { +/// // The type for which the `Tag` will be implemented +/// for SomeTag; +/// // You need to specify the `{value_of_the_type} <=> {tag}` relationship +/// SomeTag::A <=> 0, +/// SomeTag::B <=> 1, +/// // For variants with fields, you need to specify the fields: +/// SomeTag::X { v: true } <=> 2, +/// SomeTag::X { v: false } <=> 3, +/// // For tuple variants use named syntax: +/// SomeTag::Y { 0: true, 1: true } <=> 4, +/// SomeTag::Y { 0: false, 1: true } <=> 5, +/// SomeTag::Y { 0: true, 1: false } <=> 6, +/// SomeTag::Y { 0: false, 1: false } <=> 7, +/// } +/// +/// assert_eq!(SomeTag::A.into_usize(), 0); +/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3); +/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5); +/// +/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B); +/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true }); +/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false)); +/// ``` +/// +/// Structs are supported: +/// +/// ``` +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// struct Flags { a: bool, b: bool } +/// +/// impl_tag! { +/// for Flags; +/// Flags { a: true, b: true } <=> 3, +/// Flags { a: false, b: true } <=> 2, +/// Flags { a: true, b: false } <=> 1, +/// Flags { a: false, b: false } <=> 0, +/// } +/// ``` +/// +// This is supposed to produce a compile error, but does not, +// see for more information. +// +// Using the same pattern twice results in a compile error: +// +// ```compile_fail +// # use rustc_data_structures::impl_tag; +// #[derive(Copy, Clone)] +// struct Unit; +// +// impl_tag! { +// for Unit; +// Unit <=> 0, +// Unit <=> 1, +// } +// ``` +// +// Using the same tag twice results in a compile error: +// +// ```compile_fail +// # use rustc_data_structures::impl_tag; +// #[derive(Copy, Clone)] +// enum E { A, B }; +// +// impl_tag! { +// for E; +// E::A <=> 0, +// E::B <=> 0, +// } +// ``` +// +/// Not specifying all values results in a compile error: +/// +/// ```compile_fail,E0004 +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// enum E { +/// A, +/// B, +/// } +/// +/// impl_tag! { +/// for E; +/// E::A <=> 0, +/// } +/// ``` +#[macro_export] +macro_rules! impl_tag { + ( + for $Self:ty; + $( + $($path:ident)::* $( { $( $fields:tt )* })? <=> $tag:literal, + )* + ) => { + // Safety: + // `into_usize` only returns one of `$tag`s, + // `bits_for_tags` is called on all `$tag`s, + // thus `BITS` constant is correct. + unsafe impl $crate::tagged_ptr::Tag for $Self { + const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[ + $( $tag, )* + ]); + + fn into_usize(self) -> usize { + // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc) + // (or at least it should, see ) + #[forbid(unreachable_patterns)] + match self { + // `match` is doing heavy lifting here, by requiring exhaustiveness + $( + $($path)::* $( { $( $fields )* } )? => $tag, + )* + } + } + + unsafe fn from_usize(tag: usize) -> Self { + // Similarly to the above, this forbids repeating tags + // (or at least it should, see ) + #[forbid(unreachable_patterns)] + match tag { + $( + $tag => $($path)::* $( { $( $fields )* } )?, + )* + + // Safety: + // `into_usize` only returns one of `$tag`s, + // all `$tag`s are filtered up above, + // thus if this is reached, the safety contract of this + // function was already breached. + _ => unsafe { + debug_assert!( + false, + "invalid tag: {tag}\ + (this is a bug in the caller of `from_usize`)" + ); + std::hint::unreachable_unchecked() + }, + } + } + + } + }; +} + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs new file mode 100644 index 0000000000000..26d1cf3b45422 --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs @@ -0,0 +1,33 @@ +#[test] +fn bits_constant() { + use crate::tagged_ptr::Tag; + + #[derive(Copy, Clone)] + struct Unit; + impl_tag! { for Unit; Unit <=> 0, } + assert_eq!(Unit::BITS, 0); + + #[derive(Copy, Clone)] + struct Unit1; + impl_tag! { for Unit1; Unit1 <=> 1, } + assert_eq!(Unit1::BITS, 1); + + #[derive(Copy, Clone)] + struct Unit2; + impl_tag! { for Unit2; Unit2 <=> 0b10, } + assert_eq!(Unit2::BITS, 2); + + #[derive(Copy, Clone)] + struct Unit3; + impl_tag! { for Unit3; Unit3 <=> 0b100, } + assert_eq!(Unit3::BITS, 3); + + #[derive(Copy, Clone)] + enum Enum { + A, + B, + C, + } + impl_tag! { for Enum; Enum::A <=> 0b1, Enum::B <=> 0b1000, Enum::C <=> 0b10, } + assert_eq!(Enum::BITS, 4); +} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1061c32079305..f520faa6a6154 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1626,29 +1626,12 @@ struct ParamTag { constness: hir::Constness, } -unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag { - const BITS: u32 = 2; - - #[inline] - fn into_usize(self) -> usize { - match self { - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0, - Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1, - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2, - Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3, - } - } - - #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - match ptr { - 0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, - 1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, - 2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, - 3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const }, - _ => std::hint::unreachable_unchecked(), - } - } +impl_tag! { + for ParamTag; + ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } <=> 0, + ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } <=> 1, + ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } <=> 2, + ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::Const } <=> 3, } impl<'tcx> fmt::Debug for ParamEnv<'tcx> { From 0892a7380b1bde39b979a00de1d11cef3357a717 Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Mon, 17 Apr 2023 15:57:29 -0600 Subject: [PATCH 12/76] change usages of explicit_item_bounds to bound_explicit_item_bounds --- .../rustc_hir_analysis/src/check/check.rs | 9 +++-- .../rustc_hir_analysis/src/check/wfcheck.rs | 10 +++-- .../src/collect/item_bounds.rs | 11 ++--- .../src/generator_interior/mod.rs | 3 +- .../src/opaque_hidden_inferred_bound.rs | 4 +- compiler/rustc_lint/src/unused.rs | 40 +++++++++++-------- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_mir_transform/src/generator.rs | 4 +- compiler/rustc_privacy/src/lib.rs | 7 +++- .../src/traits/object_safety.rs | 5 ++- src/librustdoc/clean/mod.rs | 19 +++++---- .../clippy_lints/src/future_not_send.rs | 7 ++-- src/tools/clippy/clippy_utils/src/ty.rs | 5 ++- 13 files changed, 76 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0c54fd70c9b5e..680562ccf6229 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -319,9 +319,12 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( selftys: vec![], }; let prohibit_opaque = tcx - .explicit_item_bounds(def_id) - .iter() - .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); + .bound_explicit_item_bounds(def_id.to_def_id()) + .transpose_iter() + .try_for_each(|bound| { + let predicate = bound.map_bound(|&(predicate, _)| predicate).subst_identity(); + predicate.visit_with(&mut visitor) + }); if let Some(ty) = prohibit_opaque.break_value() { visitor.visit_item(&item); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 53197bc849106..9b89e51bacfc9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -360,7 +360,10 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe tcx, param_env, item_def_id, - tcx.explicit_item_bounds(item_def_id).to_vec(), + tcx.bound_explicit_item_bounds(item_def_id.to_def_id()) + .transpose_iter() + .map(|bound| bound.map_bound(|b| *b).subst_identity()) + .collect::>(), &FxIndexSet::default(), gat_def_id.def_id, gat_generics, @@ -1122,10 +1125,11 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { /// Assuming the defaults are used, check that all predicates (bounds on the /// assoc type and where clauses on the trait) hold. fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, span: Span) { - let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); + let bounds = wfcx.tcx().bound_explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let wf_obligations = bounds.transpose_iter().flat_map(|b| { + let (bound, bound_span) = b.map_bound(|b| *b).subst_identity(); let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::predicate_obligations( wfcx.infcx, diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 2e56d24638cdb..5b2f1419a6921 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -130,9 +130,10 @@ pub(super) fn item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<&'_ ty::List>> { - let bounds = tcx.mk_predicates_from_iter(util::elaborate( - tcx, - tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), - )); - ty::EarlyBinder(bounds) + tcx.bound_explicit_item_bounds(def_id).map_bound(|bounds| { + tcx.mk_predicates_from_iter(util::elaborate( + tcx, + bounds.iter().map(|&(bound, _span)| bound), + )) + }) } diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 8feef332de8a7..1d17af8da8538 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -571,7 +571,8 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) { + for bound in fcx.tcx.bound_explicit_item_bounds(def).transpose_iter() { + let predicate = bound.map_bound(|&(predicate, _)| predicate).subst_identity(); // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index f9d43fe220036..5c408c749456b 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -74,7 +74,9 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) { + for bound in cx.tcx.bound_explicit_item_bounds(def_id).transpose_iter() { + let (pred, pred_span) = bound.map_bound(|b| *b).subst_identity(); + // Liberate bound regions in the predicate since we // don't actually care about lifetimes in this check. let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind()); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index d677d51881e0e..7e4852e3d3bf0 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -254,23 +254,29 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { - elaborate(cx.tcx, cx.tcx.explicit_item_bounds(def).iter().cloned()) - // We only care about self bounds for the impl-trait - .filter_only_self() - .find_map(|(pred, _span)| { - // We only look at the `DefId`, so it is safe to skip the binder here. - if let ty::PredicateKind::Clause(ty::Clause::Trait( - ref poly_trait_predicate, - )) = pred.kind().skip_binder() - { - let def_id = poly_trait_predicate.trait_ref.def_id; - - is_def_must_use(cx, def_id, span) - } else { - None - } - }) - .map(|inner| MustUsePath::Opaque(Box::new(inner))) + elaborate( + cx.tcx, + cx.tcx + .bound_explicit_item_bounds(def) + .transpose_iter() + .map(|bound| bound.map_bound(|b| *b).subst_identity()), + ) + // We only care about self bounds for the impl-trait + .filter_only_self() + .find_map(|(pred, _span)| { + // We only look at the `DefId`, so it is safe to skip the binder here. + if let ty::PredicateKind::Clause(ty::Clause::Trait( + ref poly_trait_predicate, + )) = pred.kind().skip_binder() + { + let def_id = poly_trait_predicate.trait_ref.def_id; + + is_def_must_use(cx, def_id, span) + } else { + None + } + }) + .map(|inner| MustUsePath::Opaque(Box::new(inner))) } ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f9d3ffc8f0063..f65117f4934d7 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1611,7 +1611,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { + self.bound_explicit_item_bounds(*def_id).skip_binder().iter().any(|(predicate, _)| { let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { return false; }; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 507e12d723894..c2c3d2dda3f4c 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1800,7 +1800,9 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in tcx.explicit_item_bounds(def) { + for bound in tcx.bound_explicit_item_bounds(def).transpose_iter() { + let predicate = bound.map_bound(|&(pred, _)| pred).subst_identity(); + // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 9567329192d52..cd48280526f8c 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -269,7 +269,7 @@ where // and are visited by shallow visitors. self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: tcx.explicit_item_bounds(def_id), + predicates: tcx.bound_explicit_item_bounds(def_id).skip_binder(), })?; } } @@ -1784,7 +1784,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn bounds(&mut self) -> &mut Self { self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: self.tcx.explicit_item_bounds(self.item_def_id), + predicates: self + .tcx + .bound_explicit_item_bounds(self.item_def_id.to_def_id()) + .skip_binder(), }); self } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index b8ad1925e4eaa..b7ca37c058ccb 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -297,8 +297,9 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .flat_map(|item| tcx.explicit_item_bounds(item.def_id)) - .filter_map(|pred_span| predicate_references_self(tcx, *pred_span)) + .flat_map(|item| tcx.bound_explicit_item_bounds(item.def_id).transpose_iter()) + .map(|bound| bound.map_bound(|b| *b).subst_identity()) + .filter_map(|pred_span| predicate_references_self(tcx, pred_span)) .collect() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 04379c2bca97d..25031b0102243 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -421,9 +421,9 @@ fn clean_projection<'tcx>( if cx.tcx.is_impl_trait_in_trait(ty.skip_binder().def_id) { let bounds = cx .tcx - .explicit_item_bounds(ty.skip_binder().def_id) - .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.skip_binder().substs)) + .bound_explicit_item_bounds(ty.skip_binder().def_id) + .subst_iter_copied(cx.tcx, ty.skip_binder().substs) + .map(|(pred, _)| pred) .collect::>(); return clean_middle_opaque_bounds(cx, bounds); } @@ -1315,10 +1315,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } if let ty::TraitContainer = assoc_item.container { - let bounds = tcx.explicit_item_bounds(assoc_item.def_id); + let bounds = tcx + .bound_explicit_item_bounds(assoc_item.def_id) + .transpose_iter() + .map(|bound| bound.map_bound(|b| *b).subst_identity()); let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; let predicates = - tcx.arena.alloc_from_iter(bounds.into_iter().chain(predicates).copied()); + tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), @@ -1844,9 +1847,9 @@ pub(crate) fn clean_middle_ty<'tcx>( // by looking up the bounds associated with the def_id. let bounds = cx .tcx - .explicit_item_bounds(def_id) - .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) + .bound_explicit_item_bounds(def_id) + .subst_iter_copied(cx.tcx, substs) + .map(|(bound, _)| bound) .collect::>(); clean_middle_opaque_bounds(cx, bounds) } diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index ed0bd58c770c7..73ae2406f9dbc 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -4,7 +4,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, AliasTy, Clause, EarlyBinder, PredicateKind}; +use rustc_middle::ty::{self, AliasTy, Clause, PredicateKind}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; @@ -64,10 +64,9 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { } let ret_ty = return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(fn_def_id).expect_owner()); if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { - let preds = cx.tcx.explicit_item_bounds(def_id); + let preds = cx.tcx.bound_explicit_item_bounds(def_id); let mut is_future = false; - for &(p, _span) in preds { - let p = EarlyBinder(p).subst(cx.tcx, substs); + for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { if let Some(trait_pred) = p.to_opt_poly_trait_pred() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 8b996c188161d..058f6b0306dcf 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -90,7 +90,8 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) { + for bound in cx.tcx.bound_explicit_item_bounds(def_id).transpose_iter() { + let (predicate, _span) = bound.map_bound(|b| *b).subst_identity(); match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through // and check substituions to find `U`. @@ -267,7 +268,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) { + for (predicate, _) in cx.tcx.bound_explicit_item_bounds(*def_id).skip_binder() { if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; From f3b279fcc54eea8e4fb094d1672a3907489aa66b Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Mon, 17 Apr 2023 16:43:46 -0600 Subject: [PATCH 13/76] add EarlyBinder to output of explicit_item_bounds; replace bound_explicit_item_bounds usages; remove bound_explicit_item_bounds query --- .../src/diagnostics/conflict_errors.rs | 2 +- compiler/rustc_hir_analysis/src/check/check.rs | 6 ++---- .../src/check/compare_impl_item.rs | 4 ++-- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 6 +++--- .../rustc_hir_analysis/src/collect/item_bounds.rs | 13 +++++++------ compiler/rustc_hir_analysis/src/variance/mod.rs | 2 +- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 6 +++--- .../rustc_hir_typeck/src/generator_interior/mod.rs | 4 ++-- .../rustc_infer/src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_infer/src/infer/opaque_types.rs | 2 +- .../rustc_lint/src/opaque_hidden_inferred_bound.rs | 4 ++-- compiler/rustc_lint/src/unused.rs | 2 +- .../rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 6 +++++- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 7 ------- compiler/rustc_mir_transform/src/generator.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 7 ++----- .../src/traits/object_safety.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 4 ++-- src/librustdoc/clean/mod.rs | 6 +++--- .../clippy/clippy_lints/src/future_not_send.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 6 +++--- 26 files changed, 49 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 49e74a1b000d4..7ad9de0572090 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -706,7 +706,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .copied() .find_map(find_fn_kind_from_did), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx - .bound_explicit_item_bounds(def_id) + .explicit_item_bounds(def_id) .subst_iter_copied(tcx, substs) .find_map(find_fn_kind_from_did), ty::Closure(_, substs) => match substs.as_closure().kind() { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 680562ccf6229..1dfffafd1d329 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -318,10 +318,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( tcx, selftys: vec![], }; - let prohibit_opaque = tcx - .bound_explicit_item_bounds(def_id.to_def_id()) - .transpose_iter() - .try_for_each(|bound| { + let prohibit_opaque = + tcx.explicit_item_bounds(def_id).transpose_iter().try_for_each(|bound| { let predicate = bound.map_bound(|&(predicate, _)| predicate).subst_identity(); predicate.visit_with(&mut visitor) }); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index fe87aae8ed111..48214b899a4b8 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -839,7 +839,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.substs)); // Recurse into bounds - for (pred, pred_span) in self.interner().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { + for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -2023,7 +2023,7 @@ pub(super) fn check_type_bounds<'tcx>( }; let obligations: Vec<_> = tcx - .bound_explicit_item_bounds(trait_ty.def_id) + .explicit_item_bounds(trait_ty.def_id) .subst_iter_copied(tcx, rebased_substs) .map(|(concrete_ty_bound, span)| { debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 9b89e51bacfc9..fc40916f8fead 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -360,7 +360,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe tcx, param_env, item_def_id, - tcx.bound_explicit_item_bounds(item_def_id.to_def_id()) + tcx.explicit_item_bounds(item_def_id) .transpose_iter() .map(|bound| bound.map_bound(|b| *b).subst_identity()) .collect::>(), @@ -1125,7 +1125,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { /// Assuming the defaults are used, check that all predicates (bounds on the /// assoc type and where clauses on the trait) hold. fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocItem, span: Span) { - let bounds = wfcx.tcx().bound_explicit_item_bounds(item.def_id); + let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); let wf_obligations = bounds.transpose_iter().flat_map(|b| { @@ -1592,7 +1592,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { } }); for (bound, bound_span) in tcx - .bound_explicit_item_bounds(opaque_ty.def_id) + .explicit_item_bounds(opaque_ty.def_id) .subst_iter_copied(tcx, opaque_ty.substs) { let bound = self.wfcx.normalize(bound_span, None, bound); diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 5b2f1419a6921..80d6bc7db9e8f 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -79,14 +79,14 @@ fn opaque_type_bounds<'tcx>( pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: LocalDefId, -) -> &'_ [(ty::Predicate<'_>, Span)] { +) -> ty::EarlyBinder<&'_ [(ty::Predicate<'_>, Span)]> { match tcx.opt_rpitit_info(def_id.to_def_id()) { // RPITIT's bounds are the same as opaque type bounds, but with // a projection self type. Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item(); let opaque_ty = item.expect_opaque_ty(); - return opaque_type_bounds( + return ty::EarlyBinder(opaque_type_bounds( tcx, opaque_def_id.expect_local(), opaque_ty.bounds, @@ -95,7 +95,7 @@ pub(super) fn explicit_item_bounds( ty::InternalSubsts::identity_for_item(tcx, def_id), ), item.span, - ); + )); } // These should have been fed! Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), @@ -103,7 +103,7 @@ pub(super) fn explicit_item_bounds( } let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { + let bounds = match tcx.hir().get(hir_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), span, @@ -123,14 +123,15 @@ pub(super) fn explicit_item_bounds( opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) } _ => bug!("item_bounds called on {:?}", def_id), - } + }; + ty::EarlyBinder(bounds) } pub(super) fn item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<&'_ ty::List>> { - tcx.bound_explicit_item_bounds(def_id).map_bound(|bounds| { + tcx.explicit_item_bounds(def_id).map_bound(|bounds| { tcx.mk_predicates_from_iter(util::elaborate( tcx, bounds.iter().map(|&(bound, _span)| bound), diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 4d240e90b143d..d8625bd21e8eb 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -153,7 +153,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id); - for pred in tcx.bound_explicit_item_bounds(item_def_id.to_def_id()).transpose_iter() { + for pred in tcx.explicit_item_bounds(item_def_id).transpose_iter() { let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); debug!(?pred); diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 6c2ce62722a54..aefde8109a07a 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -530,7 +530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for ty in [first_ty, second_ty] { for (pred, _) in self .tcx - .bound_explicit_item_bounds(rpit_def_id) + .explicit_item_bounds(rpit_def_id) .subst_iter_copied(self.tcx, substs) { let pred = pred.kind().rebind(match pred.kind().skip_binder() { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 8c2495e1dd8c5..7046269c2de22 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -172,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self .deduce_closure_signature_from_predicates( expected_ty, - self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), + self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), ), ty::Dynamic(ref object_type, ..) => { let sig = object_type.projection_bounds().find_map(|pb| { @@ -713,13 +713,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self .tcx - .bound_explicit_item_bounds(def_id) + .explicit_item_bounds(def_id) .subst_iter_copied(self.tcx, substs) .find_map(|(p, s)| get_future_output(p, s))?, ty::Error(_) => return None, ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self .tcx - .bound_explicit_item_bounds(proj.def_id) + .explicit_item_bounds(proj.def_id) .subst_iter_copied(self.tcx, proj.substs) .find_map(|(p, s)| get_future_output(p, s))?, _ => span_bug!( diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 1d17af8da8538..5af824e0f5748 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -571,8 +571,8 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for bound in fcx.tcx.bound_explicit_item_bounds(def).transpose_iter() { - let predicate = bound.map_bound(|&(predicate, _)| predicate).subst_identity(); + for bound in fcx.tcx.explicit_item_bounds(def).transpose_iter() { + let predicate = bound.map_bound(|&(pred, _)| pred).subst_identity(); // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b0c376a26f614..547f851526f0a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -402,7 +402,7 @@ impl<'tcx> InferCtxt<'tcx> { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( + self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( |(predicate, _)| { predicate .kind() diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 680465bdab690..334395945ea96 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -540,7 +540,7 @@ impl<'tcx> InferCtxt<'tcx> { .obligations; } - let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id()); + let item_bounds = tcx.explicit_item_bounds(def_id); for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) { let predicate = predicate.fold_with(&mut BottomUpFolder { diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 5c408c749456b..1d41021140315 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for bound in cx.tcx.bound_explicit_item_bounds(def_id).transpose_iter() { + for bound in cx.tcx.explicit_item_bounds(def_id).transpose_iter() { let (pred, pred_span) = bound.map_bound(|b| *b).subst_identity(); // Liberate bound regions in the predicate since we @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // with `impl Send: OtherTrait`. for (assoc_pred, assoc_pred_span) in cx .tcx - .bound_explicit_item_bounds(proj.projection_ty.def_id) + .explicit_item_bounds(proj.projection_ty.def_id) .subst_iter_copied(cx.tcx, &proj.projection_ty.substs) { let assoc_pred = assoc_pred.fold_with(proj_replacer); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 7e4852e3d3bf0..8de358cf8ab11 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -257,7 +257,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { elaborate( cx.tcx, cx.tcx - .bound_explicit_item_bounds(def) + .explicit_item_bounds(def) .transpose_iter() .map(|bound| bound.map_bound(|b| *b).subst_identity()), ) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 31798afb852c5..0ca1d9ac6ff82 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -203,7 +203,11 @@ impl IntoArgs for (CrateNum, SimplifiedType) { } provide! { tcx, def_id, other, cdata, - explicit_item_bounds => { table_defaulted_array } + explicit_item_bounds => { + let lazy = cdata.root.tables.explicit_item_bounds.get(cdata, def_id.index); + let output = if lazy.is_default() { &mut [] } else { tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx))) }; + ty::EarlyBinder(&*output) + } explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d6500cd93a7d0..fd308d5cad152 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1425,7 +1425,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_explicit_item_bounds(&mut self, def_id: DefId) { debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id); - let bounds = self.tcx.explicit_item_bounds(def_id); + let bounds = self.tcx.explicit_item_bounds(def_id).skip_binder(); record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7e26e05025ff1..f024ba46b6410 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -274,7 +274,7 @@ rustc_queries! { /// `key` is the `DefId` of the associated type or opaque type. /// /// Bounds from the parent (e.g. with nested impl trait) are not included. - query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f65117f4934d7..68c5b205fa047 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1611,7 +1611,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.bound_explicit_item_bounds(*def_id).skip_binder().iter().any(|(predicate, _)| { + self.explicit_item_bounds(def_id).skip_binder().iter().any(|(predicate, _)| { let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { return false; }; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index af76cf7cc4e0d..0d4f69a27cf24 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -911,7 +911,7 @@ pub trait PrettyPrinter<'tcx>: // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = tcx.bound_explicit_item_bounds(def_id); + let bounds = tcx.explicit_item_bounds(def_id); let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index dbe2eebe33604..d0bcad0d02360 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -694,13 +694,6 @@ impl<'tcx> TyCtxt<'tcx> { if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } - pub fn bound_explicit_item_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> { - ty::EarlyBinder(self.explicit_item_bounds(def_id)) - } - /// Returns names of captured upvars for closures and generators. /// /// Here are some examples: diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index c2c3d2dda3f4c..e4396d70b7e5d 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1800,7 +1800,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for bound in tcx.bound_explicit_item_bounds(def).transpose_iter() { + for bound in tcx.explicit_item_bounds(def).transpose_iter() { let predicate = bound.map_bound(|&(pred, _)| pred).subst_identity(); // We only look at the `DefId`, so it is safe to skip the binder here. diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index cd48280526f8c..c607c7fd5f4a7 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -269,7 +269,7 @@ where // and are visited by shallow visitors. self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: tcx.bound_explicit_item_bounds(def_id).skip_binder(), + predicates: tcx.explicit_item_bounds(def_id).skip_binder(), })?; } } @@ -1784,10 +1784,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn bounds(&mut self) -> &mut Self { self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: self - .tcx - .bound_explicit_item_bounds(self.item_def_id.to_def_id()) - .skip_binder(), + predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(), }); self } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index b7ca37c058ccb..c09658cd4e158 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -297,7 +297,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .flat_map(|item| tcx.bound_explicit_item_bounds(item.def_id).transpose_iter()) + .flat_map(|item| tcx.explicit_item_bounds(item.def_id).transpose_iter()) .map(|bound| bound.map_bound(|b| *b).subst_identity()) .filter_map(|pred_span| predicate_references_self(tcx, pred_span)) .collect() diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 9683e48478edc..0974c5ffaa25a 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -50,7 +50,7 @@ impl<'tcx> RustIrDatabase<'tcx> { where ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option>, { - let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id); + let bounds = self.interner.tcx.explicit_item_bounds(def_id); bounds .0 .iter() @@ -506,7 +506,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0); - let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0); + let explicit_item_bounds = self.interner.tcx.explicit_item_bounds(opaque_ty_id.0); let bounds = explicit_item_bounds .0 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 25031b0102243..00932c59cca9c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -421,7 +421,7 @@ fn clean_projection<'tcx>( if cx.tcx.is_impl_trait_in_trait(ty.skip_binder().def_id) { let bounds = cx .tcx - .bound_explicit_item_bounds(ty.skip_binder().def_id) + .explicit_item_bounds(ty.skip_binder().def_id) .subst_iter_copied(cx.tcx, ty.skip_binder().substs) .map(|(pred, _)| pred) .collect::>(); @@ -1316,7 +1316,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( if let ty::TraitContainer = assoc_item.container { let bounds = tcx - .bound_explicit_item_bounds(assoc_item.def_id) + .explicit_item_bounds(assoc_item.def_id) .transpose_iter() .map(|bound| bound.map_bound(|b| *b).subst_identity()); let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; @@ -1847,7 +1847,7 @@ pub(crate) fn clean_middle_ty<'tcx>( // by looking up the bounds associated with the def_id. let bounds = cx .tcx - .bound_explicit_item_bounds(def_id) + .explicit_item_bounds(def_id) .subst_iter_copied(cx.tcx, substs) .map(|(bound, _)| bound) .collect::>(); diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 73ae2406f9dbc..ff838c2d56e43 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { } let ret_ty = return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(fn_def_id).expect_owner()); if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { - let preds = cx.tcx.bound_explicit_item_bounds(def_id); + let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { if let Some(trait_pred) = p.to_opt_poly_trait_pred() { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 058f6b0306dcf..5f768928adf05 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -90,7 +90,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for bound in cx.tcx.bound_explicit_item_bounds(def_id).transpose_iter() { + for bound in cx.tcx.explicit_item_bounds(def_id).transpose_iter() { let (predicate, _span) = bound.map_bound(|b| *b).subst_identity(); match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through @@ -268,7 +268,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.bound_explicit_item_bounds(*def_id).skip_binder() { + for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; @@ -744,7 +744,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx - .bound_explicit_item_bounds(ty.def_id) + .explicit_item_bounds(ty.def_id) .subst_iter_copied(cx.tcx, ty.substs) { match pred.kind().skip_binder() { From e54854f6a93f4121ac55d895830414d33bd3aa8e Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Mon, 17 Apr 2023 17:19:08 -0600 Subject: [PATCH 14/76] add subst_identity_iter and subst_identity_iter_copied methods on EarlyBinder; use this to simplify some EarlyBinder noise around explicit_item_bounds calls --- .../rustc_hir_analysis/src/check/check.rs | 9 ++--- .../rustc_hir_analysis/src/check/wfcheck.rs | 6 +-- .../rustc_hir_analysis/src/variance/mod.rs | 3 +- .../src/generator_interior/mod.rs | 3 +- .../src/opaque_hidden_inferred_bound.rs | 4 +- compiler/rustc_lint/src/unused.rs | 40 ++++++++----------- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/subst.rs | 12 ++++++ compiler/rustc_mir_transform/src/generator.rs | 4 +- .../src/traits/object_safety.rs | 3 +- src/librustdoc/clean/mod.rs | 6 +-- src/tools/clippy/clippy_utils/src/ty.rs | 3 +- 12 files changed, 44 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1dfffafd1d329..d84e7b5881cfe 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -318,11 +318,10 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( tcx, selftys: vec![], }; - let prohibit_opaque = - tcx.explicit_item_bounds(def_id).transpose_iter().try_for_each(|bound| { - let predicate = bound.map_bound(|&(predicate, _)| predicate).subst_identity(); - predicate.visit_with(&mut visitor) - }); + let prohibit_opaque = tcx + .explicit_item_bounds(def_id) + .subst_identity_iter_copied() + .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); if let Some(ty) = prohibit_opaque.break_value() { visitor.visit_item(&item); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index fc40916f8fead..80ab711c15c0e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -361,8 +361,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe param_env, item_def_id, tcx.explicit_item_bounds(item_def_id) - .transpose_iter() - .map(|bound| bound.map_bound(|b| *b).subst_identity()) + .subst_identity_iter_copied() .collect::>(), &FxIndexSet::default(), gat_def_id.def_id, @@ -1128,8 +1127,7 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = bounds.transpose_iter().flat_map(|b| { - let (bound, bound_span) = b.map_bound(|b| *b).subst_identity(); + let wf_obligations = bounds.subst_identity_iter_copied().flat_map(|(bound, bound_span)| { let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::predicate_obligations( wfcx.infcx, diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index d8625bd21e8eb..e735b048d7343 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -153,8 +153,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id); - for pred in tcx.explicit_item_bounds(item_def_id).transpose_iter() { - let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); + for (pred, _) in tcx.explicit_item_bounds(item_def_id).subst_iter_copied(tcx, id_substs) { debug!(?pred); // We only ignore opaque type substs if the opaque type is the outermost type. diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 5af824e0f5748..d23fe9650805d 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -571,8 +571,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for bound in fcx.tcx.explicit_item_bounds(def).transpose_iter() { - let predicate = bound.map_bound(|&(pred, _)| pred).subst_identity(); + for (predicate, _) in fcx.tcx.explicit_item_bounds(def).subst_identity_iter_copied() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 1d41021140315..15715c8fca039 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -74,9 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for bound in cx.tcx.explicit_item_bounds(def_id).transpose_iter() { - let (pred, pred_span) = bound.map_bound(|b| *b).subst_identity(); - + for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { // Liberate bound regions in the predicate since we // don't actually care about lifetimes in this check. let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind()); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 8de358cf8ab11..eb175e96997b3 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -254,29 +254,23 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { - elaborate( - cx.tcx, - cx.tcx - .explicit_item_bounds(def) - .transpose_iter() - .map(|bound| bound.map_bound(|b| *b).subst_identity()), - ) - // We only care about self bounds for the impl-trait - .filter_only_self() - .find_map(|(pred, _span)| { - // We only look at the `DefId`, so it is safe to skip the binder here. - if let ty::PredicateKind::Clause(ty::Clause::Trait( - ref poly_trait_predicate, - )) = pred.kind().skip_binder() - { - let def_id = poly_trait_predicate.trait_ref.def_id; - - is_def_must_use(cx, def_id, span) - } else { - None - } - }) - .map(|inner| MustUsePath::Opaque(Box::new(inner))) + elaborate(cx.tcx, cx.tcx.explicit_item_bounds(def).subst_identity_iter_copied()) + // We only care about self bounds for the impl-trait + .filter_only_self() + .find_map(|(pred, _span)| { + // We only look at the `DefId`, so it is safe to skip the binder here. + if let ty::PredicateKind::Clause(ty::Clause::Trait( + ref poly_trait_predicate, + )) = pred.kind().skip_binder() + { + let def_id = poly_trait_predicate.trait_ref.def_id; + + is_def_must_use(cx, def_id, span) + } else { + None + } + }) + .map(|inner| MustUsePath::Opaque(Box::new(inner))) } ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 68c5b205fa047..a5e98fe6224dc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1611,7 +1611,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).skip_binder().iter().any(|(predicate, _)| { + self.explicit_item_bounds(def_id).subst_identity_iter_copied().any(|(predicate, _)| { let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { return false; }; diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 3e1b0706f6688..6361789d3973b 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -625,6 +625,12 @@ where ) -> SubstIter<'s, 'tcx, I> { SubstIter { it: self.0.into_iter(), tcx, substs } } + + /// Similar to [`subst_identity`](EarlyBinder::subst_identity), + /// but on an iterator of `TypeFoldable` values. + pub fn subst_identity_iter(self) -> I::IntoIter { + self.0.into_iter() + } } pub struct SubstIter<'s, 'tcx, I: IntoIterator> { @@ -677,6 +683,12 @@ where ) -> SubstIterCopied<'s, 'tcx, I> { SubstIterCopied { it: self.0.into_iter(), tcx, substs } } + + /// Similar to [`subst_identity`](EarlyBinder::subst_identity), + /// but on an iterator of values that deref to a `TypeFoldable`. + pub fn subst_identity_iter_copied(self) -> impl Iterator::Target> { + self.0.into_iter().map(|v| *v) + } } pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index e4396d70b7e5d..4cfb2e1fffa88 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1800,9 +1800,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for bound in tcx.explicit_item_bounds(def).transpose_iter() { - let predicate = bound.map_bound(|&(pred, _)| pred).subst_identity(); - + for (predicate, _) in tcx.explicit_item_bounds(def).subst_identity_iter_copied() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index c09658cd4e158..73e2efc3b000e 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -297,8 +297,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .flat_map(|item| tcx.explicit_item_bounds(item.def_id).transpose_iter()) - .map(|bound| bound.map_bound(|b| *b).subst_identity()) + .flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied()) .filter_map(|pred_span| predicate_references_self(tcx, pred_span)) .collect() } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 00932c59cca9c..c992a5388d199 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1315,10 +1315,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } if let ty::TraitContainer = assoc_item.container { - let bounds = tcx - .explicit_item_bounds(assoc_item.def_id) - .transpose_iter() - .map(|bound| bound.map_bound(|b| *b).subst_identity()); + let bounds = + tcx.explicit_item_bounds(assoc_item.def_id).subst_identity_iter_copied(); let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; let predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 5f768928adf05..cb700126c2bd5 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -90,8 +90,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for bound in cx.tcx.explicit_item_bounds(def_id).transpose_iter() { - let (predicate, _span) = bound.map_bound(|b| *b).subst_identity(); + for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { match predicate.kind().skip_binder() { // For `impl Trait`, it will register a predicate of `T: Trait`, so we go through // and check substituions to find `U`. From 96905d568a6f1db806d43047a6392c5e2766009e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 20 Apr 2023 18:49:40 +0000 Subject: [PATCH 15/76] Use `impl Tag for $T` syntax for `impl_tag!` --- .../rustc_data_structures/src/tagged_ptr/impl_tag.rs | 12 ++++++------ .../src/tagged_ptr/impl_tag/tests.rs | 10 +++++----- compiler/rustc_middle/src/ty/mod.rs | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs index deaaee4cc1728..c996895936866 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -23,7 +23,7 @@ /// /// impl_tag! { /// // The type for which the `Tag` will be implemented -/// for SomeTag; +/// impl Tag for SomeTag; /// // You need to specify the `{value_of_the_type} <=> {tag}` relationship /// SomeTag::A <=> 0, /// SomeTag::B <=> 1, @@ -54,7 +54,7 @@ /// struct Flags { a: bool, b: bool } /// /// impl_tag! { -/// for Flags; +/// impl Tag for Flags; /// Flags { a: true, b: true } <=> 3, /// Flags { a: false, b: true } <=> 2, /// Flags { a: true, b: false } <=> 1, @@ -73,7 +73,7 @@ // struct Unit; // // impl_tag! { -// for Unit; +// impl Tag for Unit; // Unit <=> 0, // Unit <=> 1, // } @@ -87,7 +87,7 @@ // enum E { A, B }; // // impl_tag! { -// for E; +// impl Tag for E; // E::A <=> 0, // E::B <=> 0, // } @@ -104,14 +104,14 @@ /// } /// /// impl_tag! { -/// for E; +/// impl Tag for E; /// E::A <=> 0, /// } /// ``` #[macro_export] macro_rules! impl_tag { ( - for $Self:ty; + impl Tag for $Self:ty; $( $($path:ident)::* $( { $( $fields:tt )* })? <=> $tag:literal, )* diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs index 26d1cf3b45422..cd19b30ff5340 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs @@ -4,22 +4,22 @@ fn bits_constant() { #[derive(Copy, Clone)] struct Unit; - impl_tag! { for Unit; Unit <=> 0, } + impl_tag! { impl Tag for Unit; Unit <=> 0, } assert_eq!(Unit::BITS, 0); #[derive(Copy, Clone)] struct Unit1; - impl_tag! { for Unit1; Unit1 <=> 1, } + impl_tag! { impl Tag for Unit1; Unit1 <=> 1, } assert_eq!(Unit1::BITS, 1); #[derive(Copy, Clone)] struct Unit2; - impl_tag! { for Unit2; Unit2 <=> 0b10, } + impl_tag! { impl Tag for Unit2; Unit2 <=> 0b10, } assert_eq!(Unit2::BITS, 2); #[derive(Copy, Clone)] struct Unit3; - impl_tag! { for Unit3; Unit3 <=> 0b100, } + impl_tag! { impl Tag for Unit3; Unit3 <=> 0b100, } assert_eq!(Unit3::BITS, 3); #[derive(Copy, Clone)] @@ -28,6 +28,6 @@ fn bits_constant() { B, C, } - impl_tag! { for Enum; Enum::A <=> 0b1, Enum::B <=> 0b1000, Enum::C <=> 0b10, } + impl_tag! { impl Tag for Enum; Enum::A <=> 0b1, Enum::B <=> 0b1000, Enum::C <=> 0b10, } assert_eq!(Enum::BITS, 4); } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f520faa6a6154..d13c71b78e466 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1627,7 +1627,7 @@ struct ParamTag { } impl_tag! { - for ParamTag; + impl Tag for ParamTag; ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } <=> 0, ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } <=> 1, ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } <=> 2, From 7cfecf26f77f0d2c3d83be946d4da6ab997c939e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 20 Apr 2023 19:07:57 +0000 Subject: [PATCH 16/76] Remove confusing comment --- .../src/tagged_ptr/impl_tag.rs | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs index c996895936866..d263bed9581ad 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -62,37 +62,6 @@ /// } /// ``` /// -// This is supposed to produce a compile error, but does not, -// see for more information. -// -// Using the same pattern twice results in a compile error: -// -// ```compile_fail -// # use rustc_data_structures::impl_tag; -// #[derive(Copy, Clone)] -// struct Unit; -// -// impl_tag! { -// impl Tag for Unit; -// Unit <=> 0, -// Unit <=> 1, -// } -// ``` -// -// Using the same tag twice results in a compile error: -// -// ```compile_fail -// # use rustc_data_structures::impl_tag; -// #[derive(Copy, Clone)] -// enum E { A, B }; -// -// impl_tag! { -// impl Tag for E; -// E::A <=> 0, -// E::B <=> 0, -// } -// ``` -// /// Not specifying all values results in a compile error: /// /// ```compile_fail,E0004 From ad8c7b6705d94bdf9293fbfe0c4d386d5f7e81a2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 20 Apr 2023 19:24:04 +0000 Subject: [PATCH 17/76] Simplify `bits_for_tags` impl --- compiler/rustc_data_structures/src/tagged_ptr.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index a25046986cc59..2914eece6796b 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs @@ -155,7 +155,9 @@ pub const fn bits_for_tags(mut tags: &[usize]) -> u32 { while let &[tag, ref rest @ ..] = tags { tags = rest; - let b = bits_for_tag(tag); + // bits required to represent `tag`, + // position of the most significant 1 + let b = usize::BITS - tag.leading_zeros(); if b > bits { bits = b; } @@ -164,18 +166,6 @@ pub const fn bits_for_tags(mut tags: &[usize]) -> u32 { bits } -/// Returns `(size_of::() * 8) - tag.leading_zeros()` -const fn bits_for_tag(mut tag: usize) -> u32 { - let mut bits = 0; - - while tag > 0 { - bits += 1; - tag >>= 1; - } - - bits -} - unsafe impl Pointer for Box { const BITS: u32 = bits_for::(); From 57316559e4d6161ee1ac66d1c8db68562bdd0eaa Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Fri, 21 Apr 2023 10:45:06 -0500 Subject: [PATCH 18/76] Fix no_global_oom_handling build `provide_sorted_batch` in core is incorrectly marked with `#[cfg(not(no_global_oom_handling))]` which prevents core from building with the cfg enabled. Nothing in core allocates memory including this function, so the `cfg` gate is incorrect. --- library/core/src/slice/sort.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 07fd96f929586..e6e3b55efa9ae 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -1456,7 +1456,6 @@ pub struct TimSortRun { /// Takes a range as denoted by start and end, that is already sorted and extends it to the right if /// necessary with sorts optimized for smaller ranges such as insertion sort. -#[cfg(not(no_global_oom_handling))] fn provide_sorted_batch(v: &mut [T], start: usize, mut end: usize, is_less: &mut F) -> usize where F: FnMut(&T, &T) -> bool, From 5a69b5d0f9753a7e780849ec930b1bb48653588b Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Thu, 20 Apr 2023 12:33:32 -0600 Subject: [PATCH 19/76] Changes from review --- .../src/generator_interior/mod.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 16 +++++++++++++++- .../src/rmeta/decoder/cstore_impl.rs | 6 +----- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_mir_transform/src/generator.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 17 ++++++----------- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index d23fe9650805d..5b432475fc384 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -571,7 +571,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for (predicate, _) in fcx.tcx.explicit_item_bounds(def).subst_identity_iter_copied() { + for &(predicate, _) in fcx.tcx.explicit_item_bounds(def).skip_binder() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 951fb303e3cf9..44e3ccf7e4b8f 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -23,7 +23,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::GeneratorDiagnosticData; -use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility}; +use rustc_middle::ty::{self, ParameterizedOverTcx, Predicate, Ty, TyCtxt, Visibility}; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; use rustc_session::cstore::{ @@ -857,6 +857,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) } + fn get_explicit_item_bounds( + self, + index: DefIndex, + tcx: TyCtxt<'tcx>, + ) -> ty::EarlyBinder<&'tcx [(Predicate<'tcx>, Span)]> { + let lazy = self.root.tables.explicit_item_bounds.get(self, index); + let output = if lazy.is_default() { + &mut [] + } else { + tcx.arena.alloc_from_iter(lazy.decode((self, tcx))) + }; + ty::EarlyBinder(&*output) + } + fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef { let adt_kind = match kind { DefKind::Variant => ty::AdtKind::Enum, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 0ca1d9ac6ff82..92d69aeb771fb 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -203,11 +203,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) { } provide! { tcx, def_id, other, cdata, - explicit_item_bounds => { - let lazy = cdata.root.tables.explicit_item_bounds.get(cdata, def_id.index); - let output = if lazy.is_default() { &mut [] } else { tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx))) }; - ty::EarlyBinder(&*output) - } + explicit_item_bounds => { cdata.get_explicit_item_bounds(def_id.index, tcx) } explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a5e98fe6224dc..7ac87cc80fddb 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1611,7 +1611,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).subst_identity_iter_copied().any(|(predicate, _)| { + self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { return false; }; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 4cfb2e1fffa88..a75d3108575fd 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1800,7 +1800,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for (predicate, _) in tcx.explicit_item_bounds(def).subst_identity_iter_copied() { + for &(predicate, _) in tcx.explicit_item_bounds(def).skip_binder() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 0974c5ffaa25a..c319b2e31c7e6 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -50,12 +50,11 @@ impl<'tcx> RustIrDatabase<'tcx> { where ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option>, { - let bounds = self.interner.tcx.explicit_item_bounds(def_id); - bounds - .0 - .iter() - .map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)) - .filter_map(|bound| LowerInto::>::lower_into(bound, self.interner)) + self.interner + .tcx + .explicit_item_bounds(def_id) + .subst_iter_copied(self.interner.tcx, &bound_vars) + .filter_map(|(bound, _)| LowerInto::>::lower_into(bound, self.interner)) .collect() } } @@ -509,12 +508,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let explicit_item_bounds = self.interner.tcx.explicit_item_bounds(opaque_ty_id.0); let bounds = explicit_item_bounds - .0 - .iter() + .subst_iter_copied(self.interner.tcx, &bound_vars) .map(|(bound, _)| { - explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars) - }) - .map(|bound| { bound.fold_with(&mut ReplaceOpaqueTyFolder { tcx: self.interner.tcx, opaque_ty_id, From 06ff310cf95349da078e4cac0c5377172766fa94 Mon Sep 17 00:00:00 2001 From: Obei Sideg Date: Fri, 14 Apr 2023 18:02:41 +0300 Subject: [PATCH 20/76] Migrate `rustc_hir_analysis` to session diagnostic Part 4: Finishing `check/mod.rs` file --- compiler/rustc_hir_analysis/messages.ftl | 37 ++++ compiler/rustc_hir_analysis/src/check/mod.rs | 160 +++++++++--------- compiler/rustc_hir_analysis/src/errors.rs | 138 +++++++++++++++ tests/ui/repr/repr-transparent.stderr | 2 +- .../transparent-enum-too-many-variants.stderr | 2 + 5 files changed, 254 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 1d7965ff5f66e..f32ae509e335a 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -225,3 +225,40 @@ hir_analysis_functions_names_duplicated = functions names are duplicated hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code .help = add `#![feature(simd_ffi)]` to the crate attributes to enable + +hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` + .label = cannot specialize default item `{$ident}` + .ok_label = parent `impl` is here + .note = to specialize, `{$ident}` in the parent `impl` must be marked `default` + +hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` + .note = parent implementation is in crate `{$cname}` + +hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}` + .label = missing `{$missing_items_msg}` in implementation + +hir_analysis_missing_trait_item_suggestion = implement the missing item: `{$snippet}` + +hir_analysis_missing_trait_item_label = `{$item}` from trait + +hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}` + .label = missing one of `{$missing_items_msg}` in implementation + .note = required because of this annotation + +hir_analysis_missing_trait_item_unstable = not all trait items implemented, missing: `{$missing_item_name}` + .note = default implementation of `{$missing_item_name}` is unstable + .some_note = use of unstable library feature '{$feature}': {$r} + .none_note = use of unstable library feature '{$feature}' + +hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number} + .label = needs exactly one variant, but has {$number} + .many_label = too many variants in `{$path}` + .multi_label = variant here + +hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$desc} needs at most one non-zero-sized field, but has {$field_count} + .label = needs at most one non-zero-sized field, but has {$field_count} + .labels = this field is non-zero-sized + +hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one non-zero-sized field, but has {$field_count} + .label = needs at most one non-zero-sized field, but has {$field_count} + .labels = this field is non-zero-sized diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 4b3f3cf169dc0..08154cdae4784 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -74,7 +74,7 @@ pub use check::check_abi; use check::check_mod_item_types; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; @@ -90,6 +90,7 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor; use std::num::NonZeroU32; +use crate::errors; use crate::require_c_abi_if_c_variadic; use crate::util::common::indenter; @@ -171,29 +172,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) { let span = tcx.def_span(impl_item); let ident = tcx.item_name(impl_item); - let mut err = struct_span_err!( - tcx.sess, - span, - E0520, - "`{}` specializes an item from a parent `impl`, but that item is not marked `default`", - ident, - ); - err.span_label(span, format!("cannot specialize default item `{}`", ident)); - - match tcx.span_of_impl(parent_impl) { - Ok(span) => { - err.span_label(span, "parent `impl` is here"); - err.note(&format!( - "to specialize, `{}` in the parent `impl` must be marked `default`", - ident - )); - } - Err(cname) => { - err.note(&format!("parent implementation is in crate `{cname}`")); - } - } - err.emit(); + let err = match tcx.span_of_impl(parent_impl) { + Ok(sp) => errors::ImplNotMarkedDefault::Ok { span, ident, ok_label: sp }, + Err(cname) => errors::ImplNotMarkedDefault::Err { span, ident, cname }, + }; + + tcx.sess.emit_err(err); } fn missing_items_err( @@ -211,15 +196,6 @@ fn missing_items_err( .collect::>() .join("`, `"); - let impl_span = tcx.def_span(impl_def_id); - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing: `{missing_items_msg}`", - ); - err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation")); - // `Span` before impl block closing brace. let hi = full_impl_span.hi() - BytePos(1); // Point at the place right before the closing brace of the relevant `impl` to suggest @@ -228,6 +204,8 @@ fn missing_items_err( // Obtain the level of indentation ending in `sugg_sp`. let padding = tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new()); + let (mut missing_trait_item, mut missing_trait_item_none, mut missing_trait_item_label) = + (Vec::new(), Vec::new(), Vec::new()); for &trait_item in missing_items { let snippet = suggestion_signature( @@ -236,16 +214,30 @@ fn missing_items_err( tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(), ); let code = format!("{}{}\n{}", padding, snippet, padding); - let msg = format!("implement the missing item: `{snippet}`"); - let appl = Applicability::HasPlaceholders; if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) { - err.span_label(span, format!("`{}` from trait", trait_item.name)); - err.tool_only_span_suggestion(sugg_sp, &msg, code, appl); + missing_trait_item_label + .push(errors::MissingTraitItemLabel { span, item: trait_item.name }); + missing_trait_item.push(errors::MissingTraitItemSuggestion { + span: sugg_sp, + code, + snippet, + }); } else { - err.span_suggestion_hidden(sugg_sp, &msg, code, appl); + missing_trait_item_none.push(errors::MissingTraitItemSuggestionNone { + span: sugg_sp, + code, + snippet, + }) } } - err.emit(); + + tcx.sess.emit_err(errors::MissingTraitItem { + span: tcx.span_of_impl(impl_def_id.to_def_id()).unwrap(), + missing_items_msg, + missing_trait_item_label, + missing_trait_item, + missing_trait_item_none, + }); } fn missing_items_must_implement_one_of_err( @@ -257,19 +249,11 @@ fn missing_items_must_implement_one_of_err( let missing_items_msg = missing_items.iter().map(Ident::to_string).collect::>().join("`, `"); - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing one of: `{missing_items_msg}`", - ); - err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation")); - - if let Some(annotation_span) = annotation_span { - err.span_note(annotation_span, "required because of this annotation"); - } - - err.emit(); + tcx.sess.emit_err(errors::MissingOneOfTraitItem { + span: impl_span, + note: annotation_span, + missing_items_msg, + }); } fn default_body_is_unstable( @@ -281,25 +265,31 @@ fn default_body_is_unstable( issue: Option, ) { let missing_item_name = tcx.associated_item(item_did).name; - let use_of_unstable_library_feature_note = match reason { - Some(r) => format!("use of unstable library feature '{feature}': {r}"), - None => format!("use of unstable library feature '{feature}'"), + let (mut some_note, mut none_note, mut reason_str) = (false, false, String::new()); + match reason { + Some(r) => { + some_note = true; + reason_str = r.to_string(); + } + None => none_note = true, }; - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing: `{missing_item_name}`", - ); - err.note(format!("default implementation of `{missing_item_name}` is unstable")); - err.note(use_of_unstable_library_feature_note); + let mut err = tcx.sess.create_err(errors::MissingTraitItemUnstable { + span: impl_span, + some_note, + none_note, + missing_item_name, + feature, + reason: reason_str, + }); + rustc_session::parse::add_feature_diagnostics_for_issue( &mut err, &tcx.sess.parse_sess, feature, rustc_feature::GateIssue::Library(issue), ); + err.emit(); } @@ -488,16 +478,18 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d .iter() .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap()) .collect(); - let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),); - let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}"); - err.span_label(sp, &msg); + let (mut spans, mut many) = (Vec::new(), None); if let [start @ .., end] = &*variant_spans { - for variant_span in start { - err.span_label(*variant_span, ""); - } - err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did))); + spans = start.to_vec(); + many = Some(*end); } - err.emit(); + tcx.sess.emit_err(errors::TransparentEnumVariant { + span: sp, + spans, + many, + number: adt.variants().len(), + path: tcx.def_path_str(did), + }); } /// Emit an error when encountering two or more non-zero-sized fields in a transparent @@ -509,21 +501,21 @@ fn bad_non_zero_sized_fields<'tcx>( field_spans: impl Iterator, sp: Span, ) { - let msg = format!("needs at most one non-zero-sized field, but has {field_count}"); - let mut err = struct_span_err!( - tcx.sess, - sp, - E0690, - "{}transparent {} {}", - if adt.is_enum() { "the variant of a " } else { "" }, - adt.descr(), - msg, - ); - err.span_label(sp, &msg); - for sp in field_spans { - err.span_label(sp, "this field is non-zero-sized"); + if adt.is_enum() { + tcx.sess.emit_err(errors::TransparentNonZeroSizedEnum { + span: sp, + spans: field_spans.collect(), + field_count, + desc: adt.descr(), + }); + } else { + tcx.sess.emit_err(errors::TransparentNonZeroSized { + span: sp, + spans: field_spans.collect(), + field_count, + desc: adt.descr(), + }); } - err.emit(); } // FIXME: Consider moving this method to a more fitting place. diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 2a3a683489ddd..cfce2463b1872 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -631,3 +631,141 @@ pub(crate) struct SIMDFFIHighlyExperimental { pub span: Span, pub snip: String, } + +#[derive(Diagnostic)] +pub enum ImplNotMarkedDefault { + #[diag(hir_analysis_impl_not_marked_default, code = "E0520")] + #[note] + Ok { + #[primary_span] + #[label] + span: Span, + #[label(hir_analysis_ok_label)] + ok_label: Span, + ident: Symbol, + }, + #[diag(hir_analysis_impl_not_marked_default_err, code = "E0520")] + #[note] + Err { + #[primary_span] + #[label] + span: Span, + cname: Symbol, + ident: Symbol, + }, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_trait_item, code = "E0046")] +pub(crate) struct MissingTraitItem { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub missing_trait_item_label: Vec, + #[subdiagnostic] + pub missing_trait_item: Vec, + #[subdiagnostic] + pub missing_trait_item_none: Vec, + pub missing_items_msg: String, +} + +#[derive(Subdiagnostic)] +#[label(hir_analysis_missing_trait_item_label)] +pub(crate) struct MissingTraitItemLabel { + #[primary_span] + pub span: Span, + pub item: Symbol, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_analysis_missing_trait_item_suggestion, + style = "tool-only", + applicability = "has-placeholders", + code = "{code}" +)] +pub(crate) struct MissingTraitItemSuggestion { + #[primary_span] + pub span: Span, + pub code: String, + pub snippet: String, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_analysis_missing_trait_item_suggestion, + style = "hidden", + applicability = "has-placeholders", + code = "{code}" +)] +pub(crate) struct MissingTraitItemSuggestionNone { + #[primary_span] + pub span: Span, + pub code: String, + pub snippet: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_one_of_trait_item, code = "E0046")] +pub(crate) struct MissingOneOfTraitItem { + #[primary_span] + #[label] + pub span: Span, + #[note] + pub note: Option, + pub missing_items_msg: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_trait_item_unstable, code = "E0046")] +#[note] +pub(crate) struct MissingTraitItemUnstable { + #[primary_span] + pub span: Span, + #[note(hir_analysis_some_note)] + pub some_note: bool, + #[note(hir_analysis_none_note)] + pub none_note: bool, + pub missing_item_name: Symbol, + pub feature: Symbol, + pub reason: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_enum_variant, code = "E0731")] +pub(crate) struct TransparentEnumVariant { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_multi_label)] + pub spans: Vec, + #[label(hir_analysis_many_label)] + pub many: Option, + pub number: usize, + pub path: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_non_zero_sized_enum, code = "E0690")] +pub(crate) struct TransparentNonZeroSizedEnum<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_labels)] + pub spans: Vec, + pub field_count: usize, + pub desc: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_non_zero_sized, code = "E0690")] +pub(crate) struct TransparentNonZeroSized<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_labels)] + pub spans: Vec, + pub field_count: usize, + pub desc: &'a str, +} diff --git a/tests/ui/repr/repr-transparent.stderr b/tests/ui/repr/repr-transparent.stderr index f1c570b952356..cb1e233777656 100644 --- a/tests/ui/repr/repr-transparent.stderr +++ b/tests/ui/repr/repr-transparent.stderr @@ -58,7 +58,7 @@ error[E0731]: transparent enum needs exactly one variant, but has 2 LL | enum MultipleVariants { | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2 LL | Foo(String), - | --- + | --- variant here LL | Bar, | --- too many variants in `MultipleVariants` diff --git a/tests/ui/repr/transparent-enum-too-many-variants.stderr b/tests/ui/repr/transparent-enum-too-many-variants.stderr index fb44757efaf13..1a500257f48c5 100644 --- a/tests/ui/repr/transparent-enum-too-many-variants.stderr +++ b/tests/ui/repr/transparent-enum-too-many-variants.stderr @@ -5,6 +5,8 @@ LL | enum Foo { | ^^^^^^^^ needs exactly one variant, but has 2 LL | A(u8), B(u8), | - - too many variants in `Foo` + | | + | variant here error: aborting due to previous error From 1c3efc6356597c9f014260d56a456bfb7d64b714 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 21 Apr 2023 15:01:16 +0200 Subject: [PATCH 21/76] Add new rustdoc book chapter to describe in-doc settings --- src/doc/rustdoc/src/SUMMARY.md | 1 + src/doc/rustdoc/src/how-to-read-rustdoc.md | 7 +- .../src/images/collapsed-long-item.png | Bin 0 -> 17017 bytes .../src/images/collapsed-trait-impls.png | Bin 0 -> 44225 bytes .../src/read-documentation/in-doc-settings.md | 64 ++++++++++++++++++ 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 src/doc/rustdoc/src/images/collapsed-long-item.png create mode 100644 src/doc/rustdoc/src/images/collapsed-trait-impls.png create mode 100644 src/doc/rustdoc/src/read-documentation/in-doc-settings.md diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md index 747cc629ba44b..b512135d92770 100644 --- a/src/doc/rustdoc/src/SUMMARY.md +++ b/src/doc/rustdoc/src/SUMMARY.md @@ -3,6 +3,7 @@ - [What is rustdoc?](what-is-rustdoc.md) - [Command-line arguments](command-line-arguments.md) - [How to read rustdoc output](how-to-read-rustdoc.md) + - [In-doc settings](read-documentation/in-doc-settings.md) - [How to write documentation](how-to-write-documentation.md) - [What to include (and exclude)](write-documentation/what-to-include.md) - [The `#[doc]` attribute](write-documentation/the-doc-attribute.md) diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index 56342f65d9998..21ce9a38b09d6 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -68,7 +68,7 @@ Typing in the search bar instantly searches the available documentation for the string entered with a fuzzy matching algorithm that is tolerant of minor typos. -By default, the search results give are "In Names", +By default, the search results given are "In Names", meaning that the fuzzy match is made against the names of items. Matching names are shown on the left, and the first few words of their descriptions are given on the right. @@ -105,11 +105,6 @@ will match these queries: But it *does not* match `Result` or `Result>`. -### Changing displayed theme - -You can change the displayed theme by opening the settings menu (the gear -icon in the upper right) and then pick a new one from there. - ### Shortcuts Pressing `S` while focused elsewhere on the page will move focus to the diff --git a/src/doc/rustdoc/src/images/collapsed-long-item.png b/src/doc/rustdoc/src/images/collapsed-long-item.png new file mode 100644 index 0000000000000000000000000000000000000000..c382870c64a659f945fdd76fdefd315db4eed709 GIT binary patch literal 17017 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 AYybcN literal 0 HcmV?d00001 diff --git a/src/doc/rustdoc/src/images/collapsed-trait-impls.png b/src/doc/rustdoc/src/images/collapsed-trait-impls.png new file mode 100644 index 0000000000000000000000000000000000000000..f685656e09a9cc42b44545824bb37582e4e01226 GIT binary patch literal 44225 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 hq?>KE|2O>l6<3}1&DmxFfg2p`Q