From 8e91a51cd81de5cf686d21db891634fecdc250c0 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Tue, 2 Apr 2024 18:54:24 +0200 Subject: [PATCH 001/153] DOC: Add FFI example for slice::from_raw_parts() --- library/core/src/slice/raw.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 29a12f106c5..d001688d79d 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -83,6 +83,27 @@ use crate::ub_checks; /// } /// ``` /// +/// ### FFI: Handling null pointers +/// +/// In languages such as C++, pointers to empty collections are not guaranteed to be non-null. +/// When accepting such pointers, they have to be checked for null-ness to avoid undefined +/// behavior. +/// +/// ``` +/// use std::slice; +/// +/// unsafe extern "C" fn handle_slice(ptr: *const f32, len: usize) { +/// let data = if ptr.is_null() { +/// // `len` is assumed to be 0. +/// &[] +/// } else { +/// unsafe { slice::from_raw_parts(ptr, len) } +/// }; +/// dbg!(data); +/// // ... +/// } +/// ``` +/// /// [valid]: ptr#safety /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] From 22319bf6ba861eb0b5efb81aaf7616db30f4872f Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 20:44:59 +0200 Subject: [PATCH 002/153] Add "safety" comment --- library/core/src/slice/raw.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index d001688d79d..8ff429218a4 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -92,11 +92,16 @@ use crate::ub_checks; /// ``` /// use std::slice; /// +/// /// # Safety +/// /// +/// /// If ptr is not NULL, it must be correctly aligned and +/// /// point to `len` initialized items of type `f32`. /// unsafe extern "C" fn handle_slice(ptr: *const f32, len: usize) { /// let data = if ptr.is_null() { /// // `len` is assumed to be 0. /// &[] /// } else { +/// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; /// dbg!(data); From 4df1303cff1eeb3b0c7f00d70fecf160279e7263 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 20:53:23 +0200 Subject: [PATCH 003/153] Extend the example code and assert the result --- library/core/src/slice/raw.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 8ff429218a4..efdd210c1fa 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -92,11 +92,13 @@ use crate::ub_checks; /// ``` /// use std::slice; /// +/// /// Sum the elements of an FFI slice. +/// /// /// /// # Safety /// /// /// /// If ptr is not NULL, it must be correctly aligned and /// /// point to `len` initialized items of type `f32`. -/// unsafe extern "C" fn handle_slice(ptr: *const f32, len: usize) { +/// unsafe extern "C" fn sum_slice(ptr: *const f32, len: usize) -> f32 { /// let data = if ptr.is_null() { /// // `len` is assumed to be 0. /// &[] @@ -104,9 +106,14 @@ use crate::ub_checks; /// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; -/// dbg!(data); -/// // ... +/// data.sum() /// } +/// +/// // This could be the result of C++'s std::vector::data(): +/// let ptr = std::ptr::null(); +/// // And this could be std::vector::size(): +/// let len = 0; +/// assert_eq!(unsafe { sum_slice(ptr, len) }, 0.0); /// ``` /// /// [valid]: ptr#safety From 30b676cc00324c16963ef529ba37b49e0200ac5f Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 21:18:00 +0200 Subject: [PATCH 004/153] Add missing .into_iter() --- library/core/src/slice/raw.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index efdd210c1fa..a42c2cc4e63 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -106,7 +106,7 @@ use crate::ub_checks; /// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; -/// data.sum() +/// data.into_iter().sum() /// } /// /// // This could be the result of C++'s std::vector::data(): From c8a36979e6410058ec359ce6abf68077b3237116 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 29 Apr 2024 12:09:19 +0200 Subject: [PATCH 005/153] Recommend to never display zero disambiguators when demangling v0 symbol names --- src/doc/rustc/src/symbol-mangling/v0.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustc/src/symbol-mangling/v0.md b/src/doc/rustc/src/symbol-mangling/v0.md index 61f747fac83..e6709eb9a1a 100644 --- a/src/doc/rustc/src/symbol-mangling/v0.md +++ b/src/doc/rustc/src/symbol-mangling/v0.md @@ -150,6 +150,15 @@ the *[disambiguator]* is used to make the name unique across the crate graph. > ``` > > Recommended demangling: `mycrate::example` +> +> Note: The compiler may re-use the *crate-root* form to express arbitrary +> unscoped, undisambiguated identifiers, such as for new basic types that have +> not been added to the grammar yet. To achieve that, it will emit a *crate-root* +> without an explicit disambiguator, relying on the fact that such an +> undisambiguated crate name cannot occur in practice. For example, the basic +> type `f128` would be encode as `C4f128`. For this to have the desired effect, +> demanglers are expected to never render zero disambiguators of crate roots. +> I.e. `C4f128` is expected to be displayed as `f128` and not `f128[0]`. ### Path: Inherent impl [inherent-impl]: #path-inherent-impl @@ -539,6 +548,10 @@ This allows disambiguators that are encoded sequentially to use minimal bytes. > **Recommended Demangling** > > The *disambiguator* may or may not be displayed; see recommendations for rules that use *disambiguator*. +> Generally, it is recommended that zero disambiguators are never displayed unless their accompanying +> identifier is empty (like is the case for unnamed items such as closures). +> When rendering a disambiguator, it can be shortened to a length reasonable for the context, +> similar to how git commit hashes are rarely displayed in full. ## Lifetime [lifetime]: #lifetime From 47334d2184eb88139cea6dffdf794a00e215030c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 5 Apr 2024 17:35:33 +0000 Subject: [PATCH 006/153] Refactor never type behavior code --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 31 +++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index afba812a8e7..2a2c4ac10b2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { body_id: LocalDefId, ) -> FnCtxt<'a, 'tcx> { let (diverging_fallback_behavior, diverging_block_behavior) = - parse_never_type_options_attr(root_ctxt.tcx); + never_type_behavior(root_ctxt.tcx); FnCtxt { body_id, param_env, @@ -380,9 +380,30 @@ impl<'tcx> LoweredTy<'tcx> { } } +fn never_type_behavior(tcx: TyCtxt<'_>) -> (DivergingFallbackBehavior, DivergingBlockBehavior) { + let (fallback, block) = parse_never_type_options_attr(tcx); + let fallback = fallback.unwrap_or_else(|| default_fallback(tcx)); + let block = block.unwrap_or_default(); + + (fallback, block) +} + +/// Returns the default fallback which is used when there is no explicit override via `#![never_type_options(...)]`. +fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior { + use DivergingFallbackBehavior::*; + + // `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff + if tcx.features().never_type_fallback { + return FallbackToNiko; + } + + // Otherwise: fallback to `()` + FallbackToUnit +} + fn parse_never_type_options_attr( tcx: TyCtxt<'_>, -) -> (DivergingFallbackBehavior, DivergingBlockBehavior) { +) -> (Option, Option) { use DivergingFallbackBehavior::*; // Error handling is dubious here (unwraps), but that's probably fine for an internal attribute. @@ -432,11 +453,5 @@ fn parse_never_type_options_attr( ); } - let fallback = fallback.unwrap_or_else(|| { - if tcx.features().never_type_fallback { FallbackToNiko } else { FallbackToUnit } - }); - - let block = block.unwrap_or_default(); - (fallback, block) } From 31a88794a0c2e1e066dbbab66dae60f8d9e19bcd Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 5 Apr 2024 17:57:27 +0000 Subject: [PATCH 007/153] Edition 2024: Make `!` fallback to `!` --- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 2a2c4ac10b2..10d832f9726 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -392,6 +392,11 @@ fn never_type_behavior(tcx: TyCtxt<'_>) -> (DivergingFallbackBehavior, Diverging fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior { use DivergingFallbackBehavior::*; + // Edition 2024: fallback to `!` + if tcx.sess.edition().at_least_rust_2024() { + return FallbackToNever; + } + // `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff if tcx.features().never_type_fallback { return FallbackToNiko; From 3b3e5042353359f8a2398680c25b8b160e0fad0a Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 5 Apr 2024 17:58:40 +0000 Subject: [PATCH 008/153] Add a test for never type fallback edition change --- .../never-type-fallback.e2021.run.stdout | 1 + .../never-type-fallback.e2024.run.stdout | 1 + tests/ui/editions/never-type-fallback.rs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) create mode 100644 tests/ui/editions/never-type-fallback.e2021.run.stdout create mode 100644 tests/ui/editions/never-type-fallback.e2024.run.stdout create mode 100644 tests/ui/editions/never-type-fallback.rs diff --git a/tests/ui/editions/never-type-fallback.e2021.run.stdout b/tests/ui/editions/never-type-fallback.e2021.run.stdout new file mode 100644 index 00000000000..4122f7ac1ee --- /dev/null +++ b/tests/ui/editions/never-type-fallback.e2021.run.stdout @@ -0,0 +1 @@ +return type = () diff --git a/tests/ui/editions/never-type-fallback.e2024.run.stdout b/tests/ui/editions/never-type-fallback.e2024.run.stdout new file mode 100644 index 00000000000..df2eeae60b4 --- /dev/null +++ b/tests/ui/editions/never-type-fallback.e2024.run.stdout @@ -0,0 +1 @@ +return type = ! diff --git a/tests/ui/editions/never-type-fallback.rs b/tests/ui/editions/never-type-fallback.rs new file mode 100644 index 00000000000..a5b75219295 --- /dev/null +++ b/tests/ui/editions/never-type-fallback.rs @@ -0,0 +1,16 @@ +//@ revisions: e2021 e2024 +// +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +// +//@ run-pass +//@ check-run-results + +fn main() { + print_return_type_of(|| panic!()); +} + +fn print_return_type_of(_: impl FnOnce() -> R) { + println!("return type = {}", std::any::type_name::()); +} From 0f63cd1056dc44a1a7d167cee7c80f46abdeae71 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 11 Apr 2024 17:29:36 +0000 Subject: [PATCH 009/153] Add some more tests for the never type fallback --- .../never-type-fallback-breaking.e2024.stderr | 26 +++++++++++ .../editions/never-type-fallback-breaking.rs | 34 ++++++++++++++ .../from_infer_breaking_with_unit_fallback.rs | 29 ++++++++++++ ...er_breaking_with_unit_fallback.unit.stderr | 12 +++++ .../ui/never_type/question_mark_from_never.rs | 46 +++++++++++++++++++ 5 files changed, 147 insertions(+) create mode 100644 tests/ui/editions/never-type-fallback-breaking.e2024.stderr create mode 100644 tests/ui/editions/never-type-fallback-breaking.rs create mode 100644 tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs create mode 100644 tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr create mode 100644 tests/ui/never_type/question_mark_from_never.rs diff --git a/tests/ui/editions/never-type-fallback-breaking.e2024.stderr b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr new file mode 100644 index 00000000000..e9a8882eb6c --- /dev/null +++ b/tests/ui/editions/never-type-fallback-breaking.e2024.stderr @@ -0,0 +1,26 @@ +error[E0277]: the trait bound `!: Default` is not satisfied + --> $DIR/never-type-fallback-breaking.rs:17:17 + | +LL | true => Default::default(), + | ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` + | + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) + = help: did you intend to use the type `()` here instead? + +error[E0277]: the trait bound `!: Default` is not satisfied + --> $DIR/never-type-fallback-breaking.rs:30:5 + | +LL | deserialize()?; + | ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!` + | + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) + = help: did you intend to use the type `()` here instead? +note: required by a bound in `deserialize` + --> $DIR/never-type-fallback-breaking.rs:26:23 + | +LL | fn deserialize() -> Option { + | ^^^^^^^ required by this bound in `deserialize` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/editions/never-type-fallback-breaking.rs b/tests/ui/editions/never-type-fallback-breaking.rs new file mode 100644 index 00000000000..7dfa4702807 --- /dev/null +++ b/tests/ui/editions/never-type-fallback-breaking.rs @@ -0,0 +1,34 @@ +//@ revisions: e2021 e2024 +// +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] compile-flags: -Zunstable-options +// +//@[e2021] run-pass +//@[e2024] check-fail + +fn main() { + m(); + q(); +} + +fn m() { + let x = match true { + true => Default::default(), + //[e2024]~^ error: the trait bound `!: Default` is not satisfied + false => panic!("..."), + }; + + dbg!(x); +} + +fn q() -> Option<()> { + fn deserialize() -> Option { + Some(T::default()) + } + + deserialize()?; + //[e2024]~^ error: the trait bound `!: Default` is not satisfied + + None +} diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs new file mode 100644 index 00000000000..19a1f9d0e13 --- /dev/null +++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs @@ -0,0 +1,29 @@ +// issue: rust-lang/rust#66757 +// +// This is a *minimization* of the issue. +// Note that the original version with the `?` does not fail anymore even with fallback to unit, +// see `tests/ui/never_type/question_mark_from_never.rs`. +// +//@ revisions: unit never +//@[never] check-pass +#![allow(internal_features)] +#![feature(rustc_attrs, never_type)] +#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))] +#![cfg_attr(never, rustc_never_type_options(fallback = "never"))] + +struct E; + +impl From for E { + fn from(_: !) -> E { + E + } +} + +#[allow(unreachable_code)] +fn foo(never: !) { + >::from(never); // Ok + >::from(never); // Should the inference fail? + //[unit]~^ error: the trait bound `E: From<()>` is not satisfied +} + +fn main() {} diff --git a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr new file mode 100644 index 00000000000..3b8913ccf45 --- /dev/null +++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr @@ -0,0 +1,12 @@ +error[E0277]: the trait bound `E: From<()>` is not satisfied + --> $DIR/from_infer_breaking_with_unit_fallback.rs:25:6 + | +LL | >::from(never); // Should the inference fail? + | ^ the trait `From<()>` is not implemented for `E` + | + = help: the trait `From` is implemented for `E` + = help: for that trait implementation, expected `!`, found `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/question_mark_from_never.rs b/tests/ui/never_type/question_mark_from_never.rs new file mode 100644 index 00000000000..06d2a1926ea --- /dev/null +++ b/tests/ui/never_type/question_mark_from_never.rs @@ -0,0 +1,46 @@ +// issue: rust-lang/rust#66757 +// +// See also: `tests/ui/never_type/from_infer_breaking_with_unit_fallback.rs`. +// +//@ revisions: unit never +//@ check-pass +#![allow(internal_features)] +#![feature(rustc_attrs, never_type)] +#![cfg_attr(unit, rustc_never_type_options(fallback = "unit"))] +#![cfg_attr(never, rustc_never_type_options(fallback = "never"))] + +type Infallible = !; + +struct E; + +impl From for E { + fn from(_: Infallible) -> E { + E + } +} + +fn u32_try_from(x: u32) -> Result { + Ok(x) +} + +fn _f() -> Result<(), E> { + // In an old attempt to make `Infallible = !` this caused a problem. + // + // Because at the time the code desugared to + // + // match u32::try_from(1u32) { + // Ok(x) => x, Err(e) => return Err(E::from(e)) + // } + // + // With `Infallible = !`, `e: !` but with fallback to `()`, `e` in `E::from(e)` decayed to `()` + // causing an error. + // + // This does not happen with `Infallible = !`. + // And also does not happen with the newer `?` desugaring that does not pass `e` by value. + // (instead we only pass `Result` (where `Error = !` in this case) which does not get + // the implicit coercion and thus does not decay even with fallback to unit) + u32_try_from(1u32)?; + Ok(()) +} + +fn main() {} From e79aafcaa8891b28279739c236ae5f032a2c50b0 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 17 May 2024 14:56:26 +0200 Subject: [PATCH 010/153] Rename `DivergingFallbackBehavior` variants and don't use `::*` --- compiler/rustc_hir_typeck/src/fallback.rs | 15 +++++++-------- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 18 +++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index c79b6be6560..3cfc7437a43 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -18,12 +18,12 @@ use rustc_span::{def_id::LocalDefId, Span}; #[derive(Copy, Clone)] pub enum DivergingFallbackBehavior { /// Always fallback to `()` (aka "always spontaneous decay") - FallbackToUnit, + ToUnit, /// Sometimes fallback to `!`, but mainly fallback to `()` so that most of the crates are not broken. - FallbackToNiko, + ContextDependent, /// Always fallback to `!` (which should be equivalent to never falling back + not making /// never-to-any coercions unless necessary) - FallbackToNever, + ToNever, /// Don't fallback at all NoFallback, } @@ -403,13 +403,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> { diverging_fallback.insert(diverging_ty, ty); }; - use DivergingFallbackBehavior::*; match behavior { - FallbackToUnit => { + DivergingFallbackBehavior::ToUnit => { debug!("fallback to () - legacy: {:?}", diverging_vid); fallback_to(self.tcx.types.unit); } - FallbackToNiko => { + DivergingFallbackBehavior::ContextDependent => { if found_infer_var_info.self_in_trait && found_infer_var_info.output { // This case falls back to () to ensure that the code pattern in // tests/ui/never_type/fallback-closure-ret.rs continues to @@ -445,14 +444,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fallback_to(self.tcx.types.never); } } - FallbackToNever => { + DivergingFallbackBehavior::ToNever => { debug!( "fallback to ! - `rustc_never_type_mode = \"fallback_to_never\")`: {:?}", diverging_vid ); fallback_to(self.tcx.types.never); } - NoFallback => { + DivergingFallbackBehavior::NoFallback => { debug!( "no fallback - `rustc_never_type_mode = \"no_fallback\"`: {:?}", diverging_vid diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 10d832f9726..d6c6093e319 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -390,27 +390,23 @@ fn never_type_behavior(tcx: TyCtxt<'_>) -> (DivergingFallbackBehavior, Diverging /// Returns the default fallback which is used when there is no explicit override via `#![never_type_options(...)]`. fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior { - use DivergingFallbackBehavior::*; - // Edition 2024: fallback to `!` if tcx.sess.edition().at_least_rust_2024() { - return FallbackToNever; + return DivergingFallbackBehavior::ToNever; } // `feature(never_type_fallback)`: fallback to `!` or `()` trying to not break stuff if tcx.features().never_type_fallback { - return FallbackToNiko; + return DivergingFallbackBehavior::ContextDependent; } // Otherwise: fallback to `()` - FallbackToUnit + DivergingFallbackBehavior::ToUnit } fn parse_never_type_options_attr( tcx: TyCtxt<'_>, ) -> (Option, Option) { - use DivergingFallbackBehavior::*; - // Error handling is dubious here (unwraps), but that's probably fine for an internal attribute. // Just don't write incorrect attributes <3 @@ -426,10 +422,10 @@ fn parse_never_type_options_attr( if item.has_name(sym::fallback) && fallback.is_none() { let mode = item.value_str().unwrap(); match mode { - sym::unit => fallback = Some(FallbackToUnit), - sym::niko => fallback = Some(FallbackToNiko), - sym::never => fallback = Some(FallbackToNever), - sym::no => fallback = Some(NoFallback), + sym::unit => fallback = Some(DivergingFallbackBehavior::ToUnit), + sym::niko => fallback = Some(DivergingFallbackBehavior::ContextDependent), + sym::never => fallback = Some(DivergingFallbackBehavior::ToNever), + sym::no => fallback = Some(DivergingFallbackBehavior::NoFallback), _ => { tcx.dcx().span_err(item.span(), format!("unknown never type fallback mode: `{mode}` (supported: `unit`, `niko`, `never` and `no`)")); } From eb0ed28cedc2f5d96695d0ccd75ff831ec221a13 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 28 May 2024 15:31:26 +0200 Subject: [PATCH 011/153] Remove usage of `isize` in example `isize` is a rare integer type, replace it with a more common one. --- compiler/rustc_lint/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index ba42eae3441..6fd416ef517 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -142,7 +142,7 @@ declare_lint! { /// ```rust,compile_fail /// #![deny(box_pointers)] /// struct Foo { - /// x: Box, + /// x: Box, /// } /// ``` /// From 1a840e7732536bbf5c4d2f434d4af138983f4b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 28 May 2024 20:05:01 +0000 Subject: [PATCH 012/153] Add test for incorrect pinning suggestion The following suggestion is incorrect, as it doesn't account for the binding: ``` error[E0599]: no method named `poll` found for type parameter `F` in the current scope --> $DIR/pin-needed-to-poll-3.rs:19:28 | LL | impl Future for FutureWrapper | - method `poll` not found for this type parameter ... LL | let res = self.fut.poll(cx); | ^^^^ method not found in `F` | help: consider pinning the expression | LL ~ let res = let mut pinned = std::pin::pin!(self.fut); LL ~ pinned.as_mut().poll(cx); | ``` --- tests/ui/async-await/pin-needed-to-poll-3.rs | 25 +++++++++++++++++++ .../async-await/pin-needed-to-poll-3.stderr | 18 +++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/async-await/pin-needed-to-poll-3.rs create mode 100644 tests/ui/async-await/pin-needed-to-poll-3.stderr diff --git a/tests/ui/async-await/pin-needed-to-poll-3.rs b/tests/ui/async-await/pin-needed-to-poll-3.rs new file mode 100644 index 00000000000..11ba7d29aba --- /dev/null +++ b/tests/ui/async-await/pin-needed-to-poll-3.rs @@ -0,0 +1,25 @@ +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + + +struct FutureWrapper { + fut: F, +} + +impl Future for FutureWrapper +where + F: Future, +{ + type Output = F::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let res = self.fut.poll(cx); + //~^ ERROR no method named `poll` found for type parameter `F` in the current scope + res + } +} + +fn main() {} diff --git a/tests/ui/async-await/pin-needed-to-poll-3.stderr b/tests/ui/async-await/pin-needed-to-poll-3.stderr new file mode 100644 index 00000000000..83a0808c4ec --- /dev/null +++ b/tests/ui/async-await/pin-needed-to-poll-3.stderr @@ -0,0 +1,18 @@ +error[E0599]: no method named `poll` found for type parameter `F` in the current scope + --> $DIR/pin-needed-to-poll-3.rs:19:28 + | +LL | impl Future for FutureWrapper + | - method `poll` not found for this type parameter +... +LL | let res = self.fut.poll(cx); + | ^^^^ method not found in `F` + | +help: consider pinning the expression + | +LL ~ let res = let mut pinned = std::pin::pin!(self.fut); +LL ~ pinned.as_mut().poll(cx); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. From 5585f3133c05a33e59cd352a32fdf171447a9b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 28 May 2024 20:48:35 +0000 Subject: [PATCH 013/153] Account for existing bindings when suggesting pinning When we encounter a situation where we'd suggest `pin!()`, we now account for that expression exising as part of an assignment and provide an appropriate suggestion: ``` error[E0599]: no method named `poll` found for type parameter `F` in the current scope --> $DIR/pin-needed-to-poll-3.rs:19:28 | LL | impl Future for FutureWrapper | - method `poll` not found for this type parameter ... LL | let res = self.fut.poll(cx); | ^^^^ method not found in `F` | help: consider pinning the expression | LL ~ let mut pinned = std::pin::pin!(self.fut); LL ~ let res = pinned.as_mut().poll(cx); | ``` Fix #125661. --- .../rustc_hir_typeck/src/method/suggest.rs | 68 ++++++++++++++++--- .../async-await/pin-needed-to-poll-3.stderr | 4 +- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 54af8354c4c..75bb755183e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3326,14 +3326,66 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .source_map() .indentation_before(rcvr.span) .unwrap_or_else(|| " ".to_string()); - err.multipart_suggestion( - "consider pinning the expression", - vec![ - (rcvr.span.shrink_to_lo(), format!("let mut pinned = std::pin::pin!(")), - (rcvr.span.shrink_to_hi(), format!(");\n{indent}pinned.{pin_call}()")), - ], - Applicability::MaybeIncorrect, - ); + let mut expr = rcvr; + while let Node::Expr(call_expr) = self.tcx.parent_hir_node(expr.hir_id) + && let hir::ExprKind::MethodCall(hir::PathSegment { .. }, ..) = + call_expr.kind + { + expr = call_expr; + } + match self.tcx.parent_hir_node(expr.hir_id) { + Node::LetStmt(stmt) + if let Some(init) = stmt.init + && let Ok(code) = + self.tcx.sess.source_map().span_to_snippet(rcvr.span) => + { + // We need to take care to account for the existing binding when we + // suggest the code. + err.multipart_suggestion( + "consider pinning the expression", + vec![ + ( + stmt.span.shrink_to_lo(), + format!( + "let mut pinned = std::pin::pin!({code});\n{indent}" + ), + ), + ( + init.span.until(rcvr.span.shrink_to_hi()), + format!("pinned.{pin_call}()"), + ), + ], + Applicability::MaybeIncorrect, + ); + } + Node::Block(_) | Node::Stmt(_) => { + // There's no binding, so we can provide a slightly nicer looking + // suggestion. + err.multipart_suggestion( + "consider pinning the expression", + vec![ + ( + rcvr.span.shrink_to_lo(), + format!("let mut pinned = std::pin::pin!("), + ), + ( + rcvr.span.shrink_to_hi(), + format!(");\n{indent}pinned.{pin_call}()"), + ), + ], + Applicability::MaybeIncorrect, + ); + } + _ => { + // We don't quite know what the users' code looks like, so we don't + // provide a pinning suggestion. + err.span_help( + rcvr.span, + "consider pinning the expression with `std::pin::pin!()` and \ + assigning that to a new binding", + ); + } + } // We don't care about the other suggestions. alt_rcvr_sugg = true; } diff --git a/tests/ui/async-await/pin-needed-to-poll-3.stderr b/tests/ui/async-await/pin-needed-to-poll-3.stderr index 83a0808c4ec..e4fbef69bac 100644 --- a/tests/ui/async-await/pin-needed-to-poll-3.stderr +++ b/tests/ui/async-await/pin-needed-to-poll-3.stderr @@ -9,8 +9,8 @@ LL | let res = self.fut.poll(cx); | help: consider pinning the expression | -LL ~ let res = let mut pinned = std::pin::pin!(self.fut); -LL ~ pinned.as_mut().poll(cx); +LL ~ let mut pinned = std::pin::pin!(self.fut); +LL ~ let res = pinned.as_mut().poll(cx); | error: aborting due to 1 previous error From c72fcfbc40a57f88de1a64a2bc69f85e2844b77e Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Tue, 28 May 2024 13:38:43 +0100 Subject: [PATCH 014/153] Add Xtensa as an experimental target --- compiler/rustc_llvm/src/lib.rs | 7 +++++++ src/bootstrap/src/core/build_steps/llvm.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 6a570c97c88..ae1848a7363 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -188,6 +188,13 @@ pub fn initialize_available_targets() { LLVMInitializeHexagonAsmPrinter, LLVMInitializeHexagonAsmParser ); + init_target!( + llvm_component = "xtensa", + LLVMInitializeXtensaTargetInfo, + LLVMInitializeXtensaTarget, + LLVMInitializeXtensaTargetMC, + LLVMInitializeXtensaAsmParser + ); init_target!( llvm_component = "webassembly", LLVMInitializeWebAssemblyTargetInfo, diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 8ca7af2febe..ebac27cd92c 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -330,7 +330,7 @@ impl Step for Llvm { let llvm_exp_targets = match builder.config.llvm_experimental_targets { Some(ref s) => s, - None => "AVR;M68k;CSKY", + None => "AVR;M68k;CSKY;Xtensa", }; let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" }; From b37a448616a370ba02eeaa7d7c8289fa85d35fc9 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 12 Sep 2020 23:20:14 +0100 Subject: [PATCH 015/153] Teach rustc about the Xtensa arch. --- compiler/rustc_llvm/build.rs | 1 + compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 024f6f89a4b..cdaabb036c2 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -23,6 +23,7 @@ const OPTIONAL_COMPONENTS: &[&str] = &[ "nvptx", "hexagon", "riscv", + "xtensa", "bpf", ]; diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3fcf3aca8af..a027ddcc150 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -155,6 +155,12 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) { #define SUBTARGET_SPARC #endif +#ifdef LLVM_COMPONENT_XTENSA +#define SUBTARGET_XTENSA SUBTARGET(XTENSA) +#else +#define SUBTARGET_XTENSA +#endif + #ifdef LLVM_COMPONENT_HEXAGON #define SUBTARGET_HEXAGON SUBTARGET(Hexagon) #else @@ -180,6 +186,7 @@ extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) { SUBTARGET_MSP430 \ SUBTARGET_SPARC \ SUBTARGET_HEXAGON \ + SUBTARGET_XTENSA \ SUBTARGET_RISCV \ SUBTARGET_LOONGARCH \ From e823288c352bf19bbaaf77b7ef8958d3c8426a3f Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Sat, 12 Sep 2020 23:31:14 +0100 Subject: [PATCH 016/153] Teach rustc about the Xtensa call ABI. --- compiler/rustc_target/src/abi/call/mod.rs | 2 + compiler/rustc_target/src/abi/call/xtensa.rs | 123 +++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 compiler/rustc_target/src/abi/call/xtensa.rs diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index fc79c9232d1..5713542c17d 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -29,6 +29,7 @@ mod wasm; mod x86; mod x86_64; mod x86_win64; +mod xtensa; #[derive(Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum PassMode { @@ -903,6 +904,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } "hexagon" => hexagon::compute_abi_info(self), + "xtensa" => xtensa::compute_abi_info(cx, self), "riscv32" | "riscv64" => riscv::compute_abi_info(cx, self), "wasm32" | "wasm64" => { if cx.target_spec().adjust_abi(cx, abi, self.c_variadic) == spec::abi::Abi::Wasm { diff --git a/compiler/rustc_target/src/abi/call/xtensa.rs b/compiler/rustc_target/src/abi/call/xtensa.rs new file mode 100644 index 00000000000..addbe698925 --- /dev/null +++ b/compiler/rustc_target/src/abi/call/xtensa.rs @@ -0,0 +1,123 @@ +//! The Xtensa ABI implementation +//! +//! This ABI implementation is based on the following sources: +//! +//! Section 8.1.4 & 8.1.5 of the Xtensa ISA reference manual, as well as snippets from +//! Section 2.3 from the Xtensa programmers guide. + +use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform}; +use crate::abi::{Abi, HasDataLayout, Size, TyAbiInterface}; +use crate::spec::HasTargetSpec; + +const NUM_ARG_GPRS: u64 = 6; +const NUM_RET_GPRS: u64 = 4; +const MAX_ARG_IN_REGS_SIZE: u64 = NUM_ARG_GPRS * 32; +const MAX_RET_IN_REGS_SIZE: u64 = NUM_RET_GPRS * 32; + +fn classify_ret_ty<'a, Ty, C>(arg: &mut ArgAbi<'_, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + if arg.is_ignore() { + return; + } + + // The rules for return and argument types are the same, + // so defer to `classify_arg_ty`. + let mut arg_gprs_left = NUM_RET_GPRS; + classify_arg_ty(arg, &mut arg_gprs_left, MAX_RET_IN_REGS_SIZE); + // Ret args cannot be passed via stack, we lower to indirect and let the backend handle the invisble reference + match arg.mode { + super::PassMode::Indirect { attrs: _, meta_attrs: _, ref mut on_stack } => { + *on_stack = false; + } + _ => {} + } +} + +fn classify_arg_ty<'a, Ty, C>(arg: &mut ArgAbi<'_, Ty>, arg_gprs_left: &mut u64, max_size: u64) +where + Ty: TyAbiInterface<'a, C> + Copy, +{ + assert!(*arg_gprs_left <= NUM_ARG_GPRS, "Arg GPR tracking underflow"); + + // Ignore empty structs/unions. + if arg.layout.is_zst() { + return; + } + + let size = arg.layout.size.bits(); + let needed_align = arg.layout.align.abi.bits(); + let mut must_use_stack = false; + + // Determine the number of GPRs needed to pass the current argument + // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" + // register pairs, so may consume 3 registers. + let mut needed_arg_gprs = (size + 32 - 1) / 32; + if needed_align == 64 { + needed_arg_gprs += *arg_gprs_left % 2; + } + + if needed_arg_gprs > *arg_gprs_left + || needed_align > 128 + || (*arg_gprs_left < (max_size / 32) && needed_align == 128) + { + must_use_stack = true; + needed_arg_gprs = *arg_gprs_left; + } + *arg_gprs_left -= needed_arg_gprs; + + if must_use_stack { + arg.make_indirect_byval(None); + } else { + if is_xtensa_aggregate(arg) { + // Aggregates which are <= max_size will be passed in + // registers if possible, so coerce to integers. + + // Use a single `xlen` int if possible, 2 * `xlen` if 2 * `xlen` alignment + // is required, and a 2-element `xlen` array if only `xlen` alignment is + // required. + if size <= 32 { + arg.cast_to(Reg::i32()); + } else { + let reg = if needed_align == 2 * 32 { Reg::i64() } else { Reg::i32() }; + let total = Size::from_bits(((size + 32 - 1) / 32) * 32); + arg.cast_to(Uniform::new(reg, total)); + } + } else { + // All integral types are promoted to `xlen` + // width. + // + // We let the LLVM backend handle integral types >= xlen. + if size < 32 { + arg.extend_integer_width_to(32); + } + } + } +} + +pub fn compute_abi_info<'a, Ty, C>(_cx: &C, fn_abi: &mut FnAbi<'a, Ty>) +where + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, +{ + if !fn_abi.ret.is_ignore() { + classify_ret_ty(&mut fn_abi.ret); + } + + let mut arg_gprs_left = NUM_ARG_GPRS; + + for arg in fn_abi.args.iter_mut() { + if arg.is_ignore() { + continue; + } + classify_arg_ty(arg, &mut arg_gprs_left, MAX_ARG_IN_REGS_SIZE); + } +} + +fn is_xtensa_aggregate<'a, Ty>(arg: &ArgAbi<'a, Ty>) -> bool { + match arg.layout.abi { + Abi::Vector { .. } => true, + _ => arg.layout.is_aggregate(), + } +} From 11f70d78f59cff6baf2d9e167db38662640e11f6 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Tue, 14 May 2024 17:16:59 +0200 Subject: [PATCH 017/153] Add no_std Xtensa targets support --- compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/base/xtensa.rs | 17 +++++++++++++ compiler/rustc_target/src/spec/mod.rs | 4 +++ .../src/spec/targets/xtensa_esp32_none_elf.rs | 24 ++++++++++++++++++ .../spec/targets/xtensa_esp32s2_none_elf.rs | 23 +++++++++++++++++ .../spec/targets/xtensa_esp32s3_none_elf.rs | 24 ++++++++++++++++++ src/doc/rustc/src/platform-support.md | 3 +++ src/doc/rustc/src/platform-support/xtensa.md | 25 +++++++++++++++++++ src/tools/tidy/src/target_policy.rs | 4 +++ tests/assembly/targets/targets-elf.rs | 13 +++++++++- tests/ui/check-cfg/well-known-values.stderr | 2 +- 11 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 compiler/rustc_target/src/spec/base/xtensa.rs create mode 100644 compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs create mode 100644 compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs create mode 100644 compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs create mode 100644 src/doc/rustc/src/platform-support/xtensa.md diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index d137aaa5358..28d10dcf2ff 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -35,3 +35,4 @@ pub(crate) mod windows_gnullvm; pub(crate) mod windows_msvc; pub(crate) mod windows_uwp_gnu; pub(crate) mod windows_uwp_msvc; +pub(crate) mod xtensa; diff --git a/compiler/rustc_target/src/spec/base/xtensa.rs b/compiler/rustc_target/src/spec/base/xtensa.rs new file mode 100644 index 00000000000..31ad09c52e4 --- /dev/null +++ b/compiler/rustc_target/src/spec/base/xtensa.rs @@ -0,0 +1,17 @@ +use crate::abi::Endian; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions}; + +pub fn opts() -> TargetOptions { + TargetOptions { + os: "none".into(), + endian: Endian::Little, + c_int_width: "32".into(), + linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), + executables: true, + panic_strategy: PanicStrategy::Abort, + relocation_model: RelocModel::Static, + emit_debug_gdb_scripts: false, + atomic_cas: false, + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 83ee63e2cf2..da1da0c52bf 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1766,6 +1766,10 @@ supported_targets! { ("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda), + ("xtensa-esp32-none-elf", xtensa_esp32_none_elf), + ("xtensa-esp32s2-none-elf", xtensa_esp32s2_none_elf), + ("xtensa-esp32s3-none-elf", xtensa_esp32s3_none_elf), + ("i686-wrs-vxworks", i686_wrs_vxworks), ("x86_64-wrs-vxworks", x86_64_wrs_vxworks), ("armv7-wrs-vxworks-eabihf", armv7_wrs_vxworks_eabihf), diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs new file mode 100644 index 00000000000..bf523716313 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32_none_elf.rs @@ -0,0 +1,24 @@ +use crate::spec::{base::xtensa, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "xtensa-none-elf".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), + arch: "xtensa".into(), + metadata: crate::spec::TargetMetadata { + description: Some("Xtensa ESP32".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + + options: TargetOptions { + cpu: "esp32".into(), + linker: Some("xtensa-esp32-elf-gcc".into()), + max_atomic_width: Some(32), + atomic_cas: true, + ..xtensa::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs new file mode 100644 index 00000000000..219b2aa48c1 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs @@ -0,0 +1,23 @@ +use crate::spec::{base::xtensa, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "xtensa-none-elf".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), + arch: "xtensa".into(), + metadata: crate::spec::TargetMetadata { + description: Some("Xtensa ESP32-S2".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + + options: TargetOptions { + cpu: "esp32-s2".into(), + linker: Some("xtensa-esp32s2-elf-gcc".into()), + max_atomic_width: Some(32), + ..xtensa::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs new file mode 100644 index 00000000000..632eef3a584 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs @@ -0,0 +1,24 @@ +use crate::spec::{base::xtensa, Target, TargetOptions}; + +pub fn target() -> Target { + Target { + llvm_target: "xtensa-none-elf".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(), + arch: "xtensa".into(), + metadata: crate::spec::TargetMetadata { + description: Some("Xtensa ESP32-S3".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(false), + }, + + options: TargetOptions { + cpu: "esp32-s3".into(), + linker: Some("xtensa-esp32s3-elf-gcc".into()), + max_atomic_width: Some(32), + atomic_cas: true, + ..xtensa::opts() + }, + } +} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 77859956c95..30fe0206cd5 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -383,5 +383,8 @@ target | std | host | notes `x86_64-wrs-vxworks` | ? | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc +`xtensa-esp32-none-elf` | | | Xtensa ESP32 +`xtensa-esp32s2-none-elf` | | | Xtensa ESP32-S2 +`xtensa-esp32s3-none-elf` | | | Xtensa ESP32-S3 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/xtensa.md b/src/doc/rustc/src/platform-support/xtensa.md new file mode 100644 index 00000000000..7785977466e --- /dev/null +++ b/src/doc/rustc/src/platform-support/xtensa.md @@ -0,0 +1,25 @@ +# `xtensa-*` + +**Tier: 3** + +Targets for Xtensa CPUs. + +## Target maintainers + +- Scott Mabin [@MabezDev](https://github.com/MabezDev) +- Sergio Gasquez [@SergioGasquez](https://github.com/SergioGasquez) + +## Requirements + +The target names follow this format: `xtensa-$CPU`, where `$CPU` specifies the target chip. The following targets are currently defined: + +| Target name | Target CPU(s) | +| ------------------------- | --------------------------------------------------------------- | +| `xtensa-esp32-none-elf` | [ESP32](https://www.espressif.com/en/products/socs/esp32) | +| `xtensa-esp32s2-none-elf` | [ESP32-S2](https://www.espressif.com/en/products/socs/esp32-s2) | +| `xtensa-esp32s3-none-elf` | [ESP32-S3](https://www.espressif.com/en/products/socs/esp32-s3) | + + +## Building the target + +The targets can be built by installing the [Xtensa enabled Rust channel](https://github.com/esp-rs/rust/). See instructions in the [RISC-V and Xtensa Targets section of the The Rust on ESP Book](https://docs.esp-rs.org/book/installation/riscv-and-xtensa.html). diff --git a/src/tools/tidy/src/target_policy.rs b/src/tools/tidy/src/target_policy.rs index 382488e5721..06210c8cdb2 100644 --- a/src/tools/tidy/src/target_policy.rs +++ b/src/tools/tidy/src/target_policy.rs @@ -12,6 +12,10 @@ const EXCEPTIONS: &[&str] = &[ // FIXME: disabled since it fails on CI saying the csky component is missing "csky_unknown_linux_gnuabiv2", "csky_unknown_linux_gnuabiv2hf", + // FIXME: disabled since it requires a custom LLVM until the upstream LLVM adds support for the target (https://github.com/espressif/llvm-project/issues/4) + "xtensa_esp32_none_elf", + "xtensa_esp32s2_none_elf", + "xtensa_esp32s3_none_elf", ]; pub fn check(root_path: &Path, bad: &mut bool) { diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 0db2a358002..4c54fe639e3 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -573,7 +573,18 @@ //@ revisions: x86_64_wrs_vxworks //@ [x86_64_wrs_vxworks] compile-flags: --target x86_64-wrs-vxworks //@ [x86_64_wrs_vxworks] needs-llvm-components: x86 - +// FIXME: disabled since it requires a custom LLVM until the upstream LLVM adds support for the target (https://github.com/espressif/llvm-project/issues/4) +/* + revisions: xtensa_esp32_none_elf + [xtensa_esp32_none_elf] compile-flags: --target xtensa-esp32-none-elf + [xtensa_esp32_none_elf] needs-llvm-components: xtensa + revisions: xtensa_esp32s2_none_elf + [xtensa_esp32s2_none_elf] compile-flags: --target xtensa-esp32s2-none-elf + [xtensa_esp32s2_none_elf] needs-llvm-components: xtensa + revisions: xtensa_esp32s3_none_elf + [xtensa_esp32s3_none_elf] compile-flags: --target xtensa-esp32s3-none-elf + [xtensa_esp32s3_none_elf] needs-llvm-components: xtensa +*/ // Sanity-check that each target can produce assembly code. #![feature(no_core, lang_items)] diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 0c50ec1abba..3796dca1727 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -129,7 +129,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, and `x86_64` + = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From 14348d951912022c4b23d7316f06a78a2791da01 Mon Sep 17 00:00:00 2001 From: Kjetil Kjeka Date: Fri, 31 May 2024 22:45:27 +0200 Subject: [PATCH 018/153] NVPTX: Avoid PassMode::Direct for C ABI --- compiler/rustc_target/src/abi/call/nvptx64.rs | 47 +++++++++++++++---- tests/assembly/nvptx-c-abi-ret-v7.rs | 1 - tests/ui/abi/compatibility.rs | 10 ++-- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index c6b6f66e6be..ac68e8879f6 100644 --- a/compiler/rustc_target/src/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs @@ -1,23 +1,54 @@ use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform}; use crate::abi::{HasDataLayout, TyAbiInterface}; +use super::{ArgAttribute, ArgAttributes, ArgExtension, CastTarget}; + fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { - if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 { - ret.make_indirect(); - } else { - // FIXME: this is wrong! Need to decide which ABI we really want here. - ret.make_direct_deprecated(); + if ret.layout.is_aggregate() && ret.layout.is_sized() { + classify_aggregate(ret) + } else if ret.layout.size.bits() < 32 && ret.layout.is_sized() { + ret.extend_integer_width_to(32); } } fn classify_arg(arg: &mut ArgAbi<'_, Ty>) { - if arg.layout.is_aggregate() { - arg.make_indirect_byval(None); - } else if arg.layout.size.bits() < 32 { + if arg.layout.is_aggregate() && arg.layout.is_sized() { + classify_aggregate(arg) + } else if arg.layout.size.bits() < 32 && arg.layout.is_sized() { arg.extend_integer_width_to(32); } } +/// the pass mode used for aggregates in arg and ret position +fn classify_aggregate(arg: &mut ArgAbi<'_, Ty>) { + let align_bytes = arg.layout.align.abi.bytes(); + let size = arg.layout.size; + + let reg = match align_bytes { + 1 => Reg::i8(), + 2 => Reg::i16(), + 4 => Reg::i32(), + 8 => Reg::i64(), + 16 => Reg::i128(), + _ => unreachable!("Align is given as power of 2 no larger than 16 bytes"), + }; + + if align_bytes == size.bytes() { + arg.cast_to(CastTarget { + prefix: [Some(reg), None, None, None, None, None, None, None], + rest: Uniform::new(Reg::i8(), Size::from_bytes(0)), + attrs: ArgAttributes { + regular: ArgAttribute::default(), + arg_ext: ArgExtension::None, + pointee_size: Size::ZERO, + pointee_align: None, + }, + }); + } else { + arg.cast_to(Uniform::new(reg, size)); + } +} + fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>) where Ty: TyAbiInterface<'a, C> + Copy, diff --git a/tests/assembly/nvptx-c-abi-ret-v7.rs b/tests/assembly/nvptx-c-abi-ret-v7.rs index 0c1594a5f20..8992cb8d540 100644 --- a/tests/assembly/nvptx-c-abi-ret-v7.rs +++ b/tests/assembly/nvptx-c-abi-ret-v7.rs @@ -1,7 +1,6 @@ //@ assembly-output: ptx-linker //@ compile-flags: --crate-type cdylib -C target-cpu=sm_86 -Z unstable-options -Clinker-flavor=llbc //@ only-nvptx64 -//@ ignore-nvptx64 // The PTX ABI stability is tied to major versions of the PTX ISA // These tests assume major version 7 diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index c27a107a639..1be9ada2822 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -55,13 +55,9 @@ //@ revisions: csky //@[csky] compile-flags: --target csky-unknown-linux-gnuabiv2 //@[csky] needs-llvm-components: csky - -// FIXME: disabled on nvptx64 since the target ABI fails the sanity check -// see https://github.com/rust-lang/rust/issues/117480 -/* revisions: nvptx64 - [nvptx64] compile-flags: --target nvptx64-nvidia-cuda - [nvptx64] needs-llvm-components: nvptx -*/ +//@ revisions: nvptx64 +//@[nvptx64] compile-flags: --target nvptx64-nvidia-cuda +//@[nvptx64] needs-llvm-components: nvptx #![feature(rustc_attrs, unsized_fn_params, transparent_unions)] #![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)] #![allow(unused, improper_ctypes_definitions, internal_features)] From a49fe0a58c81f2fe10c5cf0cc5b22113253de893 Mon Sep 17 00:00:00 2001 From: Kjetil Kjeka Date: Fri, 31 May 2024 23:12:33 +0200 Subject: [PATCH 019/153] NVPTX:_Especially add the DoubleI32 struct as a nvptx abi test case since it was used as an example when discussing possible problems --- tests/assembly/nvptx-c-abi-arg-v7.rs | 10 ++++++++++ tests/assembly/nvptx-c-abi-ret-v7.rs | 11 +++++++++++ .../nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/tests/assembly/nvptx-c-abi-arg-v7.rs b/tests/assembly/nvptx-c-abi-arg-v7.rs index 99f90ea526e..27b64b58f04 100644 --- a/tests/assembly/nvptx-c-abi-arg-v7.rs +++ b/tests/assembly/nvptx-c-abi-arg-v7.rs @@ -40,6 +40,11 @@ pub struct TripleU16 { h: u16, } #[repr(C)] +pub struct DoubleI32 { + f: i32, + g: i32, +} +#[repr(C)] pub struct TripleU32 { f: u32, g: u32, @@ -175,6 +180,11 @@ pub unsafe extern "C" fn f_triple_u16_arg(_a: TripleU16) {} #[no_mangle] pub unsafe extern "C" fn f_triple_u32_arg(_a: TripleU32) {} +// CHECK: .visible .func f_double_i32_arg( +// CHECK: .param .align 4 .b8 f_double_i32_arg_param_0[8] +#[no_mangle] +pub unsafe extern "C" fn f_double_i32_arg(_a: DoubleI32) {} + // CHECK: .visible .func f_triple_u64_arg( // CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24] #[no_mangle] diff --git a/tests/assembly/nvptx-c-abi-ret-v7.rs b/tests/assembly/nvptx-c-abi-ret-v7.rs index 8992cb8d540..56ab182fcce 100644 --- a/tests/assembly/nvptx-c-abi-ret-v7.rs +++ b/tests/assembly/nvptx-c-abi-ret-v7.rs @@ -40,6 +40,11 @@ pub struct TripleU16 { h: u16, } #[repr(C)] +pub struct DoubleI32 { + f: i32, + g: i32, +} +#[repr(C)] pub struct TripleU32 { f: u32, g: u32, @@ -186,6 +191,12 @@ pub unsafe extern "C" fn f_triple_u16_ret() -> TripleU16 { TripleU16 { f: 18, g: 19, h: 20 } } +// CHECK: .visible .func (.param .align 4 .b8 func_retval0[8]) f_double_i32_ret( +#[no_mangle] +pub unsafe extern "C" fn f_double_i32_ret() -> DoubleI32 { + DoubleI32 { f: 1, g: 2 } +} + // CHECK: .visible .func (.param .align 4 .b8 func_retval0[12]) f_triple_u32_ret( #[no_mangle] pub unsafe extern "C" fn f_triple_u32_ret() -> TripleU32 { diff --git a/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs b/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs index ce1d732f367..fb3a325a41f 100644 --- a/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs +++ b/tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs @@ -50,6 +50,11 @@ pub struct TripleU16 { h: u16, } #[repr(C)] +pub struct DoubleI32 { + f: i32, + g: i32, +} +#[repr(C)] pub struct TripleU32 { f: u32, g: u32, @@ -180,6 +185,11 @@ pub unsafe extern "ptx-kernel" fn f_triple_u8_arg(_a: TripleU8) {} #[no_mangle] pub unsafe extern "ptx-kernel" fn f_triple_u16_arg(_a: TripleU16) {} +// CHECK: .visible .entry f_double_i32_arg( +// CHECK: .param .align 4 .b8 f_double_i32_arg_param_0[8] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_double_i32_arg(_a: DoubleI32) {} + // CHECK: .visible .entry f_triple_u32_arg( // CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12] #[no_mangle] From 87ad80a6384824fb5e13cc54278eb5aaa36a89a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 1 Jun 2024 13:03:07 -0700 Subject: [PATCH 020/153] Add `target_env = "p1"` to the `wasm32-wasip1` target This commit sets the `target_env` key for the `wasm32-wasi{,p1,p1-threads}` targets to the string `"p1"`. This mirrors how the `wasm32-wasip2` target has `target_env = "p2"`. The intention of this is to more easily detect each target in downstream crates to enable adding custom code per-target. cc #125803 --- .../rustc_target/src/spec/targets/wasm32_wasip1.rs | 1 + .../src/spec/targets/wasm32_wasip1_threads.rs | 1 + .../src/platform-support/wasm32-wasip1-threads.md | 12 ++++++++++++ src/doc/rustc/src/platform-support/wasm32-wasip1.md | 11 +++++++++++ src/doc/rustc/src/platform-support/wasm32-wasip2.md | 8 ++++++++ 5 files changed, 33 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index 7cbe9f09e6c..4c2d222b590 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs @@ -18,6 +18,7 @@ pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "wasi".into(); + options.env = "p1".into(); options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs index c592b944d44..38af48ab266 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs @@ -13,6 +13,7 @@ pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "wasi".into(); + options.env = "p1".into(); options.add_pre_link_args( LinkerFlavor::WasmLld(Cc::No), diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 519e9cc7cc4..66cf964bd25 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -150,3 +150,15 @@ or another engine that supports `wasi-threads` is installed and can be found in 5. Apply such [a change](https://github.com/g0djan/rust/compare/godjan/wasi-threads...g0djan:rust:godjan/wasi-run-ui-tests?expand=1) with an engine from the step 1. 6. Run `./x.py test --target wasm32-wasip1-threads tests/ui` and save the list of failed tests. 7. For both lists of failed tests run `cat list | sort > sorted_list` and compare it with `diff sorted_list1 sorted_list2`. + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] +``` + +Prior to Rust 1.80 the `target_env = "p1"` key was not set. Currently the +`target_feature = "atomics"` is Nightly-only. Note that the precise `#[cfg]` +necessary to detect this target may change as the target becomes more stable. diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 4faa1988735..3f6ed130e12 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -121,3 +121,14 @@ can be tested locally, for example, with: ```text ./x.py test --target wasm32-wasip1 tests/ui ``` + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p1"))] +``` + +Note that the `target_env = "p1"` condition first appeared in Rust 1.80. Prior +to Rust 1.80 the `target_env` condition was not set. diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index a385600cc22..7b4eb31b214 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -53,3 +53,11 @@ This target is not tested in CI at this time. Locally it can be tested with a ```text ./x.py test --target wasm32-wasip2 tests/ui ``` + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +``` +#[cfg(all(target_os = "wasi", target_env = "p2"))] +``` From 5ecb034cc307e40feda18f216f44564b13fa2a65 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 1 Jun 2024 13:40:41 -0700 Subject: [PATCH 021/153] Update test expectations --- tests/ui/check-cfg/well-known-values.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 0c50ec1abba..95a92283db1 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -147,7 +147,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From d313e7e1836e3f92f42f6acdea449224288a1f23 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 2 Jun 2024 11:28:04 -0700 Subject: [PATCH 022/153] Fix testing examples in documentation --- src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md | 2 +- src/doc/rustc/src/platform-support/wasm32-wasip1.md | 2 +- src/doc/rustc/src/platform-support/wasm32-wasip2.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md index 66cf964bd25..2b3d15e93c8 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1-threads.md @@ -155,7 +155,7 @@ or another engine that supports `wasi-threads` is installed and can be found in It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p1", target_feature = "atomics"))] ``` diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md index 3f6ed130e12..fb70bbdc2b4 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md @@ -126,7 +126,7 @@ can be tested locally, for example, with: It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p1"))] ``` diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md index 7b4eb31b214..1e53fbc178e 100644 --- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md +++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md @@ -58,6 +58,6 @@ This target is not tested in CI at this time. Locally it can be tested with a It's recommended to conditionally compile code for this target with: -``` +```text #[cfg(all(target_os = "wasi", target_env = "p2"))] ``` From b2949ff9118715ce26af3c0b023921ca855ca772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Mon, 3 Jun 2024 07:17:19 +0200 Subject: [PATCH 023/153] Spruce up the diagnostics of some early lints --- compiler/rustc_expand/messages.ftl | 2 +- compiler/rustc_lint/messages.ftl | 12 ++++++---- .../rustc_lint/src/context/diagnostics.rs | 5 ++-- compiler/rustc_lint/src/lints.rs | 4 ++++ compiler/rustc_lint_defs/src/builtin.rs | 9 +++---- compiler/rustc_lint_defs/src/lib.rs | 5 +++- compiler/rustc_resolve/src/imports.rs | 24 ++++++++++++------- tests/ui/extern-flag/no-nounused.rs | 2 +- tests/ui/extern-flag/no-nounused.stderr | 3 ++- .../macros/issue-61053-missing-repetition.rs | 6 ++--- .../issue-61053-missing-repetition.stderr | 6 ++--- .../rfc-3086-metavar-expr/syntax-errors.rs | 2 +- .../syntax-errors.stderr | 2 +- tests/ui/parser/macro/macro-repeat.stderr | 4 ++-- .../ui/pub/pub-reexport-priv-extern-crate.rs | 2 +- .../pub/pub-reexport-priv-extern-crate.stderr | 6 ++++- .../ui/rust-2018/macro-use-warned-against.rs | 2 +- .../rust-2018/macro-use-warned-against.stderr | 3 ++- tests/ui/unused-crate-deps/deny-attr.rs | 2 +- tests/ui/unused-crate-deps/deny-attr.stderr | 3 ++- tests/ui/unused-crate-deps/deny-cmdline.rs | 2 +- .../ui/unused-crate-deps/deny-cmdline.stderr | 3 ++- tests/ui/unused-crate-deps/libfib.rs | 2 +- tests/ui/unused-crate-deps/libfib.stderr | 3 ++- tests/ui/unused-crate-deps/unused-aliases.rs | 2 +- .../unused-crate-deps/unused-aliases.stderr | 3 ++- tests/ui/unused-crate-deps/warn-attr.rs | 2 +- tests/ui/unused-crate-deps/warn-attr.stderr | 3 ++- .../unused-crate-deps/warn-cmdline-static.rs | 2 +- .../warn-cmdline-static.stderr | 3 ++- tests/ui/unused-crate-deps/warn-cmdline.rs | 2 +- .../ui/unused-crate-deps/warn-cmdline.stderr | 3 ++- 32 files changed, 83 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 530b37aadb1..2959589f474 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -154,7 +154,7 @@ expand_unsupported_key_value = key-value macro attributes are not supported expand_var_still_repeating = - variable '{$ident}' is still repeating at this depth + variable `{$ident}` is still repeating at this depth expand_wrong_fragment_kind = non-{$kind} macro in {$kind} position: {$name} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fb71cb60140..14d25a6add7 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -445,7 +445,8 @@ lint_macro_is_private = macro `{$ident}` is private lint_macro_rule_never_used = rule #{$n} of macro `{$name}` is never used lint_macro_use_deprecated = - deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead + applying the `#[macro_use]` attribute to an `extern crate` item is deprecated + .help = remove it and import macros at use sites with a `use` item instead lint_malformed_attribute = malformed lint attribute input @@ -456,7 +457,7 @@ lint_map_unit_fn = `Iterator::map` call that discard the iterator's values .map_label = after this call to map, the resulting iterator is `impl Iterator`, which means the only information carried by the iterator is the number of items .suggestion = you might have meant to use `Iterator::for_each` -lint_metavariable_still_repeating = variable '{$name}' is still repeating at this depth +lint_metavariable_still_repeating = variable `{$name}` is still repeating at this depth lint_metavariable_wrong_operator = meta-variable repeats with different Kleene operator @@ -632,8 +633,8 @@ lint_pattern_in_bodiless = patterns aren't allowed in functions without bodies lint_pattern_in_foreign = patterns aren't allowed in foreign function declarations .label = pattern not allowed in foreign function -lint_private_extern_crate_reexport = - extern crate `{$ident}` is private, and cannot be re-exported, consider declaring with `pub` +lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported + .suggestion = consider making the `extern crate` item publicly accessible lint_proc_macro_back_compat = using an old version of `{$crate_name}` .note = older versions of the `{$crate_name}` crate will stop compiling in future versions of Rust; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives @@ -847,7 +848,8 @@ lint_unused_coroutine = }{$post} that must be used .note = coroutines are lazy and do nothing unless resumed -lint_unused_crate_dependency = external crate `{$extern_crate}` unused in `{$local_crate}`: remove the dependency or add `use {$extern_crate} as _;` +lint_unused_crate_dependency = extern crate `{$extern_crate}` is unused in crate `{$local_crate}` + .help = remove the dependency or add `use {$extern_crate} as _;` to the crate root lint_unused_def = unused {$pre}`{$def}`{$post} that must be used .suggestion = use `let _ = ...` to ignore the resulting value diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 26f34486a3d..e1676d18b6e 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -340,8 +340,9 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & lints::MacroUseDeprecated.decorate_lint(diag); } BuiltinLintDiag::UnusedMacroUse => lints::UnusedMacroUse.decorate_lint(diag), - BuiltinLintDiag::PrivateExternCrateReexport(ident) => { - lints::PrivateExternCrateReexport { ident }.decorate_lint(diag); + BuiltinLintDiag::PrivateExternCrateReexport { source: ident, extern_crate_span } => { + lints::PrivateExternCrateReexport { ident, sugg: extern_crate_span.shrink_to_lo() } + .decorate_lint(diag); } BuiltinLintDiag::UnusedLabel => lints::UnusedLabel.decorate_lint(diag), BuiltinLintDiag::MacroIsPrivate(ident) => { diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 84d46ef3b65..31ef2f7da0b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2313,6 +2313,7 @@ pub mod unexpected_cfg_value { #[derive(LintDiagnostic)] #[diag(lint_macro_use_deprecated)] +#[help] pub struct MacroUseDeprecated; #[derive(LintDiagnostic)] @@ -2323,6 +2324,8 @@ pub struct UnusedMacroUse; #[diag(lint_private_extern_crate_reexport, code = E0365)] pub struct PrivateExternCrateReexport { pub ident: Ident, + #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")] + pub sugg: Span, } #[derive(LintDiagnostic)] @@ -2416,6 +2419,7 @@ pub struct UnknownMacroVariable { #[derive(LintDiagnostic)] #[diag(lint_unused_crate_dependency)] +#[help] pub struct UnusedCrateDependency { pub extern_crate: Symbol, pub local_crate: Symbol, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 93995fe60a3..d3f2ede8588 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -512,8 +512,9 @@ declare_lint! { /// This will produce: /// /// ```text - /// error: external crate `regex` unused in `lint_example`: remove the dependency or add `use regex as _;` + /// error: extern crate `regex` is unused in crate `lint_example` /// | + /// = help: remove the dependency or add `use regex as _;` to the crate root /// note: the lint level is defined here /// --> src/lib.rs:1:9 /// | @@ -2202,8 +2203,7 @@ declare_lint! { } declare_lint! { - /// The `macro_use_extern_crate` lint detects the use of the - /// [`macro_use` attribute]. + /// The `macro_use_extern_crate` lint detects the use of the [`macro_use` attribute]. /// /// ### Example /// @@ -2221,12 +2221,13 @@ declare_lint! { /// This will produce: /// /// ```text - /// error: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead + /// error: applying the `#[macro_use]` attribute to an `extern crate` item is deprecated /// --> src/main.rs:3:1 /// | /// 3 | #[macro_use] /// | ^^^^^^^^^^^^ /// | + /// = help: remove it and import macros at use sites with a `use` item instead /// note: the lint level is defined here /// --> src/main.rs:1:9 /// | diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index c8a9fb02bf2..b5f21bd8be2 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -707,7 +707,10 @@ pub enum BuiltinLintDiag { }, MacroUseDeprecated, UnusedMacroUse, - PrivateExternCrateReexport(Ident), + PrivateExternCrateReexport { + source: Ident, + extern_crate_span: Span, + }, UnusedLabel, MacroIsPrivate(Ident), UnusedMacroDefinition(Symbol), diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 6bbde26db34..30cbd730d59 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -259,13 +259,18 @@ struct UnresolvedImportError { // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. -fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool { +fn pub_use_of_private_extern_crate_hack( + import: Import<'_>, + binding: NameBinding<'_>, +) -> Option { match (&import.kind, &binding.kind) { - (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) => { - matches!(binding_import.kind, ImportKind::ExternCrate { .. }) - && import.expect_vis().is_public() + (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) + if let ImportKind::ExternCrate { id, .. } = binding_import.kind + && import.expect_vis().is_public() => + { + Some(id) } - _ => false, + _ => None, } } @@ -275,7 +280,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> { let import_vis = import.expect_vis().to_def_id(); let vis = if binding.vis.is_at_least(import_vis, self.tcx) - || pub_use_of_private_extern_crate_hack(import, binding) + || pub_use_of_private_extern_crate_hack(import, binding).is_some() { import_vis } else { @@ -1253,12 +1258,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // All namespaces must be re-exported with extra visibility for an error to occur. if !any_successful_reexport { let (ns, binding) = reexport_error.unwrap(); - if pub_use_of_private_extern_crate_hack(import, binding) { + if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import, binding) { self.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, import_id, import.span, - BuiltinLintDiag::PrivateExternCrateReexport(ident), + BuiltinLintDiag::PrivateExternCrateReexport { + source: ident, + extern_crate_span: self.tcx.source_span(self.local_def_id(extern_crate_id)), + }, ); } else { if ns == TypeNS { diff --git a/tests/ui/extern-flag/no-nounused.rs b/tests/ui/extern-flag/no-nounused.rs index bed8006542c..30b66339876 100644 --- a/tests/ui/extern-flag/no-nounused.rs +++ b/tests/ui/extern-flag/no-nounused.rs @@ -2,5 +2,5 @@ //@ compile-flags: -Zunstable-options -Dunused-crate-dependencies //@ edition:2018 -fn main() { //~ ERROR external crate `somedep` unused in `no_nounused` +fn main() { //~ ERROR extern crate `somedep` is unused in crate `no_nounused` } diff --git a/tests/ui/extern-flag/no-nounused.stderr b/tests/ui/extern-flag/no-nounused.stderr index 171079287f0..2b42e851561 100644 --- a/tests/ui/extern-flag/no-nounused.stderr +++ b/tests/ui/extern-flag/no-nounused.stderr @@ -1,9 +1,10 @@ -error: external crate `somedep` unused in `no_nounused`: remove the dependency or add `use somedep as _;` +error: extern crate `somedep` is unused in crate `no_nounused` --> $DIR/no-nounused.rs:5:1 | LL | fn main() { | ^ | + = help: remove the dependency or add `use somedep as _;` to the crate root = note: requested on the command line with `-D unused-crate-dependencies` error: aborting due to 1 previous error diff --git a/tests/ui/macros/issue-61053-missing-repetition.rs b/tests/ui/macros/issue-61053-missing-repetition.rs index 6b36c730b82..77c94f24171 100644 --- a/tests/ui/macros/issue-61053-missing-repetition.rs +++ b/tests/ui/macros/issue-61053-missing-repetition.rs @@ -3,7 +3,7 @@ macro_rules! foo { () => {}; ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; - //~^ ERROR variable 'j' is still repeating + //~^ ERROR variable `j` is still repeating } macro_rules! bar { @@ -12,12 +12,12 @@ macro_rules! bar { macro_rules! nested { () => {}; ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; - //~^ ERROR variable 'j' is still repeating + //~^ ERROR variable `j` is still repeating } }; ( $( $i:ident = $($j:ident),+ );* ) => { $(macro_rules! $i { - () => { $j }; //~ ERROR variable 'j' is still repeating + () => { $j }; //~ ERROR variable `j` is still repeating })* }; } diff --git a/tests/ui/macros/issue-61053-missing-repetition.stderr b/tests/ui/macros/issue-61053-missing-repetition.stderr index 738f711f04e..ba254401f17 100644 --- a/tests/ui/macros/issue-61053-missing-repetition.stderr +++ b/tests/ui/macros/issue-61053-missing-repetition.stderr @@ -1,4 +1,4 @@ -error: variable 'j' is still repeating at this depth +error: variable `j` is still repeating at this depth --> $DIR/issue-61053-missing-repetition.rs:5:52 | LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![deny(meta_variable_misuse)] | ^^^^^^^^^^^^^^^^^^^^ -error: variable 'j' is still repeating at this depth +error: variable `j` is still repeating at this depth --> $DIR/issue-61053-missing-repetition.rs:14:60 | LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; @@ -20,7 +20,7 @@ LL | ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; | | | expected repetition -error: variable 'j' is still repeating at this depth +error: variable `j` is still repeating at this depth --> $DIR/issue-61053-missing-repetition.rs:20:21 | LL | ( $( $i:ident = $($j:ident),+ );* ) => { diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs index 9fec546ecd6..1eda5f5bb6b 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs @@ -35,7 +35,7 @@ macro_rules! no_curly__no_rhs_dollar__no_round { #[rustfmt::skip] // autoformatters can break a few of the error traces macro_rules! no_curly__rhs_dollar__round { ( $( $i:ident ),* ) => { count($i) }; - //~^ ERROR variable 'i' is still repeating at this depth + //~^ ERROR variable `i` is still repeating at this depth } #[rustfmt::skip] // autoformatters can break a few of the error traces diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr index e9cef5ec6cc..3fa3839bae2 100644 --- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr +++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr @@ -208,7 +208,7 @@ error: `count` can not be placed inside the inner-most repetition LL | ( $i:ident ) => { ${ count($i) } }; | ^^^^^^^^^^^^^ -error: variable 'i' is still repeating at this depth +error: variable `i` is still repeating at this depth --> $DIR/syntax-errors.rs:37:36 | LL | ( $( $i:ident ),* ) => { count($i) }; diff --git a/tests/ui/parser/macro/macro-repeat.stderr b/tests/ui/parser/macro/macro-repeat.stderr index ade2bbf9b0b..ba722ab6cf9 100644 --- a/tests/ui/parser/macro/macro-repeat.stderr +++ b/tests/ui/parser/macro/macro-repeat.stderr @@ -1,10 +1,10 @@ -error: variable 'v' is still repeating at this depth +error: variable `v` is still repeating at this depth --> $DIR/macro-repeat.rs:3:9 | LL | $v | ^^ -error: variable 'v' is still repeating at this depth +error: variable `v` is still repeating at this depth --> $DIR/macro-repeat.rs:3:9 | LL | $v diff --git a/tests/ui/pub/pub-reexport-priv-extern-crate.rs b/tests/ui/pub/pub-reexport-priv-extern-crate.rs index dd5cd420fa5..fb495be4001 100644 --- a/tests/ui/pub/pub-reexport-priv-extern-crate.rs +++ b/tests/ui/pub/pub-reexport-priv-extern-crate.rs @@ -1,5 +1,5 @@ extern crate core; -pub use core as reexported_core; //~ ERROR `core` is private, and cannot be re-exported +pub use core as reexported_core; //~ ERROR `core` is private and cannot be re-exported //~^ WARN this was previously accepted mod foo1 { diff --git a/tests/ui/pub/pub-reexport-priv-extern-crate.stderr b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr index 3fa5b0f9aef..915d07fd08a 100644 --- a/tests/ui/pub/pub-reexport-priv-extern-crate.stderr +++ b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr @@ -22,7 +22,7 @@ note: the crate import `core` is defined here LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ -error[E0365]: extern crate `core` is private, and cannot be re-exported, consider declaring with `pub` +error[E0365]: extern crate `core` is private and cannot be re-exported --> $DIR/pub-reexport-priv-extern-crate.rs:2:9 | LL | pub use core as reexported_core; @@ -31,6 +31,10 @@ LL | pub use core as reexported_core; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 = note: `#[deny(pub_use_of_private_extern_crate)]` on by default +help: consider making the `extern crate` item publicly accessible + | +LL | pub extern crate core; + | +++ error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2018/macro-use-warned-against.rs b/tests/ui/rust-2018/macro-use-warned-against.rs index 1e78acf201d..d6bb5150178 100644 --- a/tests/ui/rust-2018/macro-use-warned-against.rs +++ b/tests/ui/rust-2018/macro-use-warned-against.rs @@ -4,7 +4,7 @@ #![warn(macro_use_extern_crate, unused)] -#[macro_use] //~ WARN should be replaced at use sites with a `use` item +#[macro_use] //~ WARN applying the `#[macro_use]` attribute to an `extern crate` item is deprecated extern crate macro_use_warned_against; #[macro_use] //~ WARN unused `#[macro_use]` extern crate macro_use_warned_against2; diff --git a/tests/ui/rust-2018/macro-use-warned-against.stderr b/tests/ui/rust-2018/macro-use-warned-against.stderr index 6b46f002e32..3ac1f127051 100644 --- a/tests/ui/rust-2018/macro-use-warned-against.stderr +++ b/tests/ui/rust-2018/macro-use-warned-against.stderr @@ -1,9 +1,10 @@ -warning: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead +warning: applying the `#[macro_use]` attribute to an `extern crate` item is deprecated --> $DIR/macro-use-warned-against.rs:7:1 | LL | #[macro_use] | ^^^^^^^^^^^^ | + = help: remove it and import macros at use sites with a `use` item instead note: the lint level is defined here --> $DIR/macro-use-warned-against.rs:5:9 | diff --git a/tests/ui/unused-crate-deps/deny-attr.rs b/tests/ui/unused-crate-deps/deny-attr.rs index 3b2e8b5677e..71f478b6b7d 100644 --- a/tests/ui/unused-crate-deps/deny-attr.rs +++ b/tests/ui/unused-crate-deps/deny-attr.rs @@ -4,6 +4,6 @@ //@ aux-crate:bar=bar.rs #![deny(unused_crate_dependencies)] -//~^ ERROR external crate `bar` unused in +//~^ ERROR extern crate `bar` is unused in fn main() {} diff --git a/tests/ui/unused-crate-deps/deny-attr.stderr b/tests/ui/unused-crate-deps/deny-attr.stderr index 89e87c9d5ac..7540d9cdc16 100644 --- a/tests/ui/unused-crate-deps/deny-attr.stderr +++ b/tests/ui/unused-crate-deps/deny-attr.stderr @@ -1,9 +1,10 @@ -error: external crate `bar` unused in `deny_attr`: remove the dependency or add `use bar as _;` +error: extern crate `bar` is unused in crate `deny_attr` --> $DIR/deny-attr.rs:6:1 | LL | #![deny(unused_crate_dependencies)] | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root note: the lint level is defined here --> $DIR/deny-attr.rs:6:9 | diff --git a/tests/ui/unused-crate-deps/deny-cmdline.rs b/tests/ui/unused-crate-deps/deny-cmdline.rs index d32e8e205af..890c01e0016 100644 --- a/tests/ui/unused-crate-deps/deny-cmdline.rs +++ b/tests/ui/unused-crate-deps/deny-cmdline.rs @@ -5,4 +5,4 @@ //@ aux-crate:bar=bar.rs fn main() {} -//~^ ERROR external crate `bar` unused in +//~^ ERROR extern crate `bar` is unused in diff --git a/tests/ui/unused-crate-deps/deny-cmdline.stderr b/tests/ui/unused-crate-deps/deny-cmdline.stderr index fc526878ef0..b48d1ec1ba9 100644 --- a/tests/ui/unused-crate-deps/deny-cmdline.stderr +++ b/tests/ui/unused-crate-deps/deny-cmdline.stderr @@ -1,9 +1,10 @@ -error: external crate `bar` unused in `deny_cmdline`: remove the dependency or add `use bar as _;` +error: extern crate `bar` is unused in crate `deny_cmdline` --> $DIR/deny-cmdline.rs:7:1 | LL | fn main() {} | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root = note: requested on the command line with `-D unused-crate-dependencies` error: aborting due to 1 previous error diff --git a/tests/ui/unused-crate-deps/libfib.rs b/tests/ui/unused-crate-deps/libfib.rs index 8a5ec758e56..d7729c9ebe7 100644 --- a/tests/ui/unused-crate-deps/libfib.rs +++ b/tests/ui/unused-crate-deps/libfib.rs @@ -5,7 +5,7 @@ //@ compile-flags:--crate-type lib -Wunused-crate-dependencies pub fn fib(n: u32) -> Vec { -//~^ WARNING external crate `bar` unused in +//~^ WARNING extern crate `bar` is unused in let mut prev = 0; let mut cur = 1; let mut v = vec![]; diff --git a/tests/ui/unused-crate-deps/libfib.stderr b/tests/ui/unused-crate-deps/libfib.stderr index 15833126bd6..da6893f5034 100644 --- a/tests/ui/unused-crate-deps/libfib.stderr +++ b/tests/ui/unused-crate-deps/libfib.stderr @@ -1,9 +1,10 @@ -warning: external crate `bar` unused in `libfib`: remove the dependency or add `use bar as _;` +warning: extern crate `bar` is unused in crate `libfib` --> $DIR/libfib.rs:7:1 | LL | pub fn fib(n: u32) -> Vec { | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root = note: requested on the command line with `-W unused-crate-dependencies` warning: 1 warning emitted diff --git a/tests/ui/unused-crate-deps/unused-aliases.rs b/tests/ui/unused-crate-deps/unused-aliases.rs index f86f6bbf356..2db50cec971 100644 --- a/tests/ui/unused-crate-deps/unused-aliases.rs +++ b/tests/ui/unused-crate-deps/unused-aliases.rs @@ -6,7 +6,7 @@ //@ aux-crate:barbar=bar.rs #![warn(unused_crate_dependencies)] -//~^ WARNING external crate `barbar` unused in +//~^ WARNING extern crate `barbar` is unused in use bar as _; diff --git a/tests/ui/unused-crate-deps/unused-aliases.stderr b/tests/ui/unused-crate-deps/unused-aliases.stderr index c8c6c4507b0..d4093b102d5 100644 --- a/tests/ui/unused-crate-deps/unused-aliases.stderr +++ b/tests/ui/unused-crate-deps/unused-aliases.stderr @@ -1,9 +1,10 @@ -warning: external crate `barbar` unused in `unused_aliases`: remove the dependency or add `use barbar as _;` +warning: extern crate `barbar` is unused in crate `unused_aliases` --> $DIR/unused-aliases.rs:8:1 | LL | #![warn(unused_crate_dependencies)] | ^ | + = help: remove the dependency or add `use barbar as _;` to the crate root note: the lint level is defined here --> $DIR/unused-aliases.rs:8:9 | diff --git a/tests/ui/unused-crate-deps/warn-attr.rs b/tests/ui/unused-crate-deps/warn-attr.rs index b558c0678d6..c40ed001732 100644 --- a/tests/ui/unused-crate-deps/warn-attr.rs +++ b/tests/ui/unused-crate-deps/warn-attr.rs @@ -5,6 +5,6 @@ //@ aux-crate:bar=bar.rs #![warn(unused_crate_dependencies)] -//~^ WARNING external crate `bar` unused in +//~^ WARNING extern crate `bar` is unused in fn main() {} diff --git a/tests/ui/unused-crate-deps/warn-attr.stderr b/tests/ui/unused-crate-deps/warn-attr.stderr index 0d38315704b..2c72961093c 100644 --- a/tests/ui/unused-crate-deps/warn-attr.stderr +++ b/tests/ui/unused-crate-deps/warn-attr.stderr @@ -1,9 +1,10 @@ -warning: external crate `bar` unused in `warn_attr`: remove the dependency or add `use bar as _;` +warning: extern crate `bar` is unused in crate `warn_attr` --> $DIR/warn-attr.rs:7:1 | LL | #![warn(unused_crate_dependencies)] | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root note: the lint level is defined here --> $DIR/warn-attr.rs:7:9 | diff --git a/tests/ui/unused-crate-deps/warn-cmdline-static.rs b/tests/ui/unused-crate-deps/warn-cmdline-static.rs index ccb404e3033..eb51543ad1a 100644 --- a/tests/ui/unused-crate-deps/warn-cmdline-static.rs +++ b/tests/ui/unused-crate-deps/warn-cmdline-static.rs @@ -7,4 +7,4 @@ //@ no-prefer-dynamic fn main() {} -//~^ WARNING external crate `bar` unused in +//~^ WARNING extern crate `bar` is unused in diff --git a/tests/ui/unused-crate-deps/warn-cmdline-static.stderr b/tests/ui/unused-crate-deps/warn-cmdline-static.stderr index 65956461d64..79a3ade8719 100644 --- a/tests/ui/unused-crate-deps/warn-cmdline-static.stderr +++ b/tests/ui/unused-crate-deps/warn-cmdline-static.stderr @@ -1,9 +1,10 @@ -warning: external crate `bar` unused in `warn_cmdline_static`: remove the dependency or add `use bar as _;` +warning: extern crate `bar` is unused in crate `warn_cmdline_static` --> $DIR/warn-cmdline-static.rs:9:1 | LL | fn main() {} | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root = note: requested on the command line with `-W unused-crate-dependencies` warning: 1 warning emitted diff --git a/tests/ui/unused-crate-deps/warn-cmdline.rs b/tests/ui/unused-crate-deps/warn-cmdline.rs index 8d390e02ca5..cdeff5e5f60 100644 --- a/tests/ui/unused-crate-deps/warn-cmdline.rs +++ b/tests/ui/unused-crate-deps/warn-cmdline.rs @@ -6,4 +6,4 @@ //@ aux-crate:bar=bar.rs fn main() {} -//~^ WARNING external crate `bar` unused in +//~^ WARNING extern crate `bar` is unused in diff --git a/tests/ui/unused-crate-deps/warn-cmdline.stderr b/tests/ui/unused-crate-deps/warn-cmdline.stderr index ea675ba9a1e..f5df83ca884 100644 --- a/tests/ui/unused-crate-deps/warn-cmdline.stderr +++ b/tests/ui/unused-crate-deps/warn-cmdline.stderr @@ -1,9 +1,10 @@ -warning: external crate `bar` unused in `warn_cmdline`: remove the dependency or add `use bar as _;` +warning: extern crate `bar` is unused in crate `warn_cmdline` --> $DIR/warn-cmdline.rs:8:1 | LL | fn main() {} | ^ | + = help: remove the dependency or add `use bar as _;` to the crate root = note: requested on the command line with `-W unused-crate-dependencies` warning: 1 warning emitted From c59a2b2746c7c22bd684cbd5a5da0affc7d11a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 4 Jun 2024 16:47:23 +0200 Subject: [PATCH 024/153] Cleanup: HIR ty lowering: Consolidate assoc item access checking --- compiler/rustc_hir_analysis/messages.ftl | 4 + compiler/rustc_hir_analysis/src/errors.rs | 12 +++ .../src/hir_ty_lowering/bounds.rs | 50 ++++------- .../src/hir_ty_lowering/mod.rs | 89 ++++++++++++------- .../assoc-inherent-private.stderr | 4 +- tests/ui/traits/item-privacy.stderr | 7 +- 6 files changed, 97 insertions(+), 69 deletions(-) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 67959d9dfed..cb9a642ca39 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -8,6 +8,10 @@ hir_analysis_assoc_item_constraints_not_allowed_here = associated item constraints are not allowed here .label = associated item constraint not allowed here +hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private + .label = private {$kind} + .defined_here_label = the {$kind} is defined here + hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}` hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named -> diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 8a9d4cd4ac7..8c65bed4de2 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -55,6 +55,18 @@ pub struct AssocKindMismatchWrapInBracesSugg { pub hi: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_assoc_item_is_private, code = E0624)] +pub struct AssocItemIsPrivate { + #[primary_span] + #[label] + pub span: Span, + pub kind: &'static str, + pub name: Ident, + #[label(hir_analysis_defined_here_label)] + pub defined_here_label: Span, +} + #[derive(Diagnostic)] #[diag(hir_analysis_assoc_item_not_found, code = E0220)] pub struct AssocItemNotFound<'a> { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index b6a1799c03f..999da63e176 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -292,30 +292,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )? }; - let (assoc_ident, def_scope) = - tcx.adjust_ident_and_get_scope(constraint.ident, candidate.def_id(), hir_ref_id); - - // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()` - // instead of calling `filter_by_name_and_kind` which would needlessly normalize the - // `assoc_ident` again and again. - let assoc_item = tcx - .associated_items(candidate.def_id()) - .filter_by_name_unhygienic(assoc_ident.name) - .find(|i| i.kind == assoc_kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident) - .expect("missing associated item"); - - if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) { - let reported = tcx - .dcx() - .struct_span_err( - constraint.span, - format!("{} `{}` is private", assoc_item.kind, constraint.ident), - ) - .with_span_label(constraint.span, format!("private {}", assoc_item.kind)) - .emit(); - self.set_tainted_by_errors(reported); - } - tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), constraint.span, None); + let assoc_item = self + .probe_assoc_item( + constraint.ident, + assoc_kind, + hir_ref_id, + constraint.span, + candidate.def_id(), + ) + .expect("failed to find associated item"); duplicates .entry(assoc_item.def_id) @@ -406,10 +391,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Create the generic arguments for the associated type or constant by joining the // parent arguments (the arguments of the trait) and the own arguments (the ones of // the associated item itself) and construct an alias type using them. - let alias_ty = candidate.map_bound(|trait_ref| { - let ident = Ident::new(assoc_item.name, constraint.ident.span); + let alias_term = candidate.map_bound(|trait_ref| { let item_segment = hir::PathSegment { - ident, + ident: constraint.ident, hir_id: constraint.hir_id, res: Res::Err, args: Some(constraint.gen_args), @@ -428,15 +412,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. - if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } = - constraint.kind - { - let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args)); - let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id); + if let Some(anon_const) = constraint.ct() { + let ty = alias_term + .map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args)); + let ty = + check_assoc_const_binding_type(tcx, constraint.ident, ty, constraint.hir_id); tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty)); } - alias_ty + alias_term }; match constraint.kind { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 54b7f7f36ed..34bf8c027b7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1166,8 +1166,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let trait_did = bound.def_id(); - let assoc_ty_did = self.probe_assoc_ty(assoc_ident, hir_ref_id, span, trait_did).unwrap(); - let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound); + let assoc_ty = self + .probe_assoc_item(assoc_ident, ty::AssocKind::Type, hir_ref_id, span, trait_did) + .expect("failed to find associated type"); + let ty = self.lower_assoc_ty(span, assoc_ty.def_id, assoc_segment, bound); if let Some(variant_def_id) = variant_resolution { tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { @@ -1183,7 +1185,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(DefKind::AssocTy, assoc_ty_did, " also"); + could_refer_to(DefKind::AssocTy, assoc_ty.def_id, " also"); lint.span_suggestion( span, @@ -1193,7 +1195,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); }); } - Ok((ty, DefKind::AssocTy, assoc_ty_did)) + Ok((ty, DefKind::AssocTy, assoc_ty.def_id)) } fn probe_inherent_assoc_ty( @@ -1220,7 +1222,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let candidates: Vec<_> = tcx .inherent_impls(adt_did)? .iter() - .filter_map(|&impl_| Some((impl_, self.probe_assoc_ty_unchecked(name, block, impl_)?))) + .filter_map(|&impl_| { + let (item, scope) = + self.probe_assoc_item_unchecked(name, ty::AssocKind::Type, block, impl_)?; + Some((impl_, (item.def_id, scope))) + }) .collect(); if candidates.is_empty() { @@ -1264,7 +1270,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }, )?; - self.check_assoc_ty(assoc_item, name, def_scope, block, span); + self.check_assoc_item(assoc_item, name, def_scope, block, span); // FIXME(fmease): Currently creating throwaway `parent_args` to please // `lower_generic_args_of_assoc_item`. Modify the latter instead (or sth. similar) to @@ -1351,50 +1357,69 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - fn probe_assoc_ty(&self, name: Ident, block: HirId, span: Span, scope: DefId) -> Option { - let (item, def_scope) = self.probe_assoc_ty_unchecked(name, block, scope)?; - self.check_assoc_ty(item, name, def_scope, block, span); + /// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1]. + /// + /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability. + fn probe_assoc_item( + &self, + ident: Ident, + kind: ty::AssocKind, + block: HirId, + span: Span, + scope: DefId, + ) -> Option { + let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?; + self.check_assoc_item(item.def_id, ident, scope, block, span); Some(item) } - fn probe_assoc_ty_unchecked( + /// Given name and kind search for the assoc item in the provided scope + /// *without* checking if it's accessible[^1]. + /// + /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability. + fn probe_assoc_item_unchecked( &self, - name: Ident, + ident: Ident, + kind: ty::AssocKind, block: HirId, scope: DefId, - ) -> Option<(DefId, DefId)> { + ) -> Option<(ty::AssocItem, /*scope*/ DefId)> { let tcx = self.tcx(); - let (ident, def_scope) = tcx.adjust_ident_and_get_scope(name, scope, block); + let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block); // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()` // instead of calling `filter_by_name_and_kind` which would needlessly normalize the // `ident` again and again. - let item = tcx.associated_items(scope).in_definition_order().find(|i| { - i.kind.namespace() == Namespace::TypeNS - && i.ident(tcx).normalize_to_macros_2_0() == ident - })?; + let item = tcx + .associated_items(scope) + .filter_by_name_unhygienic(ident.name) + .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?; - Some((item.def_id, def_scope)) + Some((*item, def_scope)) } - fn check_assoc_ty(&self, item: DefId, name: Ident, def_scope: DefId, block: HirId, span: Span) { + /// Check if the given assoc item is accessible in the provided scope wrt. visibility and stability. + fn check_assoc_item( + &self, + item_def_id: DefId, + ident: Ident, + scope: DefId, + block: HirId, + span: Span, + ) { let tcx = self.tcx(); - let kind = DefKind::AssocTy; - if !tcx.visibility(item).is_accessible_from(def_scope, tcx) { - let kind = tcx.def_kind_descr(kind, item); - let msg = format!("{kind} `{name}` is private"); - let def_span = tcx.def_span(item); - let reported = tcx - .dcx() - .struct_span_err(span, msg) - .with_code(E0624) - .with_span_label(span, format!("private {kind}")) - .with_span_label(def_span, format!("{kind} defined here")) - .emit(); + if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) { + let reported = tcx.dcx().emit_err(crate::errors::AssocItemIsPrivate { + span, + kind: tcx.def_descr(item_def_id), + name: ident, + defined_here_label: tcx.def_span(item_def_id), + }); self.set_tainted_by_errors(reported); } - tcx.check_stability(item, Some(block), span, None); + + tcx.check_stability(item_def_id, Some(block), span, None); } fn probe_traits_that_match_assoc_ty( diff --git a/tests/ui/associated-inherent-types/assoc-inherent-private.stderr b/tests/ui/associated-inherent-types/assoc-inherent-private.stderr index d67b45dae3f..e3802a9f5bc 100644 --- a/tests/ui/associated-inherent-types/assoc-inherent-private.stderr +++ b/tests/ui/associated-inherent-types/assoc-inherent-private.stderr @@ -2,7 +2,7 @@ error[E0624]: associated type `P` is private --> $DIR/assoc-inherent-private.rs:10:10 | LL | type P = (); - | ------ associated type defined here + | ------ the associated type is defined here ... LL | type U = m::T::P; | ^^^^^^^ private associated type @@ -11,7 +11,7 @@ error[E0624]: associated type `P` is private --> $DIR/assoc-inherent-private.rs:21:10 | LL | pub(super) type P = bool; - | ----------------- associated type defined here + | ----------------- the associated type is defined here ... LL | type V = n::n::T::P; | ^^^^^^^^^^ private associated type diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index d08bb4745bf..4b5339b64ad 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -195,14 +195,17 @@ error[E0624]: associated type `A` is private --> $DIR/item-privacy.rs:119:12 | LL | type A = u8; - | ------ associated type defined here + | ------ the associated type is defined here ... LL | let _: T::A; | ^^^^ private associated type -error: associated type `A` is private +error[E0624]: associated type `A` is private --> $DIR/item-privacy.rs:128:9 | +LL | type A = u8; + | ------ the associated type is defined here +... LL | A = u8, | ^^^^^^ private associated type From f7d49fdf4f16fe691561663468efc4fbcbdb6ba4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 May 2024 16:26:37 +1000 Subject: [PATCH 025/153] Print `token::Interpolated` with token stream pretty printing. Instead of using AST pretty printing. This is a step towards removing `token::Interpolated`, which will eventually (in #124141) be replaced with a token stream within invisible delimiters. This changes (improves) the output of the `stringify!` macro in some cases. This is allowed. As the `stringify!` docs say: "Note that the expanded results of the input tokens may change in the future. You should be careful if you rely on the output." Test changes: - tests/ui/macros/stringify.rs: this used to test both token stream pretty printing and AST pretty printing via different ways of invoking of `stringify!` (i.e. `$expr` vs `$tt`). But those two different invocations now give the same result, which is a nice consistency improvement. This removes the need for all the `c2*` macros. The AST pretty printer now has more thorough testing thanks to #125236. - tests/ui/proc-macro/*: minor improvements where small differences between `INPUT (DISPLAY)` output and `DEEP-RE-COLLECTED (DISPLAY)` output disappear. --- compiler/rustc_ast_pretty/src/pprust/state.rs | 25 +- tests/ui/macros/stringify.rs | 259 ++++-------------- tests/ui/macros/trace_faulty_macros.rs | 2 +- tests/ui/macros/trace_faulty_macros.stderr | 12 +- .../capture-macro-rules-invoke.stdout | 4 +- .../expr-stmt-nonterminal-tokens.stdout | 15 +- .../issue-78675-captured-inner-attrs.stdout | 4 +- 7 files changed, 75 insertions(+), 246 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 4c29ca0ca46..0576640fef8 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -870,18 +870,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } fn nonterminal_to_string(&self, nt: &Nonterminal) -> String { - match nt { - token::NtExpr(e) => self.expr_to_string(e), - token::NtMeta(e) => self.attr_item_to_string(e), - token::NtTy(e) => self.ty_to_string(e), - token::NtPath(e) => self.path_to_string(e), - token::NtItem(e) => self.item_to_string(e), - token::NtBlock(e) => self.block_to_string(e), - token::NtStmt(e) => self.stmt_to_string(e), - token::NtPat(e) => self.pat_to_string(e), - token::NtLiteral(e) => self.expr_to_string(e), - token::NtVis(e) => self.vis_to_string(e), - } + // We extract the token stream from the AST fragment and pretty print + // it, rather than using AST pretty printing, because `Nonterminal` is + // slated for removal in #124141. (This method will also then be + // removed.) + self.tts_to_string(&TokenStream::from_nonterminal_ast(nt)) } /// Print the token kind precisely, without converting `$crate` into its respective crate name. @@ -1015,6 +1008,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere Self::to_string(|s| s.print_attr_item(ai, ai.path.span)) } + fn tts_to_string(&self, tokens: &TokenStream) -> String { + Self::to_string(|s| s.print_tts(tokens, false)) + } + fn to_string(f: impl FnOnce(&mut State<'_>)) -> String { let mut printer = State::new(); f(&mut printer); @@ -2060,10 +2057,6 @@ impl<'a> State<'a> { }) } - pub(crate) fn tts_to_string(&self, tokens: &TokenStream) -> String { - Self::to_string(|s| s.print_tts(tokens, false)) - } - pub(crate) fn path_segment_to_string(&self, p: &ast::PathSegment) -> String { Self::to_string(|s| s.print_path_segment(p, false)) } diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 6b215ba525d..f06c1f99069 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -37,25 +37,22 @@ macro_rules! vis { ($vis:vis) => { stringify!($vis) }; } // the same result (which is preferable.) macro_rules! c1 { ($frag:ident, [$($tt:tt)*], $s:literal) => { + // Prior to #125174: + // - the first of these two lines created a `TokenKind::Interpolated` + // that was printed by the AST pretty printer; + // - the second of these two lines created a token stream that was + // printed by the TokenStream pretty printer. + // + // Now they are both printed by the TokenStream pretty printer. But it + // doesn't hurt to keep both assertions to ensure this remains true. + // + // (This also explains the name `c1`. There used to be a `c2` macro for + // cases where the two pretty printers produced different output.) assert_eq!($frag!($($tt)*), $s); assert_eq!(stringify!($($tt)*), $s); }; } -// Use this when AST pretty-printing and TokenStream pretty-printing give -// different results. -// -// `c1` and `c2` could be in a single macro, but having them separate makes it -// easy to find the cases where the two pretty-printing approaches give -// different results. -macro_rules! c2 { - ($frag:ident, [$($tt:tt)*], $s1:literal, $s2:literal $(,)?) => { - assert_ne!($s1, $s2, "should use `c1!` instead"); - assert_eq!($frag!($($tt)*), $s1); - assert_eq!(stringify!($($tt)*), $s2); - }; -} - #[test] fn test_block() { c1!(block, [ {} ], "{}"); @@ -76,7 +73,7 @@ fn test_expr() { // ExprKind::Array c1!(expr, [ [] ], "[]"); c1!(expr, [ [true] ], "[true]"); - c2!(expr, [ [true,] ], "[true]", "[true,]"); + c1!(expr, [ [true,] ], "[true,]"); c1!(expr, [ [true, true] ], "[true, true]"); // ExprKind::ConstBlock @@ -85,11 +82,11 @@ fn test_expr() { // ExprKind::Call c1!(expr, [ f() ], "f()"); c1!(expr, [ f::() ], "f::()"); - c2!(expr, [ f :: < u8>( ) ], "f::()", "f :: < u8>()"); + c1!(expr, [ f :: < u8>( ) ], "f :: < u8>()"); c1!(expr, [ f::<1>() ], "f::<1>()"); c1!(expr, [ f::<'a, u8, 1>() ], "f::<'a, u8, 1>()"); c1!(expr, [ f(true) ], "f(true)"); - c2!(expr, [ f(true,) ], "f(true)", "f(true,)"); + c1!(expr, [ f(true,) ], "f(true,)"); c1!(expr, [ ()() ], "()()"); // ExprKind::MethodCall @@ -101,7 +98,7 @@ fn test_expr() { c1!(expr, [ () ], "()"); c1!(expr, [ (true,) ], "(true,)"); c1!(expr, [ (true, false) ], "(true, false)"); - c2!(expr, [ (true, false,) ], "(true, false)", "(true, false,)"); + c1!(expr, [ (true, false,) ], "(true, false,)"); // ExprKind::Binary c1!(expr, [ true || false ], "true || false"); @@ -131,16 +128,6 @@ fn test_expr() { c1!(expr, [ if let Some(a) = b { c } else { d } ], "if let Some(a) = b { c } else { d }"); c1!(expr, [ if let _ = true && false {} ], "if let _ = true && false {}"); c1!(expr, [ if let _ = (true && false) {} ], "if let _ = (true && false) {}"); - macro_rules! c2_if_let { - ($expr:expr, $expr_expected:expr, $tokens_expected:expr $(,)?) => { - c2!(expr, [ if let _ = $expr {} ], $expr_expected, $tokens_expected); - }; - } - c2_if_let!( - true && false, - "if let _ = (true && false) {}", - "if let _ = true && false {}", - ); c1!(expr, [ match () { _ if let _ = Struct {} => {} } ], "match () { _ if let _ = Struct {} => {} }" @@ -203,31 +190,6 @@ fn test_expr() { } ], "match self { Ok => 1, Err => 0, }" ); - macro_rules! c2_match_arm { - ([ $expr:expr ], $expr_expected:expr, $tokens_expected:expr $(,)?) => { - c2!(expr, [ match () { _ => $expr } ], $expr_expected, $tokens_expected); - }; - } - c2_match_arm!( - [ { 1 } - 1 ], - "match () { _ => ({ 1 }) - 1, }", - "match () { _ => { 1 } - 1 }", - ); - c2_match_arm!( - [ m!() - 1 ], - "match () { _ => m!() - 1, }", - "match () { _ => m!() - 1 }", - ); - c2_match_arm!( - [ m![] - 1 ], - "match () { _ => m![] - 1, }", - "match () { _ => m![] - 1 }", - ); - c2_match_arm!( - [ m! {} - 1 ], - "match () { _ => m! {} - 1, }", - "match () { _ => m! {} - 1 }", - ); // ExprKind::Closure c1!(expr, [ || {} ], "|| {}"); @@ -242,22 +204,19 @@ fn test_expr() { c1!(expr, [ static async || self ], "static async || self"); c1!(expr, [ static async move || self ], "static async move || self"); c1!(expr, [ || -> u8 { self } ], "|| -> u8 { self }"); - c2!(expr, [ 1 + || {} ], "1 + (|| {})", "1 + || {}"); // AST?? + c1!(expr, [ 1 + || {} ], "1 + || {}"); // ExprKind::Block c1!(expr, [ {} ], "{}"); c1!(expr, [ unsafe {} ], "unsafe {}"); c1!(expr, [ 'a: {} ], "'a: {}"); c1!(expr, [ #[attr] {} ], "#[attr] {}"); - c2!(expr, + c1!(expr, [ { #![attr] } ], - "{\n\ - \x20 #![attr]\n\ - }", "{ #![attr] }" ); @@ -289,7 +248,7 @@ fn test_expr() { c1!(expr, [ ..hi ], "..hi"); c1!(expr, [ lo.. ], "lo.."); c1!(expr, [ lo..hi ], "lo..hi"); - c2!(expr, [ lo .. hi ], "lo..hi", "lo .. hi"); + c1!(expr, [ lo .. hi ], "lo .. hi"); c1!(expr, [ ..=hi ], "..=hi"); c1!(expr, [ lo..=hi ], "lo..=hi"); c1!(expr, [ -2..=-1 ], "-2..=-1"); @@ -382,11 +341,7 @@ fn test_item() { c1!(item, [ pub extern crate self as std; ], "pub extern crate self as std;"); // ItemKind::Use - c2!(item, - [ pub use crate::{a, b::c}; ], - "pub use crate::{a, b::c};", - "pub use crate::{ a, b::c };" // FIXME - ); + c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{ a, b::c };"); // FIXME c1!(item, [ pub use A::*; ], "pub use A::*;"); // ItemKind::Static @@ -418,24 +373,19 @@ fn test_item() { // ItemKind::ForeignMod c1!(item, [ extern "C" {} ], "extern \"C\" {}"); - c2!(item, - [ pub extern "C" {} ], - "extern \"C\" {}", // ?? - "pub extern \"C\" {}" - ); + c1!(item, [ pub extern "C" {} ], "pub extern \"C\" {}"); c1!(item, [ unsafe extern "C++" {} ], "unsafe extern \"C++\" {}"); // ItemKind::GlobalAsm: untestable because this test works pre-expansion. // ItemKind::TyAlias - c2!(item, + c1!(item, [ pub default type Type<'a>: Bound where Self: 'a, = T; ], - "pub default type Type<'a>: Bound where Self: 'a = T;", "pub default type Type<'a>: Bound where Self: 'a, = T;" ); @@ -451,7 +401,7 @@ fn test_item() { ], "enum Empty { Unit, Tuple(), Struct {}, }" ); - c2!(item, + c1!(item, [ enum Enum where @@ -462,13 +412,6 @@ fn test_item() { Struct { t: T }, } ], - "enum Enum where T: 'a {\n\ - \x20 Unit,\n\ - \x20 Tuple(T),\n\ - \x20 Struct {\n\ - \x20 t: T,\n\ - \x20 },\n\ - }", "enum Enum where T: 'a, { Unit, Tuple(T), Struct { t: T }, }" ); @@ -477,7 +420,7 @@ fn test_item() { c1!(item, [ struct Tuple(); ], "struct Tuple();"); c1!(item, [ struct Tuple(T); ], "struct Tuple(T);"); c1!(item, [ struct Struct {} ], "struct Struct {}"); - c2!(item, + c1!(item, [ struct Struct where @@ -486,29 +429,23 @@ fn test_item() { t: T, } ], - "struct Struct where T: 'a {\n\ - \x20 t: T,\n\ - }", "struct Struct where T: 'a, { t: T, }" ); // ItemKind::Union c1!(item, [ pub union Union {} ], "pub union Union {}"); - c2!(item, + c1!(item, [ union Union where T: 'a { t: T, } ], - "union Union where T: 'a {\n\ - \x20 t: T,\n\ - }", "union Union where T: 'a { t: T, }" ); // ItemKind::Trait c1!(item, [ pub unsafe auto trait Send {} ], "pub unsafe auto trait Send {}"); - c2!(item, + c1!(item, [ trait Trait<'a>: Sized where @@ -516,7 +453,6 @@ fn test_item() { { } ], - "trait Trait<'a>: Sized where Self: 'a {}", "trait Trait<'a>: Sized where Self: 'a, {}" ); @@ -547,11 +483,7 @@ fn test_item() { ], "macro_rules! stringify { () => {}; }" ); - c2!(item, - [ pub macro stringify() {} ], - "pub macro stringify { () => {} }", // ?? - "pub macro stringify() {}" - ); + c1!(item, [ pub macro stringify() {} ], "pub macro stringify() {}"); } #[test] @@ -577,7 +509,7 @@ fn test_pat() { // PatKind::Struct c1!(pat, [ Struct {} ], "Struct {}"); c1!(pat, [ Struct:: {} ], "Struct:: {}"); - c2!(pat, [ Struct ::< u8 > {} ], "Struct:: {}", "Struct ::< u8 > {}"); + c1!(pat, [ Struct ::< u8 > {} ], "Struct ::< u8 > {}"); c1!(pat, [ Struct::<'static> {} ], "Struct::<'static> {}"); c1!(pat, [ Struct { x } ], "Struct { x }"); c1!(pat, [ Struct { x: _x } ], "Struct { x: _x }"); @@ -597,8 +529,8 @@ fn test_pat() { // PatKind::Or c1!(pat, [ true | false ], "true | false"); - c2!(pat, [ | true ], "true", "| true"); - c2!(pat, [ |true| false ], "true | false", "|true| false"); + c1!(pat, [ | true ], "| true"); + c1!(pat, [ |true| false ], "|true| false"); // PatKind::Path c1!(pat, [ crate::Path ], "crate::Path"); @@ -631,7 +563,7 @@ fn test_pat() { // PatKind::Slice c1!(pat, [ [] ], "[]"); c1!(pat, [ [true] ], "[true]"); - c2!(pat, [ [true,] ], "[true]", "[true,]"); + c1!(pat, [ [true,] ], "[true,]"); c1!(pat, [ [true, false] ], "[true, false]"); // PatKind::Rest @@ -658,7 +590,7 @@ fn test_path() { c1!(path, [ crate::thing ], "crate::thing"); c1!(path, [ Self::thing ], "Self::thing"); c1!(path, [ Self<'static> ], "Self<'static>"); - c2!(path, [ Self::<'static> ], "Self<'static>", "Self::<'static>"); + c1!(path, [ Self::<'static> ], "Self::<'static>"); c1!(path, [ Self() ], "Self()"); c1!(path, [ Self() -> () ], "Self() -> ()"); } @@ -666,40 +598,12 @@ fn test_path() { #[test] fn test_stmt() { // StmtKind::Local - c2!(stmt, [ let _ ], "let _;", "let _"); - c2!(stmt, [ let x = true ], "let x = true;", "let x = true"); - c2!(stmt, [ let x: bool = true ], "let x: bool = true;", "let x: bool = true"); - c2!(stmt, [ let (a, b) = (1, 2) ], "let (a, b) = (1, 2);", "let (a, b) = (1, 2)"); - c2!(stmt, - [ let (a, b): (u32, u32) = (1, 2) ], - "let (a, b): (u32, u32) = (1, 2);", - "let (a, b): (u32, u32) = (1, 2)" - ); - c2!(stmt, - [ let _ = f() else { return; } ], - "let _ = f() else { return; };", - "let _ = f() else { return; }", - ); - macro_rules! c2_let_expr_minus_one { - ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { - c2!(stmt, [ let _ = $expr - 1 ], $stmt_expected, $tokens_expected); - }; - } - c2_let_expr_minus_one!( - [ match void {} ], - "let _ = match void {} - 1;", - "let _ = match void {} - 1", - ); - macro_rules! c2_let_expr_else_return { - ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { - c2!(stmt, [ let _ = $expr else { return; } ], $stmt_expected, $tokens_expected); - }; - } - c2_let_expr_else_return!( - [ f() ], - "let _ = f() else { return; };", - "let _ = f() else { return; }", - ); + c1!(stmt, [ let _ ], "let _"); + c1!(stmt, [ let x = true ], "let x = true"); + c1!(stmt, [ let x: bool = true ], "let x: bool = true"); + c1!(stmt, [ let (a, b) = (1, 2) ], "let (a, b) = (1, 2)"); + c1!(stmt, [ let (a, b): (u32, u32) = (1, 2) ], "let (a, b): (u32, u32) = (1, 2)"); + c1!(stmt, [ let _ = f() else { return; } ], "let _ = f() else { return; }"); // StmtKind::Item c1!(stmt, [ struct S; ], "struct S;"); @@ -709,62 +613,7 @@ fn test_stmt() { c1!(stmt, [ loop {} ], "loop {}"); // StmtKind::Semi - c2!(stmt, [ 1 + 1 ], "1 + 1;", "1 + 1"); - macro_rules! c2_expr_as_stmt { - // Parse as expr, then reparse as stmt. - // - // The c2_minus_one macro below can't directly call `c2!(stmt, ...)` - // because `$expr - 1` cannot be parsed directly as a stmt. A statement - // boundary occurs after the `match void {}`, after which the `-` token - // hits "no rules expected this token in macro call". - // - // The unwanted statement boundary is exactly why the pretty-printer is - // injecting parentheses around the subexpression, which is the behavior - // we are interested in testing. - ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { - c2!(stmt, [ $expr ], $stmt_expected, $tokens_expected); - }; - } - macro_rules! c2_minus_one { - ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { - c2_expr_as_stmt!([ $expr - 1 ], $stmt_expected, $tokens_expected); - }; - } - c2_minus_one!( - [ match void {} ], - "(match void {}) - 1;", - "match void {} - 1", - ); - c2_minus_one!( - [ match void {}() ], - "(match void {})() - 1;", - "match void {}() - 1", - ); - c2_minus_one!( - [ match void {}[0] ], - "(match void {})[0] - 1;", - "match void {}[0] - 1", - ); - c2_minus_one!( - [ loop { break 1; } ], - "(loop { break 1; }) - 1;", - "loop { break 1; } - 1", - ); - c2_minus_one!( - [ m!() ], - "m!() - 1;", - "m!() - 1" - ); - c2_minus_one!( - [ m![] ], - "m![] - 1;", - "m![] - 1" - ); - c2_minus_one!( - [ m! {} ], - "(m! {}) - 1;", - "m! {} - 1" - ); + c1!(stmt, [ 1 + 1 ], "1 + 1"); // StmtKind::Empty c1!(stmt, [ ; ], ";"); @@ -793,14 +642,14 @@ fn test_ty() { c1!(ty, [ &'a T ], "&'a T"); c1!(ty, [ &'a mut [T] ], "&'a mut [T]"); c1!(ty, [ &A>>> ], "&A>>>"); - c2!(ty, [ &A > > > ], "&A>>>", "&A > > >"); + c1!(ty, [ &A > > > ], "&A > > >"); // TyKind::BareFn c1!(ty, [ fn() ], "fn()"); c1!(ty, [ fn() -> () ], "fn() -> ()"); c1!(ty, [ fn(u8) ], "fn(u8)"); c1!(ty, [ fn(x: u8) ], "fn(x: u8)"); - c2!(ty, [ for<> fn() ], "fn()", "for<> fn()"); + c1!(ty, [ for<> fn() ], "for<> fn()"); c1!(ty, [ for<'a> fn() ], "for<'a> fn()"); // TyKind::Never @@ -819,7 +668,7 @@ fn test_ty() { c1!(ty, [ T ], "T"); c1!(ty, [ Ref<'a> ], "Ref<'a>"); c1!(ty, [ PhantomData ], "PhantomData"); - c2!(ty, [ PhantomData:: ], "PhantomData", "PhantomData::"); + c1!(ty, [ PhantomData:: ], "PhantomData::"); c1!(ty, [ Fn() -> ! ], "Fn() -> !"); c1!(ty, [ Fn(u8) -> ! ], "Fn(u8) -> !"); c1!(ty, [ ::Type ], "::Type"); @@ -864,23 +713,19 @@ fn test_ty() { #[test] fn test_vis() { // VisibilityKind::Public - c2!(vis, [ pub ], "pub ", "pub"); + c1!(vis, [ pub ], "pub"); // VisibilityKind::Restricted - c2!(vis, [ pub(crate) ], "pub(crate) ", "pub(crate)"); - c2!(vis, [ pub(self) ], "pub(self) ", "pub(self)"); - c2!(vis, [ pub(super) ], "pub(super) ", "pub(super)"); - c2!(vis, [ pub(in crate) ], "pub(in crate) ", "pub(in crate)"); - c2!(vis, [ pub(in self) ], "pub(in self) ", "pub(in self)"); - c2!(vis, [ pub(in super) ], "pub(in super) ", "pub(in super)"); - c2!(vis, [ pub(in path::to) ], "pub(in path::to) ", "pub(in path::to)"); - c2!(vis, [ pub(in ::path::to) ], "pub(in ::path::to) ", "pub(in ::path::to)"); - c2!(vis, [ pub(in self::path::to) ], "pub(in self::path::to) ", "pub(in self::path::to)"); - c2!(vis, - [ pub(in super::path::to) ], - "pub(in super::path::to) ", - "pub(in super::path::to)" - ); + c1!(vis, [ pub(crate) ], "pub(crate)"); + c1!(vis, [ pub(self) ], "pub(self)"); + c1!(vis, [ pub(super) ], "pub(super)"); + c1!(vis, [ pub(in crate) ], "pub(in crate)"); + c1!(vis, [ pub(in self) ], "pub(in self)"); + c1!(vis, [ pub(in super) ], "pub(in super)"); + c1!(vis, [ pub(in path::to) ], "pub(in path::to)"); + c1!(vis, [ pub(in ::path::to) ], "pub(in ::path::to)"); + c1!(vis, [ pub(in self::path::to) ], "pub(in self::path::to)"); + c1!(vis, [ pub(in super::path::to) ], "pub(in super::path::to)"); // VisibilityKind::Inherited // This one is different because directly calling `vis!` does not work. diff --git a/tests/ui/macros/trace_faulty_macros.rs b/tests/ui/macros/trace_faulty_macros.rs index ec1ce1a1f92..87036bb9c6f 100644 --- a/tests/ui/macros/trace_faulty_macros.rs +++ b/tests/ui/macros/trace_faulty_macros.rs @@ -46,7 +46,7 @@ macro_rules! test { (let $p:pat = $e:expr) => {test!(($p,$e))}; // this should be expr // vvv - (($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found pattern `1 + 1` + (($p:pat, $e:pat)) => {let $p = $e;}; //~ ERROR expected expression, found pattern `1+1` } fn foo() { diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 665dcc7d091..66d7b76bb07 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -50,7 +50,7 @@ LL | my_recursive_macro!(); = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro! ();` -error: expected expression, found pattern `A { a: a, b: 0, c: _, .. }` +error: expected expression, found pattern `A { a : a, b : 0, c : _, .. }` --> $DIR/trace_faulty_macros.rs:16:9 | LL | $a @@ -69,7 +69,7 @@ LL | #[derive(Debug)] LL | fn use_derive_macro_as_attr() {} | -------------------------------- not a `struct`, `enum` or `union` -error: expected expression, found pattern `1 + 1` +error: expected expression, found pattern `1+1` --> $DIR/trace_faulty_macros.rs:49:37 | LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; @@ -96,7 +96,7 @@ LL | let a = pat_macro!(); = note: expanding `pat_macro! { }` = note: to `pat_macro! (A { a : a, b : 0, c : _, .. });` = note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }` - = note: to `A { a: a, b: 0, c: _, .. }` + = note: to `A { a : a, b : 0, c : _, .. }` note: trace_macro --> $DIR/trace_faulty_macros.rs:53:5 @@ -105,9 +105,9 @@ LL | test!(let x = 1+1); | ^^^^^^^^^^^^^^^^^^ | = note: expanding `test! { let x = 1+1 }` - = note: to `test! ((x, 1 + 1))` - = note: expanding `test! { (x, 1 + 1) }` - = note: to `let x = 1 + 1;` + = note: to `test! ((x, 1+1))` + = note: expanding `test! { (x, 1+1) }` + = note: to `let x = 1+1;` error: aborting due to 5 previous errors diff --git a/tests/ui/proc-macro/capture-macro-rules-invoke.stdout b/tests/ui/proc-macro/capture-macro-rules-invoke.stdout index 71e34119ba7..172e5ec6e42 100644 --- a/tests/ui/proc-macro/capture-macro-rules-invoke.stdout +++ b/tests/ui/proc-macro/capture-macro-rules-invoke.stdout @@ -11,9 +11,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ span: $DIR/capture-macro-rules-invoke.rs:21:21: 21:26 (#3), }, ] -PRINT-BANG INPUT (DISPLAY): 1 + 1, { "a" }, let a = 1;, String, my_name, 'a, my_val = 30, -std::option::Option, pub(in some::path) , [a b c], -30 -PRINT-BANG RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30, +PRINT-BANG INPUT (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30, std::option::Option, pub(in some::path), [a b c], -30 PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): 1 + 1, { "a" }, let a = 1, String, my_name, 'a, my_val = 30, std :: option :: Option, pub(in some :: path), [a b c], - 30 diff --git a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout index e11d2c0715c..6523f2485cd 100644 --- a/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout +++ b/tests/ui/proc-macro/expr-stmt-nonterminal-tokens.stdout @@ -1,5 +1,4 @@ -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] 0; 0 }, } -PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = #[allow(warnings)] #[allow(warnings)] 0; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = #[allow(warnings)] #[allow(warnings)] 0; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", @@ -122,8 +121,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #3 bytes(308..357), }, ] -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0; }; 0 }, } -PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 }; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", @@ -280,8 +278,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #11 bytes(432..485), }, ] -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH; }; 0 }, } -PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH }; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", @@ -358,8 +355,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #15 bytes(432..485), }, ] -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 + 1; }; 0 }, } -PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { 0 + 1 }; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { 0 + 1 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", @@ -449,8 +445,7 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ span: #19 bytes(432..485), }, ] -PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH + 1; }; 0 }, } -PRINT-DERIVE DEEP-RE-COLLECTED (DISPLAY): enum E { V = { let _ = { PATH + 1 }; 0 }, } +PRINT-DERIVE INPUT (DISPLAY): enum E { V = { let _ = { PATH + 1 }; 0 }, } PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "enum", diff --git a/tests/ui/proc-macro/issue-78675-captured-inner-attrs.stdout b/tests/ui/proc-macro/issue-78675-captured-inner-attrs.stdout index 37ecf3a8df3..346f87643c2 100644 --- a/tests/ui/proc-macro/issue-78675-captured-inner-attrs.stdout +++ b/tests/ui/proc-macro/issue-78675-captured-inner-attrs.stdout @@ -1,6 +1,4 @@ -PRINT-BANG INPUT (DISPLAY): foo! { #[fake_attr] mod bar { - #![doc = r" Foo"] -} } +PRINT-BANG INPUT (DISPLAY): foo! { #[fake_attr] mod bar { #![doc = r" Foo"] } } PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): foo! { #[fake_attr] mod bar { #! [doc = r" Foo"] } } PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { From 537f531b4ea648d4be0e53db00a5a6c15745bdac Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 10 May 2024 12:41:52 -0700 Subject: [PATCH 026/153] Promote `arm64ec-pc-windows-msvc` to tier 2 --- library/std/src/os/linux/raw.rs | 6 +++++- src/ci/github-actions/jobs.yml | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../src/platform-support/arm64ec-pc-windows-msvc.md | 11 ++++++----- src/tools/build-manifest/src/main.rs | 1 + 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/library/std/src/os/linux/raw.rs b/library/std/src/os/linux/raw.rs index c29dd62bc06..d53674d3c5f 100644 --- a/library/std/src/os/linux/raw.rs +++ b/library/std/src/os/linux/raw.rs @@ -244,7 +244,11 @@ mod arch { pub use libc::{blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; } -#[cfg(target_arch = "aarch64")] +#[cfg(any( + target_arch = "aarch64", + // Arm64EC is Windows-only, but docs are always build as Linux, so re-use AArch64 for Arm64EC. + all(doc, target_arch = "arm64ec") +))] mod arch { use crate::os::raw::{c_int, c_long}; diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index ca86f3f0110..44ac555831a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -421,6 +421,7 @@ auto: RUST_CONFIGURE_ARGS: >- --build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc + --target=aarch64-pc-windows-msvc,arm64ec-pc-windows-msvc --enable-full-tools --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 77859956c95..53a8ba6d3d5 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -146,6 +146,7 @@ target | std | notes [`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android `arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 `arm-unknown-linux-musleabihf` | ✓ | Armv6 Linux with musl 1.2.3, hardfloat +[`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ✓ | Arm64EC Windows MSVC [`armebv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian [`armebv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | Bare Armv7-R, Big Endian, hardfloat `armv5te-unknown-linux-gnueabi` | ✓ | Armv5TE Linux (kernel 4.4, glibc 2.23) @@ -240,7 +241,6 @@ target | std | host | notes -------|:---:|:----:|------- [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin -[`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ? | | Arm64EC Windows MSVC [`aarch64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | | Apple Catalyst on ARM64 [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md index 2e827535862..dcabd21a83e 100644 --- a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md +++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md @@ -1,6 +1,6 @@ # `arm64ec-pc-windows-msvc` -**Tier: 3** +**Tier: 2** Arm64EC ("Emulation Compatible") for mixed architecture (AArch64 and x86_64) applications on AArch64 Windows 11. See . @@ -21,6 +21,9 @@ Only supported backend is LLVM 18 or above: * 18.1.4 fixed linking issue for some intrinsics implemented in `compiler_builtins`. +Visual Studio 2022 (or above) with the "ARM64/ARM64EC built tools" component and +the Windows 11 SDK are required. + ### Reusing code from other architectures - x86_64 or AArch64? Arm64EC uses `arm64ec` as its `target_arch`, but it is possible to reuse @@ -62,10 +65,8 @@ target = [ "arm64ec-pc-windows-msvc" ] ## Building Rust programs -Rust does not yet ship pre-compiled artifacts for this target. To compile for -this target, you will either need to build Rust with the target enabled (see -"Building the target" above), or build your own copy using `build-std` or -similar. +These targets are distributed through `rustup`, and otherwise require no +special configuration. ## Testing diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index bed76263b45..9f33e431274 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -71,6 +71,7 @@ static TARGETS: &[&str] = &[ "arm-unknown-linux-gnueabihf", "arm-unknown-linux-musleabi", "arm-unknown-linux-musleabihf", + "arm64ec-pc-windows-msvc", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv7-linux-androideabi", From 69769fc79776a284fed2e5d9ea9605b36f50f83a Mon Sep 17 00:00:00 2001 From: "rongfu.leng" Date: Thu, 6 Jun 2024 09:38:09 +0800 Subject: [PATCH 027/153] Expand list of trait implementers in E0277 when calling rustc with --verbose Signed-off-by: rongfu.leng --- .../src/traits/error_reporting/type_err_ctxt_ext.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 9a0929baeaf..1bdbd0f3ed7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2082,12 +2082,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }) .collect(); - let end = if candidates.len() <= 9 { candidates.len() } else { 8 }; + let end = if candidates.len() <= 9 || self.tcx.sess.opts.verbose { + candidates.len() + } else { + 8 + }; err.help(format!( "the following {other}types implement trait `{}`:{}{}", trait_ref.print_trait_sugared(), candidates[..end].join(""), - if candidates.len() > 9 { + if candidates.len() > 9 && !self.tcx.sess.opts.verbose { format!("\nand {} others", candidates.len() - 8) } else { String::new() From 1653a2d34a7f841f15b0704c7ce07c74dee2bada Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 14:59:38 -0400 Subject: [PATCH 028/153] Failing test --- tests/ui/specialization/anyid-repro-125197.rs | 17 ++++++++++++ .../auxiliary/anyid-repro-125197.rs | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/ui/specialization/anyid-repro-125197.rs create mode 100644 tests/ui/specialization/auxiliary/anyid-repro-125197.rs diff --git a/tests/ui/specialization/anyid-repro-125197.rs b/tests/ui/specialization/anyid-repro-125197.rs new file mode 100644 index 00000000000..725b1f1aff4 --- /dev/null +++ b/tests/ui/specialization/anyid-repro-125197.rs @@ -0,0 +1,17 @@ +//@ aux-build: anyid-repro-125197.rs +//@ check-pass + +// Makes sure that we don't check `specializes(impl1, impl2)` for a pair of impls that don't +// actually participate in specialization. Since , +// we don't treat inductive cycles as errors -- so we may need to winnow more pairs of impls, and +// we try to winnow impls in favor of other impls. However, if we're *inside* the `specializes` +// query, then may have a query cycle if we call `specializes` again! + +extern crate anyid_repro_125197; +use anyid_repro_125197::AnyId; + +fn main() { + let x = "hello, world"; + let y: AnyId = x.into(); + let _ = y == x; +} diff --git a/tests/ui/specialization/auxiliary/anyid-repro-125197.rs b/tests/ui/specialization/auxiliary/anyid-repro-125197.rs new file mode 100644 index 00000000000..c2794959740 --- /dev/null +++ b/tests/ui/specialization/auxiliary/anyid-repro-125197.rs @@ -0,0 +1,26 @@ +use std::fmt::Display; +use std::sync::Arc; + +pub struct AnyId(()); + +impl PartialEq for AnyId { + fn eq(&self, _: &Self) -> bool { + todo!() + } +} + +impl PartialEq for AnyId { + fn eq(&self, _: &T) -> bool { + todo!() + } +} + +impl From for AnyId { + fn from(_: T) -> Self { + todo!() + } +} + +pub trait Identifier: Display + 'static {} + +impl Identifier for T where T: PartialEq + Display + 'static {} From 4b188d9d667dfcc7ba4caf95e56cbb3a6697f292 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 15:58:05 -0400 Subject: [PATCH 029/153] Only compute specializes query if specialization is enabled in the crate of the specialized impl --- .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 1 + compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 5 +++ .../rustc_trait_selection/src/traits/mod.rs | 1 + .../src/traits/specialize/mod.rs | 42 ++++++++----------- .../ui/coherence/coherence-impls-copy.stderr | 22 +++++----- tests/ui/specialization/anyid-repro-125197.rs | 2 +- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index afee8d5646c..1cef35f082b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -314,6 +314,7 @@ provide! { tcx, def_id, other, cdata, extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) } is_no_builtins => { cdata.root.no_builtins } symbol_mangling_version => { cdata.root.symbol_mangling_version } + specialization_enabled_in => { cdata.root.specialization_enabled_in } reachable_non_generics => { let reachable_non_generics = tcx .exported_symbols(cdata.cnum) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 67c5bc8c786..89da0df8575 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -741,6 +741,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { expn_data, expn_hashes, def_path_hash_map, + specialization_enabled_in: tcx.specialization_enabled_in(LOCAL_CRATE), }) }); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c2cf5b6b712..87900c23d8d 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -290,6 +290,8 @@ pub(crate) struct CrateRoot { panic_runtime: bool, profiler_runtime: bool, symbol_mangling_version: SymbolManglingVersion, + + specialization_enabled_in: bool, } /// On-disk representation of `DefId`. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0af32a6a857..a8bf735fa5a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1494,6 +1494,11 @@ rustc_queries! { separate_provide_extern } + query specialization_enabled_in(cnum: CrateNum) -> bool { + desc { "checking whether the crate enabled `specialization`/`min_specialization`" } + separate_provide_extern + } + query specializes(_: (DefId, DefId)) -> bool { desc { "computing whether impls specialize one another" } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 7be2c4a85c5..eae2f9d1792 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -623,6 +623,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, + specialization_enabled_in: specialize::specialization_enabled_in, instantiate_and_check_impossible_predicates, is_impossible_associated_item, ..*providers diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c2727ae6bfd..c9bb0d330e1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -24,6 +24,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{codes::*, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; +use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; @@ -136,6 +137,10 @@ pub fn translate_args_with_cause<'tcx>( source_args.rebase_onto(infcx.tcx, source_impl, target_args) } +pub(super) fn specialization_enabled_in(tcx: TyCtxt<'_>, _: LocalCrate) -> bool { + tcx.features().specialization || tcx.features().min_specialization +} + /// Is `impl1` a specialization of `impl2`? /// /// Specialization is determined by the sets of types to which the impls apply; @@ -143,31 +148,18 @@ pub fn translate_args_with_cause<'tcx>( /// to. #[instrument(skip(tcx), level = "debug")] pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool { - // The feature gate should prevent introducing new specializations, but not - // taking advantage of upstream ones. - // If specialization is enabled for this crate then no extra checks are needed. - // If it's not, and either of the `impl`s is local to this crate, then this definitely - // isn't specializing - unless specialization is enabled for the `impl` span, - // e.g. if it comes from an `allow_internal_unstable` macro - let features = tcx.features(); - let specialization_enabled = features.specialization || features.min_specialization; - if !specialization_enabled { - if impl1_def_id.is_local() { - let span = tcx.def_span(impl1_def_id); - if !span.allows_unstable(sym::specialization) - && !span.allows_unstable(sym::min_specialization) - { - return false; - } - } - - if impl2_def_id.is_local() { - let span = tcx.def_span(impl2_def_id); - if !span.allows_unstable(sym::specialization) - && !span.allows_unstable(sym::min_specialization) - { - return false; - } + // We check that the specializing impl comes from a crate that has specialization enabled, + // or if the specializing impl is marked with `allow_internal_unstable`. + // + // We don't really care if the specialized impl (the parent) is in a crate that has + // specialization enabled, since it's not being specialized, and it's already been checked + // for coherence. + if !tcx.specialization_enabled_in(impl1_def_id.krate) { + let span = tcx.def_span(impl1_def_id); + if !span.allows_unstable(sym::specialization) + && !span.allows_unstable(sym::min_specialization) + { + return false; } } diff --git a/tests/ui/coherence/coherence-impls-copy.stderr b/tests/ui/coherence/coherence-impls-copy.stderr index 2d2c5064043..f529a056b0f 100644 --- a/tests/ui/coherence/coherence-impls-copy.stderr +++ b/tests/ui/coherence/coherence-impls-copy.stderr @@ -1,14 +1,3 @@ -error[E0117]: only traits defined in the current crate can be implemented for primitive types - --> $DIR/coherence-impls-copy.rs:5:1 - | -LL | impl Copy for i32 {} - | ^^^^^^^^^^^^^^--- - | | | - | | `i32` is not defined in the current crate - | impl doesn't use only types from inside the current crate - | - = note: define and implement a trait or new type instead - error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync` --> $DIR/coherence-impls-copy.rs:28:1 | @@ -30,6 +19,17 @@ LL | impl Copy for &'static [NotSync] {} | = note: define and implement a trait or new type instead +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/coherence-impls-copy.rs:5:1 + | +LL | impl Copy for i32 {} + | ^^^^^^^^^^^^^^--- + | | | + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate + | + = note: define and implement a trait or new type instead + error[E0206]: the trait `Copy` cannot be implemented for this type --> $DIR/coherence-impls-copy.rs:21:15 | diff --git a/tests/ui/specialization/anyid-repro-125197.rs b/tests/ui/specialization/anyid-repro-125197.rs index 725b1f1aff4..9428d8dc2d4 100644 --- a/tests/ui/specialization/anyid-repro-125197.rs +++ b/tests/ui/specialization/anyid-repro-125197.rs @@ -5,7 +5,7 @@ // actually participate in specialization. Since , // we don't treat inductive cycles as errors -- so we may need to winnow more pairs of impls, and // we try to winnow impls in favor of other impls. However, if we're *inside* the `specializes` -// query, then may have a query cycle if we call `specializes` again! +// query, then may have a query cycle if we call `specializes` again! extern crate anyid_repro_125197; use anyid_repro_125197::AnyId; From f976a9b208f5027c2dc0a3c9a7c952eacdddf1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 8 Jun 2024 13:39:46 +0200 Subject: [PATCH 030/153] Use native GitHub ARM64 runner for the `aarch64-gnu` job --- src/ci/github-actions/jobs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 8c84e721f5d..c59eb03a5c4 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -33,7 +33,7 @@ runners: <<: *base-job - &job-aarch64-linux - os: [ self-hosted, ARM64, linux ] + os: ubuntu-22.04-arm64-8core-32gb envs: env-x86_64-apple-tests: &env-x86_64-apple-tests From f88c647cdab91b7f82de2d68fb7ec0f4d00f86b8 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 5 Jun 2024 12:07:27 -0400 Subject: [PATCH 031/153] rewrite `short-ice` in `rmake` format --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/short-ice/Makefile | 10 ------ tests/run-make/short-ice/check.sh | 36 ------------------- tests/run-make/short-ice/rmake.rs | 31 ++++++++++++++++ 4 files changed, 31 insertions(+), 47 deletions(-) delete mode 100644 tests/run-make/short-ice/Makefile delete mode 100644 tests/run-make/short-ice/check.sh create mode 100644 tests/run-make/short-ice/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51..82f0a6531a7 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -218,7 +218,6 @@ run-make/sepcomp-cci-copies/Makefile run-make/sepcomp-inlining/Makefile run-make/sepcomp-separate/Makefile run-make/share-generics-dylib/Makefile -run-make/short-ice/Makefile run-make/silly-file-names/Makefile run-make/simd-ffi/Makefile run-make/split-debuginfo/Makefile diff --git a/tests/run-make/short-ice/Makefile b/tests/run-make/short-ice/Makefile deleted file mode 100644 index 23006fc09e2..00000000000 --- a/tests/run-make/short-ice/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include ../tools.mk - -# ignore-windows - -export RUSTC := $(RUSTC_ORIGINAL) -export LD_LIBRARY_PATH := $(HOST_RPATH_DIR) -export TMPDIR := $(TMPDIR) - -all: - bash check.sh diff --git a/tests/run-make/short-ice/check.sh b/tests/run-make/short-ice/check.sh deleted file mode 100644 index 56babd2142f..00000000000 --- a/tests/run-make/short-ice/check.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -export RUSTC_ICE=0 -RUST_BACKTRACE=1 $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-1.log 2>&1 -RUST_BACKTRACE=full $RUSTC src/lib.rs -Z treat-err-as-bug=1 1>$TMPDIR/rust-test-2.log 2>&1 - -short=$(cat $TMPDIR/rust-test-1.log | wc -l) -full=$(cat $TMPDIR/rust-test-2.log | wc -l) -rustc_query_count=$(cat $TMPDIR/rust-test-1.log | grep rustc_query_ | wc -l) -rustc_query_count_full=$(cat $TMPDIR/rust-test-2.log | grep rustc_query_ | wc -l) - -begin_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_begin_short_backtrace | wc -l) -end_count=$(cat $TMPDIR/rust-test-2.log | grep __rust_end_short_backtrace | wc -l) - -cat $TMPDIR/rust-test-1.log -echo "=====================" -cat $TMPDIR/rust-test-2.log -echo "=====================" - -echo "short backtrace: $short" -echo "full backtrace: $full" -echo "begin_count: $begin_count" -echo "end_count : $end_count" -echo "rustc_query_count: $rustc_query_count" -echo "rustc_query_count_full: $rustc_query_count_full" - -## backtraces to vary a bit depending on platform and configuration options, -## here we make sure that the short backtrace of rustc_query is shorter than the full, -## and marks are in pairs. -if [ $short -lt $full ] && - [ $begin_count -eq $end_count ] && - [ $(($rustc_query_count + 5)) -lt $rustc_query_count_full ] && - [ $rustc_query_count_full -gt 5 ]; then - exit 0 -else - exit 1 -fi diff --git a/tests/run-make/short-ice/rmake.rs b/tests/run-make/short-ice/rmake.rs new file mode 100644 index 00000000000..0aa1df61dbe --- /dev/null +++ b/tests/run-make/short-ice/rmake.rs @@ -0,0 +1,31 @@ +// Backtraces in internal compiler errors used to be unbearably long, spanning +// multiple hundreds of lines. A fix was pushed in #108938, and this test gathers +// varied metrics on level 1 and full-level backtraces to check that the output +// was shortened down to an appropriate length. +// See https://github.com/rust-lang/rust/issues/107910 + +use run_make_support::rustc; +use std::env; + +fn main() { + env::set_var("RUST_BACKTRACE", "1"); + let mut rust_test_1 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + env::set_var("RUST_BACKTRACE", "full"); + let mut rust_test_2 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let rust_test_log_1 = rust_test_1.stderr_utf8().push_str(&rust_test_1.stdout_utf8()).as_str(); + let rust_test_log_2 = rust_test_2.stderr_utf8().push_str(&rust_test_2.stdout_utf8()).as_str(); + + let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_"); + + assert!( + rust_test_log_1.lines().count() < rust_test_log_2.lines().count() + && count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace") + == count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") + && count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full + && rustc_query_count_full > 5 + ); +} + +fn count_lines_with(s: &str, search: &str) -> usize { + s.lines().filter(|l| l.contains(search)).count() +} From fe52b5439edd024b1402f4790bc8e12e0fd91d34 Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 9 Jun 2024 20:22:46 -0400 Subject: [PATCH 032/153] docs(core): make more const_ptr doctests assert instead of printing fixes #124669 --- library/core/src/ptr/const_ptr.rs | 38 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8c02aee8bfb..b1f94caed35 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -330,7 +330,7 @@ impl *const T { /// /// unsafe { /// if let Some(val_back) = ptr.as_ref() { - /// println!("We got back the value: {val_back}!"); + /// assert_eq!(val_back, &10); /// } /// } /// ``` @@ -346,7 +346,7 @@ impl *const T { /// /// unsafe { /// let val_back = &*ptr; - /// println!("We got back the value: {val_back}!"); + /// assert_eq!(val_back, &10); /// } /// ``` #[stable(feature = "ptr_as_ref", since = "1.9.0")] @@ -393,7 +393,7 @@ impl *const T { /// let ptr: *const u8 = &10u8 as *const u8; /// /// unsafe { - /// println!("We got back the value: {}!", ptr.as_ref_unchecked()); + /// assert_eq!(ptr.as_ref_unchecked(), &10); /// } /// ``` // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized. @@ -439,7 +439,7 @@ impl *const T { /// /// unsafe { /// if let Some(val_back) = ptr.as_uninit_ref() { - /// println!("We got back the value: {}!", val_back.assume_init()); + /// assert_eq!(val_back.assume_init(), 10); /// } /// } /// ``` @@ -501,8 +501,8 @@ impl *const T { /// let ptr: *const u8 = s.as_ptr(); /// /// unsafe { - /// println!("{}", *ptr.offset(1) as char); - /// println!("{}", *ptr.offset(2) as char); + /// assert_eq!(*ptr.offset(1) as char, '2'); + /// assert_eq!(*ptr.offset(2) as char, '3'); /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -573,19 +573,21 @@ impl *const T { /// # Examples /// /// ``` + /// # use std::fmt::Write; /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; /// let mut ptr: *const u8 = data.as_ptr(); /// let step = 2; /// let end_rounded_up = ptr.wrapping_offset(6); /// - /// // This loop prints "1, 3, 5, " + /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// print!("{}, ", *ptr); + /// write!(&mut out, "{}, ", *ptr).unwrap(); /// } /// ptr = ptr.wrapping_offset(step); /// } + /// assert_eq!(out.as_str(), "1, 3, 5, "); /// ``` #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -988,8 +990,8 @@ impl *const T { /// let ptr: *const u8 = s.as_ptr(); /// /// unsafe { - /// println!("{}", *ptr.add(1) as char); - /// println!("{}", *ptr.add(2) as char); + /// assert_eq!(*ptr.add(1), b'2'); + /// assert_eq!(*ptr.add(2), b'3'); /// } /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] @@ -1073,8 +1075,8 @@ impl *const T { /// /// unsafe { /// let end: *const u8 = s.as_ptr().add(3); - /// println!("{}", *end.sub(1) as char); - /// println!("{}", *end.sub(2) as char); + /// assert_eq!(*end.sub(1), b'3'); + /// assert_eq!(*end.sub(2), b'2'); /// } /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] @@ -1155,19 +1157,21 @@ impl *const T { /// # Examples /// /// ``` + /// # use std::fmt::Write; /// // Iterate using a raw pointer in increments of two elements /// let data = [1u8, 2, 3, 4, 5]; /// let mut ptr: *const u8 = data.as_ptr(); /// let step = 2; /// let end_rounded_up = ptr.wrapping_add(6); /// - /// // This loop prints "1, 3, 5, " + /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// print!("{}, ", *ptr); + /// write!(&mut out, "{}, ", *ptr).unwrap(); /// } /// ptr = ptr.wrapping_add(step); /// } + /// assert_eq!(out, "1, 3, 5, "); /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1234,19 +1238,21 @@ impl *const T { /// # Examples /// /// ``` + /// # use std::fmt::Write; /// // Iterate using a raw pointer in increments of two elements (backwards) /// let data = [1u8, 2, 3, 4, 5]; /// let mut ptr: *const u8 = data.as_ptr(); /// let start_rounded_down = ptr.wrapping_sub(2); /// ptr = ptr.wrapping_add(4); /// let step = 2; - /// // This loop prints "5, 3, 1, " + /// let mut out = String::new(); /// while ptr != start_rounded_down { /// unsafe { - /// print!("{}, ", *ptr); + /// write!(&mut out, "{}, ", *ptr).unwrap(); /// } /// ptr = ptr.wrapping_sub(step); /// } + /// assert_eq!(out, "5, 3, 1, "); /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] From bfb7757c3c059d3bbcfbc604ab326fa777be13aa Mon Sep 17 00:00:00 2001 From: Boxy Date: Mon, 10 Jun 2024 14:32:50 +0100 Subject: [PATCH 033/153] Correct parent for nested anon consts --- .../src/collect/generics_of.rs | 26 +++++++++++++++---- .../repeat_expr_hack_gives_right_generics.rs | 20 ++++++++++++++ ...peat_expr_hack_gives_right_generics.stderr | 11 ++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs create mode 100644 tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index abdf85ad707..303fa23dbc1 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -11,6 +11,7 @@ use rustc_session::lint; use rustc_span::symbol::{kw, Symbol}; use rustc_span::Span; +#[instrument(level = "debug", skip(tcx))] pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { use rustc_hir::*; @@ -66,7 +67,22 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // FIXME(#43408) always enable this once `lazy_normalization` is // stable enough and does not need a feature gate anymore. Node::AnonConst(_) => { - let parent_def_id = tcx.hir().get_parent_item(hir_id); + let parent_did = tcx.parent(def_id.to_def_id()); + + // We don't do this unconditionally because the `DefId` parent of an anon const + // might be an implicitly created closure during `async fn` desugaring. This would + // have the wrong generics. + // + // i.e. `async fn foo<'a>() { let a = [(); { 1 + 2 }]; bar().await() }` + // would implicitly have a closure in its body that would be the parent of + // the `{ 1 + 2 }` anon const. This closure's generics is simply a witness + // instead of `['a]`. + let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) { + parent_did + } else { + tcx.hir().get_parent_item(hir_id).to_def_id() + }; + debug!(?parent_did); let mut in_param_ty = false; for (_parent, node) in tcx.hir().parent_iter(hir_id) { @@ -121,7 +137,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // // This has some implications for how we get the predicates available to the anon const // see `explicit_predicates_of` for more information on this - let generics = tcx.generics_of(parent_def_id.to_def_id()); + let generics = tcx.generics_of(parent_did); let param_def_idx = generics.param_def_id_to_index[¶m_id.to_def_id()]; // In the above example this would be .params[..N#0] let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned(); @@ -147,7 +163,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { // // Note that we do not supply the parent generics when using // `min_const_generics`. - Some(parent_def_id.to_def_id()) + Some(parent_did) } } else { let parent_node = tcx.parent_hir_node(hir_id); @@ -159,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. }) if constant.hir_id() == hir_id => { - Some(parent_def_id.to_def_id()) + Some(parent_did) } // Exclude `GlobalAsm` here which cannot have generics. Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) @@ -171,7 +187,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { _ => false, }) => { - Some(parent_def_id.to_def_id()) + Some(parent_did) } _ => None, } diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs new file mode 100644 index 00000000000..899db191ae7 --- /dev/null +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.rs @@ -0,0 +1,20 @@ +// Given an anon const `a`: `{ N }` and some anon const `b` which references the +// first anon const: `{ [1; a] }`. `b` should not have any generics as it is not +// a simple `N` argument nor is it a repeat expr count. +// +// On the other hand `b` *is* a repeat expr count and so it should inherit its +// parents generics as part of the `const_evaluatable_unchecked` fcw (#76200). +// +// In this specific case however `b`'s parent should be `a` and so it should wind +// up not having any generics after all. If `a` were to inherit its generics from +// the enclosing item then the reference to `a` from `b` would contain generic +// parameters not usable by `b` which would cause us to ICE. + +fn bar() {} + +fn foo() { + bar::<{ [1; N] }>(); + //~^ ERROR: generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr new file mode 100644 index 00000000000..64548cc5a30 --- /dev/null +++ b/tests/ui/const-generics/repeat_expr_hack_gives_right_generics.stderr @@ -0,0 +1,11 @@ +error: generic parameters may not be used in const operations + --> $DIR/repeat_expr_hack_gives_right_generics.rs:16:17 + | +LL | bar::<{ [1; N] }>(); + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 1 previous error + From af4d6c74efb31e34f75dfe5faf6064a0ff9cbd7c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 10 Jun 2024 17:24:36 +0200 Subject: [PATCH 034/153] interpret: refactor dyn trait handling We can check that the vtable is for the right trait very early, and then just pass the type around. --- .../rustc_const_eval/src/interpret/cast.rs | 9 +-- .../rustc_const_eval/src/interpret/memory.rs | 19 ++++-- .../rustc_const_eval/src/interpret/place.rs | 49 -------------- .../src/interpret/terminator.rs | 37 +++++------ .../rustc_const_eval/src/interpret/traits.rs | 66 ++++++++++++++----- .../src/interpret/validity.rs | 18 ++--- .../rustc_const_eval/src/interpret/visitor.rs | 4 +- 7 files changed, 90 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 19414c72c6a..1ac899f9aa5 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -383,7 +383,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) { (&ty::Array(_, length), &ty::Slice(_)) => { let ptr = self.read_pointer(src)?; - // u64 cast is from usize to u64, which is always good let val = Immediate::new_slice( ptr, length.eval_target_usize(*self.tcx, self.param_env), @@ -401,13 +400,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (old_data, old_vptr) = val.to_scalar_pair(); let old_data = old_data.to_pointer(self)?; let old_vptr = old_vptr.to_pointer(self)?; - let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?; - if old_trait != data_a.principal() { - throw_ub!(InvalidVTableTrait { - expected_trait: data_a, - vtable_trait: old_trait, - }); - } + let ty = self.get_ptr_vtable_ty(old_vptr, Some(data_a))?; let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?; self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 521f28b7123..84c6dad1cd3 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -867,19 +867,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .ok_or_else(|| err_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset))).into()) } - pub fn get_ptr_vtable( + /// Get the dynamic type of the given vtable pointer. + /// If `expected_trait` is `Some`, it must be a vtable for the given trait. + pub fn get_ptr_vtable_ty( &self, ptr: Pointer>, - ) -> InterpResult<'tcx, (Ty<'tcx>, Option>)> { + expected_trait: Option<&'tcx ty::List>>, + ) -> InterpResult<'tcx, Ty<'tcx>> { trace!("get_ptr_vtable({:?})", ptr); let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?; if offset.bytes() != 0 { throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset))) } - match self.tcx.try_get_global_alloc(alloc_id) { - Some(GlobalAlloc::VTable(ty, trait_ref)) => Ok((ty, trait_ref)), - _ => throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset))), + let Some(GlobalAlloc::VTable(ty, vtable_trait)) = self.tcx.try_get_global_alloc(alloc_id) + else { + throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset))) + }; + if let Some(expected_trait) = expected_trait { + if vtable_trait != expected_trait.principal() { + throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait }); + } } + Ok(ty) } pub fn alloc_mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 4a86ec3f57a..a0630d7f3b5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -9,7 +9,6 @@ use tracing::{instrument, trace}; use rustc_ast::Mutability; use rustc_middle::mir; -use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_middle::{bug, span_bug}; @@ -1017,54 +1016,6 @@ where let layout = self.layout_of(raw.ty)?; Ok(self.ptr_to_mplace(ptr.into(), layout)) } - - /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. - /// Aso returns the vtable. - pub(super) fn unpack_dyn_trait( - &self, - mplace: &MPlaceTy<'tcx, M::Provenance>, - expected_trait: &'tcx ty::List>, - ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, Pointer>)> { - assert!( - matches!(mplace.layout.ty.kind(), ty::Dynamic(_, _, ty::Dyn)), - "`unpack_dyn_trait` only makes sense on `dyn*` types" - ); - let vtable = mplace.meta().unwrap_meta().to_pointer(self)?; - let (ty, vtable_trait) = self.get_ptr_vtable(vtable)?; - if expected_trait.principal() != vtable_trait { - throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait }); - } - // This is a kind of transmute, from a place with unsized type and metadata to - // a place with sized type and no metadata. - let layout = self.layout_of(ty)?; - let mplace = - MPlaceTy { mplace: MemPlace { meta: MemPlaceMeta::None, ..mplace.mplace }, layout }; - Ok((mplace, vtable)) - } - - /// Turn a `dyn* Trait` type into an value with the actual dynamic type. - /// Also returns the vtable. - pub(super) fn unpack_dyn_star>( - &self, - val: &P, - expected_trait: &'tcx ty::List>, - ) -> InterpResult<'tcx, (P, Pointer>)> { - assert!( - matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)), - "`unpack_dyn_star` only makes sense on `dyn*` types" - ); - let data = self.project_field(val, 0)?; - let vtable = self.project_field(val, 1)?; - let vtable = self.read_pointer(&vtable.to_op(self)?)?; - let (ty, vtable_trait) = self.get_ptr_vtable(vtable)?; - if expected_trait.principal() != vtable_trait { - throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait }); - } - // `data` is already the right thing but has the wrong type. So we transmute it. - let layout = self.layout_of(ty)?; - let data = data.transmute(layout, self)?; - Ok((data, vtable)) - } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index cbfe25ca8df..8f76a148679 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use either::Either; +use rustc_middle::ty::TyCtxt; use tracing::trace; use rustc_middle::span_bug; @@ -827,20 +828,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; // Obtain the underlying trait we are working on, and the adjusted receiver argument. - let (vptr, dyn_ty, adjusted_receiver) = if let ty::Dynamic(data, _, ty::DynStar) = + let (dyn_trait, dyn_ty, adjusted_recv) = if let ty::Dynamic(data, _, ty::DynStar) = receiver_place.layout.ty.kind() { - let (recv, vptr) = self.unpack_dyn_star(&receiver_place, data)?; - let (dyn_ty, _dyn_trait) = self.get_ptr_vtable(vptr)?; + let recv = self.unpack_dyn_star(&receiver_place, data)?; - (vptr, dyn_ty, recv.ptr()) + (data.principal(), recv.layout.ty, recv.ptr()) } else { // Doesn't have to be a `dyn Trait`, but the unsized tail must be `dyn Trait`. // (For that reason we also cannot use `unpack_dyn_trait`.) let receiver_tail = self .tcx .struct_tail_erasing_lifetimes(receiver_place.layout.ty, self.param_env); - let ty::Dynamic(data, _, ty::Dyn) = receiver_tail.kind() else { + let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { span_bug!( self.cur_span(), "dynamic call on non-`dyn` type {}", @@ -851,25 +851,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Get the required information from the vtable. let vptr = receiver_place.meta().unwrap_meta().to_pointer(self)?; - let (dyn_ty, dyn_trait) = self.get_ptr_vtable(vptr)?; - if dyn_trait != data.principal() { - throw_ub!(InvalidVTableTrait { - expected_trait: data, - vtable_trait: dyn_trait, - }); - } + let dyn_ty = self.get_ptr_vtable_ty(vptr, Some(receiver_trait))?; // It might be surprising that we use a pointer as the receiver even if this // is a by-val case; this works because by-val passing of an unsized `dyn // Trait` to a function is actually desugared to a pointer. - (vptr, dyn_ty, receiver_place.ptr()) + (receiver_trait.principal(), dyn_ty, receiver_place.ptr()) }; // Now determine the actual method to call. We can do that in two different ways and // compare them to ensure everything fits. - let Some(ty::VtblEntry::Method(fn_inst)) = - self.get_vtable_entries(vptr)?.get(idx).copied() - else { + let vtable_entries = if let Some(dyn_trait) = dyn_trait { + let trait_ref = dyn_trait.with_self_ty(*self.tcx, dyn_ty); + let trait_ref = self.tcx.erase_regions(trait_ref); + self.tcx.vtable_entries(trait_ref) + } else { + TyCtxt::COMMON_VTABLE_ENTRIES + }; + let Some(ty::VtblEntry::Method(fn_inst)) = vtable_entries.get(idx).copied() else { // FIXME(fee1-dead) these could be variants of the UB info enum instead of this throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method); }; @@ -898,7 +897,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let receiver_ty = Ty::new_mut_ptr(self.tcx.tcx, dyn_ty); args[0] = FnArg::Copy( ImmTy::from_immediate( - Scalar::from_maybe_pointer(adjusted_receiver, self).into(), + Scalar::from_maybe_pointer(adjusted_recv, self).into(), self.layout_of(receiver_ty)?, ) .into(), @@ -974,11 +973,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let place = match place.layout.ty.kind() { ty::Dynamic(data, _, ty::Dyn) => { // Dropping a trait object. Need to find actual drop fn. - self.unpack_dyn_trait(&place, data)?.0 + self.unpack_dyn_trait(&place, data)? } ty::Dynamic(data, _, ty::DynStar) => { // Dropping a `dyn*`. Need to find actual drop fn. - self.unpack_dyn_star(&place, data)?.0 + self.unpack_dyn_star(&place, data)? } _ => { debug_assert_eq!( diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 244a6ba48a4..1df9f5f7b2a 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -1,11 +1,11 @@ use rustc_middle::mir::interpret::{InterpResult, Pointer}; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty}; use rustc_target::abi::{Align, Size}; use tracing::trace; use super::util::ensure_monomorphic_enough; -use super::{InterpCx, Machine}; +use super::{InterpCx, MPlaceTy, Machine, MemPlaceMeta, OffsetMode, Projectable}; impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for @@ -33,28 +33,58 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok(vtable_ptr.into()) } - /// Returns a high-level representation of the entries of the given vtable. - pub fn get_vtable_entries( - &self, - vtable: Pointer>, - ) -> InterpResult<'tcx, &'tcx [ty::VtblEntry<'tcx>]> { - let (ty, poly_trait_ref) = self.get_ptr_vtable(vtable)?; - Ok(if let Some(poly_trait_ref) = poly_trait_ref { - let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty); - let trait_ref = self.tcx.erase_regions(trait_ref); - self.tcx.vtable_entries(trait_ref) - } else { - TyCtxt::COMMON_VTABLE_ENTRIES - }) - } - pub fn get_vtable_size_and_align( &self, vtable: Pointer>, ) -> InterpResult<'tcx, (Size, Align)> { - let (ty, _trait_ref) = self.get_ptr_vtable(vtable)?; + let ty = self.get_ptr_vtable_ty(vtable, None)?; let layout = self.layout_of(ty)?; assert!(layout.is_sized(), "there are no vtables for unsized types"); Ok((layout.size, layout.align.abi)) } + + /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. + pub(super) fn unpack_dyn_trait( + &self, + mplace: &MPlaceTy<'tcx, M::Provenance>, + expected_trait: &'tcx ty::List>, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { + assert!( + matches!(mplace.layout.ty.kind(), ty::Dynamic(_, _, ty::Dyn)), + "`unpack_dyn_trait` only makes sense on `dyn*` types" + ); + let vtable = mplace.meta().unwrap_meta().to_pointer(self)?; + let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?; + // This is a kind of transmute, from a place with unsized type and metadata to + // a place with sized type and no metadata. + let layout = self.layout_of(ty)?; + let mplace = mplace.offset_with_meta( + Size::ZERO, + OffsetMode::Wrapping, + MemPlaceMeta::None, + layout, + self, + )?; + Ok(mplace) + } + + /// Turn a `dyn* Trait` type into an value with the actual dynamic type. + pub(super) fn unpack_dyn_star>( + &self, + val: &P, + expected_trait: &'tcx ty::List>, + ) -> InterpResult<'tcx, P> { + assert!( + matches!(val.layout().ty.kind(), ty::Dynamic(_, _, ty::DynStar)), + "`unpack_dyn_star` only makes sense on `dyn*` types" + ); + let data = self.project_field(val, 0)?; + let vtable = self.project_field(val, 1)?; + let vtable = self.read_pointer(&vtable.to_op(self)?)?; + let ty = self.get_ptr_vtable_ty(vtable, Some(expected_trait))?; + // `data` is already the right thing but has the wrong type. So we transmute it. + let layout = self.layout_of(ty)?; + let data = data.transmute(layout, self)?; + Ok(data) + } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3407c7b8c79..92462e17da8 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -343,20 +343,16 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { match tail.kind() { ty::Dynamic(data, _, ty::Dyn) => { let vtable = meta.unwrap_meta().to_pointer(self.ecx)?; - // Make sure it is a genuine vtable pointer. - let (_dyn_ty, dyn_trait) = try_validation!( - self.ecx.get_ptr_vtable(vtable), + // Make sure it is a genuine vtable pointer for the right trait. + try_validation!( + self.ecx.get_ptr_vtable_ty(vtable, Some(data)), self.path, Ub(DanglingIntPointer(..) | InvalidVTablePointer(..)) => - InvalidVTablePtr { value: format!("{vtable}") } + InvalidVTablePtr { value: format!("{vtable}") }, + Ub(InvalidVTableTrait { expected_trait, vtable_trait }) => { + InvalidMetaWrongTrait { expected_trait, vtable_trait: *vtable_trait } + }, ); - // Make sure it is for the right trait. - if dyn_trait != data.principal() { - throw_validation_failure!( - self.path, - InvalidMetaWrongTrait { expected_trait: data, vtable_trait: dyn_trait } - ); - } } ty::Slice(..) | ty::Str => { let _len = meta.unwrap_meta().to_target_usize(self.ecx)?; diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index b812e89854b..71c057e549b 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -95,7 +95,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // unsized values are never immediate, so we can assert_mem_place let op = v.to_op(self.ecx())?; let dest = op.assert_mem_place(); - let inner_mplace = self.ecx().unpack_dyn_trait(&dest, data)?.0; + let inner_mplace = self.ecx().unpack_dyn_trait(&dest, data)?; trace!("walk_value: dyn object layout: {:#?}", inner_mplace.layout); // recurse with the inner type return self.visit_field(v, 0, &inner_mplace.into()); @@ -104,7 +104,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // DynStar types. Very different from a dyn type (but strangely part of the // same variant in `TyKind`): These are pairs where the 2nd component is the // vtable, and the first component is the data (which must be ptr-sized). - let data = self.ecx().unpack_dyn_star(v, data)?.0; + let data = self.ecx().unpack_dyn_star(v, data)?; return self.visit_field(v, 0, &data); } // Slices do not need special handling here: they have `Array` field From 040791a9c59d2f604060efb75c81f685ceb5f9db Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 10 Jun 2024 18:02:53 +0300 Subject: [PATCH 035/153] Delegation: fix ICE on late diagnostics --- .../rustc_resolve/src/late/diagnostics.rs | 7 +++++-- tests/crashes/124342.rs | 6 ------ tests/ui/delegation/ice-issue-124342.rs | 12 +++++++++++ tests/ui/delegation/ice-issue-124342.stderr | 20 +++++++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) delete mode 100644 tests/crashes/124342.rs create mode 100644 tests/ui/delegation/ice-issue-124342.rs create mode 100644 tests/ui/delegation/ice-issue-124342.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ec24eac4a9d..9eeb0da7ed2 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2041,8 +2041,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn { called }, ast::AssocItemKind::Type(..) => AssocSuggestion::AssocType, ast::AssocItemKind::Delegation(..) - if self.r.delegation_fn_sigs[&self.r.local_def_id(assoc_item.id)] - .has_self => + if self + .r + .delegation_fn_sigs + .get(&self.r.local_def_id(assoc_item.id)) + .map_or(false, |sig| sig.has_self) => { AssocSuggestion::MethodWithSelf { called } } diff --git a/tests/crashes/124342.rs b/tests/crashes/124342.rs deleted file mode 100644 index ae51b3db96f..00000000000 --- a/tests/crashes/124342.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #124342 -trait Trait2 : Trait { - reuse <() as Trait>::async { - (async || {}).await; - }; -} diff --git a/tests/ui/delegation/ice-issue-124342.rs b/tests/ui/delegation/ice-issue-124342.rs new file mode 100644 index 00000000000..ad62f6bd54a --- /dev/null +++ b/tests/ui/delegation/ice-issue-124342.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse {} + +trait Trait { + reuse to_reuse::foo { foo } + //~^ ERROR cannot find function `foo` in module `to_reuse` + //~| ERROR cannot find value `foo` in this scope +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-124342.stderr b/tests/ui/delegation/ice-issue-124342.stderr new file mode 100644 index 00000000000..f9a3684d649 --- /dev/null +++ b/tests/ui/delegation/ice-issue-124342.stderr @@ -0,0 +1,20 @@ +error[E0425]: cannot find function `foo` in module `to_reuse` + --> $DIR/ice-issue-124342.rs:7:21 + | +LL | reuse to_reuse::foo { foo } + | ^^^ not found in `to_reuse` + +error[E0425]: cannot find value `foo` in this scope + --> $DIR/ice-issue-124342.rs:7:27 + | +LL | reuse to_reuse::foo { foo } + | ^^^ + | +help: you might have meant to refer to the associated function + | +LL | reuse to_reuse::foo { Self::foo } + | ++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. From 6f78e6265a6b43ea53abf048efa688fa0cdb33d9 Mon Sep 17 00:00:00 2001 From: Bryanskiy Date: Mon, 10 Jun 2024 21:21:46 +0300 Subject: [PATCH 036/153] Delegation: fix ICE on recursive delegation --- compiler/rustc_ast_lowering/src/delegation.rs | 4 +++- tests/crashes/124347.rs | 4 ---- tests/ui/delegation/ice-issue-124347.rs | 12 ++++++++++++ tests/ui/delegation/ice-issue-124347.stderr | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) delete mode 100644 tests/crashes/124347.rs create mode 100644 tests/ui/delegation/ice-issue-124347.rs create mode 100644 tests/ui/delegation/ice-issue-124347.stderr diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 27f8a6eae02..d9dd0b3bca5 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -67,7 +67,9 @@ impl<'hir> LoweringContext<'_, 'hir> { return false; }; if let Some(local_sig_id) = sig_id.as_local() { - self.resolver.delegation_fn_sigs[&local_sig_id].has_self + // The value may be missing due to recursive delegation. + // Error will be emmited later during HIR ty lowering. + self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self) } else { match self.tcx.def_kind(sig_id) { DefKind::Fn => false, diff --git a/tests/crashes/124347.rs b/tests/crashes/124347.rs deleted file mode 100644 index d2bc555fe1c..00000000000 --- a/tests/crashes/124347.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #124347 -trait Trait: ToReuse { - reuse Trait::lolno { &self.0 }; -} diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs new file mode 100644 index 00000000000..82a96055099 --- /dev/null +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -0,0 +1,12 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +trait Trait { + reuse Trait::foo { &self.0 } + //~^ ERROR recursive delegation is not supported yet +} + +reuse foo; +//~^ ERROR recursive delegation is not supported yet + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr new file mode 100644 index 00000000000..5a3f4525d29 --- /dev/null +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -0,0 +1,14 @@ +error: recursive delegation is not supported yet + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ callee defined here + +error: recursive delegation is not supported yet + --> $DIR/ice-issue-124347.rs:9:7 + | +LL | reuse foo; + | ^^^ callee defined here + +error: aborting due to 2 previous errors + From 3ba0262c2d254c5510b97e01de198bdc05b27eab Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Mon, 27 May 2024 13:12:26 -0700 Subject: [PATCH 037/153] CI: Update riscv64gc-linux job to 22.04, rename to riscv64gc-gnu --- .../Dockerfile | 91 ++++++++---------- .../linux.config | 0 .../0001-Remove-stime-function-calls.patch | 96 ------------------- 3 files changed, 39 insertions(+), 148 deletions(-) rename src/ci/docker/host-x86_64/disabled/{riscv64gc-linux => riscv64gc-gnu}/Dockerfile (54%) rename src/ci/docker/host-x86_64/disabled/{riscv64gc-linux => riscv64gc-gnu}/linux.config (100%) delete mode 100644 src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile similarity index 54% rename from src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile rename to src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile index 07260be3587..bc7f8c30673 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile @@ -1,39 +1,36 @@ # based on armhf-gnu/Dockerfile -FROM ubuntu:20.04 +FROM ubuntu:22.04 -RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections +ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update -y && apt-get install -y --no-install-recommends \ - bc \ - bison \ - ca-certificates \ - cmake \ - cpio \ - curl \ - debian-ports-archive-keyring \ - debootstrap \ - flex \ - gcc \ - gcc-riscv64-linux-gnu \ - git \ - g++-riscv64-linux-gnu \ - g++ \ - libc6-dev \ - libc6-dev-riscv64-cross \ - libssl-dev \ - make \ - ninja-build \ - patch \ - python3 \ - qemu-system-misc \ - xz-utils + bc \ + bzip2 \ + ca-certificates \ + cmake \ + cpio \ + curl \ + file \ + flex \ + bison \ + g++ \ + g++-riscv64-linux-gnu \ + git \ + libc6-dev \ + libc6-dev-riscv64-cross \ + libssl-dev \ + make \ + ninja-build \ + python3 \ + qemu-system-riscv64 \ + xz-utils -ENV ARCH=riscv -ENV CROSS_COMPILE=riscv64-linux-gnu- +ENV ARCH=riscv \ + CROSS_COMPILE=riscv64-linux-gnu- WORKDIR /build # From https://github.com/michaeljclark/busybear-linux/blob/master/conf/linux.config -COPY host-x86_64/riscv64gc-linux/linux.config /build +COPY host-x86_64/riscv64gc-gnu/linux.config /build # Compile the kernel that we're going to be emulating with. This is # basically just done to be compatible with the QEMU target that we're going @@ -49,29 +46,22 @@ RUN curl https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.16.tar.xz | tar # Compile an instance of busybox as this provides a lightweight system and init # binary which we will boot into. Only trick here is configuring busybox to # build static binaries. -RUN curl https://busybox.net/downloads/busybox-1.31.1.tar.bz2 | tar xjf - -COPY host-x86_64/riscv64gc-linux/0001-Remove-stime-function-calls.patch /build/busybox-1.31.1/ -RUN cd /build/busybox-1.31.1 && \ - patch -p1 -i 0001-Remove-stime-function-calls.patch && \ - make defconfig && \ - sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config && \ - make -j$(nproc) && \ - make install && \ - mv _install /tmp/rootfs && \ - cd /build && \ - rm -rf busybox-1.31.1 +RUN curl https://www.busybox.net/downloads/busybox-1.32.1.tar.bz2 | tar xjf - && \ + cd busybox-1.32.1 && \ + make defconfig && \ + sed -i 's/.*CONFIG_STATIC.*/CONFIG_STATIC=y/' .config && \ + make -j$(nproc) && \ + make install && \ + mv _install /tmp/rootfs && \ + cd /build && \ + rm -rf busybox-1.32.1 -# Download the ubuntu rootfs, which we'll use as a chroot for all our tests -# This is only needed to provide /lib/* and /usr/lib/* +# Download the ubuntu rootfs, which we'll use as a chroot for all our tests. WORKDIR /tmp -RUN debootstrap --variant=minbase --arch=riscv64 --foreign focal /tmp/rootfs/ubuntu -RUN cd rootfs && mkdir proc sys dev etc etc/init.d -# rootfs/ubuntu/proc is in a weird state (access fails with ELOOP) until -# rootfs/ubuntu/debootstrap/debootstrap --second-stage is run (under emulation), -# but this takes ages. Instead hack it into a good enough state. -# /proc is used by std::env::current_exe() (which is roughly -# `readlink /proc/self/exe`) -RUN cd rootfs/ubuntu && rm -rf proc && mkdir proc +RUN mkdir rootfs/ubuntu +RUN curl https://cdimage.ubuntu.com/ubuntu-base/releases/22.04/release/ubuntu-base-22.04.2-base-riscv64.tar.gz | \ + tar xzf - -C rootfs/ubuntu && \ + cd rootfs && mkdir proc sys dev etc etc/init.d # Copy over our init script, which starts up our test server and also a few other # misc tasks @@ -95,9 +85,6 @@ RUN mkdir build && cd build && \ WORKDIR /tmp RUN rm -rf /tmp/riscv-pk -COPY scripts/cmake.sh /scripts/ -RUN /scripts/cmake.sh - COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/linux.config b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config similarity index 100% rename from src/ci/docker/host-x86_64/disabled/riscv64gc-linux/linux.config rename to src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch deleted file mode 100644 index 4437a870b20..00000000000 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c820da85c65c7f3aa9e9cb3ed71ada69bf9b783e Mon Sep 17 00:00:00 2001 -From: Alistair Francis -Date: Tue, 19 Nov 2019 13:06:40 +0100 -Subject: [PATCH] Remove stime() function calls - -stime() has been deprecated in glibc 2.31 and replaced with -clock_settime(). Let's replace the stime() function calls with -clock_settime() in preparation. - -function old new delta -rdate_main 197 224 +27 -clock_settime - 27 +27 -date_main 926 941 +15 -stime 37 - -37 ------------------------------------------------------------------------------- -(add/remove: 2/2 grow/shrink: 2/0 up/down: 69/-37) Total: 32 bytes - -Signed-off-by: Alistair Francis -Signed-off-by: Denys Vlasenko - -[Tom Eccles: adjust patch context to apply on top of 1.31.1-stable] -Signed-off-by: Tom Eccles ---- - coreutils/date.c | 6 +++++- - libbb/missing_syscalls.c | 8 -------- - util-linux/rdate.c | 8 ++++++-- - 3 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/coreutils/date.c b/coreutils/date.c -index 3414d38ae..4ade6abb4 100644 ---- a/coreutils/date.c -+++ b/coreutils/date.c -@@ -279,6 +279,9 @@ int date_main(int argc UNUSED_PARAM, char **argv) - time(&ts.tv_sec); - #endif - } -+#if !ENABLE_FEATURE_DATE_NANO -+ ts.tv_nsec = 0; -+#endif - localtime_r(&ts.tv_sec, &tm_time); - - /* If date string is given, update tm_time, and maybe set date */ -@@ -301,9 +304,10 @@ int date_main(int argc UNUSED_PARAM, char **argv) - if (date_str[0] != '@') - tm_time.tm_isdst = -1; - ts.tv_sec = validate_tm_time(date_str, &tm_time); -+ ts.tv_nsec = 0; - - /* if setting time, set it */ -- if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) { -+ if ((opt & OPT_SET) && clock_settime(CLOCK_REALTIME, &ts) < 0) { - bb_perror_msg("can't set date"); - } - } -diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c -index 87cf59b3d..dc40d9155 100644 ---- a/libbb/missing_syscalls.c -+++ b/libbb/missing_syscalls.c -@@ -15,14 +15,6 @@ pid_t getsid(pid_t pid) - return syscall(__NR_getsid, pid); - } - --int stime(const time_t *t) --{ -- struct timeval tv; -- tv.tv_sec = *t; -- tv.tv_usec = 0; -- return settimeofday(&tv, NULL); --} -- - int sethostname(const char *name, size_t len) - { - return syscall(__NR_sethostname, name, len); -diff --git a/util-linux/rdate.c b/util-linux/rdate.c -index 70f829e7f..878375d78 100644 ---- a/util-linux/rdate.c -+++ b/util-linux/rdate.c -@@ -95,9 +95,13 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) - if (!(flags & 2)) { /* no -p (-s may be present) */ - if (time(NULL) == remote_time) - bb_error_msg("current time matches remote time"); -- else -- if (stime(&remote_time) < 0) -+ else { -+ struct timespec ts; -+ ts.tv_sec = remote_time; -+ ts.tv_nsec = 0; -+ if (clock_settime(CLOCK_REALTIME, &ts) < 0) - bb_perror_msg_and_die("can't set time of day"); -+ } - } - - if (flags != 1) /* not lone -s */ --- -2.25.1 - From aafa93feeeff5a2c24cf375923b5ce116bf96425 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Wed, 29 May 2024 07:34:21 -0700 Subject: [PATCH 038/153] Move riscv64-gnu test out of disabled --- .../docker/host-x86_64/{disabled => }/riscv64gc-gnu/Dockerfile | 0 .../host-x86_64/{disabled => }/riscv64gc-gnu/linux.config | 0 src/ci/github-actions/jobs.yml | 3 +++ 3 files changed, 3 insertions(+) rename src/ci/docker/host-x86_64/{disabled => }/riscv64gc-gnu/Dockerfile (100%) rename src/ci/docker/host-x86_64/{disabled => }/riscv64gc-gnu/linux.config (100%) diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile b/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile similarity index 100% rename from src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile rename to src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config b/src/ci/docker/host-x86_64/riscv64gc-gnu/linux.config similarity index 100% rename from src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config rename to src/ci/docker/host-x86_64/riscv64gc-gnu/linux.config diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 48c39d2c33e..8c1ca64f0c4 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -118,6 +118,9 @@ auto: - image: armhf-gnu <<: *job-linux-4c + - image: riscv64gc-gnu + <<: *job-linux-4c + - image: dist-aarch64-linux env: CODEGEN_BACKENDS: llvm,cranelift From f2e7d79e0c7f3f20032b4c8755e949787abe695f Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Wed, 29 May 2024 07:35:22 -0700 Subject: [PATCH 039/153] Add riscv64-gnu to PR tests --- src/ci/github-actions/jobs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 8c1ca64f0c4..72d0ace0a13 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -91,6 +91,9 @@ pr: <<: *job-linux-16c - image: x86_64-gnu-tools <<: *job-linux-16c + # TODO: This is temporary and for testing https://github.com/rust-lang/rust/pull/125669 + - image: riscv64gc-gnu + <<: *job-linux-4c # Jobs that run when you perform a try build (@bors try) # These jobs automatically inherit envs.try, to avoid repeating From 4c4eb39bc50230f5d50f451f323cfef2e70962d6 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Fri, 31 May 2024 07:46:24 -0700 Subject: [PATCH 040/153] Add workaround for git dubious ownership issue --- src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile b/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile index bc7f8c30673..a9ffa5918b5 100644 --- a/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile @@ -88,6 +88,9 @@ RUN rm -rf /tmp/riscv-pk COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +# Avoid "fatal: detected dubious ownership in repository at '/checkout'" error +RUN git config --global --add safe.directory /checkout + ENV RUST_CONFIGURE_ARGS --qemu-riscv64-rootfs=/tmp/rootfs ENV SCRIPT python3 ../x.py --stage 2 test --host='' --target riscv64gc-unknown-linux-gnu From 6e3134972ed18e095c27378287b85c0ad455e35a Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Mon, 10 Jun 2024 12:37:32 -0700 Subject: [PATCH 041/153] Simplify provider api to improve llvm ir --- library/core/src/error.rs | 51 ++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/library/core/src/error.rs b/library/core/src/error.rs index da18fdc6e1d..042a8c9925f 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -404,9 +404,9 @@ fn request_by_type_tag<'a, I>(err: &'a (impl Error + ?Sized)) -> Option, { - let mut tagged = TaggedOption::<'a, I>(None); + let mut tagged = Tagged { tag_id: TypeId::of::(), value: TaggedOption::<'a, I>(None) }; err.provide(tagged.as_request()); - tagged.0 + tagged.value.0 } /////////////////////////////////////////////////////////////////////////////// @@ -507,16 +507,9 @@ where /// #[unstable(feature = "error_generic_member_access", issue = "99301")] #[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 -pub struct Request<'a>(dyn Erased<'a> + 'a); +pub struct Request<'a>(Tagged + 'a>); impl<'a> Request<'a> { - /// Create a new `&mut Request` from a `&mut dyn Erased` trait object. - fn new<'b>(erased: &'b mut (dyn Erased<'a> + 'a)) -> &'b mut Request<'a> { - // SAFETY: transmuting `&mut (dyn Erased<'a> + 'a)` to `&mut Request<'a>` is safe since - // `Request` is repr(transparent). - unsafe { &mut *(erased as *mut dyn Erased<'a> as *mut Request<'a>) } - } - /// Provide a value or other type with only static lifetimes. /// /// # Examples @@ -940,27 +933,28 @@ pub(crate) mod tags { #[repr(transparent)] pub(crate) struct TaggedOption<'a, I: tags::Type<'a>>(pub Option); -impl<'a, I: tags::Type<'a>> TaggedOption<'a, I> { +impl<'a, I: tags::Type<'a>> Tagged> { pub(crate) fn as_request(&mut self) -> &mut Request<'a> { - Request::new(self as &mut (dyn Erased<'a> + 'a)) + let erased = self as &mut Tagged + 'a>; + // SAFETY: transmuting `&mut Tagged + 'a>` to `&mut Request<'a>` is safe since + // `Request` is repr(transparent). + unsafe { &mut *(erased as *mut Tagged> as *mut Request<'a>) } } } /// Represents a type-erased but identifiable object. /// /// This trait is exclusively implemented by the `TaggedOption` type. -unsafe trait Erased<'a>: 'a { - /// The `TypeId` of the erased type. - fn tag_id(&self) -> TypeId; +unsafe trait Erased<'a>: 'a {} + +unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> {} + +struct Tagged { + tag_id: TypeId, + value: E, } -unsafe impl<'a, I: tags::Type<'a>> Erased<'a> for TaggedOption<'a, I> { - fn tag_id(&self) -> TypeId { - TypeId::of::() - } -} - -impl<'a> dyn Erased<'a> + 'a { +impl<'a> Tagged + 'a> { /// Returns some reference to the dynamic value if it is tagged with `I`, /// or `None` otherwise. #[inline] @@ -968,9 +962,9 @@ impl<'a> dyn Erased<'a> + 'a { where I: tags::Type<'a>, { - if self.tag_id() == TypeId::of::() { + if self.tag_id == TypeId::of::() { // SAFETY: Just checked whether we're pointing to an I. - Some(unsafe { &*(self as *const Self).cast::>() }) + Some(&unsafe { &*(self as *const Self).cast::>>() }.value) } else { None } @@ -983,9 +977,12 @@ impl<'a> dyn Erased<'a> + 'a { where I: tags::Type<'a>, { - if self.tag_id() == TypeId::of::() { - // SAFETY: Just checked whether we're pointing to an I. - Some(unsafe { &mut *(self as *mut Self).cast::>() }) + if self.tag_id == TypeId::of::() { + Some( + // SAFETY: Just checked whether we're pointing to an I. + &mut unsafe { &mut *(self as *mut Self).cast::>>() } + .value, + ) } else { None } From e1b489db8803a233d2d6633cc6aae513e0867224 Mon Sep 17 00:00:00 2001 From: Ana Hobden Date: Mon, 10 Jun 2024 13:25:56 -0700 Subject: [PATCH 042/153] Re-disable riscv64-gnu test --- .../host-x86_64/{ => disabled}/riscv64gc-gnu/Dockerfile | 0 .../host-x86_64/{ => disabled}/riscv64gc-gnu/linux.config | 0 src/ci/github-actions/jobs.yml | 6 ------ 3 files changed, 6 deletions(-) rename src/ci/docker/host-x86_64/{ => disabled}/riscv64gc-gnu/Dockerfile (100%) rename src/ci/docker/host-x86_64/{ => disabled}/riscv64gc-gnu/linux.config (100%) diff --git a/src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile similarity index 100% rename from src/ci/docker/host-x86_64/riscv64gc-gnu/Dockerfile rename to src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/Dockerfile diff --git a/src/ci/docker/host-x86_64/riscv64gc-gnu/linux.config b/src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config similarity index 100% rename from src/ci/docker/host-x86_64/riscv64gc-gnu/linux.config rename to src/ci/docker/host-x86_64/disabled/riscv64gc-gnu/linux.config diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 72d0ace0a13..48c39d2c33e 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -91,9 +91,6 @@ pr: <<: *job-linux-16c - image: x86_64-gnu-tools <<: *job-linux-16c - # TODO: This is temporary and for testing https://github.com/rust-lang/rust/pull/125669 - - image: riscv64gc-gnu - <<: *job-linux-4c # Jobs that run when you perform a try build (@bors try) # These jobs automatically inherit envs.try, to avoid repeating @@ -121,9 +118,6 @@ auto: - image: armhf-gnu <<: *job-linux-4c - - image: riscv64gc-gnu - <<: *job-linux-4c - - image: dist-aarch64-linux env: CODEGEN_BACKENDS: llvm,cranelift From 168d5c245f28bcf9fe860f7167736c4d5ac13846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 11 Jun 2024 08:11:04 +0200 Subject: [PATCH 043/153] Take `&self` in `CompletedProcess` assert matchers --- src/tools/run-make-support/src/command.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index b9e56ab632a..cc395e491ee 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -107,38 +107,38 @@ impl CompletedProcess { /// Checks that trimmed `stdout` matches trimmed `content`. #[track_caller] - pub fn assert_stdout_equals>(self, content: S) -> Self { + pub fn assert_stdout_equals>(&self, content: S) -> &Self { assert_eq!(self.stdout_utf8().trim(), content.as_ref().trim()); self } #[track_caller] - pub fn assert_stdout_not_contains>(self, needle: S) -> Self { + pub fn assert_stdout_not_contains>(&self, needle: S) -> &Self { assert_not_contains(&self.stdout_utf8(), needle.as_ref()); self } /// Checks that trimmed `stderr` matches trimmed `content`. #[track_caller] - pub fn assert_stderr_equals>(self, content: S) -> Self { + pub fn assert_stderr_equals>(&self, content: S) -> &Self { assert_eq!(self.stderr_utf8().trim(), content.as_ref().trim()); self } #[track_caller] - pub fn assert_stderr_contains>(self, needle: S) -> Self { + pub fn assert_stderr_contains>(&self, needle: S) -> &Self { assert!(self.stderr_utf8().contains(needle.as_ref())); self } #[track_caller] - pub fn assert_stderr_not_contains>(self, needle: S) -> Self { + pub fn assert_stderr_not_contains>(&self, needle: S) -> &Self { assert_not_contains(&self.stdout_utf8(), needle.as_ref()); self } #[track_caller] - pub fn assert_exit_code(self, code: i32) -> Self { + pub fn assert_exit_code(&self, code: i32) -> &Self { assert!(self.output.status.code() == Some(code)); self } From b3c2d667124a613a7c579c0e67b427be34e83e88 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 10 Jun 2024 13:00:50 +0200 Subject: [PATCH 044/153] Remove ignore-cross-compile directive from ui/macros/proc_macro --- tests/ui/macros/proc_macro.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ui/macros/proc_macro.rs b/tests/ui/macros/proc_macro.rs index ce2b041c26e..8fea4ca282c 100644 --- a/tests/ui/macros/proc_macro.rs +++ b/tests/ui/macros/proc_macro.rs @@ -1,6 +1,5 @@ //@ run-pass //@ aux-build:proc_macro_def.rs -//@ ignore-cross-compile extern crate proc_macro_def; From 1462f3d4eb6d5ce18c9c430c10315bc5543090bc Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 11 Jun 2024 08:42:20 +0200 Subject: [PATCH 045/153] Add {{target}} substitution to compiletest --- src/tools/compiletest/src/header.rs | 5 +++++ src/tools/tidy/src/target_specific_tests.rs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index fd4ab72bbf4..fc6c7217222 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1281,6 +1281,7 @@ fn expand_variables(mut value: String, config: &Config) -> String { const BUILD_BASE: &str = "{{build-base}}"; const SYSROOT_BASE: &str = "{{sysroot-base}}"; const TARGET_LINKER: &str = "{{target-linker}}"; + const TARGET: &str = "{{target}}"; if value.contains(CWD) { let cwd = env::current_dir().unwrap(); @@ -1303,6 +1304,10 @@ fn expand_variables(mut value: String, config: &Config) -> String { value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or("")); } + if value.contains(TARGET) { + value = value.replace(TARGET, &config.target); + } + value } diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index f3a64b38e8c..8be27d1e117 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -53,9 +53,9 @@ pub fn check(path: &Path, bad: &mut bool) { } else if directive.starts_with(COMPILE_FLAGS_HEADER) { let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..]; if let Some((_, v)) = compile_flags.split_once("--target") { - if let Some((arch, _)) = - v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-") - { + let v = v.trim_start_matches(|c| c == ' ' || c == '='); + let v = if v == "{{target}}" { Some((v, v)) } else { v.split_once("-") }; + if let Some((arch, _)) = v { let info = header_map.entry(revision).or_insert(RevisionInfo::default()); info.target_arch.replace(arch); } else { From 3923b686c727ceaad7a6a9139c5f0d73e29a21e7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 11 Jun 2024 16:37:23 +1000 Subject: [PATCH 046/153] Rename `needs-matching-clang` to `needs-force-clang-based-tests` This header is much more restrictive than its old name would suggest. As a result, most of the tests that use it don't actually run in any CI jobs. --- src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile | 2 +- src/tools/compiletest/src/header.rs | 2 +- src/tools/compiletest/src/header/needs.rs | 4 ++-- tests/run-make/cross-lang-lto-clang/Makefile | 2 +- tests/run-make/cross-lang-lto-pgo-smoketest/Makefile | 5 ++++- tests/run-make/cross-lang-lto-riscv-abi/rmake.rs | 5 ++++- tests/run-make/issue-84395-lto-embed-bitcode/Makefile | 5 ++++- tests/run-make/wasm-override-linker/Makefile | 5 ++++- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile index 64a1fb093b4..fa31801269a 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile @@ -47,7 +47,7 @@ ENV RUST_CONFIGURE_ARGS \ # This job appears to be checking two separate things: # - That we can build the compiler with `--enable-debug` # (without necessarily testing the result). -# - That the tests with `//@ needs-matching-clang` pass, since they +# - That the tests with `//@ needs-force-clang-based-tests` pass, since they # don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set. # - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273): # Currently we only run the subset of tests with "clang" in their name. diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index fd4ab72bbf4..a5475a158de 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -854,9 +854,9 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-asm-support", "needs-dlltool", "needs-dynamic-linking", + "needs-force-clang-based-tests", "needs-git-hash", "needs-llvm-components", - "needs-matching-clang", "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 7bc7e4b8680..b96832db67b 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -100,9 +100,9 @@ pub(super) fn handle_needs( ignore_reason: "ignored when profiler support is disabled", }, Need { - name: "needs-matching-clang", + name: "needs-force-clang-based-tests", condition: config.run_clang_based_tests_with.is_some(), - ignore_reason: "ignored when the used clang does not match the built LLVM", + ignore_reason: "ignored when RUSTBUILD_FORCE_CLANG_BASED_TESTS is not set", }, Need { name: "needs-xray", diff --git a/tests/run-make/cross-lang-lto-clang/Makefile b/tests/run-make/cross-lang-lto-clang/Makefile index acaebf439d6..acf49c8f5c8 100644 --- a/tests/run-make/cross-lang-lto-clang/Makefile +++ b/tests/run-make/cross-lang-lto-clang/Makefile @@ -1,4 +1,4 @@ -# needs-matching-clang +# needs-force-clang-based-tests # This test makes sure that cross-language inlining actually works by checking # the generated machine code. diff --git a/tests/run-make/cross-lang-lto-pgo-smoketest/Makefile b/tests/run-make/cross-lang-lto-pgo-smoketest/Makefile index 70085d9bde1..738e23f9c66 100644 --- a/tests/run-make/cross-lang-lto-pgo-smoketest/Makefile +++ b/tests/run-make/cross-lang-lto-pgo-smoketest/Makefile @@ -1,4 +1,7 @@ -# needs-matching-clang +# needs-force-clang-based-tests + +# FIXME(#126180): This test doesn't actually run anywhere, because the only +# CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. # This test makes sure that cross-language inlining can be used in conjunction # with profile-guided optimization. The test only tests that the whole workflow diff --git a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs index 04afc92bf7e..f40da662128 100644 --- a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs +++ b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs @@ -1,8 +1,11 @@ //! Make sure that cross-language LTO works on riscv targets, //! which requires extra `target-abi` metadata to be emitted. -//@ needs-matching-clang +//@ needs-force-clang-based-tests //@ needs-llvm-components riscv +// FIXME(#126180): This test doesn't actually run anywhere, because the only +// CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. + use run_make_support::{bin_name, clang, llvm_readobj, rustc}; use std::{ env, diff --git a/tests/run-make/issue-84395-lto-embed-bitcode/Makefile b/tests/run-make/issue-84395-lto-embed-bitcode/Makefile index 95c8d08a18b..aabe90754a6 100644 --- a/tests/run-make/issue-84395-lto-embed-bitcode/Makefile +++ b/tests/run-make/issue-84395-lto-embed-bitcode/Makefile @@ -1,4 +1,7 @@ -# needs-matching-clang +# needs-force-clang-based-tests + +# FIXME(#126180): This test doesn't actually run anywhere, because the only +# CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. # This test makes sure the embed bitcode in elf created with # lto-embed-bitcode=optimized is valid llvm BC module. diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile index 52339f9261c..1a01a574dee 100644 --- a/tests/run-make/wasm-override-linker/Makefile +++ b/tests/run-make/wasm-override-linker/Makefile @@ -1,4 +1,7 @@ -# needs-matching-clang +# needs-force-clang-based-tests + +# FIXME(#126180): This test doesn't actually run anywhere, because the only +# CI job that sets RUSTBUILD_FORCE_CLANG_BASED_TESTS runs very few tests. include ../tools.mk From d041b7cf30bb5b5236cd9148cde7a3017ed28679 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jun 2024 07:47:58 +0200 Subject: [PATCH 047/153] check for correct trait in size_and_align_of --- compiler/rustc_const_eval/src/interpret/eval_context.rs | 4 ++-- compiler/rustc_const_eval/src/interpret/intrinsics.rs | 6 ++++-- compiler/rustc_const_eval/src/interpret/traits.rs | 3 ++- src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 7c2100fcbe3..e28cc05cc2a 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -765,10 +765,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } Ok(Some((full_size, full_align))) } - ty::Dynamic(_, _, ty::Dyn) => { + ty::Dynamic(expected_trait, _, ty::Dyn) => { let vtable = metadata.unwrap_meta().to_pointer(self)?; // Read size and align from vtable (already checks size). - Ok(Some(self.get_vtable_size_and_align(vtable)?)) + Ok(Some(self.get_vtable_size_and_align(vtable, Some(expected_trait))?)) } ty::Slice(_) | ty::Str => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 18b76443cd9..497ae500144 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -432,12 +432,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { sym::vtable_size => { let ptr = self.read_pointer(&args[0])?; - let (size, _align) = self.get_vtable_size_and_align(ptr)?; + // `None` because we don't know which trait to expect here; any vtable is okay. + let (size, _align) = self.get_vtable_size_and_align(ptr, None)?; self.write_scalar(Scalar::from_target_usize(size.bytes(), self), dest)?; } sym::vtable_align => { let ptr = self.read_pointer(&args[0])?; - let (_size, align) = self.get_vtable_size_and_align(ptr)?; + // `None` because we don't know which trait to expect here; any vtable is okay. + let (_size, align) = self.get_vtable_size_and_align(ptr, None)?; self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 1df9f5f7b2a..44e7244a513 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -36,8 +36,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn get_vtable_size_and_align( &self, vtable: Pointer>, + expected_trait: Option<&'tcx ty::List>>, ) -> InterpResult<'tcx, (Size, Align)> { - let ty = self.get_ptr_vtable_ty(vtable, None)?; + let ty = self.get_ptr_vtable_ty(vtable, expected_trait)?; let layout = self.layout_of(ty)?; assert!(layout.is_sized(), "there are no vtables for unsized types"); Ok((layout.size, layout.align.abi)) diff --git a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs index f71df9a1c90..982d57b7372 100644 --- a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs +++ b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs @@ -1,5 +1,5 @@ -// Validation stops this too early. -//@compile-flags: -Zmiri-disable-validation +// Validation and SB stop this too early. +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows trait T1 { #[allow(dead_code)] From 3757136d8e0d8ddca294453e5a5ce70cfa3417e9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 10 Jun 2024 17:26:36 +0200 Subject: [PATCH 048/153] interpret: dyn trait metadata check: equate traits in a proper way --- .../rustc_const_eval/src/interpret/memory.rs | 4 +- .../rustc_const_eval/src/interpret/traits.rs | 36 ++++++++++++++++- ...iri-3541-dyn-vtable-trait-normalization.rs | 40 +++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 src/tools/miri/tests/pass/issues/issue-miri-3541-dyn-vtable-trait-normalization.rs diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 84c6dad1cd3..e2e39399f3a 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -884,9 +884,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub!(InvalidVTablePointer(Pointer::new(alloc_id, offset))) }; if let Some(expected_trait) = expected_trait { - if vtable_trait != expected_trait.principal() { - throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait }); - } + self.check_vtable_for_type(vtable_trait, expected_trait)?; } Ok(ty) } diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 44e7244a513..bd2c6519421 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -1,11 +1,14 @@ +use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::traits::ObligationCause; use rustc_middle::mir::interpret::{InterpResult, Pointer}; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::{Align, Size}; +use rustc_trait_selection::traits::ObligationCtxt; use tracing::trace; use super::util::ensure_monomorphic_enough; -use super::{InterpCx, MPlaceTy, Machine, MemPlaceMeta, OffsetMode, Projectable}; +use super::{throw_ub, InterpCx, MPlaceTy, Machine, MemPlaceMeta, OffsetMode, Projectable}; impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for @@ -44,6 +47,37 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Ok((layout.size, layout.align.abi)) } + /// Check that the given vtable trait is valid for a pointer/reference/place with the given + /// expected trait type. + pub(super) fn check_vtable_for_type( + &self, + vtable_trait: Option>, + expected_trait: &'tcx ty::List>, + ) -> InterpResult<'tcx> { + // Fast path: if they are equal, it's all fine. + if expected_trait.principal() == vtable_trait { + return Ok(()); + } + if let (Some(expected_trait), Some(vtable_trait)) = + (expected_trait.principal(), vtable_trait) + { + // Slow path: spin up an inference context to check if these traits are sufficiently equal. + let infcx = self.tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + let cause = ObligationCause::dummy_with_span(self.cur_span()); + // equate the two trait refs after normalization + let expected_trait = ocx.normalize(&cause, self.param_env, expected_trait); + let vtable_trait = ocx.normalize(&cause, self.param_env, vtable_trait); + if ocx.eq(&cause, self.param_env, expected_trait, vtable_trait).is_ok() { + if ocx.select_all_or_error().is_empty() { + // All good. + return Ok(()); + } + } + } + throw_ub!(InvalidVTableTrait { expected_trait, vtable_trait }); + } + /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. pub(super) fn unpack_dyn_trait( &self, diff --git a/src/tools/miri/tests/pass/issues/issue-miri-3541-dyn-vtable-trait-normalization.rs b/src/tools/miri/tests/pass/issues/issue-miri-3541-dyn-vtable-trait-normalization.rs new file mode 100644 index 00000000000..c46031de2d8 --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-miri-3541-dyn-vtable-trait-normalization.rs @@ -0,0 +1,40 @@ +#![feature(ptr_metadata)] +// This test is the result of minimizing the `emplacable` crate to reproduce +// . + +use std::{ops::FnMut, ptr::Pointee}; + +pub type EmplacerFn<'a, T> = dyn for<'b> FnMut(::Metadata) + 'a; + +#[repr(transparent)] +pub struct Emplacer<'a, T>(EmplacerFn<'a, T>) +where + T: ?Sized; + +impl<'a, T> Emplacer<'a, T> +where + T: ?Sized, +{ + pub unsafe fn from_fn<'b>(emplacer_fn: &'b mut EmplacerFn<'a, T>) -> &'b mut Self { + // This used to trigger: + // constructing invalid value: wrong trait in wide pointer vtable: expected + // `std::ops::FnMut(<[std::boxed::Box] as std::ptr::Pointee>::Metadata)`, but encountered + // `std::ops::FnMut<(usize,)>`. + unsafe { &mut *((emplacer_fn as *mut EmplacerFn<'a, T>) as *mut Self) } + } +} + +pub fn box_new_with() +where + T: ?Sized, +{ + let emplacer_closure = &mut |_meta| { + unreachable!(); + }; + + unsafe { Emplacer::::from_fn(emplacer_closure) }; +} + +fn main() { + box_new_with::<[Box]>(); +} From be4cd53536768f3b4dc27316dccfa1a0f595fc7e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jun 2024 09:05:36 +0200 Subject: [PATCH 049/153] reachable computation: clarify comments around consts --- compiler/rustc_passes/src/reachable.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 74b89546e6f..6dd8eaf7e67 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -207,18 +207,21 @@ impl<'tcx> ReachableContext<'tcx> { } hir::ItemKind::Const(_, _, init) => { - // Only things actually ending up in the final constant need to be reachable. - // Everything else is either already available as `mir_for_ctfe`, or can't be used - // by codegen anyway. + // Only things actually ending up in the final constant value are reachable + // for codegen. Everything else is only needed during const-eval, so even if + // const-eval happens in a downstream crate, all they need is + // `mir_for_ctfe`. match self.tcx.const_eval_poly_to_alloc(item.owner_id.def_id.into()) { Ok(alloc) => { let alloc = self.tcx.global_alloc(alloc.alloc_id).unwrap_memory(); self.propagate_from_alloc(alloc); } - // Reachable generic constants will be inlined into other crates - // unconditionally, so we need to make sure that their - // contents are also reachable. + // We can't figure out which value the constant will evaluate to. In + // lieu of that, we have to consider everything mentioned in the const + // initializer reachable, since it *may* end up in the final value. Err(ErrorHandled::TooGeneric(_)) => self.visit_nested_body(init), + // If there was an error evaluating the const, nothing can be reachable + // via it, and anyway compilation will fail. Err(ErrorHandled::Reported(..)) => {} } } From fe55c0091db4654ad0185831aa3dd110e5e6cd73 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 06:49:05 +0000 Subject: [PATCH 050/153] Add regression test --- tests/ui/impl-trait/recursive-bound-eval.rs | 18 ++++++++ .../ui/impl-trait/recursive-bound-eval.stderr | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 tests/ui/impl-trait/recursive-bound-eval.rs create mode 100644 tests/ui/impl-trait/recursive-bound-eval.stderr diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs new file mode 100644 index 00000000000..f992cb3071a --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -0,0 +1,18 @@ +pub trait Parser { + fn parse(&self) -> E; +} + +impl E> Parser for T { + fn parse(&self) -> E { + self() + } +} + +pub fn recursive_fn() -> impl Parser { + //~^ ERROR: cycle detected + move || recursive_fn().parse() + //~^ ERROR: type annotations needed + //~| ERROR: no method named `parse` found for opaque type +} + +fn main() {} diff --git a/tests/ui/impl-trait/recursive-bound-eval.stderr b/tests/ui/impl-trait/recursive-bound-eval.stderr new file mode 100644 index 00000000000..c7283380234 --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.stderr @@ -0,0 +1,42 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-bound-eval.rs:13:28 + | +LL | move || recursive_fn().parse() + | ^^^^^ cannot infer type + +error[E0599]: no method named `parse` found for opaque type `impl Parser<_>` in the current scope + --> $DIR/recursive-bound-eval.rs:13:28 + | +LL | move || recursive_fn().parse() + | ^^^^^ method not found in `impl Parser<_>` + | + = help: items from traits can only be used if the trait is implemented and in scope +help: trait `Parser` which provides `parse` is implemented but not in scope; perhaps you want to import it + | +LL + use Parser; + | + +error[E0391]: cycle detected when computing type of opaque `recursive_fn::{opaque#0}` + --> $DIR/recursive-bound-eval.rs:11:29 + | +LL | pub fn recursive_fn() -> impl Parser { + | ^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `recursive_fn`... + --> $DIR/recursive-bound-eval.rs:13:13 + | +LL | move || recursive_fn().parse() + | ^^^^^^^^^^^^^^ + = note: ...which requires evaluating trait selection obligation `recursive_fn::{opaque#0}: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `recursive_fn::{opaque#0}`, completing the cycle +note: cycle used when computing type of `recursive_fn::{opaque#0}` + --> $DIR/recursive-bound-eval.rs:11:29 + | +LL | pub fn recursive_fn() -> impl Parser { + | ^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0391, E0599. +For more information about an error, try `rustc --explain E0282`. From 6cca6da1265b9bede368f34da6be42057adc9834 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 06:49:12 +0000 Subject: [PATCH 051/153] Revert "When checking whether an impl applies, constrain hidden types of opaque types." This reverts commit 29a630eb72ffb94c3708947afae1e948ad3cb189. --- .../src/traits/select/mod.rs | 2 +- tests/ui/impl-trait/equality.rs | 13 +++--- tests/ui/impl-trait/equality.stderr | 15 +++++-- tests/ui/impl-trait/nested_impl_trait.stderr | 16 +++---- tests/ui/impl-trait/recursive-bound-eval.rs | 8 ++-- .../ui/impl-trait/recursive-bound-eval.stderr | 42 ------------------- ...rsive-type-alias-impl-trait-declaration.rs | 2 +- ...e-type-alias-impl-trait-declaration.stderr | 12 ++++-- .../constrain_in_projection.current.stderr | 11 +++++ .../constrain_in_projection.rs | 3 +- .../constrain_in_projection2.current.stderr | 18 +++----- .../constrain_in_projection2.rs | 3 +- .../issue-84660-unsoundness.next.stderr | 23 ---------- .../issue-84660-unsoundness.rs | 8 +--- ....stderr => issue-84660-unsoundness.stderr} | 2 +- .../nested-tait-inference.rs | 13 +++--- .../nested-tait-inference2.current.stderr | 17 -------- .../nested-tait-inference2.next.stderr | 9 ---- .../nested-tait-inference2.rs | 7 +--- .../nested-tait-inference2.stderr | 16 +++++++ .../normalize-hidden-types.current.stderr | 19 +++++---- .../self-referential-2.current.stderr | 14 +++++++ .../self-referential-2.rs | 4 +- .../self-referential-3.rs | 2 +- .../self-referential-3.stderr | 12 ++++-- 25 files changed, 120 insertions(+), 171 deletions(-) delete mode 100644 tests/ui/impl-trait/recursive-bound-eval.stderr create mode 100644 tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr rename tests/ui/type-alias-impl-trait/{issue-84660-unsoundness.current.stderr => issue-84660-unsoundness.stderr} (90%) delete mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr create mode 100644 tests/ui/type-alias-impl-trait/self-referential-2.current.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4a935f4a64a..4306a803524 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2563,7 +2563,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 952f81f1978..828b5aac896 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot satisfy `>::Output == i32` + //~^ ERROR cannot add `impl Foo` to `u32` } } @@ -32,15 +32,12 @@ trait Leak: Sized { } impl Leak for T { default type T = (); - default fn leak(self) -> Self::T { - panic!() - } + default fn leak(self) -> Self::T { panic!() } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { - self - } + fn leak(self) -> i32 { self } } -fn main() {} +fn main() { +} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c9ba1a5ba32..69f4cbbbf42 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,13 +22,20 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0284]: type annotations needed: cannot satisfy `>::Output == i32` +error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ cannot satisfy `>::Output == i32` + | ^ no implementation for `u32 + impl Foo` + | + = help: the trait `Add` is not implemented for `u32` + = help: the following other types implement trait `Add`: + <&'a u32 as Add> + <&u32 as Add<&u32>> + > + error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0284, E0308. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index f7c708a1dfa..1f9a2a5e9d6 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,23 +46,19 @@ error[E0277]: the trait bound `impl Into: Into` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | -help: consider further restricting this bound - | -LL | fn bad_in_ret_position(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ + = help: the trait `Into` is implemented for `T` + = note: required for `impl Into` to implement `Into` error[E0277]: the trait bound `impl Into: Into` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Into`, which is required by `impl Into: Into` | -help: consider further restricting this bound - | -LL | fn bad(x: impl Into + std::fmt::Debug) -> impl Into { x } - | +++++++++++++++++ + = help: the trait `Into` is implemented for `T` + = note: required for `impl Into` to implement `Into` error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs index f992cb3071a..591553e7ceb 100644 --- a/tests/ui/impl-trait/recursive-bound-eval.rs +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -1,3 +1,8 @@ +//! Test that we can evaluate nested obligations when invoking methods on recursive calls on +//! an RPIT. + +//@ check-pass + pub trait Parser { fn parse(&self) -> E; } @@ -9,10 +14,7 @@ impl E> Parser for T { } pub fn recursive_fn() -> impl Parser { - //~^ ERROR: cycle detected move || recursive_fn().parse() - //~^ ERROR: type annotations needed - //~| ERROR: no method named `parse` found for opaque type } fn main() {} diff --git a/tests/ui/impl-trait/recursive-bound-eval.stderr b/tests/ui/impl-trait/recursive-bound-eval.stderr deleted file mode 100644 index c7283380234..00000000000 --- a/tests/ui/impl-trait/recursive-bound-eval.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/recursive-bound-eval.rs:13:28 - | -LL | move || recursive_fn().parse() - | ^^^^^ cannot infer type - -error[E0599]: no method named `parse` found for opaque type `impl Parser<_>` in the current scope - --> $DIR/recursive-bound-eval.rs:13:28 - | -LL | move || recursive_fn().parse() - | ^^^^^ method not found in `impl Parser<_>` - | - = help: items from traits can only be used if the trait is implemented and in scope -help: trait `Parser` which provides `parse` is implemented but not in scope; perhaps you want to import it - | -LL + use Parser; - | - -error[E0391]: cycle detected when computing type of opaque `recursive_fn::{opaque#0}` - --> $DIR/recursive-bound-eval.rs:11:29 - | -LL | pub fn recursive_fn() -> impl Parser { - | ^^^^^^^^^^^^^^ - | -note: ...which requires type-checking `recursive_fn`... - --> $DIR/recursive-bound-eval.rs:13:13 - | -LL | move || recursive_fn().parse() - | ^^^^^^^^^^^^^^ - = note: ...which requires evaluating trait selection obligation `recursive_fn::{opaque#0}: core::marker::Unpin`... - = note: ...which again requires computing type of opaque `recursive_fn::{opaque#0}`, completing the cycle -note: cycle used when computing type of `recursive_fn::{opaque#0}` - --> $DIR/recursive-bound-eval.rs:11:29 - | -LL | pub fn recursive_fn() -> impl Parser { - | ^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0282, E0391, E0599. -For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index 7874a21f3ae..aab10be2de2 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` + //~^ ERROR can't compare `Bar` with `(Foo, i32)` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index 2d4707f8a27..bc810c0f88f 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,9 +1,15 @@ -error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` +error[E0277]: can't compare `Bar` with `(Foo, i32)` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ + | ^^^ no implementation for `Bar == (Foo, i32)` +LL | +LL | Bar + | --- return type was inferred to be `Bar` here + | + = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` + = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr new file mode 100644 index 00000000000..c215d197db4 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `Foo: Trait` is not satisfied + --> $DIR/constrain_in_projection.rs:24:14 + | +LL | let x = >::Assoc::default(); + | ^^^ the trait `Trait` is not implemented for `Foo` + | + = help: the trait `Trait<()>` is implemented for `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 2a246900106..7d7d16361ae 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@check-pass +//@[next]check-pass #![feature(type_alias_impl_trait)] @@ -22,6 +22,7 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); + //[current]~^ `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 0d6eac4216b..69df5c77f9d 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,19 +1,13 @@ -error[E0283]: type annotations needed: cannot satisfy `Foo: Trait` +error[E0277]: the trait bound `Foo: Trait` is not satisfied --> $DIR/constrain_in_projection2.rs:27:14 | LL | let x = >::Assoc::default(); - | ^^^ help: use the fully qualified path to an implementation: `::Assoc` + | ^^^ the trait `Trait` is not implemented for `Foo` | -note: multiple `impl`s satisfying `Foo: Trait` found - --> $DIR/constrain_in_projection2.rs:18:1 - | -LL | impl Trait<()> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Trait for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + = help: the following other types implement trait `Trait`: + > + > error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index 0066131f015..af222f6c153 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -25,7 +25,8 @@ impl Trait for Foo { fn bop(_: Bar) { let x = >::Assoc::default(); - //~^ ERROR: cannot satisfy `Foo: Trait` + //[next]~^ ERROR: cannot satisfy `Foo: Trait` + //[current]~^^ ERROR: `Foo: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr deleted file mode 100644 index 607f0b062ab..00000000000 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `>::Out == ()` - --> $DIR/issue-84660-unsoundness.rs:22:37 - | -LL | fn convert(_i: In) -> Self::Out { - | _____________________________________^ -LL | | -LL | | unreachable!(); -LL | | } - | |_____^ cannot satisfy `>::Out == ()` - -error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:28:1 - | -LL | impl Trait for Out { - | ------------------------------------ first implementation here -... -LL | impl Trait<(), In> for Out { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0119, E0284. -For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 99a5d36066b..48d4b0c96ff 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -1,10 +1,6 @@ // Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an // impl header being accepted was used to create unsoundness. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver - #![feature(type_alias_impl_trait)] trait Foo {} @@ -20,13 +16,11 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { - //[next]~^ ERROR: type annotations needed unreachable!(); } } -impl Trait<(), In> for Out { - //~^ ERROR conflicting implementations of trait `Trait` +impl Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait` type Out = In; fn convert(i: In) -> Self::Out { i diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr rename to tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr index a7ff097e8bf..461da20f37b 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:28:1 + --> $DIR/issue-84660-unsoundness.rs:23:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 70495c44706..82248971692 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -1,21 +1,18 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@check-pass - use std::fmt::Debug; type FooX = impl Debug; -trait Foo {} +trait Foo { } -impl Foo<()> for () {} +impl Foo<()> for () { } fn foo() -> impl Foo { + //~^ ERROR: the trait bound `(): Foo` is not satisfied + // FIXME(type-alias-impl-trait): We could probably make this work. () } -fn main() {} +fn main() { } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr deleted file mode 100644 index c7b7af152ab..00000000000 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0283]: type annotations needed: cannot satisfy `(): Foo` - --> $DIR/nested-tait-inference2.rs:17:13 - | -LL | fn foo() -> impl Foo { - | ^^^^^^^^^^^^^^ - | -note: multiple `impl`s satisfying `(): Foo` found - --> $DIR/nested-tait-inference2.rs:14:1 - | -LL | impl Foo<()> for () {} - | ^^^^^^^^^^^^^^^^^^^ -LL | impl Foo for () {} - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr deleted file mode 100644 index 9647d9e376e..00000000000 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `impl Foo == ()` - --> $DIR/nested-tait-inference2.rs:19:5 - | -LL | () - | ^^ cannot satisfy `impl Foo == ()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index fe2f76e552a..0d7f5bad25f 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -1,10 +1,6 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver - use std::fmt::Debug; type FooX = impl Debug; @@ -15,9 +11,8 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //[current]~^ ERROR: cannot satisfy `(): Foo` + //~^ ERROR: the trait bound `(): Foo` is not satisfied () - //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr new file mode 100644 index 00000000000..241342b0509 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/nested-tait-inference2.rs:13:13 + | +LL | fn foo() -> impl Foo { + | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` +LL | +LL | () + | -- return type was inferred to be `()` here + | + = help: the following other types implement trait `Foo`: + <() as Foo<()>> + <() as Foo> + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index eff29303bf1..a40dac06a01 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,17 +22,21 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error: concrete type differs from previous defining opaque type use +error[E0308]: mismatched types --> $DIR/normalize-hidden-types.rs:43:25 | +LL | type Opaque = impl Sized; + | ---------- the expected opaque type +... LL | let _: Opaque = dyn_hoops::(0); - | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(::Gat<'a>)` + | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` + | | + | expected due to this | -note: previous use here - --> $DIR/normalize-hidden-types.rs:44:9 - | -LL | None - | ^^^^ + = note: expected opaque type `typeck::Opaque` + found raw pointer `*const (dyn FnOnce(()) + 'static)` + = help: consider constraining the associated type `::Gat<'_>` to `()` or calling a method that returns `::Gat<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -48,3 +52,4 @@ LL | None error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr new file mode 100644 index 00000000000..3ae3590ca7f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -0,0 +1,14 @@ +error[E0277]: can't compare `i32` with `Foo` + --> $DIR/self-referential-2.rs:10:13 + | +LL | fn bar() -> Bar { + | ^^^ no implementation for `i32 == Foo` +LL | 42_i32 + | ------ return type was inferred to be `i32` here + | + = help: the trait `PartialEq` is not implemented for `i32` + = help: the trait `PartialEq` is implemented for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f4102f2e2cb..f96364ccfcd 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@ check-pass +//@[next] check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq; fn bar() -> Bar { - 42_i32 + 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index 3b015ab322a..b33051da2d7 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` + //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index caa9f9691dd..32eac622e51 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,11 +1,15 @@ -error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` +error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` +LL | +LL | i + | - return type was inferred to be `&i32` here | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + = help: the trait `PartialEq>` is not implemented for `&i32` + = help: the trait `PartialEq` is implemented for `i32` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. From 03fa9b807379dbce92b346b489acecff6082e283 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 06:54:38 +0000 Subject: [PATCH 052/153] Also test under next solver --- .../recursive-bound-eval.next.stderr | 9 ++++++++ tests/ui/impl-trait/recursive-bound-eval.rs | 6 ++++- ...=> issue-84660-unsoundness.current.stderr} | 2 +- .../issue-84660-unsoundness.next.stderr | 23 +++++++++++++++++++ .../issue-84660-unsoundness.rs | 8 ++++++- ...r => nested-tait-inference.current.stderr} | 2 +- .../nested-tait-inference.rs | 13 +++++++---- ... => nested-tait-inference2.current.stderr} | 2 +- .../nested-tait-inference2.next.stderr | 9 ++++++++ .../nested-tait-inference2.rs | 7 +++++- 10 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 tests/ui/impl-trait/recursive-bound-eval.next.stderr rename tests/ui/type-alias-impl-trait/{issue-84660-unsoundness.stderr => issue-84660-unsoundness.current.stderr} (90%) create mode 100644 tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr rename tests/ui/type-alias-impl-trait/{nested-tait-inference.stderr => nested-tait-inference.current.stderr} (90%) rename tests/ui/type-alias-impl-trait/{nested-tait-inference2.stderr => nested-tait-inference2.current.stderr} (91%) create mode 100644 tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr diff --git a/tests/ui/impl-trait/recursive-bound-eval.next.stderr b/tests/ui/impl-trait/recursive-bound-eval.next.stderr new file mode 100644 index 00000000000..4bab290d71c --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-bound-eval.rs:20:13 + | +LL | move || recursive_fn().parse() + | ^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs index 591553e7ceb..7859c8983fc 100644 --- a/tests/ui/impl-trait/recursive-bound-eval.rs +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -1,7 +1,10 @@ //! Test that we can evaluate nested obligations when invoking methods on recursive calls on //! an RPIT. -//@ check-pass +//@revisions: next current +//@[next] compile-flags: -Znext-solver + +//@[current] check-pass pub trait Parser { fn parse(&self) -> E; @@ -15,6 +18,7 @@ impl E> Parser for T { pub fn recursive_fn() -> impl Parser { move || recursive_fn().parse() + //[next]~^ ERROR: type annotations needed } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr rename to tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index 461da20f37b..a7ff097e8bf 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:23:1 + --> $DIR/issue-84660-unsoundness.rs:28:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr new file mode 100644 index 00000000000..607f0b062ab --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -0,0 +1,23 @@ +error[E0284]: type annotations needed: cannot satisfy `>::Out == ()` + --> $DIR/issue-84660-unsoundness.rs:22:37 + | +LL | fn convert(_i: In) -> Self::Out { + | _____________________________________^ +LL | | +LL | | unreachable!(); +LL | | } + | |_____^ cannot satisfy `>::Out == ()` + +error[E0119]: conflicting implementations of trait `Trait` + --> $DIR/issue-84660-unsoundness.rs:28:1 + | +LL | impl Trait for Out { + | ------------------------------------ first implementation here +... +LL | impl Trait<(), In> for Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0284. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 48d4b0c96ff..fd1f3c6353c 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -1,6 +1,10 @@ // Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an // impl header being accepted was used to create unsoundness. +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + #![feature(type_alias_impl_trait)] trait Foo {} @@ -16,11 +20,13 @@ trait Trait { impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { + //[next]~^ ERROR: cannot satisfy `>::Out == ()` unreachable!(); } } -impl Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait` +impl Trait<(), In> for Out { + //~^ ERROR conflicting implementations of trait `Trait` type Out = In; fn convert(i: In) -> Self::Out { i diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr similarity index 90% rename from tests/ui/type-alias-impl-trait/nested-tait-inference.stderr rename to tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr index 172ecded7a2..34532afcbba 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference.rs:12:13 + --> $DIR/nested-tait-inference.rs:17:13 | LL | fn foo() -> impl Foo { | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 82248971692..50d51c7faf9 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -1,18 +1,23 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + use std::fmt::Debug; type FooX = impl Debug; -trait Foo { } +trait Foo {} -impl Foo<()> for () { } +impl Foo<()> for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied + //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied // FIXME(type-alias-impl-trait): We could probably make this work. () } -fn main() { } +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr similarity index 91% rename from tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr rename to tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index 241342b0509..614bc09872f 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/nested-tait-inference2.rs:13:13 + --> $DIR/nested-tait-inference2.rs:17:13 | LL | fn foo() -> impl Foo { | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr new file mode 100644 index 00000000000..9647d9e376e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `impl Foo == ()` + --> $DIR/nested-tait-inference2.rs:19:5 + | +LL | () + | ^^ cannot satisfy `impl Foo == ()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index 0d7f5bad25f..28d72b0cbee 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -1,6 +1,10 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::fmt::Debug; type FooX = impl Debug; @@ -11,8 +15,9 @@ impl Foo<()> for () {} impl Foo for () {} fn foo() -> impl Foo { - //~^ ERROR: the trait bound `(): Foo` is not satisfied + //[current]~^ ERROR: the trait bound `(): Foo` is not satisfied () + //[next]~^ ERROR: cannot satisfy `impl Foo == ()` } fn main() {} From 7255c2825df1b6497dea1d689173a62ea872244f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:13:38 +0000 Subject: [PATCH 053/153] run-make-support: remove `env_var` This is incorrectly named (it's actually `env_clear`), and is itself a gigantic footgun: removing `TMPDIR` on Unix and `TMP`/`TEMP` on Windows basically wrecks anything that relies on `std::env::temp_dir` from functioning correctly. For example, this includes rustc's codegen. --- src/tools/run-make-support/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index cea1313e29d..93e41b593d1 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -364,12 +364,6 @@ macro_rules! impl_common_helpers { self } - /// Clear all environmental variables. - pub fn env_var(&mut self) -> &mut Self { - self.cmd.env_clear(); - self - } - /// Generic command argument provider. Prefer specific helper methods if possible. /// Note that for some executables, arguments might be platform specific. For C/C++ /// compilers, arguments might be platform *and* compiler specific. From a3feeb3afe075898e4112baa90d948ef57ce4401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:13:01 +0000 Subject: [PATCH 054/153] run-make-support: add drop bomb module --- .../run-make-support/src/drop_bomb/mod.rs | 50 +++++++++++++++++++ .../run-make-support/src/drop_bomb/tests.rs | 15 ++++++ src/tools/run-make-support/src/lib.rs | 1 + 3 files changed, 66 insertions(+) create mode 100644 src/tools/run-make-support/src/drop_bomb/mod.rs create mode 100644 src/tools/run-make-support/src/drop_bomb/tests.rs diff --git a/src/tools/run-make-support/src/drop_bomb/mod.rs b/src/tools/run-make-support/src/drop_bomb/mod.rs new file mode 100644 index 00000000000..2fc84892c1b --- /dev/null +++ b/src/tools/run-make-support/src/drop_bomb/mod.rs @@ -0,0 +1,50 @@ +//! This module implements "drop bombs" intended for use by command wrappers to ensure that the +//! constructed commands are *eventually* executed. This is exactly like `rustc_errors::Diag` where +//! we force every `Diag` to be consumed or we emit a bug, but we panic instead. +//! +//! This is adapted from and simplified for our +//! purposes. + +use std::ffi::{OsStr, OsString}; +use std::panic; + +#[cfg(test)] +mod tests; + +#[derive(Debug)] +pub(crate) struct DropBomb { + command: OsString, + defused: bool, + armed_line: u32, +} + +impl DropBomb { + /// Arm a [`DropBomb`]. If the value is dropped without being [`defused`][Self::defused], then + /// it will panic. It is expected that the command wrapper uses `#[track_caller]` to help + /// propagate the caller info from rmake.rs. + #[track_caller] + pub(crate) fn arm>(command: S) -> DropBomb { + DropBomb { + command: command.as_ref().into(), + defused: false, + armed_line: panic::Location::caller().line(), + } + } + + /// Defuse the [`DropBomb`]. This will prevent the drop bomb from panicking when dropped. + pub(crate) fn defuse(&mut self) { + self.defused = true; + } +} + +impl Drop for DropBomb { + fn drop(&mut self) { + if !self.defused && !std::thread::panicking() { + panic!( + "command constructed but not executed at line {}: `{}`", + self.armed_line, + self.command.to_string_lossy() + ) + } + } +} diff --git a/src/tools/run-make-support/src/drop_bomb/tests.rs b/src/tools/run-make-support/src/drop_bomb/tests.rs new file mode 100644 index 00000000000..4a488c0f670 --- /dev/null +++ b/src/tools/run-make-support/src/drop_bomb/tests.rs @@ -0,0 +1,15 @@ +use super::DropBomb; + +#[test] +#[should_panic] +fn test_arm() { + let bomb = DropBomb::arm("hi :3"); + drop(bomb); // <- armed bomb should explode when not defused +} + +#[test] +fn test_defuse() { + let mut bomb = DropBomb::arm("hi :3"); + bomb.defuse(); + drop(bomb); // <- defused bomb should not explode +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 93e41b593d1..20ad25efaf0 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -7,6 +7,7 @@ pub mod cc; pub mod clang; mod command; pub mod diff; +mod drop_bomb; pub mod llvm_readobj; pub mod run; pub mod rustc; From d6955445f53062a8af3e5a4e84dbf756a7913cbe Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Mon, 10 Jun 2024 17:55:28 -0700 Subject: [PATCH 055/153] Simplify `[T; N]::try_map` signature People keep making fun of this signature for being so gnarly. Associated type bounds lend it a much simpler scribbling. ChangeOutputType can also come along for the ride. --- library/core/src/array/mod.rs | 6 ++---- library/core/src/ops/try_trait.rs | 4 +++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 05874ab6c4c..2569ce23707 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -533,11 +533,9 @@ impl [T; N] { /// assert_eq!(c, Some(a)); /// ``` #[unstable(feature = "array_try_map", issue = "79711")] - pub fn try_map(self, f: F) -> ChangeOutputType + pub fn try_map(self, f: impl FnMut(T) -> R) -> ChangeOutputType where - F: FnMut(T) -> R, - R: Try, - R::Residual: Residual<[R::Output; N]>, + R: Try>, { drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f))) } diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 483f55b2070..cd444c86ed0 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -363,7 +363,9 @@ pub trait Residual { } #[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")] -pub(crate) type ChangeOutputType = <::Residual as Residual>::TryType; +#[allow(type_alias_bounds)] +pub(crate) type ChangeOutputType>, V> = + >::TryType; /// An adapter for implementing non-try methods via the `Try` implementation. /// From 54e704437b3968c3cb14bf8ceb08ca34610425ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:21:04 +0000 Subject: [PATCH 056/153] run-make-support: arm command with drop bombs - Update all command wrappers and command construction helpers with `#[track_caller]` where suitable to help the drop bomb panic message. - Remove `Deref`/`DerefMut` for `Command` because it was causing issues with resolving to `std::process::Command` in a method call chain. --- src/tools/run-make-support/src/cc.rs | 7 +- src/tools/run-make-support/src/clang.rs | 2 + src/tools/run-make-support/src/command.rs | 115 +++++++++++++----- src/tools/run-make-support/src/diff/mod.rs | 10 +- src/tools/run-make-support/src/lib.rs | 25 ++-- .../run-make-support/src/llvm_readobj.rs | 2 + src/tools/run-make-support/src/run.rs | 30 ++--- src/tools/run-make-support/src/rustc.rs | 5 + src/tools/run-make-support/src/rustdoc.rs | 5 + 9 files changed, 137 insertions(+), 64 deletions(-) diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index 5c0158d7547..8694740cfc3 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -7,6 +7,7 @@ use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname}; /// /// WARNING: This means that what flags are accepted by the underlying C compiler is /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`. +#[track_caller] pub fn cc() -> Cc { Cc::new() } @@ -25,6 +26,7 @@ impl Cc { /// /// WARNING: This means that what flags are accepted by the underlying C compile is /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`. + #[track_caller] pub fn new() -> Self { let compiler = env_var("CC"); @@ -84,11 +86,6 @@ impl Cc { self.cmd.arg(path.as_ref()); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } /// `EXTRACFLAGS` diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index d2ebed7ab06..a31004659c1 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -4,6 +4,7 @@ use crate::command::Command; use crate::{bin_name, env_var}; /// Construct a new `clang` invocation. `clang` is not always available for all targets. +#[track_caller] pub fn clang() -> Clang { Clang::new() } @@ -18,6 +19,7 @@ crate::impl_common_helpers!(Clang); impl Clang { /// Construct a new `clang` invocation. `clang` is not always available for all targets. + #[track_caller] pub fn new() -> Self { let clang = env_var("CLANG"); let cmd = Command::new(clang); diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs index b9e56ab632a..f427e50906f 100644 --- a/src/tools/run-make-support/src/command.rs +++ b/src/tools/run-make-support/src/command.rs @@ -1,36 +1,107 @@ -use crate::{assert_not_contains, handle_failed_output}; +use std::ffi; use std::ffi::OsStr; use std::io::Write; -use std::ops::{Deref, DerefMut}; +use std::panic; +use std::path::Path; use std::process::{Command as StdCommand, ExitStatus, Output, Stdio}; -/// This is a custom command wrapper that simplifies working with commands -/// and makes it easier to ensure that we check the exit status of executed -/// processes. +use crate::drop_bomb::DropBomb; +use crate::{assert_not_contains, handle_failed_output}; + +/// This is a custom command wrapper that simplifies working with commands and makes it easier to +/// ensure that we check the exit status of executed processes. +/// +/// # A [`Command`] must be executed +/// +/// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If +/// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test +/// to panic. Execution methods [`run`] and [`run_fail`] will defuse the drop bomb. A test +/// containing constructed but never executed commands is dangerous because it can give a false +/// sense of confidence. +/// +/// [`run`]: Self::run +/// [`run_fail`]: Self::run_fail #[derive(Debug)] pub struct Command { cmd: StdCommand, stdin: Option>, + drop_bomb: DropBomb, } impl Command { - pub fn new>(program: S) -> Self { - Self { cmd: StdCommand::new(program), stdin: None } + #[track_caller] + pub fn new>(program: P) -> Self { + let program = program.as_ref(); + Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) } } pub fn set_stdin(&mut self, stdin: Box<[u8]>) { self.stdin = Some(stdin); } + /// Specify an environment variable. + pub fn env(&mut self, key: K, value: V) -> &mut Self + where + K: AsRef, + V: AsRef, + { + self.cmd.env(key, value); + self + } + + /// Remove an environmental variable. + pub fn env_remove(&mut self, key: K) -> &mut Self + where + K: AsRef, + { + self.cmd.env_remove(key); + self + } + + /// Generic command argument provider. Prefer specific helper methods if possible. + /// Note that for some executables, arguments might be platform specific. For C/C++ + /// compilers, arguments might be platform *and* compiler specific. + pub fn arg(&mut self, arg: S) -> &mut Self + where + S: AsRef, + { + self.cmd.arg(arg); + self + } + + /// Generic command arguments provider. Prefer specific helper methods if possible. + /// Note that for some executables, arguments might be platform specific. For C/C++ + /// compilers, arguments might be platform *and* compiler specific. + pub fn args(&mut self, args: &[S]) -> &mut Self + where + S: AsRef, + { + self.cmd.args(args); + self + } + + /// Inspect what the underlying [`std::process::Command`] is up to the + /// current construction. + pub fn inspect(&mut self, inspector: I) -> &mut Self + where + I: FnOnce(&StdCommand), + { + inspector(&self.cmd); + self + } + + /// Set the path where the command will be run. + pub fn current_dir>(&mut self, path: P) -> &mut Self { + self.cmd.current_dir(path); + self + } + /// Run the constructed command and assert that it is successfully run. #[track_caller] pub fn run(&mut self) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - let output = self.command_output(); if !output.status().success() { - handle_failed_output(&self, output, caller_line_number); + handle_failed_output(&self, output, panic::Location::caller().line()); } output } @@ -38,18 +109,16 @@ impl Command { /// Run the constructed command and assert that it does not successfully run. #[track_caller] pub fn run_fail(&mut self) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - let output = self.command_output(); if output.status().success() { - handle_failed_output(&self, output, caller_line_number); + handle_failed_output(&self, output, panic::Location::caller().line()); } output } #[track_caller] - pub(crate) fn command_output(&mut self) -> CompletedProcess { + fn command_output(&mut self) -> CompletedProcess { + self.drop_bomb.defuse(); // let's make sure we piped all the input and outputs self.cmd.stdin(Stdio::piped()); self.cmd.stdout(Stdio::piped()); @@ -71,20 +140,6 @@ impl Command { } } -impl Deref for Command { - type Target = StdCommand; - - fn deref(&self) -> &Self::Target { - &self.cmd - } -} - -impl DerefMut for Command { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.cmd - } -} - /// Represents the result of an executed process. /// The various `assert_` helper methods should preferably be used for /// checking the contents of stdout/stderr. diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index d864ddf4eb1..0fb6fec9d58 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -2,9 +2,12 @@ use regex::Regex; use similar::TextDiff; use std::path::Path; +use crate::drop_bomb::DropBomb; + #[cfg(test)] mod tests; +#[track_caller] pub fn diff() -> Diff { Diff::new() } @@ -16,10 +19,12 @@ pub struct Diff { actual: Option, actual_name: Option, normalizers: Vec<(String, String)>, + drop_bomb: DropBomb, } impl Diff { /// Construct a bare `diff` invocation. + #[track_caller] pub fn new() -> Self { Self { expected: None, @@ -27,6 +32,7 @@ impl Diff { actual: None, actual_name: None, normalizers: Vec::new(), + drop_bomb: DropBomb::arm("diff"), } } @@ -79,9 +85,9 @@ impl Diff { self } - /// Executes the diff process, prints any differences to the standard error. #[track_caller] - pub fn run(&self) { + pub fn run(&mut self) { + self.drop_bomb.defuse(); let expected = self.expected.as_ref().expect("expected text not set"); let mut actual = self.actual.as_ref().expect("actual text not set").to_string(); let expected_name = self.expected_name.as_ref().unwrap(); diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 20ad25efaf0..bf74d94f911 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -17,6 +17,7 @@ use std::env; use std::ffi::OsString; use std::fs; use std::io; +use std::panic; use std::path::{Path, PathBuf}; pub use gimli; @@ -32,6 +33,7 @@ pub use run::{cmd, run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; +#[track_caller] pub fn env_var(name: &str) -> String { match env::var(name) { Ok(v) => v, @@ -39,6 +41,7 @@ pub fn env_var(name: &str) -> String { } } +#[track_caller] pub fn env_var_os(name: &str) -> OsString { match env::var_os(name) { Some(v) => v, @@ -66,11 +69,13 @@ pub fn is_darwin() -> bool { target().contains("darwin") } +#[track_caller] pub fn python_command() -> Command { let python_path = env_var("PYTHON"); Command::new(python_path) } +#[track_caller] pub fn htmldocck() -> Command { let mut python = python_command(); python.arg(source_root().join("src/etc/htmldocck.py")); @@ -162,15 +167,13 @@ pub fn cwd() -> PathBuf { /// available on the platform! #[track_caller] pub fn cygpath_windows>(path: P) -> String { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - + let caller = panic::Location::caller(); let mut cygpath = Command::new("cygpath"); cygpath.arg("-w"); cygpath.arg(path.as_ref()); - let output = cygpath.command_output(); + let output = cygpath.run(); if !output.status().success() { - handle_failed_output(&cygpath, output, caller_line_number); + handle_failed_output(&cygpath, output, caller.line()); } // cygpath -w can attach a newline output.stdout_utf8().trim().to_string() @@ -179,13 +182,11 @@ pub fn cygpath_windows>(path: P) -> String { /// Run `uname`. This assumes that `uname` is available on the platform! #[track_caller] pub fn uname() -> String { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - + let caller = panic::Location::caller(); let mut uname = Command::new("uname"); - let output = uname.command_output(); + let output = uname.run(); if !output.status().success() { - handle_failed_output(&uname, output, caller_line_number); + handle_failed_output(&uname, output, caller.line()); } output.stdout_utf8() } @@ -393,7 +394,7 @@ macro_rules! impl_common_helpers { where I: FnOnce(&::std::process::Command), { - inspector(&self.cmd); + self.cmd.inspect(inspector); self } @@ -410,7 +411,7 @@ macro_rules! impl_common_helpers { } /// Set the path where the command will be run. - pub fn current_dir>(&mut self, path: P) -> &mut Self { + pub fn current_dir>(&mut self, path: P) -> &mut Self { self.cmd.current_dir(path); self } diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index db2f9db6e41..57ddfc205e6 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -5,6 +5,7 @@ use crate::env_var; /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. +#[track_caller] pub fn llvm_readobj() -> LlvmReadobj { LlvmReadobj::new() } @@ -20,6 +21,7 @@ crate::impl_common_helpers!(LlvmReadobj); impl LlvmReadobj { /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. + #[track_caller] pub fn new() -> Self { let llvm_bin_dir = env_var("LLVM_BIN_DIR"); let llvm_bin_dir = PathBuf::from(llvm_bin_dir); diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 4a6fd7c432e..6fa1a75363c 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,5 +1,6 @@ use std::env; use std::ffi::OsStr; +use std::panic; use std::path::{Path, PathBuf}; use crate::command::{Command, CompletedProcess}; @@ -7,7 +8,8 @@ use crate::{cwd, env_var, is_windows, set_host_rpath}; use super::handle_failed_output; -fn run_common(name: &str) -> (Command, CompletedProcess) { +#[track_caller] +fn run_common(name: &str) -> Command { let mut bin_path = PathBuf::new(); bin_path.push(cwd()); bin_path.push(name); @@ -34,19 +36,17 @@ fn run_common(name: &str) -> (Command, CompletedProcess) { cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); } - let output = cmd.command_output(); - (cmd, output) + cmd } /// Run a built binary and make sure it succeeds. #[track_caller] pub fn run(name: &str) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(name); + let caller = panic::Location::caller(); + let mut cmd = run_common(name); + let output = cmd.run(); if !output.status().success() { - handle_failed_output(&cmd, output, caller_line_number); + handle_failed_output(&cmd, output, caller.line()); } output } @@ -54,18 +54,18 @@ pub fn run(name: &str) -> CompletedProcess { /// Run a built binary and make sure it fails. #[track_caller] pub fn run_fail(name: &str) -> CompletedProcess { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let (cmd, output) = run_common(name); + let caller = panic::Location::caller(); + let mut cmd = run_common(name); + let output = cmd.run_fail(); if output.status().success() { - handle_failed_output(&cmd, output, caller_line_number); + handle_failed_output(&cmd, output, caller.line()); } output } -/// Create a new custom Command. -/// This should be preferred to creating `std::process::Command` directly. +/// Create a new custom [`Command`]. This should be preferred to creating [`std::process::Command`] +/// directly. +#[track_caller] pub fn cmd>(program: S) -> Command { let mut command = Command::new(program); set_host_rpath(&mut command); diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 5ea231442bc..32fa5018d80 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -5,11 +5,13 @@ use std::path::Path; use crate::{command, cwd, env_var, set_host_rpath}; /// Construct a new `rustc` invocation. +#[track_caller] pub fn rustc() -> Rustc { Rustc::new() } /// Construct a new `rustc` aux-build invocation. +#[track_caller] pub fn aux_build() -> Rustc { Rustc::new_aux_build() } @@ -22,6 +24,7 @@ pub struct Rustc { crate::impl_common_helpers!(Rustc); +#[track_caller] fn setup_common() -> Command { let rustc = env_var("RUSTC"); let mut cmd = Command::new(rustc); @@ -34,12 +37,14 @@ impl Rustc { // `rustc` invocation constructor methods /// Construct a new `rustc` invocation. + #[track_caller] pub fn new() -> Self { let cmd = setup_common(); Self { cmd } } /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). + #[track_caller] pub fn new_aux_build() -> Self { let mut cmd = setup_common(); cmd.arg("--crate-type=lib"); diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 39a698a47b4..332906f739a 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -5,11 +5,13 @@ use crate::command::Command; use crate::{env_var, env_var_os, set_host_rpath}; /// Construct a plain `rustdoc` invocation with no flags set. +#[track_caller] pub fn bare_rustdoc() -> Rustdoc { Rustdoc::bare() } /// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. +#[track_caller] pub fn rustdoc() -> Rustdoc { Rustdoc::new() } @@ -21,6 +23,7 @@ pub struct Rustdoc { crate::impl_common_helpers!(Rustdoc); +#[track_caller] fn setup_common() -> Command { let rustdoc = env_var("RUSTDOC"); let mut cmd = Command::new(rustdoc); @@ -30,12 +33,14 @@ fn setup_common() -> Command { impl Rustdoc { /// Construct a bare `rustdoc` invocation. + #[track_caller] pub fn bare() -> Self { let cmd = setup_common(); Self { cmd } } /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. + #[track_caller] pub fn new() -> Self { let mut cmd = setup_common(); let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); From ca95f783c1cb84ea5739681ba284eccbb41ebf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 15:45:57 +0000 Subject: [PATCH 057/153] tests/run-make: update tests to use new API --- tests/run-make/compiler-builtins/rmake.rs | 2 +- tests/run-make/rustdoc-map-file/rmake.rs | 2 +- tests/run-make/rustdoc-scrape-examples-macros/rmake.rs | 2 +- tests/run-make/rustdoc-scrape-examples-remap/scrape.rs | 2 +- tests/run-make/rustdoc-themes/rmake.rs | 2 +- tests/run-make/rustdoc-with-out-dir-option/rmake.rs | 2 +- tests/run-make/rustdoc-with-output-option/rmake.rs | 2 +- tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index a2c0ad5f6de..a102e5b3390 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -35,7 +35,7 @@ fn main() { let rustc = env_var("RUSTC"); let bootstrap_cargo = env_var("BOOTSTRAP_CARGO"); let mut cmd = cmd(bootstrap_cargo); - cmd.args([ + cmd.args(&[ "build", "--manifest-path", manifest_path.to_str().unwrap(), diff --git a/tests/run-make/rustdoc-map-file/rmake.rs b/tests/run-make/rustdoc-map-file/rmake.rs index de75561c9fb..08f9595ef9f 100644 --- a/tests/run-make/rustdoc-map-file/rmake.rs +++ b/tests/run-make/rustdoc-map-file/rmake.rs @@ -9,5 +9,5 @@ fn main() { .output(&out_dir) .run(); // FIXME (GuillaumeGomez): Port the python script to Rust as well. - assert!(python_command().arg("validate_json.py").arg(&out_dir).status().unwrap().success()); + python_command().arg("validate_json.py").arg(&out_dir).run(); } diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index c9650def347..bfe4a1df456 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -56,5 +56,5 @@ fn main() { .arg(&ex_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs index 41efb837458..6bf48a94a49 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs @@ -45,5 +45,5 @@ pub fn scrape(extra_args: &[&str]) { } rustdoc.run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-themes/rmake.rs b/tests/run-make/rustdoc-themes/rmake.rs index c28821b7628..bfda2d97888 100644 --- a/tests/run-make/rustdoc-themes/rmake.rs +++ b/tests/run-make/rustdoc-themes/rmake.rs @@ -28,5 +28,5 @@ fn main() { std::fs::write(&test_css, test_content).unwrap(); rustdoc().output(&out_dir).input("foo.rs").arg("--theme").arg(&test_css).run(); - assert!(htmldocck().arg(out_dir).arg("foo.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("foo.rs").run(); } diff --git a/tests/run-make/rustdoc-with-out-dir-option/rmake.rs b/tests/run-make/rustdoc-with-out-dir-option/rmake.rs index 405da8412ae..ded89c9ae79 100644 --- a/tests/run-make/rustdoc-with-out-dir-option/rmake.rs +++ b/tests/run-make/rustdoc-with-out-dir-option/rmake.rs @@ -3,5 +3,5 @@ use run_make_support::{htmldocck, rustdoc}; fn main() { let out_dir = "rustdoc"; rustdoc().input("src/lib.rs").crate_name("foobar").crate_type("lib").output(&out_dir).run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-with-output-option/rmake.rs b/tests/run-make/rustdoc-with-output-option/rmake.rs index a3b1c8ca0dd..f7fbbec6986 100644 --- a/tests/run-make/rustdoc-with-output-option/rmake.rs +++ b/tests/run-make/rustdoc-with-output-option/rmake.rs @@ -12,5 +12,5 @@ fn main() { .arg(&out_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } diff --git a/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs b/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs index b536fbe2303..4a8896cc975 100644 --- a/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs +++ b/tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs @@ -12,5 +12,5 @@ fn main() { .arg(&out_dir) .run(); - assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success()); + htmldocck().arg(out_dir).arg("src/lib.rs").run(); } From d308a70890b66a6e81bfc46286caed915a34c8f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:10:55 +0000 Subject: [PATCH 058/153] run-make-support: bump version --- Cargo.lock | 2 +- src/tools/run-make-support/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba8b2c27005..e5ea9fee8a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3452,7 +3452,7 @@ dependencies = [ [[package]] name = "run_make_support" -version = "0.0.0" +version = "0.1.0" dependencies = [ "gimli 0.28.1", "object 0.34.0", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index cf4ae4b16cd..5450620e7f0 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "run_make_support" -version = "0.0.0" +version = "0.1.0" edition = "2021" [dependencies] From 5ec3eef9e70551a7eef059cfc9d039f053805cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sun, 9 Jun 2024 14:11:12 +0000 Subject: [PATCH 059/153] run-make-support: add changelog --- src/tools/run-make-support/CHANGELOG.md | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/tools/run-make-support/CHANGELOG.md diff --git a/src/tools/run-make-support/CHANGELOG.md b/src/tools/run-make-support/CHANGELOG.md new file mode 100644 index 00000000000..a37de9fda80 --- /dev/null +++ b/src/tools/run-make-support/CHANGELOG.md @@ -0,0 +1,67 @@ +# Changelog + +All notable changes to the `run_make_support` library should be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the support +library should adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) even if it's +not intended for public consumption (it's moreso to help internally, to help test writers track +changes to the support library). + +This support library will probably never reach 1.0. Please bump the minor version in `Cargo.toml` if +you make any breaking changes or other significant changes, or bump the patch version for bug fixes. + +## [0.1.0] - 2024-06-09 + +### Changed + +- Use *drop bombs* to enforce that commands are executed; a command invocation will panic if it is + constructed but never executed. Execution methods `Command::{run, run_fail}` will defuse the drop + bomb. +- Added `Command` helpers that forward to `std::process::Command` counterparts. + +### Removed + +- The `env_var` method which was incorrectly named and is `env_clear` underneath and is a footgun + from `impl_common_helpers`. For example, removing `TMPDIR` on Unix and `TMP`/`TEMP` breaks + `std::env::temp_dir` and wrecks anything using that, such as rustc's codgen. +- Removed `Deref`/`DerefMut` for `run_make_support::Command` -> `std::process::Command` because it + causes a method chain like `htmldocck().arg().run()` to fail, because `arg()` resolves to + `std::process::Command` which also returns a `&mut std::process::Command`, causing the `run()` to + be not found. + +## [0.0.0] - 2024-06-09 + +Consider this version to contain all changes made to the support library before we started to track +changes in this changelog. + +### Added + +- Custom command wrappers around `std::process::Command` (`run_make_support::Command`) and custom + wrapper around `std::process::Output` (`CompletedProcess`) to make it more convenient to work with + commands and their output, and help avoid forgetting to check for exit status. + - `Command`: `set_stdin`, `run`, `run_fail`. + - `CompletedProcess`: `std{err,out}_utf8`, `status`, `assert_std{err,out}_{equals, contains, + not_contains}`, `assert_exit_code`. +- `impl_common_helpers` macro to avoid repeating adding common convenience methods, including: + - Environment manipulation methods: `env`, `env_remove` + - Command argument providers: `arg`, `args` + - Common invocation inspection (of the command invocation up until `inspect` is called): + `inspect` + - Execution methods: `run` (for commands expected to succeed execution, exit status `0`) and + `run_fail` (for commands expected to fail execution, exit status non-zero). +- Command wrappers around: `rustc`, `clang`, `cc`, `rustc`, `rustdoc`, `llvm-readobj`. +- Thin helpers to construct `python` and `htmldocck` commands. +- `run` and `run_fail` (like `Command::{run, run_fail}`) for running binaries, which sets suitable + env vars (like `LD_LIB_PATH` or equivalent, `TARGET_RPATH_ENV`, `PATH` on Windows). +- Pseudo command `diff` which has similar functionality as the cli util but not the same API. +- Convenience panic-on-fail helpers `env_var`, `env_var_os`, `cwd` for their `std::env` conterparts. +- Convenience panic-on-fail helpers for reading respective env vars: `target`, `source_root`. +- Platform check helpers: `is_windows`, `is_msvc`, `cygpath_windows`, `uname`. +- fs helpers: `copy_dir_all`. +- `recursive_diff` helper. +- Generic `assert_not_contains` helper. +- Scoped run-with-teardown helper `run_in_tmpdir` which is designed to run commands in a temporary + directory that is cleared when closure returns. +- Helpers for constructing the name of binaries and libraries: `rust_lib_name`, `static_lib_name`, + `bin_name`, `dynamic_lib_name`. +- Re-export libraries: `gimli`, `object`, `regex`, `wasmparsmer`. From db44cae343fa306b6b2263355dc3f9a5f5db82b4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jun 2024 12:12:21 +0200 Subject: [PATCH 060/153] interpret: ensure we check bool/char for validity when they are used in a cast --- .../rustc_const_eval/src/interpret/cast.rs | 10 +++++-- .../src/interpret/intrinsics.rs | 16 +++++----- .../src/interpret/operator.rs | 29 ++++++++++--------- compiler/rustc_middle/src/ty/consts/int.rs | 15 ++++------ .../tests/fail/validity/invalid_char_cast.rs | 21 ++++++++++++++ .../fail/validity/invalid_char_cast.stderr | 20 +++++++++++++ .../tests/fail/validity/invalid_char_match.rs | 26 +++++++++++++++++ .../fail/validity/invalid_char_match.stderr | 23 +++++++++++++++ .../tests/fail/validity/invalid_enum_cast.rs | 15 ++++++++++ .../fail/validity/invalid_enum_cast.stderr | 20 +++++++++++++ 10 files changed, 159 insertions(+), 36 deletions(-) create mode 100644 src/tools/miri/tests/fail/validity/invalid_char_cast.rs create mode 100644 src/tools/miri/tests/fail/validity/invalid_char_cast.stderr create mode 100644 src/tools/miri/tests/fail/validity/invalid_char_match.rs create mode 100644 src/tools/miri/tests/fail/validity/invalid_char_match.stderr create mode 100644 src/tools/miri/tests/fail/validity/invalid_enum_cast.rs create mode 100644 src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 19414c72c6a..0a45bbb3edb 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -274,9 +274,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Let's make sure v is sign-extended *if* it has a signed type. let signed = src_layout.abi.is_signed(); // Also asserts that abi is `Scalar`. - let v = scalar.to_bits(src_layout.size)?; - let v = if signed { self.sign_extend(v, src_layout) } else { v }; - trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty); + let v = match src_layout.ty.kind() { + Uint(_) | RawPtr(..) | FnPtr(..) => scalar.to_uint(src_layout.size)?, + Int(_) => scalar.to_int(src_layout.size)? as u128, // we will cast back to `i128` below if the sign matters + Bool => scalar.to_bool()?.into(), + Char => scalar.to_char()?.into(), + _ => span_bug!(self.cur_span(), "invalid int-like cast from {}", src_layout.ty), + }; Ok(match *cast_ty.kind() { // int -> int diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index dac5c10addc..7f16d441606 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -197,7 +197,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW)) let layout_val = self.layout_of(instance_args.type_at(0))?; let val = self.read_scalar(&args[0])?; - let val_bits = val.to_bits(layout_val.size)?; + let val_bits = val.to_bits(layout_val.size)?; // sign is ignored here let layout_raw_shift = self.layout_of(self.tcx.types.u32)?; let raw_shift = self.read_scalar(&args[1])?; @@ -484,7 +484,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ret_layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, Scalar> { assert!(layout.ty.is_integral(), "invalid type for numeric intrinsic: {}", layout.ty); - let bits = val.to_bits(layout.size)?; + let bits = val.to_bits(layout.size)?; // these operations all ignore the sign let extra = 128 - u128::from(layout.size.bits()); let bits_out = match name { sym::ctpop => u128::from(bits.count_ones()), @@ -519,6 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; + // sign does not matter for 0 test, so `to_bits` is fine if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, @@ -545,22 +546,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.binary_op(mir_op.wrapping_to_overflowing().unwrap(), l, r)?.to_scalar_pair(); Ok(if overflowed.to_bool()? { let size = l.layout.size; - let num_bits = size.bits(); if l.layout.abi.is_signed() { // For signed ints the saturated value depends on the sign of the first // term since the sign of the second term can be inferred from this and // the fact that the operation has overflowed (if either is 0 no // overflow can occur) - let first_term: u128 = l.to_scalar().to_bits(l.layout.size)?; - let first_term_positive = first_term & (1 << (num_bits - 1)) == 0; - if first_term_positive { + let first_term: i128 = l.to_scalar().to_int(l.layout.size)?; + if first_term >= 0 { // Negative overflow not possible since the positive first term // can only increase an (in range) negative term for addition - // or corresponding negated positive term for subtraction + // or corresponding negated positive term for subtraction. Scalar::from_int(size.signed_int_max(), size) } else { - // Positive overflow not possible for similar reason - // max negative + // Positive overflow not possible for similar reason. Scalar::from_int(size.signed_int_min(), size) } } else { diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index c821c98073d..a6eef9f5662 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -437,23 +437,24 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; Ok(ImmTy::from_scalar(res, layout)) } - _ if layout.ty.is_integral() => { - let val = val.to_scalar(); - let val = val.to_bits(layout.size)?; + ty::Int(..) => { + let val = val.to_scalar().to_int(layout.size)?; let res = match un_op { - Not => self.truncate(!val, layout), // bitwise negation, then truncate - Neg => { - // arithmetic negation - assert!(layout.abi.is_signed()); - let val = self.sign_extend(val, layout) as i128; - let res = val.wrapping_neg(); - let res = res as u128; - // Truncate to target type. - self.truncate(res, layout) - } + Not => !val, + Neg => val.wrapping_neg(), _ => span_bug!(self.cur_span(), "Invalid integer op {:?}", un_op), }; - Ok(ImmTy::from_uint(res, layout)) + let res = ScalarInt::truncate_from_int(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) + } + ty::Uint(..) => { + let val = val.to_scalar().to_uint(layout.size)?; + let res = match un_op { + Not => !val, + _ => span_bug!(self.cur_span(), "Invalid unsigned integer op {:?}", un_op), + }; + let res = ScalarInt::truncate_from_uint(res, layout.size).0; + Ok(ImmTy::from_scalar(res.into(), layout)) } ty::RawPtr(..) => { assert_eq!(un_op, PtrMetadata); diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 52320dd141b..13691b61941 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -209,8 +209,8 @@ impl ScalarInt { #[inline] pub fn try_from_uint(i: impl Into, size: Size) -> Option { - let data = i.into(); - if size.truncate(data) == data { Some(Self::raw(data, size)) } else { None } + let (r, overflow) = Self::truncate_from_uint(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. @@ -223,20 +223,15 @@ impl ScalarInt { #[inline] pub fn try_from_int(i: impl Into, size: Size) -> Option { - let i = i.into(); - // `into` performed sign extension, we have to truncate - let truncated = size.truncate(i as u128); - if size.sign_extend(truncated) as i128 == i { - Some(Self::raw(truncated, size)) - } else { - None - } + let (r, overflow) = Self::truncate_from_int(i, size); + if overflow { None } else { Some(r) } } /// Returns the truncated result, and whether truncation changed the value. #[inline] pub fn truncate_from_int(i: impl Into, size: Size) -> (Self, bool) { let data = i.into(); + // `into` performed sign extension, we have to truncate let r = Self::raw(size.truncate(data as u128), size); (r, size.sign_extend(r.data) as i128 != data) } diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.rs b/src/tools/miri/tests/fail/validity/invalid_char_cast.rs new file mode 100644 index 00000000000..6a590dc7ba1 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.rs @@ -0,0 +1,21 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn cast(ptr: *const char) -> u32 { + mir! { + { + RET = *ptr as u32; //~ERROR: interpreting an invalid 32-bit value as a char + Return() + } + } +} + +pub fn main() { + let v = u32::MAX; + cast(&v as *const u32 as *const char); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr new file mode 100644 index 00000000000..1b5c838cf46 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_cast.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: interpreting an invalid 32-bit value as a char: $HEX + --> $DIR/invalid_char_cast.rs:LL:CC + | +LL | RET = *ptr as u32; + | ^^^^^^^^^^^^^^^^^ interpreting an invalid 32-bit value as a char: $HEX + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `cast` at $DIR/invalid_char_cast.rs:LL:CC +note: inside `main` + --> $DIR/invalid_char_cast.rs:LL:CC + | +LL | cast(&v as *const u32 as *const char); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.rs b/src/tools/miri/tests/fail/validity/invalid_char_match.rs new file mode 100644 index 00000000000..6c2e65b2bb7 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.rs @@ -0,0 +1,26 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; + +#[custom_mir(dialect = "runtime", phase = "optimized")] +fn switch_int(ptr: *const char) { + mir! { + { + match *ptr { //~ERROR: interpreting an invalid 32-bit value as a char + '0' => ret, + _ => ret, + } + } + ret = { + Return() + } + } +} + +pub fn main() { + let v = u32::MAX; + switch_int(&v as *const u32 as *const char); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_char_match.stderr b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr new file mode 100644 index 00000000000..7706ed97316 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_char_match.stderr @@ -0,0 +1,23 @@ +error: Undefined Behavior: interpreting an invalid 32-bit value as a char: $HEX + --> $DIR/invalid_char_match.rs:LL:CC + | +LL | / match *ptr { +LL | | '0' => ret, +LL | | _ => ret, +LL | | } + | |_____________^ interpreting an invalid 32-bit value as a char: $HEX + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `switch_int` at $DIR/invalid_char_match.rs:LL:CC +note: inside `main` + --> $DIR/invalid_char_match.rs:LL:CC + | +LL | switch_int(&v as *const u32 as *const char); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs new file mode 100644 index 00000000000..faf5fb699a6 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs @@ -0,0 +1,15 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation + +#[derive(Copy, Clone)] +#[allow(unused)] +enum E {A, B, C } + +fn cast(ptr: *const E) { unsafe { + let _val = *ptr as u32; //~ERROR: enum value has invalid tag +}} + +pub fn main() { + let v = u32::MAX; + cast(&v as *const u32 as *const E); +} diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr new file mode 100644 index 00000000000..d8988876045 --- /dev/null +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: enum value has invalid tag: 0xff + --> $DIR/invalid_enum_cast.rs:LL:CC + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ enum value has invalid tag: 0xff + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `cast` at $DIR/invalid_enum_cast.rs:LL:CC +note: inside `main` + --> $DIR/invalid_enum_cast.rs:LL:CC + | +LL | cast(&v as *const u32 as *const E); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + From de4ac0c465facfdfd56ce08dc6bb5cfee901561c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jun 2024 13:28:36 +0200 Subject: [PATCH 061/153] add const eval bool-to-int cast test --- .../ui/consts/const-eval/ub-invalid-values.rs | 11 ++++++++++ .../const-eval/ub-invalid-values.stderr | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/ui/consts/const-eval/ub-invalid-values.rs create mode 100644 tests/ui/consts/const-eval/ub-invalid-values.stderr diff --git a/tests/ui/consts/const-eval/ub-invalid-values.rs b/tests/ui/consts/const-eval/ub-invalid-values.rs new file mode 100644 index 00000000000..1724a88dd3d --- /dev/null +++ b/tests/ui/consts/const-eval/ub-invalid-values.rs @@ -0,0 +1,11 @@ +const fn bool_cast(ptr: *const bool) { unsafe { + let _val = *ptr as u32; //~ERROR: evaluation of constant value failed + //~^ interpreting an invalid 8-bit value as a bool +}} + +const _: () = { + let v = 3_u8; + bool_cast(&v as *const u8 as *const bool); +}; + +fn main() {} diff --git a/tests/ui/consts/const-eval/ub-invalid-values.stderr b/tests/ui/consts/const-eval/ub-invalid-values.stderr new file mode 100644 index 00000000000..edf72f731e5 --- /dev/null +++ b/tests/ui/consts/const-eval/ub-invalid-values.stderr @@ -0,0 +1,20 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/ub-invalid-values.rs:2:16 + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ interpreting an invalid 8-bit value as a bool: 0x03 + | +note: inside `bool_cast` + --> $DIR/ub-invalid-values.rs:2:16 + | +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ +note: inside `_` + --> $DIR/ub-invalid-values.rs:8:5 + | +LL | bool_cast(&v as *const u8 as *const bool); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. From f8e25a687e02f741075a653215a8feedc0b6e7cd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Jun 2024 14:09:07 +0200 Subject: [PATCH 062/153] Add `path` function to `run-make-support` --- src/tools/run-make-support/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b17f217c133..20b7bdfdcef 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -76,6 +76,11 @@ pub fn htmldocck() -> Command { python } +/// Returns the path for a local test file. +pub fn path>(p: P) -> PathBuf { + cwd().join(p.as_ref()) +} + /// Path to the root rust-lang/rust source checkout. pub fn source_root() -> PathBuf { env_var("SOURCE_ROOT").into() From e8b04cc95fe1412e2ef369397a60f0667e99880f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 9 Jun 2024 11:02:19 +0200 Subject: [PATCH 063/153] Migrate `run-make/multiple-emits` to `rmake.rs` --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/multiple-emits/Makefile | 7 ------- tests/run-make/multiple-emits/rmake.rs | 13 +++++++++++++ 3 files changed, 13 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/multiple-emits/Makefile create mode 100644 tests/run-make/multiple-emits/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51..86da061b2bc 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -145,7 +145,6 @@ run-make/mismatching-target-triples/Makefile run-make/missing-crate-dependency/Makefile run-make/mixing-libs/Makefile run-make/msvc-opt-minsize/Makefile -run-make/multiple-emits/Makefile run-make/native-link-modifier-bundle/Makefile run-make/native-link-modifier-verbatim-linker/Makefile run-make/native-link-modifier-verbatim-rustc/Makefile diff --git a/tests/run-make/multiple-emits/Makefile b/tests/run-make/multiple-emits/Makefile deleted file mode 100644 index d1f29764485..00000000000 --- a/tests/run-make/multiple-emits/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out 2>&1 - rm $(TMPDIR)/out.ll $(TMPDIR)/out.s - $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out2.ext 2>&1 - rm $(TMPDIR)/out2.ll $(TMPDIR)/out2.s diff --git a/tests/run-make/multiple-emits/rmake.rs b/tests/run-make/multiple-emits/rmake.rs new file mode 100644 index 00000000000..67c0ebb9864 --- /dev/null +++ b/tests/run-make/multiple-emits/rmake.rs @@ -0,0 +1,13 @@ +use run_make_support::{cwd, path, rustc}; + +fn main() { + rustc().input("foo.rs").emit("asm,llvm-ir").output("out").run(); + + assert!(path("out.ll").is_file()); + assert!(path("out.s").is_file()); + + rustc().input("foo.rs").emit("asm,llvm-ir").output("out2.ext").run(); + + assert!(path("out2.ll").is_file()); + assert!(path("out2.s").is_file()); +} From 19a2dfea881568fb63e55e8535634ad33c783f02 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 8 Jun 2024 23:17:11 +0200 Subject: [PATCH 064/153] Migrate `tests/run-make/prefer-dylib` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/prefer-dylib/Makefile | 9 --------- tests/run-make/prefer-dylib/rmake.rs | 16 ++++++++++++++++ 3 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/prefer-dylib/Makefile create mode 100644 tests/run-make/prefer-dylib/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51..fb65c96c4aa 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -177,7 +177,6 @@ run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile -run-make/prefer-dylib/Makefile run-make/prefer-rlib/Makefile run-make/pretty-print-to-file/Makefile run-make/pretty-print-with-dep-file/Makefile diff --git a/tests/run-make/prefer-dylib/Makefile b/tests/run-make/prefer-dylib/Makefile deleted file mode 100644 index cc26e70ae67..00000000000 --- a/tests/run-make/prefer-dylib/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib -C prefer-dynamic - $(RUSTC) foo.rs -C prefer-dynamic - $(call RUN,foo) - rm $(TMPDIR)/*bar* - $(call FAIL,foo) diff --git a/tests/run-make/prefer-dylib/rmake.rs b/tests/run-make/prefer-dylib/rmake.rs new file mode 100644 index 00000000000..ad9fd8a15a2 --- /dev/null +++ b/tests/run-make/prefer-dylib/rmake.rs @@ -0,0 +1,16 @@ +//@ ignore-cross-compile + +use run_make_support::{cwd, dynamic_lib_name, read_dir, run, run_fail, rustc}; +use std::fs::remove_file; +use std::process::Command; + +fn main() { + rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").arg("-Cprefer-dynamic").run(); + rustc().input("foo.rs").arg("-Cprefer-dynamic").run(); + + run("foo"); + + remove_file(dynamic_lib_name("bar")).unwrap(); + // This time the command should fail. + run_fail("foo"); +} From 534b5855a6baf6da084c261593cdfb84cec01755 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 11 Jun 2024 15:08:59 +0200 Subject: [PATCH 065/153] bump stage0 compiler --- src/stage0 | 856 ++++++++++++++++++++++++++--------------------------- 1 file changed, 428 insertions(+), 428 deletions(-) diff --git a/src/stage0 b/src/stage0 index ed88549e698..f36010fa4b4 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,434 +14,434 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-05-26 +compiler_date=2024-06-11 compiler_version=beta -rustfmt_date=2024-05-29 +rustfmt_date=2024-06-11 rustfmt_version=nightly -dist/2024-05-26/rustc-beta-aarch64-apple-darwin.tar.gz=b899079e4c3541762db909b2ec2fd73ca10c26874308831346770c35be29d6e4 -dist/2024-05-26/rustc-beta-aarch64-apple-darwin.tar.xz=2370613f7b60baee5dfccb0adf1586ec960d8590863e2be1571e5efe10f7eaf2 -dist/2024-05-26/rustc-beta-i686-pc-windows-msvc.tar.gz=d8976f398b8fdc3a43894cdd783c83bf0d7db33d6d059dd5387dd7a2840c70b6 -dist/2024-05-26/rustc-beta-i686-pc-windows-msvc.tar.xz=1eeb53dfc82b902e5f9e11bb631b0c2812c7f81a84c1023c69903debb6fff4da -dist/2024-05-26/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=512c74d27fc57bddaf8ec8865afc1ec3dc37106e07a9ef60921b2f852c16ef88 -dist/2024-05-26/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=48b01607a0316817505d4286ce075dacdb38fc170aae7e8b4daa7b75272916f9 -dist/2024-05-26/rustc-beta-aarch64-pc-windows-msvc.tar.gz=f9c8260ce005ffb02213b23530abc8bda5f74104ede11202a6b379e1cead640c -dist/2024-05-26/rustc-beta-aarch64-pc-windows-msvc.tar.xz=567989038185ddbf00d5ef5f7bde9934cce7c8d932db81c3c635283512d8983c -dist/2024-05-26/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=9fe58cd58e0f758d338d1ee427186f2ac0b644ef9decf457d4b6c0f67df475e4 -dist/2024-05-26/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=c589495fc21e7bfe3ff19736ba79ff78bc8899bc95f714e93ae4d410a704b0c8 -dist/2024-05-26/rustc-beta-x86_64-unknown-freebsd.tar.gz=4d9206a4361ed0d400decc68b2d908447de0390801bb5ef49885b42e31fc8b07 -dist/2024-05-26/rustc-beta-x86_64-unknown-freebsd.tar.xz=215b0f6ce7885bc2fa8c5d8352e4c5b9bfddb6d92f398ece00ede1bb693c92bc -dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a7f32c585c191b194a271c3baec3e81d8daac6a107ab5fada0b94e6c31dc295a -dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=ea7a5b798e251fea669265bb66d8e20889e1fa0dd71c5cbb7caf9eb187462fa4 -dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=44cb994404abeb3b9f873cacae90a208b3243a98d6c7366a7f211a81180eb3af -dist/2024-05-26/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=49cdde9184c78d03a3fc1af955c0cb37ab290f6d4f0f3a71ce37903df389f804 -dist/2024-05-26/rustc-beta-x86_64-pc-windows-gnu.tar.gz=fe9aebf5129393a8525c9be7fb3120b61a346028d23a19727dac37bb282d4731 -dist/2024-05-26/rustc-beta-x86_64-pc-windows-gnu.tar.xz=760ea53130788d624e3cbee11ade75b38abeaa10701e8205ae5cd8781f54d5f4 -dist/2024-05-26/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=0a7412f1c722cf74736120b9fce90e4f432da4a51f2d7a53320362e7e829f661 -dist/2024-05-26/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=e82df323b5544ca55a23db09fd23dff72cacc575dd25e7e056033ff2ca5ba3e3 -dist/2024-05-26/rustc-beta-aarch64-unknown-linux-musl.tar.gz=9b9e7fe38a6e1fe44e629a8523d6b3acdf199b2bb94e7cb2bc9dc4858faf2022 -dist/2024-05-26/rustc-beta-aarch64-unknown-linux-musl.tar.xz=cf1c8a2e68d22d078b69fcffa64dafa9d3b54ad4983b485368dc297c4109645e -dist/2024-05-26/rustc-beta-x86_64-pc-windows-msvc.tar.gz=9069c6b50e3842e03ed13cdd39513a17ae4251fb47893c02c58b5f4704b4c9ff -dist/2024-05-26/rustc-beta-x86_64-pc-windows-msvc.tar.xz=6a315e496629f9b57fa9b82e6cb705cc7aacde690b3619c81dfa57382bdb64ac -dist/2024-05-26/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=c31a1bf28a4d2c4470032e893b043c25c349ff07facda18587a2eb76cff648e4 -dist/2024-05-26/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=36da69f87daec24b9810ece65d51abc41128ee1874be14bbc46f74c09a3b20f2 -dist/2024-05-26/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=6b9aab90326c804aeb88bcfbc8055438bae0fb721b9d8b1a64b062836ba9efa4 -dist/2024-05-26/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=d0aeed09775c58a17649c42e0b641f20c44479056db43116ad452e771a88ddfc -dist/2024-05-26/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=4b1293f35b04a2f9e01e9752b3e8a5b61aa2375930fa72a8c3d04f52f4fbcad3 -dist/2024-05-26/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=06a653d79b84399798df9f3e636160f56c774a1593e7ad9a57f6e35a3d54fa77 -dist/2024-05-26/rustc-beta-x86_64-unknown-illumos.tar.gz=827865d233d702017b592d6c46954b54f18ffb758f79bfedf59fb535168b9b18 -dist/2024-05-26/rustc-beta-x86_64-unknown-illumos.tar.xz=4258e58b103e5a579e57059bdb1f61fa8e54854c80340888a11a2e81040bfc32 -dist/2024-05-26/rustc-beta-x86_64-unknown-linux-musl.tar.gz=be7f3f7485cfb378e105f8ea09b4a1fb6b78cd68e2a5b7e1cc354c6abfa55953 -dist/2024-05-26/rustc-beta-x86_64-unknown-linux-musl.tar.xz=ee6c02cdf6baa8cbadf8dc53a075582db428a0b149dec7c0f70bb182f49df79a -dist/2024-05-26/rustc-beta-s390x-unknown-linux-gnu.tar.gz=cbf5cc045498ade9d1051de75b127e78d7986f5dee9ca39586e9e9e3bfe066d2 -dist/2024-05-26/rustc-beta-s390x-unknown-linux-gnu.tar.xz=8803daf2ffadd1c76f7591dd765bccb8630336c00a9419f4e9e9a2fc882cd1c7 -dist/2024-05-26/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=9546048a0d5022d19770398f27e8c51cee4fd5879ec012709b8683a5ea9acd62 -dist/2024-05-26/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=5da5076d933127e616a289f6ba9bdea41f0f8f2604436c440a12f7007e5bee79 -dist/2024-05-26/rustc-beta-i686-unknown-linux-gnu.tar.gz=2f20e8666a768b32913a61e49f1774ad0fd616af874eab37b8fcff5344479806 -dist/2024-05-26/rustc-beta-i686-unknown-linux-gnu.tar.xz=1ac7c922764f406db986050f526f5b4490d789978cafad00db668cb4128d64da -dist/2024-05-26/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=d685e5d7efd8f312f22c0d1c132618f6112e528a51e451fa3279e71d66b46a4d -dist/2024-05-26/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=bb378be1b0bd6187cca16f5142f6d516790b8acc330f64af4371dd15751aff4f -dist/2024-05-26/rustc-beta-i686-pc-windows-gnu.tar.gz=5a628010b3fd859aae9b75086ad299fdee3159c6f7b8c5b93b24f56f392af0c6 -dist/2024-05-26/rustc-beta-i686-pc-windows-gnu.tar.xz=7546c4cbbc9c33dbed8895608116393855d73b99987e5e1fb2e6a8e88b0ed3cf -dist/2024-05-26/rustc-beta-x86_64-unknown-netbsd.tar.gz=5c10adf9a0d2b917d05e285b8754925d324a43335639d6caeae6bc815f70a852 -dist/2024-05-26/rustc-beta-x86_64-unknown-netbsd.tar.xz=49015adf19be4847dc5de824718a07f741b921a6c4f5565ae9d57b2ff24977c3 -dist/2024-05-26/rustc-beta-x86_64-apple-darwin.tar.gz=399a4751cf0f1015cd67b312f89a3b57f1a2e0b2b7052aa943dd87ff88e10e2c -dist/2024-05-26/rustc-beta-x86_64-apple-darwin.tar.xz=214178058be3e0d305838e1cc0c4de7d7a6aaeb3df1c8de451aa598bab46bc13 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=fc8ba79857b1f1d8d27049e3322db0e9dd8e8f55e9899a7651826d29d18ccbd8 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=d83f291dd371fec862e71e382db853d3547c1f8fc5cf475765e91054ffe4b40d -dist/2024-05-26/rust-std-beta-i686-pc-windows-msvc.tar.gz=4e831a551c6903d6995162c7e4ca35dcb421e50659a52e33b5d82a071ffc9c6d -dist/2024-05-26/rust-std-beta-i686-pc-windows-msvc.tar.xz=4944a6c8bd5716811eaa34d932899cb7a7b1ef16def784663867921357b98b89 -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=25cf208ccd2bfd922d43f7d5e6000daf523fdea3c436795a641af43ca5af3c3e -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=846bcd9b52a0c267bc0f5870dde2b672f002df8397d31ec4d55ef407ac9f7097 -dist/2024-05-26/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=2043dc32a5df5da4c289119d70896b88ec527ca72509eafbe39592bf18451c2d -dist/2024-05-26/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=20bffebf6414d6c5eb357280a301a7d7b6e2fe778423403aaa9106ce16ead498 -dist/2024-05-26/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a67464ceea45dd3bfd20156091e1ac070ad1f921f70cb8c11c0a5945e857cc40 -dist/2024-05-26/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=b8518464ed51eb07fe9874dd38eb81004a58a994e95f1062ec5ab01db0d7cbd1 -dist/2024-05-26/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=398e2a8c2c1ff8e19f810513f1d4105c57b509290393d346ff56a78c58419c54 -dist/2024-05-26/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=3cb98ea534755f69a050df188c4b0b4282e5778609a8df6bd7dc9a467966344b -dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=aaf44990f5ea7055c911d414e7ba74ec6457d347648b13eba087ef87030fef34 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=32aa99692fe79711fa637b4f222fc5bcce3673845fee99692ef2cdc94acd033a -dist/2024-05-26/rust-std-beta-wasm32-wasip1.tar.gz=7711323738d70039ac2dcc39812610464b5d06f4a24db127143964424f07692c -dist/2024-05-26/rust-std-beta-wasm32-wasip1.tar.xz=413fc4b5480274ede6fc389d2563655cea0d438baee6b4f6c0d8757a4179d8e3 -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=b46cc9fab639276eb86be72746f3e484020014041cadff276da79f2c62b16376 -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=f4241afe5137e9a28fefd20115154dedfdd0db6d62e70e8b447a9999d238bf98 -dist/2024-05-26/rust-std-beta-x86_64-unknown-illumos.tar.gz=7b963148cf41ec6c918448d71929190474ac18b4770581e8ca41c9aa06d0d548 -dist/2024-05-26/rust-std-beta-x86_64-unknown-illumos.tar.xz=11d363e7e1325daa6161206f659b2da1cb64e1a6a49bedea2afd0993692e0110 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=2846fb587bc1e04ebcc15c4401eca652ec4a9a3ee07c4c8901ba8f0dec8bd307 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c9aba9b367861d861b7c21969c64ed7c56db27b295b79498f817d28afe6258d6 -dist/2024-05-26/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=dccd96c4f24fd935c04f29b1ac10f936ee92b9c8ecc71ca494d60555a3541a80 -dist/2024-05-26/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=6b22b9c8526b4c5e25e7b6583df7c626388d3ff177e1f7b22c57ffec07bdcde2 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=d85b7dc13e34927030b76f0578dfa8da22025b914e8f024e611a05f55f2ff60c -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=327beab489c253a802259760afc82ac337fe2addd2f26877610e1a2ca8a20c47 -dist/2024-05-26/rust-std-beta-thumbv7m-none-eabi.tar.gz=3b78f640fbc54016515b15fe5eba6c3d3f679582f33fbbd7656a9514bf04de25 -dist/2024-05-26/rust-std-beta-thumbv7m-none-eabi.tar.xz=f8fa181333351d8673b938b0395be2632110cdc6ad40f2b2bbc254643f5047df -dist/2024-05-26/rust-std-beta-wasm32-wasi.tar.gz=fa1f7cbf6784e9d1487a88f1942a223056315d45968d1f23ac262d81e6a3a1ca -dist/2024-05-26/rust-std-beta-wasm32-wasi.tar.xz=e13ce9734bebabf39839b27310c4a97c1553a34988bb2de69c9f4ad38592da48 -dist/2024-05-26/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=93c06f87883dd3b8abc504ee10c0d46ad702ec7266f13996a8e8dbbdcc6adfb8 -dist/2024-05-26/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=f785f3f53f47cd70cb3b1e04f46ae56f937814a895d132db470e21d9eb3f0eba -dist/2024-05-26/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=7bdb39efb763f3272550f229d97145515e73c9510b54c53246436c068fa4b98e -dist/2024-05-26/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=33960973887d3e4dc5f72550dd636c28bf6d5a9319c23c2ea1a14bb4c33eccf3 -dist/2024-05-26/rust-std-beta-x86_64-unknown-redox.tar.gz=16194e687a77d25e67d575f4e8a202d070771b6e51fb261d3a4673978b4c2a76 -dist/2024-05-26/rust-std-beta-x86_64-unknown-redox.tar.xz=0ce66624b0d2c1e476c730fc96718e8ff52780f8d5d6968e39a30cb9bd906b22 -dist/2024-05-26/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=01555fb03930106ae6be0c4bbc185a5f8cbec27375aedf4201529ed6856ac02d -dist/2024-05-26/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=3fa3ec9e478370a2874e7a47dcd84f714612b0eb05a8cbb6ff9379250e750278 -dist/2024-05-26/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=b84dc461e790fdcbf8084d2adb42398e51f162416522f2901f1d82d07915ee70 -dist/2024-05-26/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=8792ac895cd373b3fa8f4913e5a1b098d97ca1ca8f71beb15ca614111ea9bbbc -dist/2024-05-26/rust-std-beta-i686-unknown-linux-musl.tar.gz=5133f49db7ba73e900d8431838cbc12a5a276ff0f95fcd10a5791d5b4ef9b714 -dist/2024-05-26/rust-std-beta-i686-unknown-linux-musl.tar.xz=607131ca6ed1feab6289035445be404060281d3b1f720f40eb985b0341d2f2cd -dist/2024-05-26/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=aa8ba338e80abadf4383c34a686b1fa331e31a4cf0bb067576288f265a86aac3 -dist/2024-05-26/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=46fdbdffd351933cc1bebeaee3e2b26bee28c2356a9b337a4472346ee6cac9c9 -dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=dbbd9d0f3b4ecd1cac5d9c6ee62e5e099fd5f05dd8703c9035d5280b38e3a601 -dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=60edbb54ab8f1b982057a79063e6cf0fe5e4041c6306251e54cfca7014de84c9 -dist/2024-05-26/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=7ab82e3ae01242203d9d72b7d3c01c3bd70ef4d9ddcc86feaf025ae120558dad -dist/2024-05-26/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=148500507545bc8addedd8fe2f1df836c9aba894afb06bcb6f8a1258d9590999 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=5b9d7ca3c0b76a23ac412aae8421750b144c9e9fdacdb34a637a6f5f353d9bc9 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=7c856cc68e7d0b972258cc8f37731e72b9dd7eb88fc143fdea5220f4f60f6db0 -dist/2024-05-26/rust-std-beta-x86_64-unknown-uefi.tar.gz=5ddf07fcfd6e2cf17104f26fdfbaed3fa9055708b0ca63b1b0e675df8690b04f -dist/2024-05-26/rust-std-beta-x86_64-unknown-uefi.tar.xz=bbe32665b93efc6cf2fc5c28af448f85efa3810734a121033a92eac06b8414b1 -dist/2024-05-26/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=cde6a9cfb0aeced8be963fd7faa0456d506b6d693e84afd6a5423ac37a69d944 -dist/2024-05-26/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=026bdb53279ebb5f6a50f581b12ca2aa2c4de9655e786a3a17a606b2db4ff49d -dist/2024-05-26/rust-std-beta-i686-linux-android.tar.gz=8a21fb5147985941fc9eb8581e9970997240d8af19d6348e8b1b4296ecbea47c -dist/2024-05-26/rust-std-beta-i686-linux-android.tar.xz=ac5fd73f5a6ddc8c0644b32626c0bc53c885788e3e9fe331e2b598b86f0daebd -dist/2024-05-26/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=1f791a99dbed0179a1ea7b36fd13128c5c05d08489c8baa0ce660b6bbaf42a05 -dist/2024-05-26/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=92f8573bb786beb5cc74f3842a57d2725409ca7c2b12ed64f7ee543bb3ee477a -dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=faf08553004fda1e2215116221cf35c7ea4a9f9c51b5bbe4bf16c99235d571de -dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=81a5f8c273f7403091781bd7ad110fe7103392bef4350bba0e029385bc0ce0a7 -dist/2024-05-26/rust-std-beta-x86_64-apple-darwin.tar.gz=2a2bf00ca629cd0c7bdcc7333456f5766db2a805cba1c88a1a89cfe76a0f5d09 -dist/2024-05-26/rust-std-beta-x86_64-apple-darwin.tar.xz=b3ac3042484e972962a3e67b4f9251380135d6cf07b9589c5e3e94b0dbdb70fb -dist/2024-05-26/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=c1953526bed228077dd42be2e570d1276fcf04868e4c8d426d23e00037178617 -dist/2024-05-26/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=71310bef84016c25c949826121b8bf78eabac6d7c34b3397961ad39493df49c2 -dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=d8fa9332e29f19b8b06dbafa2b6b13eb3479b9b28601372dabcee0cbb2a4d0ab -dist/2024-05-26/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=84daea4b14a3eb2712120652ebb2c342e6a37f984f1512dfa3cbd3531fb5cf53 -dist/2024-05-26/rust-std-beta-armebv7r-none-eabihf.tar.gz=348822ddf1f918cf56e6b76cdcfd3c4d4f50fb8e45c8b8c803e639910150b044 -dist/2024-05-26/rust-std-beta-armebv7r-none-eabihf.tar.xz=0f26d6888811e8ce6f0324bc5b4cbd667fbd8771e3e42192410d15e1d45033d5 -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=42b49ef649da71c425b9de48812c23470638ac876f489f4c1c35ac116ba0d078 -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=1111d46b2f5ef019cfb894b1a330721ee6fa1cf19b6f3c1abd8f866f8a208b3c -dist/2024-05-26/rust-std-beta-thumbv7em-none-eabi.tar.gz=4a41109968645be22ef1540037ac0a73789583eb250381d8431dfa6c8dd3a652 -dist/2024-05-26/rust-std-beta-thumbv7em-none-eabi.tar.xz=10007bd59e6cd60e924e472c19df1bda10bf6c60887ed91fb9874a7e596f9e72 -dist/2024-05-26/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=09d74fb8bd049910c60f585193af33fa51eab82dd2211030d71f3dcfba128a96 -dist/2024-05-26/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=2cdabc7be85304a7675fcebd53b8dd0e4183007fe0f81db3811df0d8bc712120 -dist/2024-05-26/rust-std-beta-x86_64-apple-ios.tar.gz=2061188c2361ce7b3a62a5bf45012aed708a8a86c2e5d1035a8c82b2ce868aa9 -dist/2024-05-26/rust-std-beta-x86_64-apple-ios.tar.xz=b6fd849acd590c2b853783b12b7b559395cc6698c6ab60d3b58a8475c809b9c6 -dist/2024-05-26/rust-std-beta-armv7r-none-eabihf.tar.gz=1915d8b728f8e37d7ede0da8cf2281676b970281c486d683f58d9bccfac2868e -dist/2024-05-26/rust-std-beta-armv7r-none-eabihf.tar.xz=21323f2a4eb7d46924438d0cc341b5d4e35b1ddb5abb02604980b5b055449e40 -dist/2024-05-26/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2f6ff815e3f4ed2913a27bb30c51c3992e60fa4d7d00a6ea8c648f19c9fd56bd -dist/2024-05-26/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=ae6d85a4ee1a98084f3b95befb923ccb57eb42a05ef1fc9f4e5d6736a63edc09 -dist/2024-05-26/rust-std-beta-x86_64-linux-android.tar.gz=580b1f05fc5530fe0078e958b8740ac538ba1b2589e2c893a6b25f12fa4609f5 -dist/2024-05-26/rust-std-beta-x86_64-linux-android.tar.xz=8eccdb906d4f28404172d6e09dbe8a33a89cdf4dea168c446a3f38d719b63ec7 -dist/2024-05-26/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=91c10648eaa115ebb2436cf78031d86704a917c2641090c2fc30d3234f2ed316 -dist/2024-05-26/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=376e28b76c9b0fb590b7a7b3700debb4bd5878d861c144aa69502a0aaba2c9ba -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=9a02c999175b39b1ae4a99a5556f42c89ce02b9c6e25688cfe573833256f9a0b -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=5dbcb9a42313fcbec57d26877175320bde265a1c1c1f8a3415bb742b86810153 -dist/2024-05-26/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=df780a07a1322e981da7083938d755dbefe0a2fa00c6acbe5658469400b79d32 -dist/2024-05-26/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=611fe18a51c4d84b231d3cf9a2dc47913071698634b7b3c4c066b1e92ef5adee -dist/2024-05-26/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=0f30d5e28ed599888e8125b3614070ef3da7d9b52442fd11e15993a84b678432 -dist/2024-05-26/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=7118728e4dfb3283f4f6ffdf0cb92e4f1dbee7a8d9ee79c2cb4cad99e90507f5 -dist/2024-05-26/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f1f1a976de6ad212370887bc8079a0ce6b491ca9bad3e4e8d2ba06e4eafae2d3 -dist/2024-05-26/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=034a5cebd66cf8f6d9379a26744e14d7d7e681b9203589a090a0fa205296d58d -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=900ac2af2799139ea704e192f6709f364b736e31ce682e12ce2ba0471b01afa1 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=5883309a473fb227ed5c71b7f341fc6f5ff22657d089ba790fc80ac9afeb065b -dist/2024-05-26/rust-std-beta-i586-unknown-linux-musl.tar.gz=da1637ebab43f0a7b6e64ba42d8e2d06f04c7c8eda4e8f80a6fa520832288dde -dist/2024-05-26/rust-std-beta-i586-unknown-linux-musl.tar.xz=c80f46b0b5b4cd2e3ea67f4ab3df1ad4124fa6b425d598ca0b6656451a74ba44 -dist/2024-05-26/rust-std-beta-aarch64-unknown-uefi.tar.gz=f7d0413c0882917fd041704c692cf5cc5030660aa9f04ada91e5c3c3fe007c6c -dist/2024-05-26/rust-std-beta-aarch64-unknown-uefi.tar.xz=ad84c695a7eb2dccee3d3560e2140fe19c6aee116fc5fc953ac944d630d3fd64 -dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=d42f482f7c262cc9cd6f9bb5bc64019cc348c0ec552ac5b518bd92548018411a -dist/2024-05-26/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=7589cab1072cecc50a9481e025e2f62f42975e60ba3e50fa6074e57e80c97257 -dist/2024-05-26/rust-std-beta-i686-unknown-uefi.tar.gz=85392042843c9653f1f6f643c0ba1af98ab0fd5a81cf1ddb7736415238cd5fa1 -dist/2024-05-26/rust-std-beta-i686-unknown-uefi.tar.xz=9cac1dafe8fc420c163fdb0ec089443dd4632077eaef73c459f3e8a9648fc6e5 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=a2c33177e3a1d48542bd376eac44d4fc6320e58ed5b5ee1c5f58980301d7df49 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=7183769937af0c9501b8fb71ce84a41562d9d773f4647d0d76d692fc0a623994 -dist/2024-05-26/rust-std-beta-armv7a-none-eabi.tar.gz=48e17ac14232f015425b46e1cfea19eea664cd224e0ec3e5b2ff58b82174b67a -dist/2024-05-26/rust-std-beta-armv7a-none-eabi.tar.xz=e04323b38171e9c63a4cd1673a5d69a9faf6e415d69ba11e7da7f30bd77077ac -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=2bc38de25271bd34c74a97b2f09133b4d3518911bd2d32deceab3e91f7554aed -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=2aad6d3b0b86847dfb1e57394de95dcbfe799630b388933d09939d1e309df911 -dist/2024-05-26/rust-std-beta-x86_64-unknown-none.tar.gz=9de88c179553ec42bdf5e036a44318a442778396380c44387cac94658ae7a294 -dist/2024-05-26/rust-std-beta-x86_64-unknown-none.tar.xz=f526dabd3d11858320129ccabfb3e5d14249ea6db30ac882ab26ae628d91f81e -dist/2024-05-26/rust-std-beta-armv7r-none-eabi.tar.gz=fa439d79673ad7a467dda9aa40524299880378d2a44a3338d038a6c6e6ec164c -dist/2024-05-26/rust-std-beta-armv7r-none-eabi.tar.xz=e07e26bcb5bd8dc93a877d122568aa78d09f77e81a3c85538872ddea47f3b319 -dist/2024-05-26/rust-std-beta-i586-pc-windows-msvc.tar.gz=f703880c171e14a6748beadb64477e85716e1cf45f98c5342600ee850518ba60 -dist/2024-05-26/rust-std-beta-i586-pc-windows-msvc.tar.xz=17dbd60169c3f47aa031d58dcd4898032d1e4991df86ff64e684e833c717d453 -dist/2024-05-26/rust-std-beta-armebv7r-none-eabi.tar.gz=5e53e25483594947af7a2aa5f14b06d44e0eaa16a464a004cfe7b079da9d7847 -dist/2024-05-26/rust-std-beta-armebv7r-none-eabi.tar.xz=81da84696b4250ad653b29aa73e8dd70fb0db6b469d8895a1f6c587ef38b47eb -dist/2024-05-26/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=d93918290043ba801c78f1d662ab847cd19002560fa6832176bb549cc51b0e8b -dist/2024-05-26/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=46b81807b463ef523a2e522199b4cdff70b817ab45bac56d17b7cf40c2bdb908 -dist/2024-05-26/rust-std-beta-i686-unknown-linux-gnu.tar.gz=adc0fa2c9a8cc8b4204fbd0455ccb2f914ae5335d8f8f96dc3df2791cf85e625 -dist/2024-05-26/rust-std-beta-i686-unknown-linux-gnu.tar.xz=8d5531693ba346d36f89fa969826434a1583c60dd1bf61b055aff026cadcb82d -dist/2024-05-26/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=01bd0ccbae4a301cd39eb92afda2f3a4d81276c17f8a3f48f9226a36fe4b6d31 -dist/2024-05-26/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=a07afdb285f1744ea75082d0a92f07333d5fd26ab84818a1bbb91ffab047998f -dist/2024-05-26/rust-std-beta-aarch64-apple-darwin.tar.gz=333fb310bf7749b0fb81a4f0930d0db738e24098fd3b4b38d037686c713f7243 -dist/2024-05-26/rust-std-beta-aarch64-apple-darwin.tar.xz=aa720a70e396e872045fe5934444b0e1b1e4633f371dc781397192c42a970c22 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=4949dc875777c799d1fa74db866d6492b25bf15a9383867f8272c3751b1bfd99 -dist/2024-05-26/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=40eb3bffd0ca0db7dcd330e01f28ba777807f0e2e514f65e3c2aedf19b72d61c -dist/2024-05-26/rust-std-beta-loongarch64-unknown-none.tar.gz=0b719a0748343cea4f6e3fcd0dffc567de0e45eef6b8067259c5d8b61c7b8040 -dist/2024-05-26/rust-std-beta-loongarch64-unknown-none.tar.xz=e7cb82769b71b100a8453df764a231d1967e5ae41a39a0b974a31ecd6c348568 -dist/2024-05-26/rust-std-beta-aarch64-linux-android.tar.gz=9b85abd7488b16f323396e5158059104281319971933a0702055b1e508418395 -dist/2024-05-26/rust-std-beta-aarch64-linux-android.tar.xz=2164c9dd13043e16b5144670a3032adfe0e439b18a193ca22c4c6b6bab678577 -dist/2024-05-26/rust-std-beta-sparcv9-sun-solaris.tar.gz=ab9d4db4abb8057fa0e9d8cfe0d01921da5499d082402f6277e1f8ed75c32f23 -dist/2024-05-26/rust-std-beta-sparcv9-sun-solaris.tar.xz=43254c65450dde6de4ce2538b80100db01ca15632989a6ba7173b01f4acc89bc -dist/2024-05-26/rust-std-beta-x86_64-unknown-netbsd.tar.gz=07c76a68e44cb9d6ba527d17dafdc0b51c9e2b51ab1c5dbbe8784d137609a4b5 -dist/2024-05-26/rust-std-beta-x86_64-unknown-netbsd.tar.xz=caf5dc8356c9fd34f13983f338e0d44fbec83358309a60b1d7520aaaddc4ff57 -dist/2024-05-26/rust-std-beta-i686-pc-windows-gnu.tar.gz=ca3561531a6054f2236a820c77b5ce109118f720a0e1ef850cb5dc8abfd1c8ce -dist/2024-05-26/rust-std-beta-i686-pc-windows-gnu.tar.xz=955681b4b4f5b3bebee11c381b8c12a73ca7fedf4f4d80213be9035cfad722f1 -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=035483e893dc4e28689c8ddba80b0e12d4b6ff8c8075c8fbb72612edfb830d1a -dist/2024-05-26/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=e6d4f6d00972fdf6f9c9faf4e8608d7f6eca23094623ddd9c6a08237f0721825 -dist/2024-05-26/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=02f9bb16b62f6b1a02787ad30877fe5b1676524ec868789044b82cb762cd96d3 -dist/2024-05-26/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=c54719d0e78d063c1aabc9253a3cb0bb5bc9a9b88bdd02829f004c183ef225ae -dist/2024-05-26/rust-std-beta-arm-linux-androideabi.tar.gz=ab579d41fa31499c9ae0574194961d64065bbded4595c9809504826151d7ffb9 -dist/2024-05-26/rust-std-beta-arm-linux-androideabi.tar.xz=41f0ac3317212f46df64b0907487ced9b5c8e390f2d8a49f284ddf95a89c04b1 -dist/2024-05-26/rust-std-beta-i686-unknown-freebsd.tar.gz=cad37ef490a691de7b1649b94aea62af61a79d93e3f859fffaf5ccf63ca238f5 -dist/2024-05-26/rust-std-beta-i686-unknown-freebsd.tar.xz=f20be5c8c379fe9d2445eaf83fdb9b1df77117a93fa6ec0b97fbd0e5449f75bc -dist/2024-05-26/rust-std-beta-armv7-linux-androideabi.tar.gz=58eb5e6155e8f4e598f7201ad46633afda0fbc3221fdf07c57ab7c644eed4140 -dist/2024-05-26/rust-std-beta-armv7-linux-androideabi.tar.xz=c2ee165302f135710ea2158d9592731cfdbb1c2d7f529ac1557b190826aae24d -dist/2024-05-26/rust-std-beta-wasm32-unknown-emscripten.tar.gz=6268910518871d87012f8e77e31c3b525cb573f6697787b03c516e2a43846e45 -dist/2024-05-26/rust-std-beta-wasm32-unknown-emscripten.tar.xz=01cf5cd68bcd9a7f706ff1b266bc5bfb61b8b1230488b3352359ce1c604c5d36 -dist/2024-05-26/rust-std-beta-x86_64-unknown-freebsd.tar.gz=c3baafd66056b93943bde313b84b00f719fbb006045a7af869d1c0b77927ffc4 -dist/2024-05-26/rust-std-beta-x86_64-unknown-freebsd.tar.xz=7d846e6840553986ebe3f2a8dd526af5daeaad566f3b241e94c2d18dedabed85 -dist/2024-05-26/rust-std-beta-wasm32-wasip1-threads.tar.gz=b4de80001c585b3644116c7a4cc7ee6a00476058f84637c3ff49e8dfc5edcf1d -dist/2024-05-26/rust-std-beta-wasm32-wasip1-threads.tar.xz=8facfbeb32902b094512c89dac44b94f437163a8b630adc485383045ec4bfd0d -dist/2024-05-26/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0b8a82fa80653cbd2c27237b7b696f4ddd37e0a2575fca29655fd36883193659 -dist/2024-05-26/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=ea9b3e6984605bd2606aa0456e5a9ecc4addd2880104cf5ddbb7fdb81673818f -dist/2024-05-26/rust-std-beta-x86_64-pc-solaris.tar.gz=b4234ad1e817f65a7a2ecdfabfb1437ce98fd580c0bff61037ec917fd6e3c88b -dist/2024-05-26/rust-std-beta-x86_64-pc-solaris.tar.xz=b7ee8e567aa1341d76be78eccd2c5857f4757b295b32a14d4054766c41cd126c -dist/2024-05-26/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=145a8427c01b038b9bc79aed2e0ff46af87789555bd486885b3592c4bb62fe9b -dist/2024-05-26/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=d84f020657dd466ba4f45d50fe1a8c316d03291c8845c443e2c68c4b40e590c4 -dist/2024-05-26/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=96b2278c15a6f83cb37ad6af34d9c5f364198a19cedac937d5cbaafbaca63fa7 -dist/2024-05-26/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=edbe125808cfcc69189c59f7b7614e056d34b23d121f9f165a93498eb775f92f -dist/2024-05-26/rust-std-beta-thumbv7em-none-eabihf.tar.gz=dbbc72ede43591cfddb55ceb4aeb38d641a7ea7d7c0f5f4415a3c2e3a07e916a -dist/2024-05-26/rust-std-beta-thumbv7em-none-eabihf.tar.xz=6b80df5802d08d6653fea474366bf1d4c892a87738a7a9f7156ae7ef916b5de6 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=2e9c56810053a067bf91df0bf3d2c5c08c823e25fbe7267a6633ad33876ab0bb -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=494963c721fb8d1e0d44ab9ad4212aa086af2363289d7b0d8b08c1e82f71efc7 -dist/2024-05-26/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=9901fb8f28e2334b31cb594afb1a91f22fa019b13808b650d940bd2d89a1315d -dist/2024-05-26/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=583b0336f3f501eda441cdb5fbae87c4457a0bdcf896cca808111a181549b786 -dist/2024-05-26/rust-std-beta-i586-unknown-linux-gnu.tar.gz=e4fd222c2ed08e0fc1da161a23183ee222fa8755e70f4a352ae854b2cb798663 -dist/2024-05-26/rust-std-beta-i586-unknown-linux-gnu.tar.xz=81bf3475805e8af9a6297868ce9c1893c22d901fc7d16f0482c28a4655608de6 -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=c1d015599bc48664b01507da30bf152d730eaf0bd61cd907caa353b223d7adb9 -dist/2024-05-26/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=fdea1b1280e2fa5b14ef8998408557ecad0954b2502fe073e65e3ec3cacd1d22 -dist/2024-05-26/rust-std-beta-aarch64-apple-ios.tar.gz=be8fc41bb262be74ad73d375db76cc8ba277e8313a911aaabf17b02c52909b2f -dist/2024-05-26/rust-std-beta-aarch64-apple-ios.tar.xz=7ae7187a9e85b58b740cf778df6d4442e388236501d6eeee76bcef0f9f378533 -dist/2024-05-26/rust-std-beta-wasm32-unknown-unknown.tar.gz=f5d863504c8b6b3fd42123dc09ad5e2cef978d8887a8ed62a125c125a7022b32 -dist/2024-05-26/rust-std-beta-wasm32-unknown-unknown.tar.xz=a36d65ab13f0da73e38f5e034d041dbdb1dc6577508734af332b2cbda5122ad6 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=f9c9684b948b09d658689ca70b84515b3533c41edab0e25bcd8aef5e40c621f5 -dist/2024-05-26/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e595f26a2b49d2f5b36e5a7333ac6bd0b54fd1c05122d160e5c1a4708ed6d488 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=2c140b89014321f7827ce3e0b2d6cfdc84e871f05b3a0908716174719689498a -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=bfed676e39a67671f3256edb6b9e20e8ed4421d4b777627c1484afd8c0d68d85 -dist/2024-05-26/rust-std-beta-aarch64-apple-ios-sim.tar.gz=8297677d667a637cb298e9e7453ba68190a9ad314a52015bc4124817e6586ece -dist/2024-05-26/rust-std-beta-aarch64-apple-ios-sim.tar.xz=f2763a0f3a59b6c87ad1dc390cd7715587cf2b41fb58f58849243c69524905ac -dist/2024-05-26/rust-std-beta-thumbv6m-none-eabi.tar.gz=447a1c4e502b0deef96183af40f32ef3f0d011f833621d7b0a6d972c8859e986 -dist/2024-05-26/rust-std-beta-thumbv6m-none-eabi.tar.xz=5d21d53fdcbdcae5dedf1e8cf2742d05b95198c984cf42322b72e98636214364 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=f1ea6387ea140cce37c4708bbd5135d74f2861309b907b58458f2a4bb34dff13 -dist/2024-05-26/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=464f09ab8fe2fb8cda1d194d1178e025f092c13984680fcfc55f60f0f3b7f757 -dist/2024-05-26/rust-std-beta-aarch64-unknown-none.tar.gz=17b2d567838919513d8b998819f0367cee1b030882bff2be1116fcc4d3b95b1e -dist/2024-05-26/rust-std-beta-aarch64-unknown-none.tar.xz=a0571520b61b28a64055b6420ce5cbd49ebb8aaaefc73ab40df73b0ebeb142e8 -dist/2024-05-26/cargo-beta-aarch64-unknown-linux-musl.tar.gz=61a51a1409249cb99d168d88805d678f042b0cebae06f0f2be3ec3ffe507e59a -dist/2024-05-26/cargo-beta-aarch64-unknown-linux-musl.tar.xz=ea1e0fa7859596502b1b270e58599ca0d71c17060dc504a8cc801dc63a60de30 -dist/2024-05-26/cargo-beta-x86_64-pc-windows-gnu.tar.gz=ed791a607b85ed30666cf25de886892bcdab38bb2194bb5969637c4bf5700dcf -dist/2024-05-26/cargo-beta-x86_64-pc-windows-gnu.tar.xz=3cd4887501f35f9d608c25e5306b3e20473820d194e014902f1ba7e2baf365d7 -dist/2024-05-26/cargo-beta-i686-pc-windows-msvc.tar.gz=c531faa0b9af65f9987897dab8ef32d32c53d14437a76541fb7e477d73a778ca -dist/2024-05-26/cargo-beta-i686-pc-windows-msvc.tar.xz=f624fd704ee17023fe568a5f7165fd310170610b62fcfe0be374fbd53ba5e5fa -dist/2024-05-26/cargo-beta-s390x-unknown-linux-gnu.tar.gz=e4de592c9e6e58556ee56ca395838259cd239cd88be27fe27141181981ebac4f -dist/2024-05-26/cargo-beta-s390x-unknown-linux-gnu.tar.xz=b34dedc4c0312d40c7923f7fda9491ec6969002d641cff31889b96ba9becec08 -dist/2024-05-26/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=3c60bd3a7623e4a6f8691256ebdbd5b7441a13cc291803cd7e1e3a9af600def6 -dist/2024-05-26/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=07c4043b8da23bc161e8df2924c96f21c3d613e07b6d78c57c57908eeff50feb -dist/2024-05-26/cargo-beta-x86_64-unknown-freebsd.tar.gz=9e8e5e7e2725c680eef7ac4c9b962f04f31d2f59a33a4ff2025aa035f0ef9f80 -dist/2024-05-26/cargo-beta-x86_64-unknown-freebsd.tar.xz=c5e194b6bd6494101ac163902943437b3b0b1e78cfe50900fa80eda96bf37a4a -dist/2024-05-26/cargo-beta-i686-unknown-linux-gnu.tar.gz=20931f1b365f6f39fa473393ffade8bca346d00483673253a75f5718728e934f -dist/2024-05-26/cargo-beta-i686-unknown-linux-gnu.tar.xz=7ce7c900c333f79170d28fcc85603822c39b14b687db22618ae11bfd3d6d274e -dist/2024-05-26/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=152b2d0c9d1b79ef75cf5d86b880aff2e675e74d1f3456d156f782692df9062a -dist/2024-05-26/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=29852ddbc3e91ef2524a267f4037a901a5dcef4182138dc85f946b13f2defe2d -dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=084be6c65205744138bb4b32c8c64acfcd62eec48de06dce24904d7dc92d5d08 -dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=40139b0b78e8bf8b6ced7bd45675be174b51e99b0e09d5029aa2810f4ecd1850 -dist/2024-05-26/cargo-beta-x86_64-unknown-illumos.tar.gz=92448a4b52d02cc7e33c4304542f3514c1dfdd48a10a15c085caf24eae1ac955 -dist/2024-05-26/cargo-beta-x86_64-unknown-illumos.tar.xz=54757ba4bfc4ee87161dab91d3406570eae3f95f9022742b7096359e532a46bf -dist/2024-05-26/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c8d3cd13d4a2f3932b3804bfd18a11f847b5c2bb5ae32f4eb04c75f882c23471 -dist/2024-05-26/cargo-beta-aarch64-pc-windows-msvc.tar.xz=ff5b389e3645d58fd7cad66881554537d36319d84add1d897382b6ca3ca406f2 -dist/2024-05-26/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=31ea12902d3179266af423f4534881a9b2ea0131c0ee292a46e4db35efed6063 -dist/2024-05-26/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=1b467f77feaadd5d37d6faeca1f4001e7d5d1b29c4d40465c78f4d556ae23b1a -dist/2024-05-26/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=a32d5142d32f64f3adc18d9949c63e4582caac446daf8809626f3edc04dcc2ee -dist/2024-05-26/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=facf0eb79d61967126c5c49698aea3603790c13f467e40475ba4ba80d2937ee8 -dist/2024-05-26/cargo-beta-x86_64-pc-windows-msvc.tar.gz=bbc183a2ffa90e9771c1db7ae1bb260d6c5ecc86933e9d60026d5ff4975c76ac -dist/2024-05-26/cargo-beta-x86_64-pc-windows-msvc.tar.xz=154e72625aa847777464b1aa8d885f8de0f16138362ec3725f96b434d6ec3a1d -dist/2024-05-26/cargo-beta-x86_64-unknown-linux-musl.tar.gz=b45ea7d288797a7da04b71b665dca721899df248887e35b1d6903077a7f3a363 -dist/2024-05-26/cargo-beta-x86_64-unknown-linux-musl.tar.xz=cf654640589ad3326d5072be882270c8e16694400668a2b1be1feea6cd623636 -dist/2024-05-26/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=0c57f4972f64d8a418d4821492d2f069b7dd8f7b1e9626bdf59c4763ee85e06c -dist/2024-05-26/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=2ddb32aec0863593472f47c90fe9e8f008fdf69f3e33679d808383e56e5acaae -dist/2024-05-26/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=f304394966cea648c66faadc1f04d46a39e7532b913ae6f170b67eca1c03cfbf -dist/2024-05-26/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=0625fe16550bd1a1aac9699560e168836d6a31f24c2bd5f49007029684991c05 -dist/2024-05-26/cargo-beta-aarch64-apple-darwin.tar.gz=8159a07acc11cd1c1b7d0c0dcf8be269325033922c21a85ec38a9a1b11166cbf -dist/2024-05-26/cargo-beta-aarch64-apple-darwin.tar.xz=e4e935be5e89a405c06dcc77a76929a7c5fda2e576bde183a6854254720e053e -dist/2024-05-26/cargo-beta-i686-pc-windows-gnu.tar.gz=6a5c34fd6a762df06c7b25d3a25f93f8dcd9071789528365350b20ac4a0cf08b -dist/2024-05-26/cargo-beta-i686-pc-windows-gnu.tar.xz=3b0784e1ada13f88c1b3d130135406ab1b12ace88e2f296b292071ec35d15b50 -dist/2024-05-26/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=8dee7954f81238d7be66538f70cce670b724e919fcd7f2eeeef8ee492a808a8d -dist/2024-05-26/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=dd2445c26ea2c151b93bff68c164ed69a313f87fbf1f90e8024317b4a66a6185 -dist/2024-05-26/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=bdcc649bb6f425ab32caa2cc385fa3b99cbe86cc3ea7a5780788c35c029fb099 -dist/2024-05-26/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=8fb0a771f69f3d6849129a1ebf5026e256010775e8bb9befd52325243b8f188e -dist/2024-05-26/cargo-beta-x86_64-apple-darwin.tar.gz=2f4cefcb58f0ff51eef25680c926313e9b5e4a2c3beb710e7bb8eadde50c9313 -dist/2024-05-26/cargo-beta-x86_64-apple-darwin.tar.xz=5d53afb9ca5fe65a56e1d64e4746b13f9c586f81603553c0556eb02ad95df4c2 -dist/2024-05-26/cargo-beta-x86_64-unknown-netbsd.tar.gz=35c5b04d84d85c43f0c5a3bdc2aa8b8fb848961e3c4daf276704f85e47ae3fb2 -dist/2024-05-26/cargo-beta-x86_64-unknown-netbsd.tar.xz=3b0296264bd63a2d40c9d5e3a663756a5bdf442635ee8b6f54438a2767a2d04d -dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=a8c3a909f50a5de7f78672942d87aed939ee60ed6d5e50f308460a942a632545 -dist/2024-05-26/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=2ca4cb39879eba33da970197d45de82df898cf5a5bd4f4614b083fe999fac575 -dist/2024-05-26/clippy-beta-aarch64-apple-darwin.tar.gz=04c563beabcaefe80eda700ab26e975b30b5264c6202e04c9577f6c2b41bd6a9 -dist/2024-05-26/clippy-beta-aarch64-apple-darwin.tar.xz=19846f743872fd899ad66ce4820eef3f7ac056834856fe1d86c963f2e8acf2e5 -dist/2024-05-26/clippy-beta-s390x-unknown-linux-gnu.tar.gz=911554e8139df5c5b61fc85aaee2119cf36f3ec0f0e8741a7c8d92b1205bcff6 -dist/2024-05-26/clippy-beta-s390x-unknown-linux-gnu.tar.xz=1b108110da176b81daaadbc8c0a65950761fca243eb6cbf5ae0991d2bc3c89ec -dist/2024-05-26/clippy-beta-x86_64-unknown-illumos.tar.gz=264150fbe3d369f18b61f2d607b694519c2b4b50f93c8c03f7109064bea79ad7 -dist/2024-05-26/clippy-beta-x86_64-unknown-illumos.tar.xz=89a044938cf7734caaf39c98c6e2a036e544bc474a0af3a3d92e47f39534e6cc -dist/2024-05-26/clippy-beta-x86_64-unknown-linux-musl.tar.gz=f3a99c3a05280706cc042d67cec7162088cd2f62f2174bce8f074eda3d43cb8c -dist/2024-05-26/clippy-beta-x86_64-unknown-linux-musl.tar.xz=0da48481695a90c1857bc0f8ff39223b3791b8b7102143e44bcca7bcea6fcb42 -dist/2024-05-26/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=5ba8b0e2162c574dc73121a69e43fd6629df9c656d96d95e9d269c3bc6e62add -dist/2024-05-26/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=778eaf706993f617d40c22084f06d4ec8fa7455a22bcb699bd7b376d1194bd58 -dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=cdf9711390230edab20cf0552d55ebbef87263b3353fd51bf232c12d1dd131d4 -dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=5aa9b052cd0c7452ad08a1523c6fcad7df0a69f62a0a222b6a57d003d1881a6a -dist/2024-05-26/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=3d7276560656e51826e3033dcc45fd2c78c2d872951c7e3434fd5f693a37fb45 -dist/2024-05-26/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=9aa885565bf7691ed028b8838a4108313cb2e7eda4b2f96381e8d80655ff4ce8 -dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=29bcb622529f9e13b6aff7597e4c9d474f8127259f9efa96fa928eb3ba49b157 -dist/2024-05-26/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=14c7a9664a635479391eb33b90d8af80188cd38069799bb5b851b935e1848473 -dist/2024-05-26/clippy-beta-x86_64-pc-windows-msvc.tar.gz=3491ca3ce04812559abe45455e468625791aa6fc648ddc229d429159ce2b639f -dist/2024-05-26/clippy-beta-x86_64-pc-windows-msvc.tar.xz=85eca1d8659dd6c171295b0aea160eff1410bc60e15889952998460b30df03ab -dist/2024-05-26/clippy-beta-aarch64-unknown-linux-musl.tar.gz=aed3c4e45f47fd0bd6ca299f5883132e6d8b3c3f06d6bede71bb664bb0b04c10 -dist/2024-05-26/clippy-beta-aarch64-unknown-linux-musl.tar.xz=b8c475ac163435bad15fada68c29733d96f23f87cd92f5aa13ca99df21b93323 -dist/2024-05-26/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=3b42f9ffedd1b4074e7831fbf0809987866021b095eaa5f2d9481ca2765a7f85 -dist/2024-05-26/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=d71a3e5ae13c46f68f95f8fca7a3c6f8795faebf7602f8d1206e355c6d9bec08 -dist/2024-05-26/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=ce12948ba13e8f0556255a65657e9b92b996c2f96966cfefb895a6ffb8b08d47 -dist/2024-05-26/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d1d23de591053c469fccc8ae6edeae3a2a8502ea5feb95272ab90f6651c52dc1 -dist/2024-05-26/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=31ae7b2c3af5ca9b47a9eb6ff53d1717df49e3a834584659a7108a72739799bc -dist/2024-05-26/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=576332e47d5cd862581be587f03aa3a3e6abfc982fda6d26c7dcef0e2742b537 -dist/2024-05-26/clippy-beta-aarch64-pc-windows-msvc.tar.gz=8bd2c213b1dd6eea58a7896203962e9928ba9a39b0cbed5c5737b2d35c707a44 -dist/2024-05-26/clippy-beta-aarch64-pc-windows-msvc.tar.xz=dd530cb08114f28323c740e453f25b553376f0f4df977ebc79a87d09ac8e2b25 -dist/2024-05-26/clippy-beta-i686-unknown-linux-gnu.tar.gz=d8aa70bb4711bb985592632f88b2499b1fceedc294adcdb6e37f234dff0081f9 -dist/2024-05-26/clippy-beta-i686-unknown-linux-gnu.tar.xz=26349efee4513b0c37b9a963f3f6fcdeabc6857554bf3f28efa7c76c5c5b54b3 -dist/2024-05-26/clippy-beta-x86_64-apple-darwin.tar.gz=e6283756c66ff219a879799b6237df25755ac6a590e2015750bc3ac79eee322b -dist/2024-05-26/clippy-beta-x86_64-apple-darwin.tar.xz=474a5bacc986404ebdca454c28254e6af3a7865db1daf26da56497e6dd8db248 -dist/2024-05-26/clippy-beta-x86_64-pc-windows-gnu.tar.gz=2fab393b9f0fae2c087067dc42758f914d74eff81c6e87da134520b1e4bcfb97 -dist/2024-05-26/clippy-beta-x86_64-pc-windows-gnu.tar.xz=23f46cea5a99191908e79f6f145b6577ce328aa4a435c8fb84a3c5afba8b9476 -dist/2024-05-26/clippy-beta-i686-pc-windows-gnu.tar.gz=5d0b5a07967828f9d2180ecda420433962532721fcd6b5b1dcf7fd273c8ee1bb -dist/2024-05-26/clippy-beta-i686-pc-windows-gnu.tar.xz=34e36c25a1f385161d352f4d0fd03c332b9ad70c8bd96cd7928010f367d9ed07 -dist/2024-05-26/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=6bb0b231319507013f6556b88c7b32e640e182249935935796b33063f77d8c5f -dist/2024-05-26/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e029f9e9176d0562d6729ad87ba9dbaf474c003854f140da0a57ca52b2794a68 -dist/2024-05-26/clippy-beta-x86_64-unknown-netbsd.tar.gz=5aff0b8818b2639d2bb792288464b042aa2987e63e4b8d885ceed14fbd2425a6 -dist/2024-05-26/clippy-beta-x86_64-unknown-netbsd.tar.xz=6edd1afcf6bf4d9118a1dfbd8fc7f862026d179277b465da51b6b455957bc30b -dist/2024-05-26/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=8969bae5fee4a30591b55d57b06d03d7d2be08ee20d2e5d04f055f916a8e248a -dist/2024-05-26/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7dfddd258c8cfa4f6b26f739fe52bb0519543472476595d901486b53ab22ebe5 -dist/2024-05-26/clippy-beta-x86_64-unknown-freebsd.tar.gz=2462c2fdc6215312ec7a12e98f74f9cfb06c0bed30812441268bb91feb2e4a8a -dist/2024-05-26/clippy-beta-x86_64-unknown-freebsd.tar.xz=154d43b7db31cf9c25f6379c6bc0bb828fcaba99d9313e8267f705bdf810655d -dist/2024-05-26/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=ed50a1f702e574c754a0c6eabfe120b5b3286bfe004dcc58b6a857684ae44033 -dist/2024-05-26/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c7431985caefaa2d995483b0af592f828157d517828e6792c8abec0a52e2e600 -dist/2024-05-26/clippy-beta-i686-pc-windows-msvc.tar.gz=870b60708cb7fb9bd76d6c1ec2572502bbb7a86152d7e2ffb0e3d023674193a7 -dist/2024-05-26/clippy-beta-i686-pc-windows-msvc.tar.xz=292183dc34bbc648564ef99230efdb8749d3d2e34a190b62b318ef1b8f4546fc -dist/2024-05-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=c28d6ba3d8319ca2a3c810ef13637dc67df6ab5c6d3e67e085009b296a4e87d3 -dist/2024-05-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=ba1e59c352e3e10696f3b1e5516af1d7b9fc480f4b9b45f313234a9151f4db57 -dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=2efadde71b4bfbd6713b381f4e2df77a51be47818c4d7a0a9000d4f31502d50a -dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=82347bd970ad3a6e6d9565d9e6bfa994e23f849591ae6fda109f876928033952 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=c3deeda6061109a09b123df68fd83a9c11c30419b91fc73be7653e4650b1b544 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=a93bab60e6133734771ccbc807b44263c368bdb66b05491359897a23803d31be -dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=e71d212b7e25d7bbd0bdc4d04de8fa9c896239f1063f5e33067baf5278134cc5 -dist/2024-05-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=467191e0463a1f465304ffa37724da8199a112691147ae0c49fc311007fce410 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=e2be1ffefa6c19b2682d8ac219ad88956485c99d41bcdd76fe78c80ce214f331 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=7c801202c1c575c2522782f4346b4fc08abfc7f952a0cf3ad36a184e8e3c59ce -dist/2024-05-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=cbc04f5efa7849c51944612974aeadef63479202f2c0426d9301f38a54f3e023 -dist/2024-05-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=e0deed883ba554d9b863bad8f9903b5952813439469282673fcd322ab7692751 -dist/2024-05-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=d3c4d54c15e8dbc45e2182354510cb705068fd32e604d289c0c612a6942ae82c -dist/2024-05-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=a112b66030fc6d861ac988fbdb9496040a702d84409e41936c192af21d0ac7e2 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=633f765dfa420b35aead7f8e0be99d28c90dd8d76dc452321e0b1102563f9f5e -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=5db0f26d1705666dd1b6aa9c00bd24679698c7afc5b9a5df7d5588dd8be4dbd8 -dist/2024-05-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=a919f09c70fb61986dc0b4a52a75641edf18d7a4a9396fb0aae1009510bfdef1 -dist/2024-05-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=1d5781a9e6c705dd0a14ae75d4a49e5b0bf149d5d157ee19afc4fcbf6c31de29 -dist/2024-05-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=866667cc443b61ada4e25b816ee3d8e9de0d3114a9f5ce26fa36f311731f5726 -dist/2024-05-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=66cfae5d45a256b8d838a93e49a1cab0263418158ea238e07ba673dc7b3df6f1 -dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=57b29a2e3bd7d5aad05d6ac6ec8acd3f0b747ce679ea0fb53a203c5383895765 -dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=b8a5f95ab75b9a645934adb9a76513e0ff85f98de7b82aba494bd74289597d43 -dist/2024-05-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=d1ec7e5e6c8b13ef47359b1e64b972be0c4f740d18d341190db347cd89a868e7 -dist/2024-05-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=84f60a1fb717916a03c8f054610f543efd687bbfeee3b58bf8e99fa976bc7faf -dist/2024-05-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3016ced168060e3e2ba6147d3f4d13b18c76338ca80a827557b7882f168bb5ef -dist/2024-05-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=cd45818ace482132afef6b6d59d892d002a476fbad00f28182b865b56687d239 -dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=d49c9b195f063d2268074ecf9366380a968700a007f71593b1fcd8e5324b3a28 -dist/2024-05-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=66209a3abe1d64c7b00d55f526045d553e782ae994520da3a0ebdcef72142eda -dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=40f9c57aaa01f165604e47a967c2ce2af83a8c1d79f7cfa5cb737dc1513c12a0 -dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=b5e067643239ef064de01776806de26a3d728aa9a3e2b88fb619400a6a2cf4ad -dist/2024-05-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=2a860e5b10568f388252eb531913aad8aa0389d37cd2af49480802773a596be2 -dist/2024-05-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=6587860267c67a64977275f5d16b856d934f2a683ee1a6155dbf4bc9e52dc841 -dist/2024-05-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=979abfded9f0758334c867f2f493ac4741f9321c8321d9f5425adba51e19e5cf -dist/2024-05-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=392924fe23bbe9df2723e67af3cd5aba27b176c04878c62904e97fbed9bc946d -dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=9e809bab970bad03e9fc2bbae8302498053115a8db46a8bd617014d751d153be -dist/2024-05-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=8abee908fa9bfcf6e48b3e62581875ae65cc2b79b31c8df0976aa680c58e0ca8 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=48a98383da0741207106ccf93414739d7dcc37b83bfbd79b3789acd1481ca7e0 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=9706e65357de932a3325ed03153f455cc9af1d551a41327049c72a7a7cfd811b -dist/2024-05-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=eb328f79f4fa5afa2ecef6869555b5303761ef0b8fe5d69ef6eb03a01c93af9d -dist/2024-05-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=d5e7f54a4b972f8f6192a85e0185307406cfbcc50465a21c22d2fe64bbccc03c -dist/2024-05-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=b3964c1199d4cf6ed8926a5442ad95eb6c5bca8639576b5a423df0afaddf2353 -dist/2024-05-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=3b3711a87366e42348321efcb87b232f0cb9c68f8fef9f651893d599bbd03bf6 -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=2900e5fff29a5bff6bdbcd4205dd8bf5992df44534f04c1279a7cd47d050a15b -dist/2024-05-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=e5269da876cfbb5d0eb0ac24b34cf38e950a6904188fb4a7171f0504cbce654c -dist/2024-05-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=4ccb7a272765c9c59776922f0e034f2ffdc236e959d4500df9d928078016ec9c -dist/2024-05-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=5da7e0f39a0bb8c527f1db46c24713265ea7a3c9fb1bfaf84be6c6268ce68893 -dist/2024-05-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=de475ba7e107a5c144a417bb6b482b779ff954e0210c181a71a960c091a71532 -dist/2024-05-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=431c7d2d5a0c7bdb27dc15079c92cf71ce496978f1f2922e444da49e1b12affc -dist/2024-05-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=5e08f7be71e0ba29abcc3486a727df8444b818d6e4deac4728108c25382a4cc1 -dist/2024-05-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=df5b548d795cf89bc6bd6bc5608cca377e46e5829485a4f3b7d43e294e2b48d4 -dist/2024-05-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=2f2f62d57833250c2b36509e820d7d4860bfdd297f46af5eacecb6c0f27430b9 -dist/2024-05-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=d819323b185b9cb9b5fb2f1521d9f71408c026ffe345cd6b76f7ffca0917b054 -dist/2024-05-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=af87663dc3677d7a697192cd9f7e2e73f6825cd86109a3a1af424e39c2e20f5f -dist/2024-05-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=fdd0b838ff62feebfec9a7b8d516cab45568141a751641654b6ebd63165cd023 -dist/2024-05-29/rustc-nightly-aarch64-apple-darwin.tar.gz=9c328c9692688ee51fff66e43d92155752fdd67128c0f2fa3e5a642f43d7dd08 -dist/2024-05-29/rustc-nightly-aarch64-apple-darwin.tar.xz=d4f17356232fd136d2844d5888cc1425c0b942aa5ccaaf877fb8a8b357b6d4f1 -dist/2024-05-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=fe6533f08d7ce2e06e9fb337cdc32d865e8e00b8f91908737bc6354d3206eaf2 -dist/2024-05-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=dcec47a722fde1ec2eb61523a3a0efb06deed29f33e64ed1b11a01abccd20c2b -dist/2024-05-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=82f159b866d58fc7183ff923d714183f319459d9e47719551d17c8c2345ca138 -dist/2024-05-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=6bf7bcd9ba441e35bb2cc6ca2b91c8fa9dbaf72e11d57bb3371b0303701aa66c -dist/2024-05-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=e205ebc20e54660c7698f589f367dbed50bdbe46380b4505f96e8a90f9620c52 -dist/2024-05-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=8c2f2f53a77d638f36014b294dfc30d30b44899af92837d54237e7035e365d44 -dist/2024-05-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=dafb95b4125eb098fac7cbbf775f82247705f4ae39081966f1cc6530e47ab9eb -dist/2024-05-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=e450864ba5db1035016100e83e36574a50bd1037f5613abe9fb2171506458069 -dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=79d563c9dbf525955da2f0e666b8e1d8aaed2beccf8ed400ce0ee0916892bbb1 -dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=886cabea80578d4bddad4fd9eaeada7b7295c1a26f9d65a7466b078ce8f455e2 -dist/2024-05-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=96c7e311c97e0739bdb27d114e2c70b4f0300695dea7b17867b17f87609d75f4 -dist/2024-05-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=e59464ace28065d7b3ebc21bcde836c5cf6d7e442cb69dfb9751cf08f597958f -dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=43016ec0b5b33c7f16cf4f4c486b0d4e3554cc7fef139a78558c177856f047ea -dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=e74571f5b4dfb498aef90454b12ea33e927a86cc31fbfb83ab33b3e0439afa09 -dist/2024-05-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=7a7479cd717019f2e18cb022d96deb5d27c554cf411920d04229f940fbc7226c -dist/2024-05-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=bbd708d94f94da90010eb574aac0fed82490989a3f4b3b66e51d65526e0b3629 -dist/2024-05-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=f60e5f253ce5f17631620a5ed99873e6067d65a547dfbb0ea751e7b151cdf971 -dist/2024-05-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=71448313016bd45a7bbf083207a5f334c1a921b8a68bc9618cb4644c7e134716 -dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=69c481a820c25d7b59d3d63081e93f9784c00cc4efd301fb5b9680b3166e2d9b -dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=3a33c45bce9fcc91730bfed44db0c1781f9a6c8c0a4382af775f4c9b638ee5a7 -dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=d8d12e8b1f70353fd9b84ebea1ccb3a0f4bb561e99283c77ccb970ad6838cd19 -dist/2024-05-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=2890c1e4eb5eb0cfb57cf947088c43efd11e5e071bdb6191609639d541244394 -dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=0ba52772ae17e47cabd816980f0cb22bd25254ccc213da6a968bd8e635607c4c -dist/2024-05-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=4da826ffedd6468d336d97722b20f8ba49cbe7d77c7667addab19c39f731dd69 -dist/2024-05-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=463bd6103900d486e874195bd65646265449333dd5dd5f007cc57120289a5553 -dist/2024-05-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=0f4b1b482056ca489e9e74c634b733d1903ac0e6196506e635cc7edd6dc8f4d0 -dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=42b41b32eceec839cedf88ffea93c99b04ee4bc9ce095e0872bfe3a67a6f6421 -dist/2024-05-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=644896626ec0177c21ab549eff85fcf28d307848454055b4e43909455df51b01 -dist/2024-05-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=43698606a91a090ebdcd6ab5f40f8d62fc0d653eaec74ab851438abe7da8a89e -dist/2024-05-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=19b759811b9193c7b0d710b18427d7324c7ca4dafeca5d7cfebb6686761f9e67 -dist/2024-05-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=c52226e19cff041f23552589f872399723d4c6d6514db93c2d6201f70f36e013 -dist/2024-05-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=49c5b9d7551462e29ef4a036b3a6dd8905455256aff636b4fd4defc516d62e3f -dist/2024-05-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=b04be4f9b1eaf4bb5e9a2a544614ac99f466d5925108633fb8c5b700e7aece7b -dist/2024-05-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=8638b2106fbf7e5dc6837caaf07af1750b6aa24dc845e22a35d8e8e53584b2d6 -dist/2024-05-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=99710480631e11119640f6955257838648db572c4ed0d8d1b0081bace32313b0 -dist/2024-05-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=daab5b6364ad2afe80c96e8d905160e75c0783192296e88fd2b639c49b09d829 -dist/2024-05-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=0f6e0e64bbe42aae577cc0cb87d81ecb64a21c745277872177025611993c47a0 -dist/2024-05-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=fd45d7b870257bce91a33f5b971b11e0c6743e1c03eaa3c26bd201fe9be0c083 -dist/2024-05-29/rustc-nightly-x86_64-apple-darwin.tar.gz=29c34129ce3fef647140a0302fa1699af5460dab518b56d6a2257c7d7c288487 -dist/2024-05-29/rustc-nightly-x86_64-apple-darwin.tar.xz=fdf25c965c5218fad6e2949da8df88eeb9f886a8f5b9c72ec9d79a993c4829c6 \ No newline at end of file +dist/2024-06-11/rustc-beta-x86_64-unknown-freebsd.tar.gz=4bf5a3ae2656a992beedec2f41dc98c791426a1a6a88f3503b003b4d6f0ddc1f +dist/2024-06-11/rustc-beta-x86_64-unknown-freebsd.tar.xz=feaa1484586e78d77225734328d460277dde14baaf1299a30b30ef91e9a26a82 +dist/2024-06-11/rustc-beta-x86_64-unknown-illumos.tar.gz=9c692a71916f7ca9d41a97416f51d463b0495311491ba92b4d3cdb0f6c4e7c87 +dist/2024-06-11/rustc-beta-x86_64-unknown-illumos.tar.xz=97dece0cc2e4856a49f9ae17f09171fb55f140987acd0f988bbd0aa1e8971936 +dist/2024-06-11/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=6ad2e87e637302e8458d47dc1af923e38bffd7332775cfa5520c29110594d9b9 +dist/2024-06-11/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=84f6755c1377ced8ed2700b5ca9a2d38dd2e26a03e1fd636841ad46d3cf63895 +dist/2024-06-11/rustc-beta-i686-unknown-linux-gnu.tar.gz=11b439045379be2722cb42409b8bc342ff4b5f7df85e42566006cd72bb1a4e8a +dist/2024-06-11/rustc-beta-i686-unknown-linux-gnu.tar.xz=4e5103702b4e43ea71914e9c508aeb0db6382ea331c31981142163b2a89e19e1 +dist/2024-06-11/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=396a3aaefca9511086f7e5442209b70622082d133b96783b4237c3f01f42bf87 +dist/2024-06-11/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=66e46ed344af9f165b7c4fde2c576340fa81ecade61c45ecc1562de70a9203da +dist/2024-06-11/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=831420b262c5a2f44459e0daceebe271f298179c37aa5b7a1704a15bbbb1fb97 +dist/2024-06-11/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=691a6c4d0276add72cfab40968520ff48f683d4e660a50d1626ba9564dbf4914 +dist/2024-06-11/rustc-beta-aarch64-unknown-linux-musl.tar.gz=ebe1efe3c5d74e37d1c40dbd585ada7a7e256ce76911746f54994dfa15f9907f +dist/2024-06-11/rustc-beta-aarch64-unknown-linux-musl.tar.xz=3bb37fcab069713fe8aa5ca72291a439eba5af4a3cc0be9d152e5f29ccaef864 +dist/2024-06-11/rustc-beta-s390x-unknown-linux-gnu.tar.gz=c00c2ecb5aae552069395d03f4135f051da073efc68ed645348f026c1884799b +dist/2024-06-11/rustc-beta-s390x-unknown-linux-gnu.tar.xz=2c72347688058091a4bcb0c2fbcff49020df2b2c1733bc19d93b6e5149d5b13a +dist/2024-06-11/rustc-beta-aarch64-pc-windows-msvc.tar.gz=517977edaa51470d460aa9ec09309eea2082cffa6adb13571a8f36efa9351dff +dist/2024-06-11/rustc-beta-aarch64-pc-windows-msvc.tar.xz=0cc0b740cb267fde814b4971591b5797faa528b1e6250ef7b2d5220f0916208d +dist/2024-06-11/rustc-beta-x86_64-pc-windows-gnu.tar.gz=9fe7d85fdbca12fbfdb776789c336f726303c8845a6f6c93b2dc6ea8487585d4 +dist/2024-06-11/rustc-beta-x86_64-pc-windows-gnu.tar.xz=38130e3d9779ad54bd890c4001b34b7c58368ed1940e7e676947e9c05a8f6649 +dist/2024-06-11/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=acca3e045de3c0d908caec4249e3905d207d96b4a1722644457b3cbe5707422c +dist/2024-06-11/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=e4e92fc4b672f72b1f03db62ae712d9f944b982db89cf0d8dcb94adb1d560b3e +dist/2024-06-11/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=63274e707bd0d2b2f08c49f170f26773f802db833347d2aa694d345d11c841f5 +dist/2024-06-11/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=13702b24228d983710d5678e0a1003e4f77e2244fbdf599015f52adbbb77bfcc +dist/2024-06-11/rustc-beta-x86_64-pc-windows-msvc.tar.gz=ca877491bf7bf50989b9ac21c12e335fd0ff002ccf4a2c07316ae1df1a3d7e6b +dist/2024-06-11/rustc-beta-x86_64-pc-windows-msvc.tar.xz=d757a328595887039d8017e9e3faf79448850c3dd9bd3c26d309a313ccc09a38 +dist/2024-06-11/rustc-beta-x86_64-unknown-linux-musl.tar.gz=155497f2abe036f09f6aa014969d58132a9e2e4e148fea485b483e0dc3705a39 +dist/2024-06-11/rustc-beta-x86_64-unknown-linux-musl.tar.xz=6204d1fa08beeadcf1564e334cbb65a7317c571557cbc5517eb6bf08f5b0ce75 +dist/2024-06-11/rustc-beta-aarch64-apple-darwin.tar.gz=3bd7db536344c6a3d0d0bdf95986136d5db8996228802444b561783f2e7c3c9c +dist/2024-06-11/rustc-beta-aarch64-apple-darwin.tar.xz=b425561b3e7d9130fae94e78522bb262c634304ced32030828743fb332b11ecb +dist/2024-06-11/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=e2f78198d33f98aa34bedd4f5920868a8f68620e29eca2917833f6a8f23f787c +dist/2024-06-11/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=22f3b45678081fe52a9c8e89234a9939aad5623eb43ec54921effc28c0bdcd80 +dist/2024-06-11/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=beb5ec95069cbac4e53c51ea3e785ab5f25122132c8b78b196372bb2a31ed46f +dist/2024-06-11/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=17242f74c96cf581f2e40a82f6d7fbd585af2c2990cc73ad4ba7a3503dd279a3 +dist/2024-06-11/rustc-beta-x86_64-apple-darwin.tar.gz=d952d90397c70c5b53caa98b2e5d48e35780e1e5b342775c10fcbf504717d2ec +dist/2024-06-11/rustc-beta-x86_64-apple-darwin.tar.xz=14bd4336eb396a133ddbb2acd01ae799f2f68a7ac723a00a9db8c3e06bfa8027 +dist/2024-06-11/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=a2118f80091d62ebb762df0bdd159d19befb440d754034da7348aae50d63628f +dist/2024-06-11/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=a4b9d1a04d8f9cfd4daaf57fbeed3615d000c5107c6fa1b2992dad6ca552e35a +dist/2024-06-11/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=d5c16c5621e43cd3007ba4d2bc0f6e8a3a2376bc2a911e42bd2f2670ff94c12c +dist/2024-06-11/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=202662492afd863b6b6428a3bc5ed822c62ac2aeb8a0264df1d69cc5a3728d8f +dist/2024-06-11/rustc-beta-i686-pc-windows-msvc.tar.gz=a9fb64cac53595444bdbe8f152e52214812498e0c6e2b664db10f1f693a92dca +dist/2024-06-11/rustc-beta-i686-pc-windows-msvc.tar.xz=fe78c5ac51d96c3c3e222828dca3d105a2d4d7f8acd6e0d86ecd4b27ea70a4c3 +dist/2024-06-11/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=8c584010c964ef1b02e1014ca1c6ed9584c1ff781f8af115ee001e3a13213954 +dist/2024-06-11/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=4a407fb59db284ddf6fc0ccd487116fafbcd7c227f3dfd4e0b7b64dd560dc113 +dist/2024-06-11/rustc-beta-x86_64-unknown-netbsd.tar.gz=2f07a283bb0e57ad50366b67d216503a423867eae205e4354b74b748e9d3ce85 +dist/2024-06-11/rustc-beta-x86_64-unknown-netbsd.tar.xz=8008331b32e9d0daeb275327082e38671dcc91864a3ac95be67bd15ecaa852ad +dist/2024-06-11/rustc-beta-i686-pc-windows-gnu.tar.gz=c42637a8aa8666d746a45c9f47b437a9720d355b5bc6db42c2a90fb03d2c4a26 +dist/2024-06-11/rustc-beta-i686-pc-windows-gnu.tar.xz=eabe3a7e72829e0e5904ef381157cc3da169d9f5942e0367b2d1b1781c387560 +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f4010eea815cbab895c96311a456c4e3aa24c5f0d55f09052bcde59de7f286e6 +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=a8f555c713cbe4a1860ee5bc812eb624f2775e034da54bd0e37c325453d70448 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=c89619ed4ec28d4f48ef2f7e51155716483a7f4bb51fe38235e69d4694cfcbe5 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=89aa3d1add14298bd40e3bcbc6b41df91312258ac6f203fff9eca4422f0c5e9f +dist/2024-06-11/rust-std-beta-x86_64-apple-darwin.tar.gz=2303e7926bcc4fa2c67c7063fcac3a7b581fdd91fb89123cb6cdf514ff38afed +dist/2024-06-11/rust-std-beta-x86_64-apple-darwin.tar.xz=9ddf392d8c696e902c2924ff938a4bd099b9a54834dc62710e42527e464e776f +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6016b465a0cfc628f2c978ed18bc19a4a27e20a5ac11a170c40d01a857a5f50a +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=8e3d6f7ef6efead7d08b1c889bcc6e520d0a6d29226ade1b150aeb625fdb9abd +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=5f53b7630fa7703fc6752c3fb8c8eba8e25b9f77a3b91e14982510a0091d9e44 +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=8ed3c2f0b0f81d197d0dbd01aa777eb17ebc7303176601be2b2b05ebe1bcc971 +dist/2024-06-11/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=dbc1a1bb8cfb4472739d7f3a52bcd571357d2d2761f3723aa4c7d69abe9a5dfc +dist/2024-06-11/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=58f46f20d58669d497ff683d6ea85e18ff68d51a442f6e21bc20ddee779e1c4f +dist/2024-06-11/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=d71947b5ddcfe538162b14d6b785c365c34f2b6ac2f1abdc90b020c4a446a313 +dist/2024-06-11/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=ca0a665e566b3ff74c5f552e7e4e030d3cae9080dbb6055dce3aa41206b5b111 +dist/2024-06-11/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=e927c0890d2c5135d86b1960b6b182d5c47853b53eeb196b4748e7b8ec9362e4 +dist/2024-06-11/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=df33672f826ce8681d6c18ec2129ef47623b7cbaf6515cd921d39dfc05cb7a06 +dist/2024-06-11/rust-std-beta-i686-linux-android.tar.gz=2559fdcf250e7e0a1b5589e8f2bc69340f5610b7e6ddf08185936fa2e6f10534 +dist/2024-06-11/rust-std-beta-i686-linux-android.tar.xz=442f0aa53f343eec2b6984934bbf0651ff45f314d1f46dad2aa11a2f5c5a5a5b +dist/2024-06-11/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=cb657852d05766e1c18b11d99a94f3570b6c6147dbf9b2113b80236566d2d4ac +dist/2024-06-11/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=943de72c556821b67d59afd9dd128bfb01b3ba743dd3e7561c50559afd3768f4 +dist/2024-06-11/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=a7c6d3f54d925be073007e3737173b0def7d781b6bfd5345971a69300aeee9c3 +dist/2024-06-11/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=cb9115328bf6f5ae661ce5bc9cc9165c6c9e6f759f3cc5038154531b314e6013 +dist/2024-06-11/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=2a2dac9fba84958818f6b31f30f91fcfef521111827937c88aa696b646f5b075 +dist/2024-06-11/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=d16b28da0196a815f028d432dfa0957d0bfb512b259129969548bd050afac872 +dist/2024-06-11/rust-std-beta-armv7a-none-eabi.tar.gz=d78f96102490f9025598b11cb72e31e96d3f5fd566e8f7b2b2c503a37b0dc6c3 +dist/2024-06-11/rust-std-beta-armv7a-none-eabi.tar.xz=a439af58e90970b4dadaa04d8f94ea53c6c7a159117926c46b7da0eaa0d0ca5b +dist/2024-06-11/rust-std-beta-i686-pc-windows-msvc.tar.gz=d7847f3d9b1a2f50541ef3d2c25eeda469b28412817cadca52756aeb4f2c57b1 +dist/2024-06-11/rust-std-beta-i686-pc-windows-msvc.tar.xz=622cafc347ec1d3f0ef70354a0713cd255029730b17ad1f1ee951d9b0cb515e5 +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=5fee2542ee8ee8d155edc0ac36ec8822896e6f93f9f573b9284d70aeb186a05d +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=dfe9ca3e3f217922b65db0d65826c0962369fefd3d5d72d6f03039acd710f122 +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=b0937c5dcd458f313aabe07668ea338f2629bfc9c45d6139211b6923a7c7eb0e +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=65973a26c69f8ca7d3022180e2729161f7a618706cd9974fc54b14cf48f1af79 +dist/2024-06-11/rust-std-beta-aarch64-unknown-none.tar.gz=def2fc3aca20a74d023156606067f88ea8f1c8b602fb628b8f27ee43e3b62cfd +dist/2024-06-11/rust-std-beta-aarch64-unknown-none.tar.xz=43cdb54af35a6c00ee10759a3f6ff6ca5c9080ba817aaf2eab7df8f239d77196 +dist/2024-06-11/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=ae2cbe53d304442e112585dd968f72454cc33bb75d3b4d7854a04575ff7b5301 +dist/2024-06-11/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=b3192290a45ff978126f4f08e7ddaf6de8720a2f6abbc5b41536fad6f994d7ae +dist/2024-06-11/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=0e2dc167dbb66366252100fc87b94a67cca3360343302697c2989beb2eb14704 +dist/2024-06-11/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=6144604269f533eed11471b4c5d2f31a9f8340d9edf0f398a42e6e970c95b991 +dist/2024-06-11/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=b57e11248924ac54500d80525b8fe823e7dc74bc579c2b7f3f076c0a4c85ee2a +dist/2024-06-11/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=9e473a5de0d02e6d8278a9e2430af135e3d6d4ecf5ce59827b384c8f20af39c2 +dist/2024-06-11/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=1a62b5af52767e68146a45a47384b33c93b32a4579e51d41f66746e38dfa6eba +dist/2024-06-11/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=81bcf448ec54470edf60c2079ad9ef03f34052aef5fe9d8f5af933c565fdfd29 +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=88eb49f86265a7fdb49b455cf5a9a373ac1e0f7cbcac08ef2194eaefbb039b22 +dist/2024-06-11/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=bf9a278615765e199786d16f154006007ddfca0d5a5869c55a05e513a7b06580 +dist/2024-06-11/rust-std-beta-thumbv7em-none-eabihf.tar.gz=13f16402dea66facba6e10a9556e0afdbd6b004e8aa5d08e106cf76ea59b8288 +dist/2024-06-11/rust-std-beta-thumbv7em-none-eabihf.tar.xz=7ecd66dc65758cdf32cdebc38f6f399392788a7085d69ec7e8fbd63be7b3e904 +dist/2024-06-11/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=96ccb2252defcd5bcd9eca19380b9d4e4115ffb135efebe6717b1527ee440bf8 +dist/2024-06-11/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=c31f4ef95857a445bc480b73babb886e259443b3137efd694c4b67f913838212 +dist/2024-06-11/rust-std-beta-thumbv7em-none-eabi.tar.gz=0637fe1ab1284334ed4f9aec87a4b51b6983418997844e10ffe20326078f6d18 +dist/2024-06-11/rust-std-beta-thumbv7em-none-eabi.tar.xz=ac7f13ba1a107d03c1b7bb0d2e6753b926a26554c82de38263113e2d5dfeca21 +dist/2024-06-11/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=0e8a21970d4ea6331968b10e990cb6dbe3d38af393e4dc8d603efec1b59aa0bd +dist/2024-06-11/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=04b9663cef2d3507c96b77b18aff7c9beee0f6bd0e0cb9ef37b8c9cacadbb198 +dist/2024-06-11/rust-std-beta-wasm32-unknown-emscripten.tar.gz=01d4da0efebf4615da7c92c6cfdaedaf283d3f5e66c58a1b1e2e17488d86b3d3 +dist/2024-06-11/rust-std-beta-wasm32-unknown-emscripten.tar.xz=c203ec9216407f90d0bcc451e40a29e50279dae8ee161f05d9245e3cc8e1b30a +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=3621e0a16f7e6d9f292894a343941399a54b5d76a858fe5a69b83c95f15ada07 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=5944208b88c6924f8586304abea6827cdf756066158dc64200e207027143e843 +dist/2024-06-11/rust-std-beta-aarch64-unknown-uefi.tar.gz=1887e342d5c6453a63336023e51c124838762f89e9289d1abd8226a717bb96d3 +dist/2024-06-11/rust-std-beta-aarch64-unknown-uefi.tar.xz=ba0ca831ed66a72a14c8c9dd591e97d7d6cbc55762c961283088e897de4a8669 +dist/2024-06-11/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=59790fb6982ebfefc40d352d411604840b7540a6ddfb26ad14d70e139df3ab99 +dist/2024-06-11/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=c022c80da2debecdbea32ce34ef040bdebc8566a78e2867512815532746e1c95 +dist/2024-06-11/rust-std-beta-armebv7r-none-eabihf.tar.gz=4d4a380bed233e86ea957c173412b819fce00d66d369657a0778da5e4f244034 +dist/2024-06-11/rust-std-beta-armebv7r-none-eabihf.tar.xz=577763a4758c42bcf0c875d606a6dd538c07866e9a65c2b73271f0e9d0762830 +dist/2024-06-11/rust-std-beta-i586-unknown-linux-gnu.tar.gz=29f8e4dc5d88bfd66f600402022267ad85d4afcffd7142107d0fd28d0cae4cd8 +dist/2024-06-11/rust-std-beta-i586-unknown-linux-gnu.tar.xz=d030db59dd1788fa8438c52b9a8cbc6754eaf529de60fa4fa9693a687e644dfb +dist/2024-06-11/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=df978c1519ea4b50fcec2ec18d2cd9a6b813982dc50f6442af9ce340b98a8c46 +dist/2024-06-11/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=13585b56ce162922dbf03d0b6432a6af9b9059a664063a6adca957301c23b905 +dist/2024-06-11/rust-std-beta-wasm32-unknown-unknown.tar.gz=6365c96d363a345c4882ad47a3e9242f37c930a10bdc89d137e5e05b1b599351 +dist/2024-06-11/rust-std-beta-wasm32-unknown-unknown.tar.xz=480e07d3f110ff9f201315f5a01bf674ead911773241d80d9005772cfe4a3d88 +dist/2024-06-11/rust-std-beta-armv7r-none-eabi.tar.gz=0514e7022540078895be3000fa0405157bf1165762e77672f78230e62ef2c8ec +dist/2024-06-11/rust-std-beta-armv7r-none-eabi.tar.xz=659cec4d3e3f0783bf9a8b42a245b995e00b36a8ff04a9b6b458ace016d825d1 +dist/2024-06-11/rust-std-beta-i686-pc-windows-gnu.tar.gz=2c6b17e0fa22a9d528217fdb8231aefd21839e29babad0fd975fd3654a9706f2 +dist/2024-06-11/rust-std-beta-i686-pc-windows-gnu.tar.xz=c2c98b0c6b21618d5c49283f19ccdd3ba76159afd904c9683251d36317582615 +dist/2024-06-11/rust-std-beta-x86_64-pc-solaris.tar.gz=9433aed1f5f87157cf02d13e7ad375e9a2e9a260afb8419a05eeb1856069ab26 +dist/2024-06-11/rust-std-beta-x86_64-pc-solaris.tar.xz=2a39a792676fd60f47db90979fd56f3fee709d05d91b5c8bf4e0a01f39fed14e +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=29e4553e9889c3e202f550042555b5c24cf52ce68979870fe33d9e9eaad37db0 +dist/2024-06-11/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=7d56ef2eb64550f95b2ec1e1cfb9f153e9c6b412dcceef35f76db44eccd4d8a1 +dist/2024-06-11/rust-std-beta-i586-pc-windows-msvc.tar.gz=da7c08348c6834793263e136747e0e3dfcd5cd805c0c6ca25323fab8a30de427 +dist/2024-06-11/rust-std-beta-i586-pc-windows-msvc.tar.xz=3d60ea1671800cb8f271f1869186ed099f35ee8171d23df7c6ef0c79b4567540 +dist/2024-06-11/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=f3cfa8625f3586ddf48c301b7016d49d216324daaa3b76168a97f15506346c3a +dist/2024-06-11/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=2e5388097f10a3640514d1a4040f6fec090e1c4aba0259cbdd900ead7fcdfd94 +dist/2024-06-11/rust-std-beta-i686-unknown-freebsd.tar.gz=cf38eeced5efe6139043e123b217a5c3f43bef3d86001a9a51fa21b012c9b468 +dist/2024-06-11/rust-std-beta-i686-unknown-freebsd.tar.xz=e078625da24308d78603400e96454e60606bed23f1132b64efbbbc815791d58c +dist/2024-06-11/rust-std-beta-aarch64-apple-ios.tar.gz=2f1dcaa67df6adacbb850bf17ed5df8258fd2087668d028814874fc8292bf420 +dist/2024-06-11/rust-std-beta-aarch64-apple-ios.tar.xz=2a11e0abb8b162a12f72825cac59cc0df993b5582d911bdf6b97252078887651 +dist/2024-06-11/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=d7f4366df7f3599f031b9654d3c0bebd9c21ec530330283e6560cceccc17365b +dist/2024-06-11/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=cb9e8470fd9934870cbb881f7611a0bd614416faa42cfa6096a1ed19abdf9cac +dist/2024-06-11/rust-std-beta-wasm32-wasi.tar.gz=5e7d7b535a7c1449a4dcac4022de279c7676852a7da3e63dc063595dd3fa1b54 +dist/2024-06-11/rust-std-beta-wasm32-wasi.tar.xz=c4db5ad4aa261a01ba3fd8a191c7ac6323e6134b2e17522b3fe0891a642d4c87 +dist/2024-06-11/rust-std-beta-x86_64-apple-ios.tar.gz=a27f3ff22b233c72673e32bf257f766ad8e11abfaf9f83fc7c3e756f785ee83e +dist/2024-06-11/rust-std-beta-x86_64-apple-ios.tar.xz=8592a2f8b1d6c3cab199cabe8b6e9a668b90bd77bf6a5e0869e2b4f3cc6d1170 +dist/2024-06-11/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=ffd9d5acd9a2a33e6a699b850d1776521da443b52504ba77fc71d6dd7353e18d +dist/2024-06-11/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=e92eec9cd55b37f135237c98cfe00c4ee23d2ef400cc3470deb8f1a0010e94c3 +dist/2024-06-11/rust-std-beta-x86_64-unknown-illumos.tar.gz=b1d2e427120295375eecc3d8fc647fe57e1195210d7d0243b20d156f173c3155 +dist/2024-06-11/rust-std-beta-x86_64-unknown-illumos.tar.xz=b97fe83bb5050460465c57c37456868368d0ce18e5134fedad07ae00df8b7432 +dist/2024-06-11/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=25ad2d1a91456394427a5db691ebd903e56e60daa89d73598155655caf6592b6 +dist/2024-06-11/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=88b0a7fb002922f78af0f8e9580acdfeb4c341c9fad35e53daf4d6073c73ab8f +dist/2024-06-11/rust-std-beta-x86_64-unknown-netbsd.tar.gz=b5e129c655bdc051eaa5aca8c8a577914100137a5bca753df619edd22889a1c2 +dist/2024-06-11/rust-std-beta-x86_64-unknown-netbsd.tar.xz=5fc42453c00c3498af2fd60fa4345c2047f302113666bf4a1d044539e3c1e66d +dist/2024-06-11/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=afb1e9e37af72ba42b71f2a8a78ef7ba8593dbf8e35501e20a81e2aae204722e +dist/2024-06-11/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=3b7f63b544a5e8aad8a18097b915e01c1fb880d48514bd1fefe3a5d4872eae28 +dist/2024-06-11/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=bc151debda651b76573e77c489c3b9c2be4af0f632e0061e067889f21ab254fb +dist/2024-06-11/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=f2f9225460e2e7fa7d28cee2dfdab483698c6f51b0eeafe49e2d8e44381a727c +dist/2024-06-11/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=5418a327d270c603ddc903ae6061fcb6bc9bca14593f13fe10ab3fe0f4a656ca +dist/2024-06-11/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=423e7f6fd6555c6d850e7317a8677d4778bc1270d3cfefc05614ef1acc61fd96 +dist/2024-06-11/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=d30d36a72c1e874a7f9df7f805f5cea3617f912b5ad5e7163616b07022e0f7ae +dist/2024-06-11/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=4afd0b4ab3787dcbb2b2f686d56844c6aa3af69fbd72d04bd57901fdd58b6333 +dist/2024-06-11/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=0a9b8bd1d39d346a20803ede808815dbf0cd55d9167561c8aabe7db3300a3dda +dist/2024-06-11/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=e36372611dd3cdabd1f32fb942c79bd31b5fc13946448cbf9a178ad5005dc7b5 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=2fe6221704614b167d837f52cfd439d9586e27ae82a34577659f86382c3192fe +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=55ffdc97b8b6d309b1aa8443b49a5fd6133f5d7653069eb7f32625c1c0bf86ea +dist/2024-06-11/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=87386371b64d4d922dc2fd01a0db28191748002b74a59437ddbab572b0d6fce5 +dist/2024-06-11/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=6c1f9a6683a9d3ad8203b9d08ed829e4990675cb07fdc2214fc1f7970dee7e60 +dist/2024-06-11/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=525a64f28aa0d757e82558737db3150ff90ecb885c3da8e0215370e47fb2ff23 +dist/2024-06-11/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=af49d1730949036a48c05a147a3c67885326df5bea314fef2828e04433f33ef0 +dist/2024-06-11/rust-std-beta-armebv7r-none-eabi.tar.gz=eba00bc621ee0235444698e5bc67780bc93765e70bed11634a8555d8d645635b +dist/2024-06-11/rust-std-beta-armebv7r-none-eabi.tar.xz=236fe5262d76fd8ab7c12ab6c231608c7e704e5fc0d95210b47e0c86201d8a8d +dist/2024-06-11/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=ac98cc34543e6faa0429cb9756d1b0d30dc13d8d8a44380b5feecc0e7d083e40 +dist/2024-06-11/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=ed8fffbe7899a7c35e5985adae1b35b7eabd076970a8eac280e834b7877f272c +dist/2024-06-11/rust-std-beta-x86_64-linux-android.tar.gz=fa53ef5ea66f93f9fa46ac84d3cf6a16743b46a941910b092c9c71208a15defd +dist/2024-06-11/rust-std-beta-x86_64-linux-android.tar.xz=66b394876549c4faaf872d4103ee49ef59cfba5c78777c01ad1df00dc6babd14 +dist/2024-06-11/rust-std-beta-sparcv9-sun-solaris.tar.gz=63794d1cc16a541cc07b56870d86db2212c2c8e3f06e11fd9bdca90fd93aa56f +dist/2024-06-11/rust-std-beta-sparcv9-sun-solaris.tar.xz=4d419a3c4402c303b9437c7564e2bea79575623eaa0b300c2fe688d9d8f9db95 +dist/2024-06-11/rust-std-beta-aarch64-linux-android.tar.gz=b82186abf1bb250753a2640def13aa477b606e0601c5c1fdb25af0e37ea638b0 +dist/2024-06-11/rust-std-beta-aarch64-linux-android.tar.xz=57065c7b4f1f5d51d1366164b62b4114ab95f1a68cf551d12db8e9a2dad044dd +dist/2024-06-11/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=bef7ed6391f906226a20f8d2d842fbc335891d7fb92f91b1c5873ce778d70675 +dist/2024-06-11/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=d80843f5f25923605681541b285ebf6868c0368841efacd376aac4dc9f01d0ce +dist/2024-06-11/rust-std-beta-armv7r-none-eabihf.tar.gz=5b7d75f5f9294327ffb3c441b2e99fbc8402d1dfe0afaa20b2981a987e96801b +dist/2024-06-11/rust-std-beta-armv7r-none-eabihf.tar.xz=ab56542b3be354d6c4f19fefe90af2daf59507e969a4144b6553a900e37e2a4e +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=7365d0ccde4cd000b44992c80cf0e48ead99c2a00e18cde4446d9401792606a3 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=69124687ee3ff876f557b7b21c8f78f7015c5f3b6537b65480613469772e00ec +dist/2024-06-11/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=d1307c1b3fab3dcb6b1e5cfd5c30e1ef1c7b7e1e831ccecb00ce35bc2c1d8b9c +dist/2024-06-11/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=8685907906feb9e16e34d4ea72e3ad338df9d6407dca6da81739b100926efcd2 +dist/2024-06-11/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=d8c1c3d800eaedcf23c25f436e30892df1938a618200f0f041fc1921a5b517ac +dist/2024-06-11/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=53493d039721d5a2f54eb49ba7e16a205dd846bee559519182ca0af30111d182 +dist/2024-06-11/rust-std-beta-x86_64-unknown-redox.tar.gz=3f9842f81f45cbf35fd923ea69f1c88696070edfec0dcecac286519820741078 +dist/2024-06-11/rust-std-beta-x86_64-unknown-redox.tar.xz=73bc6b9b72bf6a9ba7dabe63b7a7d426eb47716466000d05802ef78ccb9128e4 +dist/2024-06-11/rust-std-beta-i686-unknown-uefi.tar.gz=c9954b477c329c3706891f77e9163d98aeadd96b1aa8a71f1eac20f316a9269f +dist/2024-06-11/rust-std-beta-i686-unknown-uefi.tar.xz=88876cb6cf03707065fe172540e82faaf5dd55332c939891253476d4da3f8a00 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=e731faa24568e97821c5960229dd9a489ea7ead964a5aa052a6db322bcc55c18 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=47b529a6e19c9d609c41809fd62906c34f23a5c515bf62d91e88a87cf7cc0c85 +dist/2024-06-11/rust-std-beta-loongarch64-unknown-none.tar.gz=c6150b3b7481f2396b305188a16c4ce2206c440e9d7639446c76566d00dc5159 +dist/2024-06-11/rust-std-beta-loongarch64-unknown-none.tar.xz=e641747ef4ae46e4d0a8a3050d00b1b8c21c0f25da53a54de8e540a9953468db +dist/2024-06-11/rust-std-beta-wasm32-wasip1-threads.tar.gz=37d141ba5beeaefd08834154f66219df734c379c9315c094433aebb75b82bca7 +dist/2024-06-11/rust-std-beta-wasm32-wasip1-threads.tar.xz=2045a0b765de96eb17e18d8028ed2e553cc998fb71a4811e3d848db320f6b9a3 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=82de12e6a2b01c0b98c83b4264a4e00ceefc424f673c97826bb28729c3f31382 +dist/2024-06-11/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=c97b8a57ed8eefd60bbfe2df54121c548d9e271d9691def843185bac9d82b703 +dist/2024-06-11/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=6903175fa7cc3fdda5545ce11f4cc504e4183e56c626e25ff2b0d20a4f5190c4 +dist/2024-06-11/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=df06eee91ba57ff2c0a779da5d746db02f682514b8c03de875f03c96d05188e5 +dist/2024-06-11/rust-std-beta-thumbv7m-none-eabi.tar.gz=d7023edb8c723803e114e5b8ed316a6839e0c37d92cf6a2a09b767ee5ea2b7b9 +dist/2024-06-11/rust-std-beta-thumbv7m-none-eabi.tar.xz=41e19659bc0e0445ebafc49740579f0ac23a9af8e233c529ba2132f3d111faa9 +dist/2024-06-11/rust-std-beta-arm-linux-androideabi.tar.gz=42c0a6bfed8ca53b8833dbee78f2eab92bee061c42a4d629e870c8e655bc3728 +dist/2024-06-11/rust-std-beta-arm-linux-androideabi.tar.xz=5f85c99315a18bfc7fcc3f0caa7218ddc3b6548eb04be0ded835b5c45ec2ae89 +dist/2024-06-11/rust-std-beta-wasm32-wasip1.tar.gz=97abd2b9a68973263da0116eb5a0b9ead2145c1550f3190d02b35606bb9dcf58 +dist/2024-06-11/rust-std-beta-wasm32-wasip1.tar.xz=4ba0ef9b136761e739ab8ef125ffd993ccf71161d69e7640d94de6d5df601dff +dist/2024-06-11/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=886562504ee3e73ceedce6cfcc8d128f22a80f0a33c84b9c29920d7760a8a208 +dist/2024-06-11/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=a8f28e60aa1938cdc7b7d46a1fa770d587be9534a291f5367a80a52772a0b458 +dist/2024-06-11/rust-std-beta-x86_64-unknown-none.tar.gz=642e7fbeaa76403ccfaf6c3c1bfaa8b94ded7311abfece44c863df231c282406 +dist/2024-06-11/rust-std-beta-x86_64-unknown-none.tar.xz=b1441ef88a1a97ecb6d7b674b571beeefab9f59fc8799d9e63b8a01078042f15 +dist/2024-06-11/rust-std-beta-i686-unknown-linux-gnu.tar.gz=fba54c97da35d0f11af99dca7cb0f43784da2104c461518149974da1f2248301 +dist/2024-06-11/rust-std-beta-i686-unknown-linux-gnu.tar.xz=e7acfab1f7bb8b2c2a0f7558b813f627a3f6b6dadcd05f62c5895f753c2f3ffa +dist/2024-06-11/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=e4d5ec39520d069609f32c4dc7dd4114623bcd112a729529a096c992fc19f61e +dist/2024-06-11/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=94d508cc6c86516ae5e3bba9366cb466635a1e3f41fd00ba6b1a44a87175fea5 +dist/2024-06-11/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=76e17967c09311f9e0c684531f21588d5bfbbdd4c707e454068df240fcfa56ab +dist/2024-06-11/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=e627a81855b3d93497b071138917dcf6382b60793a4a76073769537531d01789 +dist/2024-06-11/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=aa5a1b430e31bd5f912d378eab8447ecd920a5840c03b01799a410d86a7c4850 +dist/2024-06-11/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=20f6fc50caaff58aa2883696c61031e9cec5cc24aea94026cf9b84a7642c4d31 +dist/2024-06-11/rust-std-beta-i686-unknown-linux-musl.tar.gz=62d2daf4c1a0a6b4630559c64bc22ceccd658ea0e9e74ebf58a9b791226964fd +dist/2024-06-11/rust-std-beta-i686-unknown-linux-musl.tar.xz=34681e4cac9a6e18f1952f51d6192c8b71b970a0edaf0a06766e1a576a7898d9 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=da45a5c9a7c7c1db32d6664358699ceeb27f59247862190a93ac203e5f49f116 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=f881c61a8ed04f02576374a82f28505be2ad4b694254503d30c1ab415b6b5a74 +dist/2024-06-11/rust-std-beta-i586-unknown-linux-musl.tar.gz=2056b8d9d54baeab1fcf7dcf65916645f8404413bff60851fd97108b7822a54b +dist/2024-06-11/rust-std-beta-i586-unknown-linux-musl.tar.xz=d06fd5dcb976c5331185d308e2ac0e53597275a57603aa171a753b3d005f0667 +dist/2024-06-11/rust-std-beta-armv7-linux-androideabi.tar.gz=27fb1ba34b2331810174f88d0e75075d6af26ef3fb7cd3ec820408e819f36cc8 +dist/2024-06-11/rust-std-beta-armv7-linux-androideabi.tar.xz=f44ff932cecc16cb292a6149ac42fb440b5e4a8a6b56f55634d9031002eb56f7 +dist/2024-06-11/rust-std-beta-aarch64-apple-darwin.tar.gz=3ab3178d3c1d4b9908dc2d0b6236c147e8f787f323c0c02fb924e2d692ec839e +dist/2024-06-11/rust-std-beta-aarch64-apple-darwin.tar.xz=4b67844f0413cd1b0fde9702542eb2ce297020c29531230c37d3e2f65d56b0e3 +dist/2024-06-11/rust-std-beta-aarch64-apple-ios-sim.tar.gz=317035259b48845882a4561bd1c61108331ce68231b3362fa6e9b0a323ea3fc5 +dist/2024-06-11/rust-std-beta-aarch64-apple-ios-sim.tar.xz=04585ea6b3e53cdf62372dc64f00237d26991a2f7ca6ce06f921065957c2ffc8 +dist/2024-06-11/rust-std-beta-x86_64-unknown-freebsd.tar.gz=048684f3b437110dee704d8ef58f166806d69504a0fbf661ad71d19575cc8436 +dist/2024-06-11/rust-std-beta-x86_64-unknown-freebsd.tar.xz=43762fd9d2cf4dda5e8b64dccbabf5637dde37685530eceba060faeba8212b62 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=40b3feff4834beb31125cffff479288adb2cc8a2d9b8963943907ba2b5478589 +dist/2024-06-11/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=f088ad7f9697570c251655adbf6921341f74bb8deaa445cdb0d15e5ab556699c +dist/2024-06-11/rust-std-beta-thumbv6m-none-eabi.tar.gz=94b65456fa327c6d8acd59f1fd004feea8572374e8eadc022338de75c45a6c03 +dist/2024-06-11/rust-std-beta-thumbv6m-none-eabi.tar.xz=9ca368829aaab88a93abb580a0ecc1195ce5fa3877bd556c856ab52af51095ec +dist/2024-06-11/rust-std-beta-x86_64-unknown-uefi.tar.gz=1a9892b1efce5e6aaa361675e008c623c47056a64deb73246c4211f5194f31a9 +dist/2024-06-11/rust-std-beta-x86_64-unknown-uefi.tar.xz=e9a2df6f754ff4c1ced354250de51939efb1e003843f1d0d8962c2a25e7c0f46 +dist/2024-06-11/cargo-beta-x86_64-unknown-illumos.tar.gz=d6f794f092c47e97e822dd6526ac2622f8a7b3a3cfa8b8462b3378eb16dc4801 +dist/2024-06-11/cargo-beta-x86_64-unknown-illumos.tar.xz=bcf8204f4750c6ea9ff5667ae07de7d06e5b68e78176adb79fc1bc433f7d90c0 +dist/2024-06-11/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=27ba1abe717de9e96b802c8026a17a6b5f5dc728ba4813c705a03d54c234be3f +dist/2024-06-11/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=55cbb9abf863c05f13049bc59e99ea3e64523f0193ba1dd155b21cb732db50c2 +dist/2024-06-11/cargo-beta-i686-pc-windows-msvc.tar.gz=ceb0b610395fb2519bc6207b7916f402a17fac9685cf8b5c2ee354b350b396ff +dist/2024-06-11/cargo-beta-i686-pc-windows-msvc.tar.xz=73f1cca9028510331477a0299e214d50a3b9ad02ac035d056acce110f52a1463 +dist/2024-06-11/cargo-beta-s390x-unknown-linux-gnu.tar.gz=eb0dbf227a1ad39436af2334ddb6e90831881c75c24855e9c040bcbb6ce8d876 +dist/2024-06-11/cargo-beta-s390x-unknown-linux-gnu.tar.xz=1b95d58699e8f534b5d93ad02c4281d8e791e8c266f10820de887fe13b1d88c6 +dist/2024-06-11/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=b078cbb4e2e18b6da3618a1048b038c52bf37a398618179b1c03f25d5e154ce0 +dist/2024-06-11/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=80bd1e79864e21ed914a6a2b8ee5d66867734252002789c6d76c3f7e82133eab +dist/2024-06-11/cargo-beta-x86_64-unknown-netbsd.tar.gz=e2fb5140e90588e6ab158352e3f198ea71107a1aa01785f692d5ef64925af58d +dist/2024-06-11/cargo-beta-x86_64-unknown-netbsd.tar.xz=6bf7fc08f593ef8847b3b14a33783fb3c54c542fe61a8a92c0e462a1bbf34b9c +dist/2024-06-11/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=6cc72fe175632e68fefaea683c0569e9fe8f036488154e4f1ccd6a3135479cfa +dist/2024-06-11/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=b27004517d35019ead69bcd1a09c81aa20d2b00b57ad42655f1f434f8d66eed3 +dist/2024-06-11/cargo-beta-x86_64-pc-windows-msvc.tar.gz=e5d5945884554970344d16e90f9eed0dd60f61ed57e48b40fac2ee1d7c035475 +dist/2024-06-11/cargo-beta-x86_64-pc-windows-msvc.tar.xz=421ee0fca436d4d4d3bcd03c242f9312fa620da854b906618a1d8ab27979d609 +dist/2024-06-11/cargo-beta-aarch64-unknown-linux-musl.tar.gz=7406ba1c14e53da0a9ca696dc6c90fb816c072734f569c01f49c6b8f7d542d81 +dist/2024-06-11/cargo-beta-aarch64-unknown-linux-musl.tar.xz=917a2e63fcf03be81375143692306afb54fc2addef9f5508dd58fc1729119752 +dist/2024-06-11/cargo-beta-i686-unknown-linux-gnu.tar.gz=bdbd9c4e2808d9dd0acd219c3ba9972634d73fc4f177468bc196c66be620df65 +dist/2024-06-11/cargo-beta-i686-unknown-linux-gnu.tar.xz=e64d3405f99f8ad74984b81238a088b250be4e079e2c05aa68be1cf84f04154c +dist/2024-06-11/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=bf7c374c02676f9e5a50f4964e6deb4d3aab19ecd66c4d246de0c9a06ebd23bd +dist/2024-06-11/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=52e7907ca99467c71429d03012a3f6cdd95711b9cf002d3aa06ba25b3e53d2b1 +dist/2024-06-11/cargo-beta-x86_64-unknown-freebsd.tar.gz=bd9aace135befd19104b193e09bf982c79c8cb9cce301ff709cde2ee2dc82821 +dist/2024-06-11/cargo-beta-x86_64-unknown-freebsd.tar.xz=c0d2c3a2e56a1f43f62fb73e41b07def93baa278172d822a2a33f571d54f0463 +dist/2024-06-11/cargo-beta-x86_64-unknown-linux-musl.tar.gz=61526c6e4f0ce1a57d4831ac67252cf5a6cef3c106c6953b329bc0aa9c685e6c +dist/2024-06-11/cargo-beta-x86_64-unknown-linux-musl.tar.xz=82bcddea6b3d976e7dee07afe7f805f5a6ff66f0721d281d2c896f352f395c89 +dist/2024-06-11/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=70c5bd18c756123f033a7cec027631f71d7400cb4d0c85d7602a8a6309379070 +dist/2024-06-11/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=f8a6c7dd8ba408a5fe623a0ca1d2f8bfe287b13bc09b1d8ea636ebbdec06c557 +dist/2024-06-11/cargo-beta-x86_64-pc-windows-gnu.tar.gz=fe26e842e6e4186437ea679cc75cd37d70a98b1ed0f17ed9ac876aa0501ebd5d +dist/2024-06-11/cargo-beta-x86_64-pc-windows-gnu.tar.xz=f3fcb2b698736b3df87c06ba829a1f09c218e37b51ff1c59f165aaf8078c619f +dist/2024-06-11/cargo-beta-i686-pc-windows-gnu.tar.gz=607f623f30e25541d9e6c8412bffcb9c16f7180250a244dfe1e2606edd45db42 +dist/2024-06-11/cargo-beta-i686-pc-windows-gnu.tar.xz=604369c997e05719d0fae92f7904e6b66f662bb75add1d836cb100e0032526a3 +dist/2024-06-11/cargo-beta-aarch64-pc-windows-msvc.tar.gz=de283125b79d17f4cf24bb608819177ac1637525b8c7e67a66e798f0c0b1024a +dist/2024-06-11/cargo-beta-aarch64-pc-windows-msvc.tar.xz=8228a47ce003faf1edb4a10cf800d3316ba421a97176c97f6952743f7eddf734 +dist/2024-06-11/cargo-beta-aarch64-apple-darwin.tar.gz=8525a4015fa8078921f8bc5f67012c0d5747b7e7111079bffce79f2b696fbd4a +dist/2024-06-11/cargo-beta-aarch64-apple-darwin.tar.xz=038c700f1b0ab543bb765a4b86638fc7eb1e44257a19d5a5457fcff4fc08f280 +dist/2024-06-11/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=16c75d17531e10f1bb9e95c79d8c3aa05549db3029663c69d2f56b2d2f3214d8 +dist/2024-06-11/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=113d97f781bf8d54f457e07fbe3de1d3a0ce0a1f8054a652083b67b81f4cb642 +dist/2024-06-11/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=7856fc9731c3dd7b360eacf422ce358acb2d33a7fd8b16fa190dc77cd9bdb3de +dist/2024-06-11/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=85c930785fe9857458c9256c5a2849ae223c5dd162bd20ccc8021b2d2ff0a6ba +dist/2024-06-11/cargo-beta-x86_64-apple-darwin.tar.gz=aa4aec2cf417a7446c2990d03cfb3dcaab9d99f5ac249cbb955a59a64b5b7b0f +dist/2024-06-11/cargo-beta-x86_64-apple-darwin.tar.xz=01d4bd8dd8a58f16ee31df775d0d7046ce671dc86f8907514e3713a62aadbb12 +dist/2024-06-11/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6e5c68d0665add368a6574528184dc1d182e7d72b8da0827b69eb9f9aecbc4ac +dist/2024-06-11/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=180a6148f5c5be222d4e2626eed9cd7de2e0f62d0b456e520d1ab7c4931e1f4e +dist/2024-06-11/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=6af892aa858f35708bf9db322abf35967b1e92725e05f6974e1d9ee3cb4c7b84 +dist/2024-06-11/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=40ffc9713504366978bb6f2eea12741400164318945df22290c7b669d3b77878 +dist/2024-06-11/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=9989b0189f7a4c5aa39c39c78be04e7291cc1358ebed597636f404f56980c199 +dist/2024-06-11/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=8c7d7dc2530f25cc771c75d454fd11f3e94c7954bb869e43736860be1f253d2b +dist/2024-06-11/clippy-beta-i686-unknown-linux-gnu.tar.gz=94505902c45770c45a89ea12759bf46cd97efed657b43322d5dd09c13ed26331 +dist/2024-06-11/clippy-beta-i686-unknown-linux-gnu.tar.xz=14830f6fa92b0d814527a9aa5575d0cd529e76dbe2481533b819c735470ad684 +dist/2024-06-11/clippy-beta-x86_64-unknown-netbsd.tar.gz=5cc5f4202003b940a6a62c2384c749b741a9f6d62461ba13a6179464f6c3e6ea +dist/2024-06-11/clippy-beta-x86_64-unknown-netbsd.tar.xz=01f4f0ef78f17e4991ddf3d974ef7b1dc9d56702ee2d65ede4918e9db99ec222 +dist/2024-06-11/clippy-beta-aarch64-pc-windows-msvc.tar.gz=ee6b64a7a0fc8d8482c38d2a263f9a9ed0b9462e6bd748a72e33c5cd7dac015b +dist/2024-06-11/clippy-beta-aarch64-pc-windows-msvc.tar.xz=f91457f5dccfc81a601b075da340bf521e3cc17ba05d12f90c31c7f5b215a7bf +dist/2024-06-11/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7da546ff13b3e340f2ba22e6995566cb26e487271e3f1b68b3b7dc0bd5122623 +dist/2024-06-11/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=01807b62c65fe33acd05d10191cb16ee1bdeb1bd7b410a9c0cfd8f53006624da +dist/2024-06-11/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=64f41430de84569a7b933db7f0c573fecf99f5d0c6900e35598c94a433c0296c +dist/2024-06-11/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=b30a73278552ddf511ae82620f14ec7324f281582fa4fa9df3fe984510835aa3 +dist/2024-06-11/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=e6b0ac4bcec2871d2a50e644733399e684d7fa86798131243c4022cbe2ee5222 +dist/2024-06-11/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=edc629f04503ce88443ca6cce0b74b5833ce50f428e00a02b544f422577abb1e +dist/2024-06-11/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ac52f8b4a1b6332aca1ad2363195daf571f7f1870ffa6237441dc7928a408167 +dist/2024-06-11/clippy-beta-s390x-unknown-linux-gnu.tar.xz=96b366fa989d2f739a92ee03bcd141b666b942e0b26922acd620e0fea6d44d8d +dist/2024-06-11/clippy-beta-aarch64-unknown-linux-musl.tar.gz=8ab584ad05a7836bebb20be8d84b0dd3a29d1823dcee3897abde3a47a10e582b +dist/2024-06-11/clippy-beta-aarch64-unknown-linux-musl.tar.xz=e7b669a2936a22ed6d2a36b70a6593657488e5ed8d00a911bf33ce51c4c0cc51 +dist/2024-06-11/clippy-beta-x86_64-unknown-illumos.tar.gz=419ef233cfdbe9011d74796e8413a8b6c1f8e6281248969eaf7c9157542c1b70 +dist/2024-06-11/clippy-beta-x86_64-unknown-illumos.tar.xz=673a2f16268fba4d9bf7dca2c0758f3ee60f9754cdcefa36032b8140e6fcddbf +dist/2024-06-11/clippy-beta-i686-pc-windows-msvc.tar.gz=a3c3bd3b90c951ce404a26a59421f00a03e0dc3351d9dd2876346ff096b7361a +dist/2024-06-11/clippy-beta-i686-pc-windows-msvc.tar.xz=c3e7c1cc91f48003e1b68fdf753011711ee516bc2ff8c7227d427dd8ee98a72e +dist/2024-06-11/clippy-beta-aarch64-apple-darwin.tar.gz=ad7b4ac9cfacd860e03f8a41da51b4d279d76b7f3f2f8ac8a048a45f89a7ed04 +dist/2024-06-11/clippy-beta-aarch64-apple-darwin.tar.xz=ca5d2d63b8d7cae00c86383d9075b2292a28d1a85864877a6c8282f5596631f6 +dist/2024-06-11/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=12820c3e8b952dfa931783b550f882dd96c48d3b776fa9cdb29b02d66ad14d96 +dist/2024-06-11/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=394873c6b2499ebc385a11b512c7378b95478a0b6f530c5b313fe86b65a18eaa +dist/2024-06-11/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=8d9353baa4388d02d89b42403e07d6a61f314fc975b8fcd737d8f4edb0ab027e +dist/2024-06-11/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=3cf0511bc5b14619dd6ca1cfeed003effa7fbfecb42fc096a45a211d1ccf419a +dist/2024-06-11/clippy-beta-x86_64-pc-windows-msvc.tar.gz=cfae39e5d5cbc817aa3ba892822fe2ff122df8a648106aaf0ec18b1ce1a02632 +dist/2024-06-11/clippy-beta-x86_64-pc-windows-msvc.tar.xz=1f1f0596bef154eb3fb4e73993794850f8ad903f4dd0ef9697aa8d5b4d6ec2b7 +dist/2024-06-11/clippy-beta-x86_64-pc-windows-gnu.tar.gz=0909caa93377b2aaf2a05a345e8cfea2c69dc27bd7f7d7a9515576e90cd0aad3 +dist/2024-06-11/clippy-beta-x86_64-pc-windows-gnu.tar.xz=9125bfbaae2103f176b1e1b444fd38c7e74d3414536370037ffc6a85d8567551 +dist/2024-06-11/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=3721470fcc17f8d37c66281bb66c65a66181c80775571520fcc2dfdb583dc640 +dist/2024-06-11/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=79ec48af2925aaad12be405fb72dc9bd9e2ca89fd3a6017111020570ddeb6585 +dist/2024-06-11/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=d957f503dd4d9d228b6a445eab1183dbc6509a49ccbd475d25143cf1dd28f03d +dist/2024-06-11/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=da7ec767b4a85fa327c957888b228671b2311286043165926942504239008d3b +dist/2024-06-11/clippy-beta-i686-pc-windows-gnu.tar.gz=51ff631084254be43d79d7791000a14ad9f11239e42be73f48383f774109c2cb +dist/2024-06-11/clippy-beta-i686-pc-windows-gnu.tar.xz=52079acb4f908150d207a838cc7d3c15a725c1d61be35d0d0b2ed85b3386f3fc +dist/2024-06-11/clippy-beta-x86_64-unknown-linux-musl.tar.gz=99a534de9e5fb552a4e7a10eca2645ad260a723f42e15df3b4e2bacf82e90348 +dist/2024-06-11/clippy-beta-x86_64-unknown-linux-musl.tar.xz=7f9e6da187bb71c384f5040298c43bd303fcbc5e3034dd7fdc7b251c5d7b3a34 +dist/2024-06-11/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=acf05b62fc219ddc2fc4e4bca2bc4c2cca24398d6276bd7e7d9f8504627094c4 +dist/2024-06-11/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=c737aaf9c4bc3a743752b13159902fc5a8ce746f44221799bbcbcb1f9d04dc4c +dist/2024-06-11/clippy-beta-x86_64-apple-darwin.tar.gz=422e97d9081e66a46ec3f4c2a7ccbf9b6443c7b343e0a2e90845f233536f545c +dist/2024-06-11/clippy-beta-x86_64-apple-darwin.tar.xz=c9d02836c9d0e48684f0a343d6935848ec75e1faaf7007a6a3e0718b71e77f7b +dist/2024-06-11/clippy-beta-x86_64-unknown-freebsd.tar.gz=f207fbfca76eb22f7097eb98ccda1da513fed417371a391e43e8d19fad9b76b4 +dist/2024-06-11/clippy-beta-x86_64-unknown-freebsd.tar.xz=61e39b0aa88a1d8e131a461cb3cebd05154c261058b735f29dc6ed603464b5a1 +dist/2024-06-11/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=c68d27b08f9699c7c2cff9e9bdb7485991d8445074e8b84c2e2222fbff209f83 +dist/2024-06-11/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=d5961f82b9688b9c1ccdcaf578b8325e8ac1e0cc2ffa02131fcc3281cc88dcfd +dist/2024-06-11/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=12ccb5b1d82ad22292b337c49d1c5b0c0d584cfb4e649faf6c53471915df2473 +dist/2024-06-11/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=80fa7cb902135006046c10db64d9060103dfb1452e8e0ef256f8344fe0a9c8c5 +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=c08499ebec188f67477d0c4eac2e172b59f6d66ad4becb36330b5066af6547d8 +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=b3f29c79fc8bd64a2e62101468bbaa28338f444839659d4f99df34ccccad5eee +dist/2024-06-11/rustfmt-nightly-aarch64-apple-darwin.tar.gz=4866e6d478424fb1c01b2b98678107b9c89e67a2cce3db49833bf34007f868b3 +dist/2024-06-11/rustfmt-nightly-aarch64-apple-darwin.tar.xz=e8e6fd846f70a99e6fad735ce4f4c8bca5f6b5f2d63364c2f8a7df85c13b63f4 +dist/2024-06-11/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=f14077408a763f0fa6218ed97d7697499c2bded289a5953336c727e2de93bd92 +dist/2024-06-11/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=27324f62ecfdeeb4a66ce3c62219c491f04ac3822305ea771df0381a5f4e5418 +dist/2024-06-11/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=1147008dfa30891e264bf5f469c9528fe47bdfc729a12215e5a985179513cc66 +dist/2024-06-11/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=95fd945a6c9bcbc9549913906a8f2de20adf54b84b82fe8d981dbb5b767f0cfe +dist/2024-06-11/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=4f423c5ce278204dce918ece2af84bdb55429b7a11f630de95a1516e7b113f53 +dist/2024-06-11/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=c86fe94c9b6cbc56285478ffa715877d234af19f1b58b3fd4b2af23a0267b657 +dist/2024-06-11/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=f1200f077402474049f6b817688435db0ebef7fb52ef645d5b5d2f7ceea52a08 +dist/2024-06-11/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=a0d801ec3aa93389d5c6ae2a95be25ba3a50f53182c0a84a00c38a2f708447e4 +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=d4e28ad9b054cdd19fce6bbc37dc86210b0536aee5c23bca53a6bf1340fdb5bf +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=b0958ab975026e09ba921234353f5a81b3227d23c10ded4be4fe37831e6abd12 +dist/2024-06-11/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=f1caa15f16aa1c93ee783bf273d0ae6a7abd0b38c93c717f2d49af5444cd4e09 +dist/2024-06-11/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=130687b9de22fb1d0c4c845cff5475e5959278718e3b6a1af7f1b9e8869b527f +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=32e3881c61abfff7f9c006083045ffa5765c0b3a5a6ec46607e5428423ab76da +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=c1859b8a44306b5b3ca27b9226bbf351cd3ff3cacb4faf61200d7baa76009367 +dist/2024-06-11/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=4f5c23ba3426719c39a7c767be8db83382c84ff7798c5194aefbeda821462269 +dist/2024-06-11/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=18d9a2084cd5e55792f3841fc7d6602bd4a973726662b516289385b7908ffa4c +dist/2024-06-11/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=df5478f63a49c55ffe9cf62a1882feeca019290c0cc9a9ed5a4122b8aa1325cd +dist/2024-06-11/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=f54c3b8febfa4023a0334dfeee59d75a44f5c1d3a02d2d57959473d6ad51205a +dist/2024-06-11/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=dd2d83a7bcd45a0d5de312a2a4a28b2471a9597d318135214b45a69e1e449f91 +dist/2024-06-11/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=02a8ada9d737e115033d26b0691f2ef22428ba2f67b7fbab7c4205df8162a96b +dist/2024-06-11/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=20bde0cb3ddca790c0d126d5d590b9a35a1c8631b42fbc2d4e85cfe5aa880d04 +dist/2024-06-11/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=dd29e278f79ce1be14ad44d61039e5a6a63e0e597c4736ab153beb758ad37fb9 +dist/2024-06-11/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=09d98f5c61def16b62b980a6cef3b1b3704cde5c0ad2fdd7d23521db410b6b8d +dist/2024-06-11/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ef43e61c2d3d90b09494a8dcbb5d2375223fcba6078f2bfb02ea43750b1a76a3 +dist/2024-06-11/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=80318fdf7d55c71beb8ff1434b79776c59008f5d62c63530da9f19a67cc18484 +dist/2024-06-11/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=05ae6d4f8ed07cc75b333e606af14f239978abe197b70409a5f2aadc7de43a4d +dist/2024-06-11/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=a079a478e9a89c3a24864b44670bdffcebc139bbec9c54e7aab6394c08bcaab4 +dist/2024-06-11/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=243c2d7c23e8aeddf9729e1f7f9add6f88f50d012efa02644030110cba111713 +dist/2024-06-11/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=76b69b4b25e8c0d47b80491bcbb724a25c02d95e7f9cfe7a9c3c3570c24363c1 +dist/2024-06-11/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=027e075c94f53403f03a4fb29d4575928e1cba141fc0713c93edaa4ea5917e42 +dist/2024-06-11/rustfmt-nightly-x86_64-apple-darwin.tar.gz=b34d3f33e7ae81a5a95927997658d738a3d39db01408dad2d9fa72efb539c73f +dist/2024-06-11/rustfmt-nightly-x86_64-apple-darwin.tar.xz=7efe129502b732219d1d24d59584b5ad002e7dc5288e047b06bbc81fab36e054 +dist/2024-06-11/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=231f11ec1c6e4f57556aa32226d22328656d2ceab075cff67c8ab0a1ec32a823 +dist/2024-06-11/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=b1cd7aa45a516df3a68814ce52753eeead4134943d610449456a30c682079ad0 +dist/2024-06-11/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=3fb86c9281ae8203e1119bc00e8001afe7e894360adc791a9a0ca1d50e6a9032 +dist/2024-06-11/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=6380fcfb015a40c4605ff18f8ba54c3be9a8e6a0115ede378565d9cc9943c627 +dist/2024-06-11/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=f3ff749dedcfb259a4b2d66ae30245caeb79fdec3b41a3bb4f65d50b1cf18120 +dist/2024-06-11/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=1ca50ca8ff36df7433a4ab4c8a63c3c91e214f6c7889843edfb9120c1f4f68d4 +dist/2024-06-11/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=a7f5f171dfef5b67498c93354d9dc5a7443d69f3f9bc0bc56b660d1450e9b7a5 +dist/2024-06-11/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=dff02f7a7e9ae58c41faf4c5731862d11fee06d17099c1ed18863219a4a82815 +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=71dc189c1d29d3fec849b47f64deb831569515e56821511b1221983eb9ed99a9 +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=17736f80644c8cdf8239940812962e6f55c1924896f79bd2581d20582a9c752a +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=b77e4a1e42c7169d91e268972a9195f7c8494e5cffa5fc71720df799a4eaf74a +dist/2024-06-11/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=8cf89f982aaa5559f2cd1721edfdc25f5e99518c418e1a6818c566d668c8f842 +dist/2024-06-11/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=7703c27800aa2d871624563380596a18deb90081e38cdf6c05cab8e794e5805c +dist/2024-06-11/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=ca9dcda51c8945db32e004424eaf26d4f541a51a78be87be0063e5a0b06fdd4f +dist/2024-06-11/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=59a2173462baaea0cef3e0f088b4e6ef64e2fe469d1833798d92e844f0126902 +dist/2024-06-11/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=0cab2fde15bbfab741eead0b084886f8b640aeb181251368464bd833fd08df73 +dist/2024-06-11/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=8473ef60ff1d5c7aee90b8e0a984c9be7e095446d87e0f13ebcf10f245c0ef0f +dist/2024-06-11/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=657a55f27794460bad174c4f9412e771c679c6b608cc3dbe32903efb075418da +dist/2024-06-11/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=bea7aff88f7d7622a23e91c437d9616a9f1adfbd56ddcb42ee33589d064d5161 +dist/2024-06-11/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=a5ab0850c71e322b1042815c443c79505f1daab2b4a69f8cce05e3761a24f10c +dist/2024-06-11/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=8c00db9c85fa8053f78285c8a546afb32d6b864795388f1ee7a6a49d12643625 +dist/2024-06-11/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=c137f5f943d1c3f14a4a8b5eca2b541c43c82738452646df524e57a6ef0cbd3c +dist/2024-06-11/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=a4087ded3076e4d487efcd4a957554255ea1fad5052a01529ea1847559f7b40f +dist/2024-06-11/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=ed2b01ad985668564ba2c3f87dcac4f5c4bcf7ea0b5ecca6a30c1f1c4b63a4ef +dist/2024-06-11/rustc-nightly-i686-pc-windows-msvc.tar.gz=41db0331bc8f9d164d4198c93234dae41c1b9d2f53d466ee8cdfba4f9704c45b +dist/2024-06-11/rustc-nightly-i686-pc-windows-msvc.tar.xz=49766cd2ad581f253f3fc0ba4f755a4aeaae954c75d41fa29a9302568e78aa75 +dist/2024-06-11/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=b57be1a1dc9e70c47564253877bc0cbbdde8a8064a6a4bcf68f8adc6b4c5d4df +dist/2024-06-11/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=cf2c4651297993671f033eb9bb9877b157638bc41cb40ccac3294c3fd13786ef +dist/2024-06-11/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=619c2eb3ed3f153d2c0ba6cbeb7f0e72c67fbb1e40c025752f94b46c9b740426 +dist/2024-06-11/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=105560769c3672133ecb063ac0a8ef541229490401470180af75151403287d3a +dist/2024-06-11/rustc-nightly-i686-unknown-linux-gnu.tar.gz=211498f7eb884908c8110ce922183bbd6cc05d96d9c8b5c9068dcfc4d29010cd +dist/2024-06-11/rustc-nightly-i686-unknown-linux-gnu.tar.xz=61beb47b917ce644defed991afa6d82028cb8f1e6a191cf5c84e8be883ad3870 +dist/2024-06-11/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=06036f5bfc00950e03a66e8dcab0eb7420fd055aadb85bd42e11845eef122122 +dist/2024-06-11/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=39d3dc95b1e0cfcc381d27540d100b8325728ef9a6a8b72a0e4ad85e2e957a63 +dist/2024-06-11/rustc-nightly-x86_64-unknown-freebsd.tar.gz=9b7badc1c8443571aec7b403e890d14846c3972b02159c8aacf3157ede69af9a +dist/2024-06-11/rustc-nightly-x86_64-unknown-freebsd.tar.xz=a1fdcbe1ca277b22c2dc8aced8ac0f34f841e7a7512fe421c2b045608c4ce07d +dist/2024-06-11/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=5e6105bc6304ea630a8170c785df11cd435521a2ac90348284898c4aab6ed5f2 +dist/2024-06-11/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=97dc7091b1ffa6a23a4b609a680c1f2f63debab80b5c01bc90fe271d6599bf89 +dist/2024-06-11/rustc-nightly-x86_64-apple-darwin.tar.gz=64769377c3714749acf6404d75f46b00ede0107840e736432d759dbfff15b6f9 +dist/2024-06-11/rustc-nightly-x86_64-apple-darwin.tar.xz=8ce829c39fdf21467307ee540c6b06b510d45c76c395947afdc2e5592d775977 +dist/2024-06-11/rustc-nightly-i686-pc-windows-gnu.tar.gz=4c9425ef2d5fdf9badec75783fe61ce0a251fde672c993c5b0069182449e2d7c +dist/2024-06-11/rustc-nightly-i686-pc-windows-gnu.tar.xz=442467ab4199e2fb62c69a96cc1c9f03478a415877996f0fef20c54760b2e8b9 +dist/2024-06-11/rustc-nightly-x86_64-unknown-illumos.tar.gz=0b4c3520ff6e5b053a6b37f7d3708fb115fbb99981f337a1786d675e70034acc +dist/2024-06-11/rustc-nightly-x86_64-unknown-illumos.tar.xz=d192e69dd328e6f930ad5b578065ebab12913762845f68ee55b43ddc9ba074a1 +dist/2024-06-11/rustc-nightly-x86_64-unknown-netbsd.tar.gz=0828f2d9395cdac8e9db6ad5c6b3cab3587fc82bccdec9962cd096e43e4f7793 +dist/2024-06-11/rustc-nightly-x86_64-unknown-netbsd.tar.xz=542f61a4c5a719f2583b0ba820207dc9d09cb9a2bb802da7cfbee5273bbfddfc +dist/2024-06-11/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=289b1bee22b8d9d84e92461694c6558476f944ac07caf2d22f0c4ccf3d29dbcf +dist/2024-06-11/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=23c86fc06ed9e7bcf8da72085ff88ec224ccddeca78ddc31032b314cb254ad64 +dist/2024-06-11/rustc-nightly-aarch64-apple-darwin.tar.gz=cf045620e63a5e623047490af956e0daf0bb321ed6a215ae355b8829c047e58e +dist/2024-06-11/rustc-nightly-aarch64-apple-darwin.tar.xz=0abec976185b9573dbc91868ab4fb84ba2837d25f3fa1d74b3a193609387f3fa +dist/2024-06-11/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=0b1146e24e4e59e4577b1e40d3ca45096864e87bcf9f258a34b9d9cf5abc3eef +dist/2024-06-11/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=289e97314fd22da08c8943d1240fa94b1cfd2cdf061dea15bfb582a9d482d6a6 +dist/2024-06-11/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=8957493cf92d57381b35d6ce5bbdb408a05c2a6becc8e2cd37b0502e3ef35ffb +dist/2024-06-11/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=9015e492f773b91054c53aca92ac704336504959779e4b916d42fc966e6058ea +dist/2024-06-11/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=aea2dc3831864dc5ea2c389c8208fc82baf1566f4e5688511495db25525e6020 +dist/2024-06-11/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=9b6f1c3b1656ee2037afe170d6909aa037d484897a83679e2115392a35559062 +dist/2024-06-11/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=3a962a42e427675df5d8fbc4e638949ec0669a95ecabcdddf5103a9c19f291ac +dist/2024-06-11/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=6fe48c92425b41ad7c3e812abe2e5decb117be178a16f6910bd60000fe8f355b +dist/2024-06-11/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=0a3147dd45cbf54e66b92baec479a5550c63327185baef3df9638c5a740e0921 +dist/2024-06-11/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=d35948d49fa1e526434ca89c2f7542fcfeb86b4ec35bb92f87f387ec37f4ccda \ No newline at end of file From e3e815370e824a9d7e74024da54acbe5ac477786 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Sep 2023 18:06:22 +0200 Subject: [PATCH 066/153] Split core's PanicInfo and std's PanicInfo. --- library/core/src/panic/panic_info.rs | 80 ++------------ library/core/src/panicking.rs | 4 +- library/std/src/panic.rs | 153 ++++++++++++++++++++++++++- library/std/src/panicking.rs | 37 +++---- 4 files changed, 177 insertions(+), 97 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 40326221258..2b7bc76fbc2 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -1,31 +1,14 @@ -use crate::any::Any; use crate::fmt; use crate::panic::Location; /// A struct providing information about a panic. /// -/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] -/// function. -/// -/// [`set_hook`]: ../../std/panic/fn.set_hook.html -/// -/// # Examples -/// -/// ```should_panic -/// use std::panic; -/// -/// panic::set_hook(Box::new(|panic_info| { -/// println!("panic occurred: {panic_info}"); -/// })); -/// -/// panic!("critical system failure"); -/// ``` +/// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`. #[lang = "panic_info"] #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] pub struct PanicInfo<'a> { - payload: &'a (dyn Any + Send), - message: Option<&'a fmt::Arguments<'a>>, + message: fmt::Arguments<'a>, location: &'a Location<'a>, can_unwind: bool, force_no_backtrace: bool, @@ -40,51 +23,12 @@ impl<'a> PanicInfo<'a> { #[doc(hidden)] #[inline] pub fn internal_constructor( - message: Option<&'a fmt::Arguments<'a>>, + message: fmt::Arguments<'a>, location: &'a Location<'a>, can_unwind: bool, force_no_backtrace: bool, ) -> Self { - struct NoPayload; - PanicInfo { location, message, payload: &NoPayload, can_unwind, force_no_backtrace } - } - - #[unstable( - feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` and related macros", - issue = "none" - )] - #[doc(hidden)] - #[inline] - pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { - self.payload = info; - } - - /// Returns the payload associated with the panic. - /// - /// This will commonly, but not always, be a `&'static str` or [`String`]. - /// - /// [`String`]: ../../std/string/struct.String.html - /// - /// # Examples - /// - /// ```should_panic - /// use std::panic; - /// - /// panic::set_hook(Box::new(|panic_info| { - /// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { - /// println!("panic occurred: {s:?}"); - /// } else { - /// println!("panic occurred"); - /// } - /// })); - /// - /// panic!("Normal panic"); - /// ``` - #[must_use] - #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn payload(&self) -> &(dyn Any + Send) { - self.payload + PanicInfo { location, message, can_unwind, force_no_backtrace } } /// If the `panic!` macro from the `core` crate (not from `std`) @@ -92,7 +36,7 @@ impl<'a> PanicInfo<'a> { /// returns that message ready to be used for example with [`fmt::write`] #[must_use] #[unstable(feature = "panic_info_message", issue = "66745")] - pub fn message(&self) -> Option<&fmt::Arguments<'_>> { + pub fn message(&self) -> fmt::Arguments<'_> { self.message } @@ -161,18 +105,8 @@ impl fmt::Display for PanicInfo<'_> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("panicked at ")?; self.location.fmt(formatter)?; - formatter.write_str(":")?; - if let Some(message) = self.message { - formatter.write_str("\n")?; - formatter.write_fmt(*message)?; - } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() { - formatter.write_str("\n")?; - formatter.write_str(payload)?; - } - // NOTE: we cannot use downcast_ref::() here - // since String is not available in core! - // The payload is a String when `std::panic!` is called with multiple arguments, - // but in that case the message is also available. + formatter.write_str(":\n")?; + formatter.write_fmt(self.message)?; Ok(()) } } diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index ca06e059b75..683894a5ab4 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -62,7 +62,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { } let pi = PanicInfo::internal_constructor( - Some(&fmt), + fmt, Location::caller(), /* can_unwind */ true, /* force_no_backtrace */ false, @@ -100,7 +100,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo // PanicInfo with the `can_unwind` flag set to false forces an abort. let pi = PanicInfo::internal_constructor( - Some(&fmt), + &fmt, Location::caller(), /* can_unwind */ false, force_no_backtrace, diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index e63b46ab705..18072f6fe3d 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -4,11 +4,162 @@ use crate::any::Any; use crate::collections; +use crate::fmt; use crate::panicking; use crate::sync::atomic::{AtomicU8, Ordering}; use crate::sync::{Condvar, Mutex, RwLock}; use crate::thread::Result; +/// A struct providing information about a panic. +/// +/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] +/// function. +/// +/// [`set_hook`]: ../../std/panic/fn.set_hook.html +/// +/// # Examples +/// +/// ```should_panic +/// use std::panic; +/// +/// panic::set_hook(Box::new(|panic_info| { +/// println!("panic occurred: {panic_info}"); +/// })); +/// +/// panic!("critical system failure"); +/// ``` +#[stable(feature = "panic_hooks", since = "1.10.0")] +#[derive(Debug)] +pub struct PanicInfo<'a> { + payload: &'a (dyn Any + Send), + location: &'a Location<'a>, + can_unwind: bool, + force_no_backtrace: bool, +} + +impl<'a> PanicInfo<'a> { + #[unstable(feature = "panic_internals", issue = "none")] + #[doc(hidden)] + #[inline] + pub fn internal_constructor( + location: &'a Location<'a>, + can_unwind: bool, + force_no_backtrace: bool, + ) -> Self { + struct NoPayload; + PanicInfo { payload: &NoPayload, location, can_unwind, force_no_backtrace } + } + + #[unstable(feature = "panic_internals", issue = "none")] + #[doc(hidden)] + #[inline] + pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { + self.payload = info; + } + + /// Returns the payload associated with the panic. + /// + /// This will commonly, but not always, be a `&'static str` or [`String`]. + /// + /// [`String`]: ../../std/string/struct.String.html + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + /// println!("panic occurred: {s:?}"); + /// } else { + /// println!("panic occurred"); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[must_use] + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn payload(&self) -> &(dyn Any + Send) { + self.payload + } + + /// Returns information about the location from which the panic originated, + /// if available. + /// + /// This method will currently always return [`Some`], but this may change + /// in future versions. + /// + /// # Examples + /// + /// ```should_panic + /// use std::panic; + /// + /// panic::set_hook(Box::new(|panic_info| { + /// if let Some(location) = panic_info.location() { + /// println!("panic occurred in file '{}' at line {}", + /// location.file(), + /// location.line(), + /// ); + /// } else { + /// println!("panic occurred but can't get location information..."); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[must_use] + #[stable(feature = "panic_hooks", since = "1.10.0")] + pub fn location(&self) -> Option<&Location<'_>> { + // NOTE: If this is changed to sometimes return None, + // deal with that case in std::panicking::default_hook and core::panicking::panic_fmt. + Some(&self.location) + } + + /// Returns whether the panic handler is allowed to unwind the stack from + /// the point where the panic occurred. + /// + /// This is true for most kinds of panics with the exception of panics + /// caused by trying to unwind out of a `Drop` implementation or a function + /// whose ABI does not support unwinding. + /// + /// It is safe for a panic handler to unwind even when this function returns + /// false, however this will simply cause the panic handler to be called + /// again. + #[must_use] + #[unstable(feature = "panic_can_unwind", issue = "92988")] + pub fn can_unwind(&self) -> bool { + self.can_unwind + } + + #[unstable( + feature = "panic_internals", + reason = "internal details of the implementation of the `panic!` and related macros", + issue = "none" + )] + #[doc(hidden)] + #[inline] + pub fn force_no_backtrace(&self) -> bool { + self.force_no_backtrace + } +} + +#[stable(feature = "panic_hook_display", since = "1.26.0")] +impl fmt::Display for PanicInfo<'_> { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("panicked at ")?; + self.location.fmt(formatter)?; + if let Some(payload) = self.payload.downcast_ref::<&'static str>() { + formatter.write_str(":\n")?; + formatter.write_str(payload)?; + } else if let Some(payload) = self.payload.downcast_ref::() { + formatter.write_str(":\n")?; + formatter.write_str(payload)?; + } + Ok(()) + } +} + #[doc(hidden)] #[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")] #[allow_internal_unstable(libstd_sys_internals, const_format_args, panic_internals, rt)] @@ -43,7 +194,7 @@ pub use crate::panicking::{set_hook, take_hook}; pub use crate::panicking::update_hook; #[stable(feature = "panic_hooks", since = "1.10.0")] -pub use core::panic::{Location, PanicInfo}; +pub use core::panic::Location; #[stable(feature = "catch_unwind", since = "1.9.0")] pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe}; diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 5699937cdb4..d6ef8f0dbbe 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -9,8 +9,8 @@ #![deny(unsafe_op_in_unsafe_fn)] -use crate::panic::BacktraceStyle; -use core::panic::{Location, PanicInfo, PanicPayload}; +use crate::panic::{BacktraceStyle, PanicInfo}; +use core::panic::{Location, PanicPayload}; use crate::any::Any; use crate::fmt; @@ -597,7 +597,7 @@ pub fn panicking() -> bool { /// Entry point of panics from the core crate (`panic_impl` lang item). #[cfg(not(any(test, doctest)))] #[panic_handler] -pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { +pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { struct FormatStringPayload<'a> { inner: &'a fmt::Arguments<'a>, string: Option, @@ -648,22 +648,20 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { } let loc = info.location().unwrap(); // The current implementation always returns Some - let msg = info.message().unwrap(); // The current implementation always returns Some + let msg = info.message(); crate::sys_common::backtrace::__rust_end_short_backtrace(move || { - // FIXME: can we just pass `info` along rather than taking it apart here, only to have - // `rust_panic_with_hook` construct a new `PanicInfo`? - if let Some(msg) = msg.as_str() { + if let Some(s) = msg.as_str() { rust_panic_with_hook( - &mut StaticStrPayload(msg), - info.message(), + &mut StaticStrPayload(s), + Some(msg), loc, info.can_unwind(), info.force_no_backtrace(), ); } else { rust_panic_with_hook( - &mut FormatStringPayload::new(msg), - info.message(), + &mut FormatStringPayload::new(&msg), + Some(msg), loc, info.can_unwind(), info.force_no_backtrace(), @@ -740,7 +738,7 @@ pub const fn begin_panic(msg: M) -> ! { /// abort or unwind. fn rust_panic_with_hook( payload: &mut dyn PanicPayload, - message: Option<&fmt::Arguments<'_>>, + message: Option>, location: &Location<'_>, can_unwind: bool, force_no_backtrace: bool, @@ -767,20 +765,17 @@ fn rust_panic_with_hook( panic_count::MustAbort::AlwaysAbort => { // Unfortunately, this does not print a backtrace, because creating // a `Backtrace` will allocate, which we must avoid here. - let panicinfo = PanicInfo::internal_constructor( - message, - location, - can_unwind, - force_no_backtrace, - ); - rtprintpanic!("{panicinfo}\npanicked after panic::always_abort(), aborting.\n"); + if let Some(message) = message { + rtprintpanic!("aborting due to panic at {location}:\n{message}\n"); + } else { + rtprintpanic!("aborting due to panic at {location}\n"); + } } } crate::sys::abort_internal(); } - let mut info = - PanicInfo::internal_constructor(message, location, can_unwind, force_no_backtrace); + let mut info = PanicInfo::internal_constructor(location, can_unwind, force_no_backtrace); let hook = HOOK.read().unwrap_or_else(PoisonError::into_inner); match *hook { // Some platforms (like wasm) know that printing to stderr won't ever actually From a519dc85f8aa1348ec9cdc46906bbcbb9d115981 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 26 Sep 2023 14:40:36 +0200 Subject: [PATCH 067/153] Document difference between core and std's PanicInfo. --- library/core/src/panic/panic_info.rs | 9 +++++++++ library/std/src/panic.rs | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 2b7bc76fbc2..6a600e2d431 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -4,6 +4,15 @@ use crate::panic::Location; /// A struct providing information about a panic. /// /// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`. +/// +/// There two `PanicInfo` types: +/// - `core::panic::PanicInfo`, which is used as an argument to a `#[panic_handler]` in `#![no_std]` programs. +/// - [`std::panic::PanicInfo`], which is used as an argument to a panic hook set by [`std::panic::set_hook`]. +/// +/// This is the first one. +/// +/// [`std::panic::set_hook`]: ../../std/panic/fn.set_hook.html +/// [`std::panic::PanicInfo`]: ../../std/panic/struct.PanicInfo.html #[lang = "panic_info"] #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 18072f6fe3d..54ab433d820 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -12,11 +12,16 @@ use crate::thread::Result; /// A struct providing information about a panic. /// -/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] -/// function. +/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] function. /// /// [`set_hook`]: ../../std/panic/fn.set_hook.html /// +/// There two `PanicInfo` types: +/// - [`core::panic::PanicInfo`], which is used as an argument to a `#[panic_handler]` in `#![no_std]` programs. +/// - `std::panic::PanicInfo`, which is used as an argument to a panic hook set by [`std::panic::set_hook`]. +/// +/// This is the second one. +/// /// # Examples /// /// ```should_panic @@ -28,6 +33,8 @@ use crate::thread::Result; /// /// panic!("critical system failure"); /// ``` +/// +/// [`core::panic::PanicInfo`]: ../../core/panic/struct.PanicInfo.html #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] pub struct PanicInfo<'a> { From 16dfc6ddc114efa7174e2daa972916bbd2f67d87 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 26 Sep 2023 14:40:50 +0200 Subject: [PATCH 068/153] Add core::panic::PanicInfo::payload() for compatibility. --- library/core/src/panic/panic_info.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 6a600e2d431..5b784ff4f80 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -81,6 +81,24 @@ impl<'a> PanicInfo<'a> { Some(&self.location) } + /// Returns the payload associated with the panic. + /// + /// On `core::panic::PanicInfo`, this method never returns anything useful. + /// It only exists because of compatibility with [`std::panic::PanicInfo`], + /// which used to be the same type. + /// + /// See [`std::panic::PanicInfo::payload`]. + /// + /// [`std::panic::PanicInfo`]: ../../std/panic/struct.PanicInfo.html + /// [`std::panic::PanicInfo::payload`]: ../../std/panic/struct.PanicInfo.html#method.payload + #[deprecated(since = "1.74.0", note = "this never returns anything useful")] + #[stable(feature = "panic_hooks", since = "1.10.0")] + #[allow(deprecated, deprecated_in_future)] + pub fn payload(&self) -> &(dyn crate::any::Any + Send) { + struct NoPayload; + &NoPayload + } + /// Returns whether the panic handler is allowed to unwind the stack from /// the point where the panic occurred. /// From 331b8a3edde67eb2418e7d9c5c6ef8d9a2a8c0b8 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 26 Sep 2023 15:02:34 +0200 Subject: [PATCH 069/153] Fix doc link. --- library/std/src/panic.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 54ab433d820..e2d182b4ba0 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -14,11 +14,9 @@ use crate::thread::Result; /// /// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] function. /// -/// [`set_hook`]: ../../std/panic/fn.set_hook.html -/// /// There two `PanicInfo` types: /// - [`core::panic::PanicInfo`], which is used as an argument to a `#[panic_handler]` in `#![no_std]` programs. -/// - `std::panic::PanicInfo`, which is used as an argument to a panic hook set by [`std::panic::set_hook`]. +/// - `std::panic::PanicInfo`, which is used as an argument to a panic hook set by [`set_hook`]. /// /// This is the second one. /// @@ -35,6 +33,7 @@ use crate::thread::Result; /// ``` /// /// [`core::panic::PanicInfo`]: ../../core/panic/struct.PanicInfo.html +/// [`set_hook`]: ../../std/panic/fn.set_hook.html #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] pub struct PanicInfo<'a> { From 83dd214f0651c680cea647c0ce7ccf451840f549 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:12:37 +0200 Subject: [PATCH 070/153] Update doc comment about core::panicking. --- library/core/src/panicking.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 683894a5ab4..aa11ae28dcb 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -1,7 +1,14 @@ //! Panic support for core //! -//! The core library cannot define panicking, but it does *declare* panicking. This -//! means that the functions inside of core are allowed to panic, but to be +//! In core, panicking is always done with a message, resulting in a core::panic::PanicInfo +//! containing a fmt::Arguments. In std, however, panicking can be done with panic_any, which throws +//! a Box containing any type of value. Because of this, std::panic::PanicInfo is a +//! different type, which contains a &dyn Any instead of a fmt::Arguments. +//! std's panic handler will convert the fmt::Arguments to a &dyn Any containing either a +//! &'static str or String containing the formatted message. +//! +//! The core library cannot define any panic handler, but it can invoke it. +//! This means that the functions inside of core are allowed to panic, but to be //! useful an upstream crate must define panicking for core to use. The current //! interface for panicking is: //! @@ -10,11 +17,6 @@ //! # { loop {} } //! ``` //! -//! This definition allows for panicking with any general message, but it does not -//! allow for failing with a `Box` value. (`PanicInfo` just contains a `&(dyn Any + Send)`, -//! for which we fill in a dummy value in `PanicInfo::internal_constructor`.) -//! The reason for this is that core is not allowed to allocate. -//! //! This module contains a few other panicking functions, but these are just the //! necessary lang items for the compiler. All panics are funneled through this //! one function. The actual symbol is declared through the `#[panic_handler]` attribute. From 0266bbf6e4be7b025f4798046121607c587e94cb Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:13:05 +0200 Subject: [PATCH 071/153] Remove core::panic::PanicInfo::internal_constructor. It no longer needs to be public. --- library/core/src/panic/panic_info.rs | 8 +------- library/core/src/panicking.rs | 10 +++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 5b784ff4f80..2a0cd8fda61 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -24,14 +24,8 @@ pub struct PanicInfo<'a> { } impl<'a> PanicInfo<'a> { - #[unstable( - feature = "panic_internals", - reason = "internal details of the implementation of the `panic!` and related macros", - issue = "none" - )] - #[doc(hidden)] #[inline] - pub fn internal_constructor( + pub(crate) fn new( message: fmt::Arguments<'a>, location: &'a Location<'a>, can_unwind: bool, diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index aa11ae28dcb..a6e55280946 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -63,7 +63,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { fn panic_impl(pi: &PanicInfo<'_>) -> !; } - let pi = PanicInfo::internal_constructor( + let pi = PanicInfo::new( fmt, Location::caller(), /* can_unwind */ true, @@ -101,12 +101,8 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pi = PanicInfo::internal_constructor( - &fmt, - Location::caller(), - /* can_unwind */ false, - force_no_backtrace, - ); + let pi = + PanicInfo::new(fmt, Location::caller(), /* can_unwind */ false, force_no_backtrace); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } From 0642cb2994c192b9e910855b7c9a258376c8e0ff Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:14:15 +0200 Subject: [PATCH 072/153] Remove std::panic::PanicInfo::internal_constructor+set_payload. We can just set the payload immediately in the constructor, and the constructor does not need to be public. --- library/std/src/panic.rs | 15 +++------------ library/std/src/panicking.rs | 13 ++++--------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index e2d182b4ba0..7adbce859f5 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -44,23 +44,14 @@ pub struct PanicInfo<'a> { } impl<'a> PanicInfo<'a> { - #[unstable(feature = "panic_internals", issue = "none")] - #[doc(hidden)] #[inline] - pub fn internal_constructor( + pub(crate) fn new( location: &'a Location<'a>, + payload: &'a (dyn Any + Send), can_unwind: bool, force_no_backtrace: bool, ) -> Self { - struct NoPayload; - PanicInfo { payload: &NoPayload, location, can_unwind, force_no_backtrace } - } - - #[unstable(feature = "panic_internals", issue = "none")] - #[doc(hidden)] - #[inline] - pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { - self.payload = info; + PanicInfo { payload, location, can_unwind, force_no_backtrace } } /// Returns the payload associated with the panic. diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index d6ef8f0dbbe..6d6aca01561 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -775,9 +775,7 @@ fn rust_panic_with_hook( crate::sys::abort_internal(); } - let mut info = PanicInfo::internal_constructor(location, can_unwind, force_no_backtrace); - let hook = HOOK.read().unwrap_or_else(PoisonError::into_inner); - match *hook { + match *HOOK.read().unwrap_or_else(PoisonError::into_inner) { // Some platforms (like wasm) know that printing to stderr won't ever actually // print anything, and if that's the case we can skip the default // hook. Since string formatting happens lazily when calling `payload` @@ -786,15 +784,12 @@ fn rust_panic_with_hook( // formatting.) Hook::Default if panic_output().is_none() => {} Hook::Default => { - info.set_payload(payload.get()); - default_hook(&info); + default_hook(&PanicInfo::new(location, payload.get(), can_unwind, force_no_backtrace)); } Hook::Custom(ref hook) => { - info.set_payload(payload.get()); - hook(&info); + hook(&PanicInfo::new(location, payload.get(), can_unwind, force_no_backtrace)); } - }; - drop(hook); + } // Indicate that we have finished executing the panic hook. After this point // it is fine if there is a panic while executing destructors, as long as it From 0087d899835cbcfa7c52e32c1825f8740621a485 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:14:55 +0200 Subject: [PATCH 073/153] Mark some PanicInfo methods as #[inline] for consistency. --- library/std/src/panic.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 7adbce859f5..ca0ec12a600 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -76,6 +76,7 @@ impl<'a> PanicInfo<'a> { /// panic!("Normal panic"); /// ``` #[must_use] + #[inline] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn payload(&self) -> &(dyn Any + Send) { self.payload @@ -106,6 +107,7 @@ impl<'a> PanicInfo<'a> { /// panic!("Normal panic"); /// ``` #[must_use] + #[inline] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn location(&self) -> Option<&Location<'_>> { // NOTE: If this is changed to sometimes return None, @@ -124,6 +126,7 @@ impl<'a> PanicInfo<'a> { /// false, however this will simply cause the panic handler to be called /// again. #[must_use] + #[inline] #[unstable(feature = "panic_can_unwind", issue = "92988")] pub fn can_unwind(&self) -> bool { self.can_unwind From 4e356f3184ff43aeb68968a8ab96a0faacf6281b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:15:21 +0200 Subject: [PATCH 074/153] Move downcasting panic payload to str to a function. --- library/std/src/panicking.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 6d6aca01561..53df0bb40b5 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -248,13 +248,7 @@ fn default_hook(info: &PanicInfo<'_>) { // The current implementation always returns `Some`. let location = info.location().unwrap(); - let msg = match info.payload().downcast_ref::<&'static str>() { - Some(s) => *s, - None => match info.payload().downcast_ref::() { - Some(s) => &s[..], - None => "Box", - }, - }; + let msg = payload_as_str(info.payload()); let thread = thread::try_current(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or(""); @@ -731,6 +725,16 @@ pub const fn begin_panic(msg: M) -> ! { } } +fn payload_as_str(payload: &dyn Any) -> &str { + if let Some(&s) = payload.downcast_ref::<&'static str>() { + s + } else if let Some(s) = payload.downcast_ref::() { + s.as_str() + } else { + "Box" + } +} + /// Central point for dispatching panics. /// /// Executes the primary logic for a panic, including checking for recursive From 22f7399b32dcf1bd4d38b7e88a9b482fba889a8f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:16:10 +0200 Subject: [PATCH 075/153] Use unnamed lifetimes for [..]Payload impl blocks. --- library/std/src/panicking.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 53df0bb40b5..a460f41b93d 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -597,11 +597,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { string: Option, } - impl<'a> FormatStringPayload<'a> { - fn new(inner: &'a fmt::Arguments<'a>) -> Self { - Self { inner, string: None } - } - + impl FormatStringPayload<'_> { fn fill(&mut self) -> &mut String { use crate::fmt::Write; @@ -615,7 +611,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { } } - unsafe impl<'a> PanicPayload for FormatStringPayload<'a> { + unsafe impl PanicPayload for FormatStringPayload<'_> { fn take_box(&mut self) -> *mut (dyn Any + Send) { // We do two allocations here, unfortunately. But (a) they're required with the current // scheme, and (b) we don't handle panic + OOM properly anyway (see comment in @@ -654,7 +650,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { ); } else { rust_panic_with_hook( - &mut FormatStringPayload::new(&msg), + &mut FormatStringPayload { inner: &msg, string: None }, Some(msg), loc, info.can_unwind(), From 1642de33d3c4e59f3b4a766d0ad1abe046f0433f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:17:16 +0200 Subject: [PATCH 076/153] Impl Display for PanicPayload to simplify things. --- library/core/src/panic.rs | 2 +- library/std/src/panicking.rs | 37 +++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 8771f40f9b4..c9f3702e178 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -144,7 +144,7 @@ pub macro unreachable_2021 { /// use. #[unstable(feature = "std_internals", issue = "none")] #[doc(hidden)] -pub unsafe trait PanicPayload { +pub unsafe trait PanicPayload: crate::fmt::Display { /// Take full ownership of the contents. /// The return type is actually `Box`, but we cannot use `Box` in core. /// diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a460f41b93d..362aa8d06f3 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -625,6 +625,12 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { } } + impl fmt::Display for FormatStringPayload<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(s) = &self.string { f.write_str(s) } else { f.write_fmt(*self.inner) } + } + } + struct StaticStrPayload(&'static str); unsafe impl PanicPayload for StaticStrPayload { @@ -637,13 +643,18 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { } } + impl fmt::Display for StaticStrPayload { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(self.0) + } + } + let loc = info.location().unwrap(); // The current implementation always returns Some let msg = info.message(); crate::sys_common::backtrace::__rust_end_short_backtrace(move || { if let Some(s) = msg.as_str() { rust_panic_with_hook( &mut StaticStrPayload(s), - Some(msg), loc, info.can_unwind(), info.force_no_backtrace(), @@ -651,7 +662,6 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { } else { rust_panic_with_hook( &mut FormatStringPayload { inner: &msg, string: None }, - Some(msg), loc, info.can_unwind(), info.force_no_backtrace(), @@ -681,7 +691,6 @@ pub const fn begin_panic(msg: M) -> ! { return crate::sys_common::backtrace::__rust_end_short_backtrace(move || { rust_panic_with_hook( &mut Payload::new(msg), - None, loc, /* can_unwind */ true, /* force_no_backtrace */ false, @@ -719,6 +728,15 @@ pub const fn begin_panic(msg: M) -> ! { } } } + + impl fmt::Display for Payload { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.inner { + Some(a) => f.write_str(payload_as_str(a)), + None => process::abort(), + } + } + } } fn payload_as_str(payload: &dyn Any) -> &str { @@ -738,7 +756,6 @@ fn payload_as_str(payload: &dyn Any) -> &str { /// abort or unwind. fn rust_panic_with_hook( payload: &mut dyn PanicPayload, - message: Option>, location: &Location<'_>, can_unwind: bool, force_no_backtrace: bool, @@ -765,11 +782,7 @@ fn rust_panic_with_hook( panic_count::MustAbort::AlwaysAbort => { // Unfortunately, this does not print a backtrace, because creating // a `Backtrace` will allocate, which we must avoid here. - if let Some(message) = message { - rtprintpanic!("aborting due to panic at {location}:\n{message}\n"); - } else { - rtprintpanic!("aborting due to panic at {location}\n"); - } + rtprintpanic!("aborting due to panic at {location}:\n{payload}\n"); } } crate::sys::abort_internal(); @@ -825,6 +838,12 @@ pub fn rust_panic_without_hook(payload: Box) -> ! { } } + impl fmt::Display for RewrapBox { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(payload_as_str(&self.0)) + } + } + rust_panic(&mut RewrapBox(payload)) } From bab26b02c78f46265d59dda4cf558918008617b2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:29:58 +0200 Subject: [PATCH 077/153] Reorder body of begin_panic for consistency. In the other functions, we put the struct and impl blocks first, such that the return expression can be at the end of the body as usual. --- library/std/src/panicking.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 362aa8d06f3..15544de9ff8 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -687,26 +687,10 @@ pub const fn begin_panic(msg: M) -> ! { intrinsics::abort() } - let loc = Location::caller(); - return crate::sys_common::backtrace::__rust_end_short_backtrace(move || { - rust_panic_with_hook( - &mut Payload::new(msg), - loc, - /* can_unwind */ true, - /* force_no_backtrace */ false, - ) - }); - struct Payload { inner: Option, } - impl Payload { - fn new(inner: A) -> Payload { - Payload { inner: Some(inner) } - } - } - unsafe impl PanicPayload for Payload { fn take_box(&mut self) -> *mut (dyn Any + Send) { // Note that this should be the only allocation performed in this code path. Currently @@ -729,7 +713,7 @@ pub const fn begin_panic(msg: M) -> ! { } } - impl fmt::Display for Payload { + impl fmt::Display for Payload { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.inner { Some(a) => f.write_str(payload_as_str(a)), @@ -737,6 +721,16 @@ pub const fn begin_panic(msg: M) -> ! { } } } + + let loc = Location::caller(); + crate::sys_common::backtrace::__rust_end_short_backtrace(move || { + rust_panic_with_hook( + &mut Payload { inner: Some(msg) }, + loc, + /* can_unwind */ true, + /* force_no_backtrace */ false, + ) + }) } fn payload_as_str(payload: &dyn Any) -> &str { From 6b2d7c47072a466b938fac75db416c9adbf59892 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 2 Oct 2023 14:58:31 +0200 Subject: [PATCH 078/153] Fix invalid markdown/html. --- library/core/src/panicking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index a6e55280946..0793c1b0f29 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -2,7 +2,7 @@ //! //! In core, panicking is always done with a message, resulting in a core::panic::PanicInfo //! containing a fmt::Arguments. In std, however, panicking can be done with panic_any, which throws -//! a Box containing any type of value. Because of this, std::panic::PanicInfo is a +//! a `Box` containing any type of value. Because of this, std::panic::PanicInfo is a //! different type, which contains a &dyn Any instead of a fmt::Arguments. //! std's panic handler will convert the fmt::Arguments to a &dyn Any containing either a //! &'static str or String containing the formatted message. From b6180a918538b3afa04bbc1c5515c0be2154e1b6 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 31 Jan 2024 09:35:17 +0100 Subject: [PATCH 079/153] Formatting. --- library/core/src/panicking.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 0793c1b0f29..94b4113b245 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -101,8 +101,12 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pi = - PanicInfo::new(fmt, Location::caller(), /* can_unwind */ false, force_no_backtrace); + let pi = PanicInfo::new( + fmt, + Location::caller(), + /* can_unwind */ false, + force_no_backtrace, + ); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. unsafe { panic_impl(&pi) } From 64e56db72aa2b1f112504504a7dceba63881cdef Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 31 Jan 2024 10:27:29 +0100 Subject: [PATCH 080/153] Rename std::panic::PanicInfo to PanicHookInfo. --- compiler/rustc_driver_impl/src/lib.rs | 9 +++--- library/core/src/error.md | 4 +-- library/core/src/panic/location.rs | 3 +- library/core/src/panic/panic_info.rs | 17 ++++------ library/core/src/panicking.rs | 12 +++---- library/std/src/panic.rs | 31 +++++++++++-------- library/std/src/panicking.rs | 25 +++++++++------ library/test/src/lib.rs | 6 ++-- tests/ui/duplicate_entry_error.rs | 4 ++- tests/ui/duplicate_entry_error.stderr | 2 +- tests/ui/panic-handler/panic-handler-std.rs | 3 +- .../ui/panic-handler/panic-handler-std.stderr | 2 +- 12 files changed, 63 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 93a65290602..fef4ce0b471 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -52,7 +52,7 @@ use std::ffi::OsString; use std::fmt::Write as _; use std::fs::{self, File}; use std::io::{self, IsTerminal, Read, Write}; -use std::panic::{self, catch_unwind, PanicInfo}; +use std::panic::{self, catch_unwind, PanicHookInfo}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; use std::str; @@ -1366,11 +1366,10 @@ pub fn install_ice_hook( let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default()); let using_internal_features_hook = using_internal_features.clone(); panic::update_hook(Box::new( - move |default_hook: &(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), - info: &PanicInfo<'_>| { + move |default_hook: &(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static), + info: &PanicHookInfo<'_>| { // Lock stderr to prevent interleaving of concurrent panics. let _guard = io::stderr().lock(); - // If the error was caused by a broken pipe then this is not a bug. // Write the error and return immediately. See #98700. #[cfg(windows)] @@ -1431,7 +1430,7 @@ pub fn install_ice_hook( /// When `install_ice_hook` is called, this function will be called as the panic /// hook. fn report_ice( - info: &panic::PanicInfo<'_>, + info: &panic::PanicHookInfo<'_>, bug_report_url: &str, extra_info: fn(&DiagCtxt), using_internal_features: &AtomicBool, diff --git a/library/core/src/error.md b/library/core/src/error.md index a5deb71e6b8..8d5a623df4b 100644 --- a/library/core/src/error.md +++ b/library/core/src/error.md @@ -17,7 +17,7 @@ The following are the primary interfaces of the panic system and the responsibilities they cover: * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically) -* [`PanicInfo`] (Reporting) +* [`PanicHookInfo`] (Reporting) * [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting) * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating) @@ -125,7 +125,7 @@ expect-as-precondition style error messages remember to focus on the word should be available and executable by the current user". [`panic_any`]: ../../std/panic/fn.panic_any.html -[`PanicInfo`]: crate::panic::PanicInfo +[`PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html [`catch_unwind`]: ../../std/panic/fn.catch_unwind.html [`resume_unwind`]: ../../std/panic/fn.resume_unwind.html [`downcast`]: crate::error::Error diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index eb27da1724e..8c04994ac0f 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -2,9 +2,10 @@ use crate::fmt; /// A struct containing information about the location of a panic. /// -/// This structure is created by [`PanicInfo::location()`]. +/// This structure is created by [`PanicHookInfo::location()`] and [`PanicInfo::location()`]. /// /// [`PanicInfo::location()`]: crate::panic::PanicInfo::location +/// [`PanicHookInfo::location()`]: ../../std/panic/struct.PanicHookInfo.html#method.location /// /// # Examples /// diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 2a0cd8fda61..7c792a58d2a 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -5,14 +5,9 @@ use crate::panic::Location; /// /// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`. /// -/// There two `PanicInfo` types: -/// - `core::panic::PanicInfo`, which is used as an argument to a `#[panic_handler]` in `#![no_std]` programs. -/// - [`std::panic::PanicInfo`], which is used as an argument to a panic hook set by [`std::panic::set_hook`]. +/// For the type used by the panic hook mechanism in `std`, see [`std::panic::PanicHookInfo`]. /// -/// This is the first one. -/// -/// [`std::panic::set_hook`]: ../../std/panic/fn.set_hook.html -/// [`std::panic::PanicInfo`]: ../../std/panic/struct.PanicInfo.html +/// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html #[lang = "panic_info"] #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] @@ -78,13 +73,13 @@ impl<'a> PanicInfo<'a> { /// Returns the payload associated with the panic. /// /// On `core::panic::PanicInfo`, this method never returns anything useful. - /// It only exists because of compatibility with [`std::panic::PanicInfo`], + /// It only exists because of compatibility with [`std::panic::PanicHookInfo`], /// which used to be the same type. /// - /// See [`std::panic::PanicInfo::payload`]. + /// See [`std::panic::PanicHookInfo::payload`]. /// - /// [`std::panic::PanicInfo`]: ../../std/panic/struct.PanicInfo.html - /// [`std::panic::PanicInfo::payload`]: ../../std/panic/struct.PanicInfo.html#method.payload + /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html + /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload #[deprecated(since = "1.74.0", note = "this never returns anything useful")] #[stable(feature = "panic_hooks", since = "1.10.0")] #[allow(deprecated, deprecated_in_future)] diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 94b4113b245..97fb1d6b732 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -1,11 +1,11 @@ //! Panic support for core //! -//! In core, panicking is always done with a message, resulting in a core::panic::PanicInfo -//! containing a fmt::Arguments. In std, however, panicking can be done with panic_any, which throws -//! a `Box` containing any type of value. Because of this, std::panic::PanicInfo is a -//! different type, which contains a &dyn Any instead of a fmt::Arguments. -//! std's panic handler will convert the fmt::Arguments to a &dyn Any containing either a -//! &'static str or String containing the formatted message. +//! In core, panicking is always done with a message, resulting in a `core::panic::PanicInfo` +//! containing a `fmt::Arguments`. In std, however, panicking can be done with panic_any, which +//! throws a `Box` containing any type of value. Because of this, +//! `std::panic::PanicHookInfo` is a different type, which contains a `&dyn Any` instead of a +//! `fmt::Arguments`. std's panic handler will convert the `fmt::Arguments` to a `&dyn Any` +//! containing either a `&'static str` or `String` containing the formatted message. //! //! The core library cannot define any panic handler, but it can invoke it. //! This means that the functions inside of core are allowed to panic, but to be diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index ca0ec12a600..77defe14b70 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -10,15 +10,21 @@ use crate::sync::atomic::{AtomicU8, Ordering}; use crate::sync::{Condvar, Mutex, RwLock}; use crate::thread::Result; +#[stable(feature = "panic_hooks", since = "1.10.0")] +#[deprecated( + since = "1.77.0", + note = "use `PanicHookInfo` instead", + suggestion = "std::panic::PanicHookInfo" +)] /// A struct providing information about a panic. /// -/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] function. +/// `PanicInfo` has been renamed to [`PanicHookInfo`] to avoid confusion with +/// [`core::panic::PanicInfo`]. +pub type PanicInfo<'a> = PanicHookInfo<'a>; + +/// A struct providing information about a panic. /// -/// There two `PanicInfo` types: -/// - [`core::panic::PanicInfo`], which is used as an argument to a `#[panic_handler]` in `#![no_std]` programs. -/// - `std::panic::PanicInfo`, which is used as an argument to a panic hook set by [`set_hook`]. -/// -/// This is the second one. +/// `PanicHookInfo` structure is passed to a panic hook set by the [`set_hook`] function. /// /// # Examples /// @@ -32,18 +38,17 @@ use crate::thread::Result; /// panic!("critical system failure"); /// ``` /// -/// [`core::panic::PanicInfo`]: ../../core/panic/struct.PanicInfo.html /// [`set_hook`]: ../../std/panic/fn.set_hook.html -#[stable(feature = "panic_hooks", since = "1.10.0")] +#[stable(feature = "panic_hook_info", since = "CURRENT_RUSTC_VERSION")] #[derive(Debug)] -pub struct PanicInfo<'a> { +pub struct PanicHookInfo<'a> { payload: &'a (dyn Any + Send), location: &'a Location<'a>, can_unwind: bool, force_no_backtrace: bool, } -impl<'a> PanicInfo<'a> { +impl<'a> PanicHookInfo<'a> { #[inline] pub(crate) fn new( location: &'a Location<'a>, @@ -51,7 +56,7 @@ impl<'a> PanicInfo<'a> { can_unwind: bool, force_no_backtrace: bool, ) -> Self { - PanicInfo { payload, location, can_unwind, force_no_backtrace } + PanicHookInfo { payload, location, can_unwind, force_no_backtrace } } /// Returns the payload associated with the panic. @@ -145,7 +150,7 @@ impl<'a> PanicInfo<'a> { } #[stable(feature = "panic_hook_display", since = "1.26.0")] -impl fmt::Display for PanicInfo<'_> { +impl fmt::Display for PanicHookInfo<'_> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("panicked at ")?; self.location.fmt(formatter)?; @@ -204,7 +209,7 @@ pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe}; /// The message can be of any (`Any + Send`) type, not just strings. /// /// The message is wrapped in a `Box<'static + Any + Send>`, which can be -/// accessed later using [`PanicInfo::payload`]. +/// accessed later using [`PanicHookInfo::payload`]. /// /// See the [`panic!`] macro for more information about panicking. #[stable(feature = "panic_any", since = "1.51.0")] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 15544de9ff8..caab7ed4b81 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -9,7 +9,7 @@ #![deny(unsafe_op_in_unsafe_fn)] -use crate::panic::{BacktraceStyle, PanicInfo}; +use crate::panic::{BacktraceStyle, PanicHookInfo}; use core::panic::{Location, PanicPayload}; use crate::any::Any; @@ -70,12 +70,12 @@ extern "C" fn __rust_foreign_exception() -> ! { enum Hook { Default, - Custom(Box) + 'static + Sync + Send>), + Custom(Box) + 'static + Sync + Send>), } impl Hook { #[inline] - fn into_box(self) -> Box) + 'static + Sync + Send> { + fn into_box(self) -> Box) + 'static + Sync + Send> { match self { Hook::Default => Box::new(default_hook), Hook::Custom(hook) => hook, @@ -105,7 +105,7 @@ static HOOK: RwLock = RwLock::new(Hook::Default); /// /// [`take_hook`]: ./fn.take_hook.html /// -/// The hook is provided with a `PanicInfo` struct which contains information +/// The hook is provided with a `PanicHookInfo` struct which contains information /// about the origin of the panic, including the payload passed to `panic!` and /// the source code location from which the panic originated. /// @@ -129,7 +129,7 @@ static HOOK: RwLock = RwLock::new(Hook::Default); /// panic!("Normal panic"); /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] -pub fn set_hook(hook: Box) + 'static + Sync + Send>) { +pub fn set_hook(hook: Box) + 'static + Sync + Send>) { if thread::panicking() { panic!("cannot modify the panic hook from a panicking thread"); } @@ -173,7 +173,7 @@ pub fn set_hook(hook: Box) + 'static + Sync + Send>) { /// ``` #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] -pub fn take_hook() -> Box) + 'static + Sync + Send> { +pub fn take_hook() -> Box) + 'static + Sync + Send> { if thread::panicking() { panic!("cannot modify the panic hook from a panicking thread"); } @@ -219,7 +219,7 @@ pub fn take_hook() -> Box) + 'static + Sync + Send> { #[unstable(feature = "panic_update_hook", issue = "92649")] pub fn update_hook(hook_fn: F) where - F: Fn(&(dyn Fn(&PanicInfo<'_>) + Send + Sync + 'static), &PanicInfo<'_>) + F: Fn(&(dyn Fn(&PanicHookInfo<'_>) + Send + Sync + 'static), &PanicHookInfo<'_>) + Sync + Send + 'static, @@ -234,7 +234,7 @@ where } /// The default panic handler. -fn default_hook(info: &PanicInfo<'_>) { +fn default_hook(info: &PanicHookInfo<'_>) { // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. let backtrace = if info.force_no_backtrace() { @@ -791,10 +791,15 @@ fn rust_panic_with_hook( // formatting.) Hook::Default if panic_output().is_none() => {} Hook::Default => { - default_hook(&PanicInfo::new(location, payload.get(), can_unwind, force_no_backtrace)); + default_hook(&PanicHookInfo::new( + location, + payload.get(), + can_unwind, + force_no_backtrace, + )); } Hook::Custom(ref hook) => { - hook(&PanicInfo::new(location, payload.get(), can_unwind, force_no_backtrace)); + hook(&PanicHookInfo::new(location, payload.get(), can_unwind, force_no_backtrace)); } } diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 7bd08a0605f..7aff7fe1fdd 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -58,7 +58,7 @@ use std::{ env, io, io::prelude::Write, mem::ManuallyDrop, - panic::{self, catch_unwind, AssertUnwindSafe, PanicInfo}, + panic::{self, catch_unwind, AssertUnwindSafe, PanicHookInfo}, process::{self, Command, Termination}, sync::mpsc::{channel, Sender}, sync::{Arc, Mutex}, @@ -123,7 +123,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Option| { + move |info: &'_ PanicHookInfo<'_>| { if !info.can_unwind() { std::mem::forget(std::io::stderr().lock()); let mut stdout = ManuallyDrop::new(std::io::stdout().lock()); @@ -726,7 +726,7 @@ fn spawn_test_subprocess( fn run_test_in_spawned_subprocess(desc: TestDesc, runnable_test: RunnableTest) -> ! { let builtin_panic_hook = panic::take_hook(); - let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| { + let record_result = Arc::new(move |panic_info: Option<&'_ PanicHookInfo<'_>>| { let test_result = match panic_info { Some(info) => calc_result(&desc, Err(info.payload()), &None, &None), None => calc_result(&desc, Ok(()), &None, &None), diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index 7ebbab47095..8e49f57a3df 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -5,7 +5,9 @@ #![feature(lang_items)] -use std::panic::PanicInfo; +extern crate core; + +use core::panic::PanicInfo; #[lang = "panic_impl"] fn panic_impl(info: &PanicInfo) -> ! { diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 3b5998df353..958e9c7527d 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -1,5 +1,5 @@ error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/duplicate_entry_error.rs:11:1 + --> $DIR/duplicate_entry_error.rs:13:1 | LL | / fn panic_impl(info: &PanicInfo) -> ! { LL | | diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 91b3997819c..051828ec880 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,8 +1,9 @@ //@ normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" //@ error-pattern: found duplicate lang item `panic_impl` +extern crate core; -use std::panic::PanicInfo; +use core::panic::PanicInfo; #[panic_handler] fn panic(info: PanicInfo) -> ! { diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index 48c216ce27e..caae16118ef 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -1,5 +1,5 @@ error[E0152]: found duplicate lang item `panic_impl` - --> $DIR/panic-handler-std.rs:8:1 + --> $DIR/panic-handler-std.rs:9:1 | LL | / fn panic(info: PanicInfo) -> ! { LL | | loop {} From 3854357ad2c164a87f7e625874d4cdc3ccd9cc33 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 31 Jan 2024 10:28:00 +0100 Subject: [PATCH 081/153] Fix deprecation version. --- library/core/src/panic/panic_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 7c792a58d2a..df8f441bf35 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -80,7 +80,7 @@ impl<'a> PanicInfo<'a> { /// /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload - #[deprecated(since = "1.74.0", note = "this never returns anything useful")] + #[deprecated(since = "1.77.0", note = "this never returns anything useful")] #[stable(feature = "panic_hooks", since = "1.10.0")] #[allow(deprecated, deprecated_in_future)] pub fn payload(&self) -> &(dyn crate::any::Any + Send) { From f5fe82fdcab33b4137b94014f05dd2986ea396ba Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 31 Jan 2024 11:32:53 +0100 Subject: [PATCH 082/153] Move deprecation of std::panic::PanicInfo to 1.80.0. --- library/std/src/panic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 77defe14b70..0f999f6a93e 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -12,7 +12,7 @@ use crate::thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] #[deprecated( - since = "1.77.0", + since = "1.80.0", note = "use `PanicHookInfo` instead", suggestion = "std::panic::PanicHookInfo" )] From ce0bc8bd588f9a2a4ba149ae6a9d3490f401c376 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 11:49:55 +0200 Subject: [PATCH 083/153] Downcast panic payload to String too in example. --- library/std/src/panic.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 0f999f6a93e..51228cc9907 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -73,6 +73,8 @@ impl<'a> PanicHookInfo<'a> { /// panic::set_hook(Box::new(|panic_info| { /// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { /// println!("panic occurred: {s:?}"); + /// } else if let Some(s) = panic_info.payload().downcast_ref::() { + /// println!("panic occurred: {s:?}"); /// } else { /// println!("panic occurred"); /// } From 32bfe703e2f8b5062a769aa1b3467c80d5bb0b95 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 11:54:11 +0200 Subject: [PATCH 084/153] Add note on panic payload type. --- library/std/src/panic.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 51228cc9907..d5566caa369 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -63,6 +63,13 @@ impl<'a> PanicHookInfo<'a> { /// /// This will commonly, but not always, be a `&'static str` or [`String`]. /// + /// A invocation of the `panic!()` macro in Rust 2021 or later will always result in a + /// panic payload of type `&'static str` or `String`. + /// + /// Only an invocation of [`panic_any`] + /// (or, in Rust 2018 and earlier, `panic!(x)` where `x` is something other than a string) + /// can result in a panic payload other than a `&'static str` or `String`. + /// /// [`String`]: ../../std/string/struct.String.html /// /// # Examples From 877a26f6c9cbd9878ea08c94cd5a698a53556511 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 12:58:46 +0200 Subject: [PATCH 085/153] Mention core's PanicInfo in error.md. --- library/core/src/error.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/error.md b/library/core/src/error.md index 8d5a623df4b..4b62391cafc 100644 --- a/library/core/src/error.md +++ b/library/core/src/error.md @@ -17,8 +17,8 @@ The following are the primary interfaces of the panic system and the responsibilities they cover: * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically) -* [`PanicHookInfo`] (Reporting) -* [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting) +* [`set_hook`], [`take_hook`], and [`PanicHookInfo`] (Reporting) +* [`#[panic_handler]`][panic-handler] and [`PanicInfo`] (Reporting in no_std) * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating) The following are the primary interfaces of the error system and the @@ -126,6 +126,7 @@ should be available and executable by the current user". [`panic_any`]: ../../std/panic/fn.panic_any.html [`PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html +[`PanicInfo`]: crate::panic::PanicInfo [`catch_unwind`]: ../../std/panic/fn.catch_unwind.html [`resume_unwind`]: ../../std/panic/fn.resume_unwind.html [`downcast`]: crate::error::Error From fb0990d1e1e67a512930665bf7df5fb91f55982c Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 12:59:09 +0200 Subject: [PATCH 086/153] Fix display of panic message in recursive panic. --- library/core/src/panic.rs | 5 +++++ library/std/src/panicking.rs | 15 ++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index c9f3702e178..b5a0932221a 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -157,4 +157,9 @@ pub unsafe trait PanicPayload: crate::fmt::Display { /// Just borrow the contents. fn get(&mut self) -> &(dyn Any + Send); + + /// Try to borrow the contents as `&str`, if possible without doing any allocations. + fn as_str(&mut self) -> Option<&str> { + None + } } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index caab7ed4b81..e4d2ee7d986 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -641,6 +641,10 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! { fn get(&mut self) -> &(dyn Any + Send) { &self.0 } + + fn as_str(&mut self) -> Option<&str> { + Some(self.0) + } } impl fmt::Display for StaticStrPayload { @@ -763,15 +767,8 @@ fn rust_panic_with_hook( // Don't try to format the message in this case, perhaps that is causing the // recursive panics. However if the message is just a string, no user-defined // code is involved in printing it, so that is risk-free. - let msg_str = message.and_then(|m| m.as_str()).map(|m| [m]); - let message = msg_str.as_ref().map(|m| fmt::Arguments::new_const(m)); - let panicinfo = PanicInfo::internal_constructor( - message.as_ref(), - location, - can_unwind, - force_no_backtrace, - ); - rtprintpanic!("{panicinfo}\nthread panicked while processing panic. aborting.\n"); + let message: &str = payload.as_str().unwrap_or_default(); + rtprintpanic!("panicked at {location}:\n{message}\nthread panicked while processing panic. aborting.\n"); } panic_count::MustAbort::AlwaysAbort => { // Unfortunately, this does not print a backtrace, because creating From de07c1a928b3a1e6e12946c9d9d0ff47c2310ead Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 13:08:27 +0200 Subject: [PATCH 087/153] Add PanicHookInfo::payload_as_str(). --- library/std/src/panic.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index d5566caa369..f1b45b18630 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -96,6 +96,45 @@ impl<'a> PanicHookInfo<'a> { self.payload } + /// Returns the payload associated with the panic, if it is a string. + /// + /// This returns the payload if it is of type `&'static str` or `String`. + /// + /// A invocation of the `panic!()` macro in Rust 2021 or later will always result in a + /// panic payload where `payload_as_str` returns `Some`. + /// + /// Only an invocation of [`panic_any`] + /// (or, in Rust 2018 and earlier, `panic!(x)` where `x` is something other than a string) + /// can result in a panic payload where `payload_as_str` returns `None`. + /// + /// # Example + /// + /// ```should_panic + /// #![feature(panic_payload_as_str)] + /// + /// std::panic::set_hook(Box::new(|panic_info| { + /// if let Some(s) = panic_info.payload_as_str() { + /// println!("panic occurred: {s:?}"); + /// } else { + /// println!("panic occurred"); + /// } + /// })); + /// + /// panic!("Normal panic"); + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "panic_payload_as_str", issue = "125175")] + pub fn payload_as_str(&self) -> Option<&str> { + if let Some(s) = self.payload.downcast_ref::<&str>() { + Some(s) + } else if let Some(s) = self.payload.downcast_ref::() { + Some(s) + } else { + None + } + } + /// Returns information about the location from which the panic originated, /// if available. /// From a345c3daf65857fb12926c3c5f4c9d8e2ca00f00 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 May 2024 13:08:40 +0200 Subject: [PATCH 088/153] Bump deprecation of std's PanicInfo alias to 1.82.0. --- library/std/src/panic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index f1b45b18630..5282c00fcca 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -12,7 +12,7 @@ use crate::thread::Result; #[stable(feature = "panic_hooks", since = "1.10.0")] #[deprecated( - since = "1.80.0", + since = "1.82.0", note = "use `PanicHookInfo` instead", suggestion = "std::panic::PanicHookInfo" )] From a6e23b126b925b270663436a1d2f4d24cc5f4711 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 11 Jun 2024 15:46:15 +0200 Subject: [PATCH 089/153] Formatting. --- library/std/src/panicking.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index e4d2ee7d986..8fd8134c111 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -768,7 +768,9 @@ fn rust_panic_with_hook( // recursive panics. However if the message is just a string, no user-defined // code is involved in printing it, so that is risk-free. let message: &str = payload.as_str().unwrap_or_default(); - rtprintpanic!("panicked at {location}:\n{message}\nthread panicked while processing panic. aborting.\n"); + rtprintpanic!( + "panicked at {location}:\n{message}\nthread panicked while processing panic. aborting.\n" + ); } panic_count::MustAbort::AlwaysAbort => { // Unfortunately, this does not print a backtrace, because creating From c84afee89851f0d0d5089d64d35225a6adb28453 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 6 Jun 2024 20:47:00 +0200 Subject: [PATCH 090/153] Implement fs wrapper for run_make_support --- src/tools/run-make-support/src/fs_wrapper.rs | 113 ++++++++++++++++++ src/tools/run-make-support/src/lib.rs | 22 ++-- tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs | 4 +- tests/run-make/c-link-to-rust-dylib/rmake.rs | 8 +- .../c-link-to-rust-staticlib/rmake.rs | 3 +- tests/run-make/cdylib/rmake.rs | 6 +- tests/run-make/compiler-builtins/rmake.rs | 6 +- tests/run-make/const-prop-lint/rmake.rs | 6 +- .../run-make/doctests-keep-binaries/rmake.rs | 8 +- tests/run-make/doctests-runtool/rmake.rs | 4 +- tests/run-make/emit-named-files/rmake.rs | 5 +- .../incr-prev-body-beyond-eof/rmake.rs | 11 +- .../issue-107495-archive-permissions/rmake.rs | 6 +- tests/run-make/mixing-formats/rmake.rs | 1 - tests/run-make/non-unicode-env/rmake.rs | 3 +- .../non-unicode-in-incremental-dir/rmake.rs | 6 +- tests/run-make/print-cfg/rmake.rs | 4 +- tests/run-make/print-to-output/rmake.rs | 4 +- tests/run-make/repr128-dwarf/rmake.rs | 5 +- tests/run-make/reset-codegen-1/rmake.rs | 14 ++- tests/run-make/resolve-rename/rmake.rs | 5 +- .../rustdoc-scrape-examples-remap/scrape.rs | 6 +- tests/run-make/rustdoc-test-args/rmake.rs | 6 +- tests/run-make/rustdoc-themes/rmake.rs | 12 +- .../rustdoc-verify-output-files/rmake.rs | 4 +- tests/run-make/wasm-custom-section/rmake.rs | 4 +- .../wasm-custom-sections-opt/rmake.rs | 6 +- .../run-make/wasm-export-all-symbols/rmake.rs | 4 +- tests/run-make/wasm-import-module/rmake.rs | 4 +- tests/run-make/wasm-panic-small/rmake.rs | 4 +- tests/run-make/wasm-spurious-import/rmake.rs | 4 +- .../wasm-stringify-ints-small/rmake.rs | 4 +- .../wasm-symbols-different-module/rmake.rs | 4 +- .../wasm-symbols-not-exported/rmake.rs | 4 +- .../wasm-symbols-not-imported/rmake.rs | 4 +- tests/run-make/windows-ws2_32/rmake.rs | 5 +- 36 files changed, 211 insertions(+), 108 deletions(-) create mode 100644 src/tools/run-make-support/src/fs_wrapper.rs diff --git a/src/tools/run-make-support/src/fs_wrapper.rs b/src/tools/run-make-support/src/fs_wrapper.rs new file mode 100644 index 00000000000..8a2bfce8b4a --- /dev/null +++ b/src/tools/run-make-support/src/fs_wrapper.rs @@ -0,0 +1,113 @@ +use std::fs; +use std::path::Path; + +/// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.. +#[track_caller] +pub fn remove_file>(path: P) { + fs::remove_file(path.as_ref()) + .expect(&format!("the file in path \"{}\" could not be removed", path.as_ref().display())); +} + +/// A wrapper around [`std::fs::copy`] which includes the file path in the panic message. +#[track_caller] +pub fn copy, Q: AsRef>(from: P, to: Q) { + fs::copy(from.as_ref(), to.as_ref()).expect(&format!( + "the file \"{}\" could not be copied over to \"{}\"", + from.as_ref().display(), + to.as_ref().display(), + )); +} + +/// A wrapper around [`std::fs::File::create`] which includes the file path in the panic message.. +#[track_caller] +pub fn create_file>(path: P) { + fs::File::create(path.as_ref()) + .expect(&format!("the file in path \"{}\" could not be created", path.as_ref().display())); +} + +/// A wrapper around [`std::fs::read`] which includes the file path in the panic message.. +#[track_caller] +pub fn read>(path: P) -> Vec { + fs::read(path.as_ref()) + .expect(&format!("the file in path \"{}\" could not be read", path.as_ref().display())) +} + +/// A wrapper around [`std::fs::read_to_string`] which includes the file path in the panic message.. +#[track_caller] +pub fn read_to_string>(path: P) -> String { + fs::read_to_string(path.as_ref()).expect(&format!( + "the file in path \"{}\" could not be read into a String", + path.as_ref().display() + )) +} + +/// A wrapper around [`std::fs::read_dir`] which includes the file path in the panic message.. +#[track_caller] +pub fn read_dir>(path: P) -> fs::ReadDir { + fs::read_dir(path.as_ref()) + .expect(&format!("the directory in path \"{}\" could not be read", path.as_ref().display())) +} + +/// A wrapper around [`std::fs::write`] which includes the file path in the panic message.. +#[track_caller] +pub fn write, C: AsRef<[u8]>>(path: P, contents: C) { + fs::write(path.as_ref(), contents.as_ref()).expect(&format!( + "the file in path \"{}\" could not be written to", + path.as_ref().display() + )); +} + +/// A wrapper around [`std::fs::remove_dir_all`] which includes the file path in the panic message.. +#[track_caller] +pub fn remove_dir_all>(path: P) { + fs::remove_dir_all(path.as_ref()).expect(&format!( + "the directory in path \"{}\" could not be removed alongside all its contents", + path.as_ref().display(), + )); +} + +/// A wrapper around [`std::fs::create_dir`] which includes the file path in the panic message.. +#[track_caller] +pub fn create_dir>(path: P) { + fs::create_dir(path.as_ref()).expect(&format!( + "the directory in path \"{}\" could not be created", + path.as_ref().display() + )); +} + +/// A wrapper around [`std::fs::create_dir_all`] which includes the file path in the panic message.. +#[track_caller] +pub fn create_dir_all>(path: P) { + fs::create_dir_all(path.as_ref()).expect(&format!( + "the directory (and all its parents) in path \"{}\" could not be created", + path.as_ref().display() + )); +} + +/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.. +#[track_caller] +pub fn metadata>(path: P) -> fs::Metadata { + fs::metadata(path.as_ref()).expect(&format!( + "the file's metadata in path \"{}\" could not be read", + path.as_ref().display() + )) +} + +/// A wrapper around [`std::fs::rename`] which includes the file path in the panic message. +#[track_caller] +pub fn rename, Q: AsRef>(from: P, to: Q) { + fs::rename(from.as_ref(), to.as_ref()).expect(&format!( + "the file \"{}\" could not be moved over to \"{}\"", + from.as_ref().display(), + to.as_ref().display(), + )); +} + +/// A wrapper around [`std::fs::set_permissions`] which includes the file path in the panic message. +#[track_caller] +pub fn set_permissions>(path: P, perm: fs::Permissions) { + fs::set_permissions(path.as_ref(), perm).expect(&format!( + "the file's permissions in path \"{}\" could not be changed", + path.as_ref().display() + )); +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index bf74d94f911..db6ca2b35db 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -8,6 +8,7 @@ pub mod clang; mod command; pub mod diff; mod drop_bomb; +pub mod fs_wrapper; pub mod llvm_readobj; pub mod run; pub mod rustc; @@ -148,7 +149,7 @@ pub fn dynamic_lib_extension() -> &'static str { } } -/// Construct a rust library (rlib) name. +/// Generate the name a rust library (rlib) would have. pub fn rust_lib_name(name: &str) -> String { format!("lib{name}.rlib") } @@ -223,15 +224,15 @@ pub fn copy_dir_all(src: impl AsRef, dst: impl AsRef) { fn copy_dir_all_inner(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { let dst = dst.as_ref(); if !dst.is_dir() { - fs::create_dir_all(&dst)?; + std::fs::create_dir_all(&dst)?; } - for entry in fs::read_dir(src)? { + for entry in std::fs::read_dir(src)? { let entry = entry?; let ty = entry.file_type()?; if ty.is_dir() { copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?; } else { - fs::copy(entry.path(), dst.join(entry.file_name()))?; + std::fs::copy(entry.path(), dst.join(entry.file_name()))?; } } Ok(()) @@ -250,13 +251,6 @@ pub fn copy_dir_all(src: impl AsRef, dst: impl AsRef) { /// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise. pub fn recursive_diff(dir1: impl AsRef, dir2: impl AsRef) { - fn read_file(path: &Path) -> Vec { - match fs::read(path) { - Ok(c) => c, - Err(e) => panic!("Failed to read `{}`: {:?}", path.display(), e), - } - } - let dir2 = dir2.as_ref(); read_dir(dir1, |entry_path| { let entry_name = entry_path.file_name().unwrap(); @@ -264,8 +258,8 @@ pub fn recursive_diff(dir1: impl AsRef, dir2: impl AsRef) { recursive_diff(&entry_path, &dir2.join(entry_name)); } else { let path2 = dir2.join(entry_name); - let file1 = read_file(&entry_path); - let file2 = read_file(&path2); + let file1 = fs_wrapper::read(&entry_path); + let file2 = fs_wrapper::read(&path2); // We don't use `assert_eq!` because they are `Vec`, so not great for display. // Why not using String? Because there might be minified files or even potentially @@ -281,7 +275,7 @@ pub fn recursive_diff(dir1: impl AsRef, dir2: impl AsRef) { } pub fn read_dir(dir: impl AsRef, callback: F) { - for entry in fs::read_dir(dir).unwrap() { + for entry in fs_wrapper::read_dir(dir) { callback(&entry.unwrap().path()); } } diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index f913aedcde7..b3227b79559 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; -use run_make_support::{aux_build, rustc, source_root}; +use run_make_support::{aux_build, fs_wrapper, rustc, source_root}; fn main() { aux_build().input("stable.rs").emit("metadata").run(); @@ -13,7 +13,7 @@ fn main() { let output = rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run(); - let version = std::fs::read_to_string(source_root().join("src/version")).unwrap(); + let version = fs_wrapper::read_to_string(source_root().join("src/version")); let expected_string = format!("stable since {}", version.trim()); output.assert_stderr_contains(expected_string); } diff --git a/tests/run-make/c-link-to-rust-dylib/rmake.rs b/tests/run-make/c-link-to-rust-dylib/rmake.rs index ec42e88032d..b8ea0b6b345 100644 --- a/tests/run-make/c-link-to-rust-dylib/rmake.rs +++ b/tests/run-make/c-link-to-rust-dylib/rmake.rs @@ -3,9 +3,9 @@ //@ ignore-cross-compile -use std::fs::remove_file; - -use run_make_support::{cc, cwd, dynamic_lib_extension, is_msvc, read_dir, run, run_fail, rustc}; +use run_make_support::{ + cc, cwd, dynamic_lib_extension, fs_wrapper, is_msvc, read_dir, run, run_fail, rustc, +}; fn main() { rustc().input("foo.rs").run(); @@ -28,7 +28,7 @@ fn main() { name.ends_with(".so") || name.ends_with(".dll") || name.ends_with(".dylib") }) { - remove_file(path).unwrap(); + fs_wrapper::remove_file(path); } }); run_fail("bar"); diff --git a/tests/run-make/c-link-to-rust-staticlib/rmake.rs b/tests/run-make/c-link-to-rust-staticlib/rmake.rs index ca28944a026..2edd36b9ec0 100644 --- a/tests/run-make/c-link-to-rust-staticlib/rmake.rs +++ b/tests/run-make/c-link-to-rust-staticlib/rmake.rs @@ -3,6 +3,7 @@ //@ ignore-cross-compile +use run_make_support::fs_wrapper::remove_file; use run_make_support::{cc, extra_c_flags, run, rustc, static_lib_name}; use std::fs; @@ -10,6 +11,6 @@ fn main() { rustc().input("foo.rs").run(); cc().input("bar.c").input(static_lib_name("foo")).out_exe("bar").args(&extra_c_flags()).run(); run("bar"); - fs::remove_file(static_lib_name("foo")); + remove_file(static_lib_name("foo")); run("bar"); } diff --git a/tests/run-make/cdylib/rmake.rs b/tests/run-make/cdylib/rmake.rs index 81166867b79..55ea227ab51 100644 --- a/tests/run-make/cdylib/rmake.rs +++ b/tests/run-make/cdylib/rmake.rs @@ -10,9 +10,7 @@ //@ ignore-cross-compile -use std::fs::remove_file; - -use run_make_support::{cc, cwd, dynamic_lib_name, is_msvc, run, rustc}; +use run_make_support::{cc, cwd, dynamic_lib_name, fs_wrapper, is_msvc, run, rustc}; fn main() { rustc().input("bar.rs").run(); @@ -25,7 +23,7 @@ fn main() { } run("foo"); - remove_file(dynamic_lib_name("foo")).unwrap(); + fs_wrapper::remove_file(dynamic_lib_name("foo")); rustc().input("foo.rs").arg("-Clto").run(); run("foo"); diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index a102e5b3390..10ff9cd282d 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -14,6 +14,7 @@ #![deny(warnings)] +use run_make_support::fs_wrapper::{read, read_dir}; use run_make_support::object::read::archive::ArchiveFile; use run_make_support::object::read::Object; use run_make_support::object::ObjectSection; @@ -55,8 +56,7 @@ fn main() { cmd.run(); let rlibs_path = target_dir.join(target).join("debug").join("deps"); - let compiler_builtins_rlib = std::fs::read_dir(rlibs_path) - .unwrap() + let compiler_builtins_rlib = read_dir(rlibs_path) .find_map(|e| { let path = e.unwrap().path(); let file_name = path.file_name().unwrap().to_str().unwrap(); @@ -70,7 +70,7 @@ fn main() { // rlib files are archives, where the archive members each a CGU, and we also have one called // lib.rmeta which is the encoded metadata. Each of the CGUs is an object file. - let data = std::fs::read(compiler_builtins_rlib).unwrap(); + let data = read(compiler_builtins_rlib); let mut defined_symbols = HashSet::new(); let mut undefined_relocations = HashSet::new(); diff --git a/tests/run-make/const-prop-lint/rmake.rs b/tests/run-make/const-prop-lint/rmake.rs index c35294f2f5a..d194f70d916 100644 --- a/tests/run-make/const-prop-lint/rmake.rs +++ b/tests/run-make/const-prop-lint/rmake.rs @@ -1,13 +1,11 @@ // Tests that const prop lints interrupting codegen don't leave `.o` files around. -use std::fs; - -use run_make_support::{cwd, rustc}; +use run_make_support::{cwd, fs_wrapper, rustc}; fn main() { rustc().input("input.rs").run_fail().assert_exit_code(1); - for entry in fs::read_dir(cwd()).unwrap() { + for entry in fs_wrapper::read_dir(cwd()) { let entry = entry.unwrap(); let path = entry.path(); diff --git a/tests/run-make/doctests-keep-binaries/rmake.rs b/tests/run-make/doctests-keep-binaries/rmake.rs index 5bc9480e4a3..e48c8a0cef3 100644 --- a/tests/run-make/doctests-keep-binaries/rmake.rs +++ b/tests/run-make/doctests-keep-binaries/rmake.rs @@ -1,13 +1,13 @@ // Check that valid binaries are persisted by running them, regardless of whether the // --run or --no-run option is used. +use run_make_support::fs_wrapper::{create_dir, remove_dir_all}; use run_make_support::{run, rustc, rustdoc}; -use std::fs::{create_dir, remove_dir_all}; use std::path::Path; fn setup_test_env(callback: F) { let out_dir = Path::new("doctests"); - create_dir(&out_dir).expect("failed to create doctests folder"); + create_dir(&out_dir); rustc().input("t.rs").crate_type("rlib").run(); callback(&out_dir, Path::new("libt.rlib")); remove_dir_all(out_dir); @@ -43,9 +43,9 @@ fn main() { check_generated_binaries(); }); // Behavior with --test-run-directory with relative paths. - setup_test_env(|_out_dir, extern_path| { + setup_test_env(|_out_dir, _extern_path| { let run_dir_path = Path::new("rundir"); - create_dir(&run_dir_path).expect("failed to create rundir folder"); + create_dir(&run_dir_path); rustdoc() .input("t.rs") diff --git a/tests/run-make/doctests-runtool/rmake.rs b/tests/run-make/doctests-runtool/rmake.rs index 6a7a931249e..5208730d336 100644 --- a/tests/run-make/doctests-runtool/rmake.rs +++ b/tests/run-make/doctests-runtool/rmake.rs @@ -1,12 +1,12 @@ // Tests behavior of rustdoc `--runtool`. +use run_make_support::fs_wrapper::{create_dir, remove_dir_all}; use run_make_support::{rustc, rustdoc}; -use std::fs::{create_dir, remove_dir_all}; use std::path::PathBuf; fn mkdir(name: &str) -> PathBuf { let dir = PathBuf::from(name); - create_dir(&dir).expect("failed to create doctests folder"); + create_dir(&dir); dir } diff --git a/tests/run-make/emit-named-files/rmake.rs b/tests/run-make/emit-named-files/rmake.rs index c4b7b9aebf6..79c3ee90c98 100644 --- a/tests/run-make/emit-named-files/rmake.rs +++ b/tests/run-make/emit-named-files/rmake.rs @@ -1,7 +1,6 @@ -use std::fs::create_dir; use std::path::Path; -use run_make_support::rustc; +use run_make_support::{fs_wrapper, rustc}; fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) { let out_file = out_dir.join(out_file); @@ -12,7 +11,7 @@ fn emit_and_check(out_dir: &Path, out_file: &str, format: &str) { fn main() { let out_dir = Path::new("emit"); - create_dir(&out_dir).unwrap(); + fs_wrapper::create_dir(&out_dir); emit_and_check(&out_dir, "libfoo.s", "asm"); emit_and_check(&out_dir, "libfoo.bc", "llvm-bc"); diff --git a/tests/run-make/incr-prev-body-beyond-eof/rmake.rs b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs index ccb1f95275e..e6d6ae95aaa 100644 --- a/tests/run-make/incr-prev-body-beyond-eof/rmake.rs +++ b/tests/run-make/incr-prev-body-beyond-eof/rmake.rs @@ -13,15 +13,14 @@ //@ ignore-nvptx64-nvidia-cuda // FIXME: can't find crate for `std` +use run_make_support::fs_wrapper as fs; use run_make_support::rustc; -use std::fs; fn main() { - // FIXME(Oneirical): Use run_make_support::fs_wrapper here. - fs::create_dir("src").unwrap(); - fs::create_dir("incr").unwrap(); - fs::copy("a.rs", "src/main.rs").unwrap(); + fs::create_dir("src"); + fs::create_dir("incr"); + fs::copy("a.rs", "src/main.rs"); rustc().incremental("incr").input("src/main.rs").run(); - fs::copy("b.rs", "src/main.rs").unwrap(); + fs::copy("b.rs", "src/main.rs"); rustc().incremental("incr").input("src/main.rs").run(); } diff --git a/tests/run-make/issue-107495-archive-permissions/rmake.rs b/tests/run-make/issue-107495-archive-permissions/rmake.rs index 72ceb10c591..ee281fe0a5f 100644 --- a/tests/run-make/issue-107495-archive-permissions/rmake.rs +++ b/tests/run-make/issue-107495-archive-permissions/rmake.rs @@ -3,8 +3,8 @@ #[cfg(unix)] extern crate libc; -use run_make_support::aux_build; -use std::fs; +use run_make_support::{aux_build, fs_wrapper}; + #[cfg(unix)] use std::os::unix::fs::PermissionsExt; use std::path::Path; @@ -20,7 +20,7 @@ fn main() { } fn verify(path: &Path) { - let perm = fs::metadata(path).unwrap().permissions(); + let perm = fs_wrapper::metadata(path).permissions(); assert!(!perm.readonly()); diff --git a/tests/run-make/mixing-formats/rmake.rs b/tests/run-make/mixing-formats/rmake.rs index 9cbff94f670..968d75b10f7 100644 --- a/tests/run-make/mixing-formats/rmake.rs +++ b/tests/run-make/mixing-formats/rmake.rs @@ -13,7 +13,6 @@ //@ ignore-cross-compile use run_make_support::{run_in_tmpdir, rustc}; -use std::fs; fn main() { run_in_tmpdir(|| { diff --git a/tests/run-make/non-unicode-env/rmake.rs b/tests/run-make/non-unicode-env/rmake.rs index ed40d7a6d7f..bffd9477f8f 100644 --- a/tests/run-make/non-unicode-env/rmake.rs +++ b/tests/run-make/non-unicode-env/rmake.rs @@ -1,3 +1,4 @@ +use run_make_support::fs_wrapper; use run_make_support::rustc; fn main() { @@ -6,6 +7,6 @@ fn main() { #[cfg(windows)] let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]); let output = rustc().input("non_unicode_env.rs").env("NON_UNICODE_VAR", non_unicode).run_fail(); - let expected = std::fs::read_to_string("non_unicode_env.stderr").unwrap(); + let expected = fs_wrapper::read_to_string("non_unicode_env.stderr"); output.assert_stderr_equals(expected); } diff --git a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs index ba1bd448743..895d9e00a2d 100644 --- a/tests/run-make/non-unicode-in-incremental-dir/rmake.rs +++ b/tests/run-make/non-unicode-in-incremental-dir/rmake.rs @@ -1,4 +1,4 @@ -use run_make_support::rustc; +use run_make_support::{fs_wrapper, rustc}; fn main() { #[cfg(unix)] @@ -17,8 +17,8 @@ fn main() { } let incr_dir = "incr-dir"; rustc().input("foo.rs").incremental(&incr_dir).run(); - for crate_dir in std::fs::read_dir(&incr_dir).unwrap() { - std::fs::create_dir(crate_dir.unwrap().path().join(&non_unicode)).unwrap(); + for crate_dir in fs_wrapper::read_dir(&incr_dir) { + fs_wrapper::create_dir(crate_dir.unwrap().path().join(&non_unicode)); } rustc().input("foo.rs").incremental(&incr_dir).run(); } diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index f382d952db4..d11eda1db2a 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -10,7 +10,7 @@ use std::ffi::OsString; use std::iter::FromIterator; use std::path::PathBuf; -use run_make_support::rustc; +use run_make_support::{fs_wrapper, rustc}; struct PrintCfg { target: &'static str, @@ -96,7 +96,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) { rustc().target(target).arg(print_arg).run(); - let output = std::fs::read_to_string(&tmp_path).unwrap(); + let output = fs_wrapper::read_to_string(&tmp_path); check_(&output, includes, disallow); } diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index ff5e6cacf4f..66f62a7015a 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -4,7 +4,7 @@ use std::ffi::OsString; use std::path::PathBuf; -use run_make_support::{rustc, target}; +use run_make_support::{fs_wrapper, rustc, target}; struct Option<'a> { target: &'a str, @@ -49,7 +49,7 @@ fn check(args: Option) { rustc().target(args.target).arg(print_arg).run(); - std::fs::read_to_string(&tmp_path).unwrap() + fs_wrapper::read_to_string(&tmp_path) }; check_(&stdout, args.includes); diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs index 27e32099396..a65cf234edf 100644 --- a/tests/run-make/repr128-dwarf/rmake.rs +++ b/tests/run-make/repr128-dwarf/rmake.rs @@ -3,7 +3,7 @@ use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian}; use object::{Object, ObjectSection}; -use run_make_support::{gimli, object, rustc}; +use run_make_support::{fs_wrapper, gimli, object, rustc}; use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; @@ -19,8 +19,7 @@ fn main() { .join("DWARF") .join("repr128"); let output = - std::fs::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output }) - .unwrap(); + fs_wrapper::read(if dsym_location.try_exists().unwrap() { dsym_location } else { output }); let obj = object::File::parse(output.as_slice()).unwrap(); let endian = if obj.is_little_endian() { RunTimeEndian::Little } else { RunTimeEndian::Big }; let dwarf = gimli::Dwarf::load(|section| -> Result<_, ()> { diff --git a/tests/run-make/reset-codegen-1/rmake.rs b/tests/run-make/reset-codegen-1/rmake.rs index c1385b2e015..19d42b3d6d5 100644 --- a/tests/run-make/reset-codegen-1/rmake.rs +++ b/tests/run-make/reset-codegen-1/rmake.rs @@ -7,8 +7,8 @@ //@ ignore-cross-compile -use run_make_support::rustc; -use std::fs; +use run_make_support::{bin_name, fs_wrapper, rustc}; +use std::path::Path; fn compile(output_file: &str, emit: Option<&str>) { let mut rustc = rustc(); @@ -28,11 +28,15 @@ fn main() { ("link-output", Some("link")), ("obj-output", Some("obj")), ("dep-output", Some("dep-info")), - ("multi-output", Some("asm,obj")), ]; for (output_file, emit) in flags { - fs::remove_file(output_file).unwrap_or_default(); + // In the None case, bin_name is required for successful Windows compilation. + let output_file = &bin_name(output_file); compile(output_file, emit); - fs::remove_file(output_file); + assert!(Path::new(output_file).is_file()); } + + compile("multi-output", Some("asm,obj")); + assert!(Path::new("multi-output.s").is_file()); + assert!(Path::new("multi-output.o").is_file()); } diff --git a/tests/run-make/resolve-rename/rmake.rs b/tests/run-make/resolve-rename/rmake.rs index a5f48c2bbcc..09bd4165b2a 100644 --- a/tests/run-make/resolve-rename/rmake.rs +++ b/tests/run-make/resolve-rename/rmake.rs @@ -5,11 +5,12 @@ // the renamed library. // See https://github.com/rust-lang/rust/pull/49253 +use run_make_support::fs_wrapper; use run_make_support::rustc; -use std::fs; + fn main() { rustc().extra_filename("-hash").input("foo.rs").run(); rustc().input("bar.rs").run(); - fs::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib").unwrap(); + fs_wrapper::rename("libfoo-hash.rlib", "libfoo-another-hash.rlib"); rustc().input("baz.rs").run(); } diff --git a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs index 6bf48a94a49..5d67ee2580f 100644 --- a/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs +++ b/tests/run-make/rustdoc-scrape-examples-remap/scrape.rs @@ -1,12 +1,10 @@ -use run_make_support::{htmldocck, rustc, rustdoc, source_root}; -use std::fs::read_dir; +use run_make_support::{fs_wrapper, htmldocck, rustc, rustdoc, source_root}; use std::path::Path; pub fn scrape(extra_args: &[&str]) { let out_dir = Path::new("rustdoc"); let crate_name = "foobar"; - let deps = read_dir("examples") - .unwrap() + let deps = fs_wrapper::read_dir("examples") .filter_map(|entry| entry.ok().map(|e| e.path())) .filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs")) .collect::>(); diff --git a/tests/run-make/rustdoc-test-args/rmake.rs b/tests/run-make/rustdoc-test-args/rmake.rs index 340ab022880..80eb768c14c 100644 --- a/tests/run-make/rustdoc-test-args/rmake.rs +++ b/tests/run-make/rustdoc-test-args/rmake.rs @@ -1,10 +1,10 @@ -use run_make_support::rustdoc; +use run_make_support::{fs_wrapper, rustdoc}; +use std::iter; use std::path::Path; -use std::{fs, iter}; fn generate_a_lot_of_cfgs(path: &Path) { let content = iter::repeat("--cfg=a\n").take(100_000).collect::(); - fs::write(path, content.as_bytes()).expect("failed to create args file"); + fs_wrapper::write(path, content.as_bytes()); } fn main() { diff --git a/tests/run-make/rustdoc-themes/rmake.rs b/tests/run-make/rustdoc-themes/rmake.rs index bfda2d97888..4174c0552be 100644 --- a/tests/run-make/rustdoc-themes/rmake.rs +++ b/tests/run-make/rustdoc-themes/rmake.rs @@ -1,15 +1,15 @@ // Test that rustdoc will properly load in a theme file and display it in the theme selector. -use run_make_support::{htmldocck, rustdoc, source_root}; +use run_make_support::{fs_wrapper, htmldocck, rustdoc, source_root}; use std::path::Path; fn main() { let out_dir = Path::new("rustdoc-themes"); let test_css = "test.css"; - let no_script = - std::fs::read_to_string(source_root().join("src/librustdoc/html/static/css/noscript.css")) - .unwrap(); + let no_script = fs_wrapper::read_to_string( + source_root().join("src/librustdoc/html/static/css/noscript.css"), + ); let mut test_content = String::new(); let mut found_begin_light = false; @@ -24,8 +24,8 @@ fn main() { } } assert!(!test_content.is_empty()); - std::fs::create_dir_all(&out_dir).unwrap(); - std::fs::write(&test_css, test_content).unwrap(); + fs_wrapper::create_dir_all(&out_dir); + fs_wrapper::write(&test_css, test_content); rustdoc().output(&out_dir).input("foo.rs").arg("--theme").arg(&test_css).run(); htmldocck().arg(out_dir).arg("foo.rs").run(); diff --git a/tests/run-make/rustdoc-verify-output-files/rmake.rs b/tests/run-make/rustdoc-verify-output-files/rmake.rs index d2d12ae83a2..1bf41c68114 100644 --- a/tests/run-make/rustdoc-verify-output-files/rmake.rs +++ b/tests/run-make/rustdoc-verify-output-files/rmake.rs @@ -1,4 +1,4 @@ -use std::fs::copy; +use run_make_support::fs_wrapper::copy; use std::path::{Path, PathBuf}; use run_make_support::{copy_dir_all, recursive_diff, rustdoc}; @@ -38,7 +38,7 @@ fn main() { assert!(out_dir.join("foobar.json").is_file()); // Copy first json output to check if it's exactly same after second compilation. - copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json")).unwrap(); + copy(out_dir.join("foobar.json"), tmp_out_dir.join("foobar.json")); // Generate json doc on the same output. generate_docs(&out_dir, JsonOutput::Yes); diff --git a/tests/run-make/wasm-custom-section/rmake.rs b/tests/run-make/wasm-custom-section/rmake.rs index 65f6d0bf347..e958f5086ac 100644 --- a/tests/run-make/wasm-custom-section/rmake.rs +++ b/tests/run-make/wasm-custom-section/rmake.rs @@ -1,13 +1,13 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::HashMap; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").run(); rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); - let file = std::fs::read("bar.wasm").unwrap(); + let file = fs_wrapper::read("bar.wasm"); let mut custom = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-custom-sections-opt/rmake.rs b/tests/run-make/wasm-custom-sections-opt/rmake.rs index 8e66caa6d68..346cffecc77 100644 --- a/tests/run-make/wasm-custom-sections-opt/rmake.rs +++ b/tests/run-make/wasm-custom-sections-opt/rmake.rs @@ -1,18 +1,18 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::HashMap; use std::path::Path; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").opt().run(); - verify(&Path::new("foo.wasm")); + verify(Path::new("foo.wasm")); } fn verify(path: &Path) { eprintln!("verify {path:?}"); - let file = std::fs::read(&path).unwrap(); + let file = fs_wrapper::read(&path); let mut custom = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-export-all-symbols/rmake.rs b/tests/run-make/wasm-export-all-symbols/rmake.rs index a6fec1fb0eb..41a2eaaafc3 100644 --- a/tests/run-make/wasm-export-all-symbols/rmake.rs +++ b/tests/run-make/wasm-export-all-symbols/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::HashMap; use std::path::Path; use wasmparser::ExternalKind::*; @@ -33,7 +33,7 @@ fn test(args: &[&str]) { fn verify_exports(path: &Path, exports: &[(&str, wasmparser::ExternalKind)]) { println!("verify {path:?}"); - let file = std::fs::read(path).unwrap(); + let file = fs_wrapper::read(path); let mut wasm_exports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { let payload = payload.unwrap(); diff --git a/tests/run-make/wasm-import-module/rmake.rs b/tests/run-make/wasm-import-module/rmake.rs index 0d3152ae99c..881242c59a2 100644 --- a/tests/run-make/wasm-import-module/rmake.rs +++ b/tests/run-make/wasm-import-module/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::HashMap; use wasmparser::TypeRef::Func; @@ -8,7 +8,7 @@ fn main() { rustc().input("foo.rs").target("wasm32-wasip1").run(); rustc().input("bar.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); - let file = std::fs::read("bar.wasm").unwrap(); + let file = fs_wrapper::read("bar.wasm"); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs index 304e5d04833..891cac4bc9f 100644 --- a/tests/run-make/wasm-panic-small/rmake.rs +++ b/tests/run-make/wasm-panic-small/rmake.rs @@ -1,7 +1,7 @@ //@ only-wasm32-wasip1 #![deny(warnings)] -use run_make_support::rustc; +use run_make_support::{fs_wrapper, rustc}; fn main() { test("a"); @@ -15,7 +15,7 @@ fn test(cfg: &str) { rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().cfg(cfg).run(); - let bytes = std::fs::read("foo.wasm").unwrap(); + let bytes = fs_wrapper::read("foo.wasm"); println!("{}", bytes.len()); assert!(bytes.len() < 40_000); } diff --git a/tests/run-make/wasm-spurious-import/rmake.rs b/tests/run-make/wasm-spurious-import/rmake.rs index eb28fdb2b01..88e4c83c94c 100644 --- a/tests/run-make/wasm-spurious-import/rmake.rs +++ b/tests/run-make/wasm-spurious-import/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::HashMap; fn main() { @@ -13,7 +13,7 @@ fn main() { .arg("-Copt-level=z") .run(); - let file = std::fs::read("main.wasm").unwrap(); + let file = fs_wrapper::read("main.wasm"); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-stringify-ints-small/rmake.rs b/tests/run-make/wasm-stringify-ints-small/rmake.rs index 8c51e26cc33..42e415b3a86 100644 --- a/tests/run-make/wasm-stringify-ints-small/rmake.rs +++ b/tests/run-make/wasm-stringify-ints-small/rmake.rs @@ -1,12 +1,12 @@ //@ only-wasm32-wasip1 #![deny(warnings)] -use run_make_support::rustc; +use run_make_support::{fs_wrapper, rustc}; fn main() { rustc().input("foo.rs").target("wasm32-wasip1").arg("-Clto").opt().run(); - let bytes = std::fs::read("foo.wasm").unwrap(); + let bytes = fs_wrapper::read("foo.wasm"); println!("{}", bytes.len()); assert!(bytes.len() < 50_000); } diff --git a/tests/run-make/wasm-symbols-different-module/rmake.rs b/tests/run-make/wasm-symbols-different-module/rmake.rs index 83970ef0b24..734f79d834a 100644 --- a/tests/run-make/wasm-symbols-different-module/rmake.rs +++ b/tests/run-make/wasm-symbols-different-module/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::collections::{HashMap, HashSet}; use std::path::Path; @@ -23,7 +23,7 @@ fn test(file: &str, args: &[&str], expected_imports: &[(&str, &[&str])]) { rustc().input(file).target("wasm32-wasip1").args(args).run(); - let file = std::fs::read(Path::new(file).with_extension("wasm")).unwrap(); + let file = fs_wrapper::read(Path::new(file).with_extension("wasm")); let mut imports = HashMap::new(); for payload in wasmparser::Parser::new(0).parse_all(&file) { diff --git a/tests/run-make/wasm-symbols-not-exported/rmake.rs b/tests/run-make/wasm-symbols-not-exported/rmake.rs index 54604f51a9e..4c817a6fd82 100644 --- a/tests/run-make/wasm-symbols-not-exported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-exported/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::path::Path; fn main() { @@ -17,7 +17,7 @@ fn main() { fn verify_symbols(path: &Path) { eprintln!("verify {path:?}"); - let file = std::fs::read(&path).unwrap(); + let file = fs_wrapper::read(&path); for payload in wasmparser::Parser::new(0).parse_all(&file) { let payload = payload.unwrap(); diff --git a/tests/run-make/wasm-symbols-not-imported/rmake.rs b/tests/run-make/wasm-symbols-not-imported/rmake.rs index 30408f078bc..58c9f9c6f45 100644 --- a/tests/run-make/wasm-symbols-not-imported/rmake.rs +++ b/tests/run-make/wasm-symbols-not-imported/rmake.rs @@ -1,6 +1,6 @@ //@ only-wasm32-wasip1 -use run_make_support::{rustc, wasmparser}; +use run_make_support::{fs_wrapper, rustc, wasmparser}; use std::path::Path; fn main() { @@ -16,7 +16,7 @@ fn main() { fn verify_symbols(path: &Path) { eprintln!("verify {path:?}"); - let file = std::fs::read(&path).unwrap(); + let file = fs_wrapper::read(&path); for payload in wasmparser::Parser::new(0).parse_all(&file) { let payload = payload.unwrap(); diff --git a/tests/run-make/windows-ws2_32/rmake.rs b/tests/run-make/windows-ws2_32/rmake.rs index b3c70c354b4..fde59452bc5 100644 --- a/tests/run-make/windows-ws2_32/rmake.rs +++ b/tests/run-make/windows-ws2_32/rmake.rs @@ -3,8 +3,7 @@ // Tests that WS2_32.dll is not unnecessarily linked, see issue #85441 use run_make_support::object::{self, read::Object}; -use run_make_support::rustc; -use std::fs; +use run_make_support::{fs_wrapper, rustc}; fn main() { rustc().input("empty.rs").run(); @@ -15,7 +14,7 @@ fn main() { } fn links_ws2_32(exe: &str) -> bool { - let binary_data = fs::read(exe).unwrap(); + let binary_data = fs_wrapper::read(exe); let file = object::File::parse(&*binary_data).unwrap(); for import in file.imports().unwrap() { if import.library().eq_ignore_ascii_case(b"WS2_32.dll") { From 26fa5c2c300f3c3a3ee3109c009bd4a6803a2a4c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 11 Jun 2024 10:13:07 +0200 Subject: [PATCH 091/153] Make issue-122805.rs big endian compatible Instead of not generating the function at all on big endian (which makes the CHECK lines fail), instead use to_le() on big endian, so that we essentially perform a bswap for both endiannesses. --- tests/codegen/issues/issue-122805.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/codegen/issues/issue-122805.rs b/tests/codegen/issues/issue-122805.rs index 6d108ada6dd..8e03c6c8884 100644 --- a/tests/codegen/issues/issue-122805.rs +++ b/tests/codegen/issues/issue-122805.rs @@ -39,17 +39,20 @@ // OPT3WINX64-NEXT: store <8 x i16> // CHECK-NEXT: ret void #[no_mangle] -#[cfg(target_endian = "little")] pub fn convert(value: [u16; 8]) -> [u8; 16] { + #[cfg(target_endian = "little")] + let bswap = u16::to_be; + #[cfg(target_endian = "big")] + let bswap = u16::to_le; let addr16 = [ - value[0].to_be(), - value[1].to_be(), - value[2].to_be(), - value[3].to_be(), - value[4].to_be(), - value[5].to_be(), - value[6].to_be(), - value[7].to_be(), + bswap(value[0]), + bswap(value[1]), + bswap(value[2]), + bswap(value[3]), + bswap(value[4]), + bswap(value[5]), + bswap(value[6]), + bswap(value[7]), ]; unsafe { core::mem::transmute::<_, [u8; 16]>(addr16) } } From be9e27e490c9fb9fa4b3c962daa1fbd3acbc58ee Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 10 Jun 2024 14:50:54 +0200 Subject: [PATCH 092/153] replace version placeholder --- compiler/rustc_feature/src/accepted.rs | 4 +- compiler/rustc_feature/src/unstable.rs | 10 +-- compiler/rustc_lint/src/shadowed_into_iter.rs | 4 +- library/alloc/src/boxed.rs | 24 +++---- .../alloc/src/collections/binary_heap/mod.rs | 7 +- library/alloc/src/ffi/c_str.rs | 2 +- library/alloc/src/rc.rs | 4 +- library/alloc/src/sync.rs | 6 +- library/alloc/src/vec/mod.rs | 2 +- library/core/src/cell.rs | 2 +- library/core/src/cell/lazy.rs | 14 ++-- library/core/src/net/ip_addr.rs | 20 +++--- library/core/src/option.rs | 2 +- library/core/src/prelude/common.rs | 2 +- library/core/src/ptr/non_null.rs | 66 +++++++++---------- library/core/src/slice/ascii.rs | 12 ++-- library/core/src/slice/iter.rs | 2 +- library/core/src/slice/mod.rs | 10 +-- library/core/src/str/mod.rs | 16 ++--- library/core/src/time.rs | 4 +- library/std/src/io/mod.rs | 2 +- library/std/src/prelude/common.rs | 2 +- library/std/src/sync/lazy_lock.rs | 22 +++---- library/std/src/sync/mod.rs | 2 +- 24 files changed, 119 insertions(+), 122 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 7c76392858c..ef141c7c25e 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -139,7 +139,7 @@ declare_features! ( /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477)), /// Allows users to provide classes for fenced code block using `class:classname`. - (accepted, custom_code_classes_in_docs, "CURRENT_RUSTC_VERSION", Some(79483)), + (accepted, custom_code_classes_in_docs, "1.80.0", Some(79483)), /// Allows using `#[debugger_visualizer]` attribute. (accepted, debugger_visualizer, "1.71.0", Some(95939)), /// Allows rustc to inject a default alloc_error_handler @@ -165,7 +165,7 @@ declare_features! ( /// Allows using `dyn Trait` as a syntax for trait objects. (accepted, dyn_trait, "1.27.0", Some(44662)), /// Allows `X..Y` patterns. - (accepted, exclusive_range_pattern, "CURRENT_RUSTC_VERSION", Some(37854)), + (accepted, exclusive_range_pattern, "1.80.0", Some(37854)), /// Allows integer match exhaustiveness checking (RFC 2591). (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907)), /// Allows explicit generic arguments specification with `impl Trait` present. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 2410019868a..2d13f430cfc 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -457,7 +457,7 @@ declare_features! ( /// Allows explicit tail calls via `become` expression. (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), /// Uses 2024 rules for matching `expr` fragments in macros. Also enables `expr_2021` fragment. - (incomplete, expr_fragment_specifier_2024, "CURRENT_RUSTC_VERSION", Some(123742)), + (incomplete, expr_fragment_specifier_2024, "1.80.0", Some(123742)), /// Allows using `efiapi`, `sysv64` and `win64` as calling convention /// for functions with varargs. (unstable, extended_varargs_abi_support, "1.65.0", Some(100189)), @@ -488,7 +488,7 @@ declare_features! ( /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), /// Allows registering static items globally, possibly across crates, to iterate over at runtime. - (unstable, global_registration, "CURRENT_RUSTC_VERSION", Some(125119)), + (unstable, global_registration, "1.80.0", Some(125119)), /// Allows using `..=X` as a patterns in slices. (unstable, half_open_range_patterns_in_slices, "1.66.0", Some(67264)), /// Allows `if let` guard in match arms. @@ -581,7 +581,7 @@ declare_features! ( (unstable, repr_simd, "1.4.0", Some(27731)), /// Allows enums like Result to be used across FFI, if T's niche value can /// be used to describe E or vise-versa. - (unstable, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)), + (unstable, result_ffi_guarantees, "1.80.0", Some(110503)), /// Allows bounding the return type of AFIT/RPITIT. (incomplete, return_type_notation, "1.70.0", Some(109417)), /// Allows `extern "rust-cold"`. @@ -623,9 +623,9 @@ declare_features! ( /// Allows unnamed fields of struct and union type (incomplete, unnamed_fields, "1.74.0", Some(49804)), /// Allows unsafe attributes. - (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)), + (unstable, unsafe_attributes, "1.80.0", Some(123757)), /// Allows unsafe on extern declarations and safety qualifiers over internal items. - (unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)), + (unstable, unsafe_extern_blocks, "1.80.0", Some(123743)), /// Allows unsized fn parameters. (unstable, unsized_fn_params, "1.49.0", Some(48055)), /// Allows unsized rvalues at arguments and parameters. diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index 41ec84faa78..85006421fdd 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -49,10 +49,10 @@ declare_lint! { /// /// ### Explanation /// - /// Since Rust CURRENT_RUSTC_VERSION, boxed slices implement `IntoIterator`. However, to avoid + /// Since Rust 1.80.0, boxed slices implement `IntoIterator`. However, to avoid /// breakage, `boxed_slice.into_iter()` in Rust 2015, 2018, and 2021 code will still /// behave as `(&boxed_slice).into_iter()`, returning an iterator over - /// references, just like in Rust CURRENT_RUSTC_VERSION and earlier. + /// references, just like in Rust 1.80.0 and earlier. /// This only applies to the method call syntax `boxed_slice.into_iter()`, not to /// any other syntax such as `for _ in boxed_slice` or `IntoIterator::into_iter(boxed_slice)`. pub BOXED_SLICE_INTO_ITER, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 21d00503001..2b5141585de 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -2123,23 +2123,23 @@ impl FromIterator for Box<[I]> { /// This implementation is required to make sure that the `Box<[I]>: IntoIterator` /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl !Iterator for Box<[I], A> {} /// This implementation is required to make sure that the `&Box<[I]>: IntoIterator` /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl<'a, I, A: Allocator> !Iterator for &'a Box<[I], A> {} /// This implementation is required to make sure that the `&mut Box<[I]>: IntoIterator` /// implementation doesn't overlap with `IntoIterator for T where T: Iterator` blanket. -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl<'a, I, A: Allocator> !Iterator for &'a mut Box<[I], A> {} // Note: the `#[rustc_skip_during_method_dispatch(boxed_slice)]` on `trait IntoIterator` // hides this implementation from explicit `.into_iter()` calls on editions < 2024, // so those calls will still resolve to the slice implementation, by reference. -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl IntoIterator for Box<[I], A> { type IntoIter = vec::IntoIter; type Item = I; @@ -2148,7 +2148,7 @@ impl IntoIterator for Box<[I], A> { } } -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl<'a, I, A: Allocator> IntoIterator for &'a Box<[I], A> { type IntoIter = slice::Iter<'a, I>; type Item = &'a I; @@ -2157,7 +2157,7 @@ impl<'a, I, A: Allocator> IntoIterator for &'a Box<[I], A> { } } -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl<'a, I, A: Allocator> IntoIterator for &'a mut Box<[I], A> { type IntoIter = slice::IterMut<'a, I>; type Item = &'a mut I; @@ -2167,7 +2167,7 @@ impl<'a, I, A: Allocator> IntoIterator for &'a mut Box<[I], A> { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl FromIterator for Box { fn from_iter>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() @@ -2175,7 +2175,7 @@ impl FromIterator for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl<'a> FromIterator<&'a char> for Box { fn from_iter>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() @@ -2183,7 +2183,7 @@ impl<'a> FromIterator<&'a char> for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl<'a> FromIterator<&'a str> for Box { fn from_iter>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() @@ -2191,7 +2191,7 @@ impl<'a> FromIterator<&'a str> for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl FromIterator for Box { fn from_iter>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() @@ -2199,7 +2199,7 @@ impl FromIterator for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl FromIterator> for Box { fn from_iter>>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() @@ -2207,7 +2207,7 @@ impl FromIterator> for Box { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "boxed_str_from_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_str_from_iter", since = "1.80.0")] impl<'a> FromIterator> for Box { fn from_iter>>(iter: T) -> Self { String::from_iter(iter).into_boxed_str() diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index a391141827e..af01db19139 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -440,10 +440,7 @@ impl BinaryHeap { /// heap.push(4); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable( - feature = "const_binary_heap_constructor", - since = "CURRENT_RUSTC_VERSION" - )] + #[rustc_const_stable(feature = "const_binary_heap_constructor", since = "1.80.0")] #[must_use] pub const fn new() -> BinaryHeap { BinaryHeap { data: vec![] } @@ -1224,7 +1221,7 @@ impl BinaryHeap { /// io::sink().write(heap.as_slice()).unwrap(); /// ``` #[must_use] - #[stable(feature = "binary_heap_as_slice", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "binary_heap_as_slice", since = "1.80.0")] pub fn as_slice(&self) -> &[T] { self.data.as_slice() } diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index b13af93d06c..f1eb195b884 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -911,7 +911,7 @@ impl From<&CStr> for Rc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Rc { /// Creates an empty CStr inside an Rc /// diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index f3a4803e0d4..c3561512c05 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2250,7 +2250,7 @@ impl Default for Rc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Rc { /// Creates an empty str inside an Rc /// @@ -2262,7 +2262,7 @@ impl Default for Rc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Rc<[T]> { /// Creates an empty `[T]` inside an Rc /// diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 5a4f9df614e..60e3918157e 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3405,7 +3405,7 @@ static STATIC_INNER_SLICE: SliceArcInnerForStatic = SliceArcInnerForStatic { }; #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Arc { /// Creates an empty str inside an Arc /// @@ -3420,7 +3420,7 @@ impl Default for Arc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Arc { /// Creates an empty CStr inside an Arc /// @@ -3439,7 +3439,7 @@ impl Default for Arc { } #[cfg(not(no_global_oom_handling))] -#[stable(feature = "more_rc_default_impls", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "more_rc_default_impls", since = "1.80.0")] impl Default for Arc<[T]> { /// Creates an empty `[T]` inside an Arc /// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index aa9b632cbed..743429d26db 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2649,7 +2649,7 @@ impl Vec<[T; N], A> { /// let mut flattened = vec.into_flattened(); /// assert_eq!(flattened.pop(), Some(6)); /// ``` - #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_flatten", since = "1.80.0")] pub fn into_flattened(self) -> Vec { let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc(); let (new_len, new_cap) = if T::IS_ZST { diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index efa0fd7b56c..b3189f14f9e 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -260,7 +260,7 @@ use crate::ptr::{self, NonNull}; mod lazy; mod once; -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] pub use lazy::LazyCell; #[stable(feature = "once_cell", since = "1.70.0")] pub use once::OnceCell; diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 80b85b95446..7c7130ec075 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -34,7 +34,7 @@ enum State { /// // 92 /// // 92 /// ``` -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] pub struct LazyCell T> { state: UnsafeCell>, } @@ -54,8 +54,8 @@ impl T> LazyCell { /// assert_eq!(&*lazy, "HELLO, WORLD!"); /// ``` #[inline] - #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_const_stable(feature = "lazy_cell", since = "1.80.0")] pub const fn new(f: F) -> LazyCell { LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } @@ -103,7 +103,7 @@ impl T> LazyCell { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "lazy_cell", since = "1.80.0")] pub fn force(this: &LazyCell) -> &T { // SAFETY: // This invalidates any mutable references to the data. The resulting @@ -167,7 +167,7 @@ impl LazyCell { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl T> Deref for LazyCell { type Target = T; #[inline] @@ -176,7 +176,7 @@ impl T> Deref for LazyCell { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl Default for LazyCell { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -185,7 +185,7 @@ impl Default for LazyCell { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl fmt::Debug for LazyCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyCell"); diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index e008215ebe9..b578756e46a 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -464,7 +464,7 @@ impl Ipv4Addr { /// /// assert_eq!(Ipv4Addr::BITS, 32); /// ``` - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ip_bits", since = "1.80.0")] pub const BITS: u32 = 32; /// Converts an IPv4 address into a `u32` representation using native byte order. @@ -492,8 +492,8 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x00), Ipv4Addr::from_bits(addr_bits)); /// /// ``` - #[rustc_const_stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] + #[stable(feature = "ip_bits", since = "1.80.0")] #[must_use] #[inline] pub const fn to_bits(self) -> u32 { @@ -512,8 +512,8 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::from(0x12345678); /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr); /// ``` - #[rustc_const_stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] + #[stable(feature = "ip_bits", since = "1.80.0")] #[must_use] #[inline] pub const fn from_bits(bits: u32) -> Ipv4Addr { @@ -1238,7 +1238,7 @@ impl Ipv6Addr { /// /// assert_eq!(Ipv6Addr::BITS, 128); /// ``` - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "ip_bits", since = "1.80.0")] pub const BITS: u32 = 128; /// Converts an IPv6 address into a `u128` representation using native byte order. @@ -1277,8 +1277,8 @@ impl Ipv6Addr { /// Ipv6Addr::from_bits(addr_bits)); /// /// ``` - #[rustc_const_stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] + #[stable(feature = "ip_bits", since = "1.80.0")] #[must_use] #[inline] pub const fn to_bits(self) -> u128 { @@ -1302,8 +1302,8 @@ impl Ipv6Addr { /// ), /// addr); /// ``` - #[rustc_const_stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] - #[stable(feature = "ip_bits", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")] + #[stable(feature = "ip_bits", since = "1.80.0")] #[must_use] #[inline] pub const fn from_bits(bits: u128) -> Ipv6Addr { diff --git a/library/core/src/option.rs b/library/core/src/option.rs index e253cfd2822..8ac2a8bb17f 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1724,7 +1724,7 @@ impl Option { /// assert_eq!(prev, Some(43)); /// ``` #[inline] - #[stable(feature = "option_take_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "option_take_if", since = "1.80.0")] pub fn take_if

(&mut self, predicate: P) -> Option where P: FnOnce(&mut T) -> bool, diff --git a/library/core/src/prelude/common.rs b/library/core/src/prelude/common.rs index 2a0331ef7b2..a6a1a055e29 100644 --- a/library/core/src/prelude/common.rs +++ b/library/core/src/prelude/common.rs @@ -14,7 +14,7 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use crate::mem::drop; -#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "size_of_prelude", since = "1.80.0")] #[doc(no_inline)] pub use crate::mem::{align_of, align_of_val, size_of, size_of_val}; diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index aac5c745d63..0504a0fc32f 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -525,8 +525,8 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[must_use = "returns a new pointer rather than modifying its argument"] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn offset(self, count: isize) -> Self where T: Sized, @@ -551,8 +551,8 @@ impl NonNull { #[must_use] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset` and `byte_offset` has // the same safety contract. @@ -611,8 +611,8 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[must_use = "returns a new pointer rather than modifying its argument"] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -638,8 +638,8 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_allow_const_fn_unstable(set_ptr_value)] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add` and `byte_add` has the same // safety contract. @@ -699,8 +699,8 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[must_use = "returns a new pointer rather than modifying its argument"] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_allow_const_fn_unstable(unchecked_neg)] pub const unsafe fn sub(self, count: usize) -> Self where @@ -732,8 +732,8 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_allow_const_fn_unstable(set_ptr_value)] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub` and `byte_sub` has the same // safety contract. @@ -847,8 +847,8 @@ impl NonNull { /// ``` #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn offset_from(self, origin: NonNull) -> isize where T: Sized, @@ -868,8 +868,8 @@ impl NonNull { /// ignoring the metadata. #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn byte_offset_from(self, origin: NonNull) -> isize { // SAFETY: the caller must uphold the safety contract for `byte_offset_from`. unsafe { self.pointer.byte_offset_from(origin.pointer) } @@ -958,8 +958,8 @@ impl NonNull { /// [`ptr::read`]: crate::ptr::read() #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn read(self) -> T where T: Sized, @@ -980,7 +980,7 @@ impl NonNull { /// [`ptr::read_volatile`]: crate::ptr::read_volatile() #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] pub unsafe fn read_volatile(self) -> T where T: Sized, @@ -999,8 +999,8 @@ impl NonNull { /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned() #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] + #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] pub const unsafe fn read_unaligned(self) -> T where T: Sized, @@ -1019,7 +1019,7 @@ impl NonNull { /// [`ptr::copy`]: crate::ptr::copy() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_to(self, dest: NonNull, count: usize) where @@ -1039,7 +1039,7 @@ impl NonNull { /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull, count: usize) where @@ -1059,7 +1059,7 @@ impl NonNull { /// [`ptr::copy`]: crate::ptr::copy() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_from(self, src: NonNull, count: usize) where @@ -1079,7 +1079,7 @@ impl NonNull { /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")] pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull, count: usize) where @@ -1095,7 +1095,7 @@ impl NonNull { /// /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place() #[inline(always)] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] pub unsafe fn drop_in_place(self) { // SAFETY: the caller must uphold the safety contract for `drop_in_place`. unsafe { ptr::drop_in_place(self.as_ptr()) } @@ -1109,7 +1109,7 @@ impl NonNull { /// [`ptr::write`]: crate::ptr::write() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write(self, val: T) where @@ -1128,7 +1128,7 @@ impl NonNull { #[inline(always)] #[doc(alias = "memset")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write_bytes(self, val: u8, count: usize) where @@ -1150,7 +1150,7 @@ impl NonNull { /// [`ptr::write_volatile`]: crate::ptr::write_volatile() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] pub unsafe fn write_volatile(self, val: T) where T: Sized, @@ -1169,7 +1169,7 @@ impl NonNull { /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned() #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")] pub const unsafe fn write_unaligned(self, val: T) where @@ -1186,7 +1186,7 @@ impl NonNull { /// /// [`ptr::replace`]: crate::ptr::replace() #[inline(always)] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] pub unsafe fn replace(self, src: T) -> T where T: Sized, @@ -1203,7 +1203,7 @@ impl NonNull { /// /// [`ptr::swap`]: crate::ptr::swap() #[inline(always)] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_swap", issue = "83163")] pub const unsafe fn swap(self, with: NonNull) where @@ -1255,7 +1255,7 @@ impl NonNull { /// ``` #[inline] #[must_use] - #[stable(feature = "non_null_convenience", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")] pub const fn align_offset(self, align: usize) -> usize where diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 19c91ba2eb9..19c7043a9e3 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -123,8 +123,8 @@ impl [u8] { /// assert_eq!(b" ".trim_ascii_start(), b""); /// assert_eq!(b"".trim_ascii_start(), b""); /// ``` - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii_start(&self) -> &[u8] { let mut bytes = self; @@ -152,8 +152,8 @@ impl [u8] { /// assert_eq!(b" ".trim_ascii_end(), b""); /// assert_eq!(b"".trim_ascii_end(), b""); /// ``` - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii_end(&self) -> &[u8] { let mut bytes = self; @@ -182,8 +182,8 @@ impl [u8] { /// assert_eq!(b" ".trim_ascii(), b""); /// assert_eq!(b"".trim_ascii(), b""); /// ``` - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 96fc87ab2e9..ca1920f9812 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -16,7 +16,7 @@ use crate::ptr::{self, without_provenance, without_provenance_mut, NonNull}; use super::{from_raw_parts, from_raw_parts_mut}; -#[stable(feature = "boxed_slice_into_iter", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "boxed_slice_into_iter", since = "1.80.0")] impl !Iterator for [T] {} #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 503107c7480..17b4f9ece9d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2082,8 +2082,8 @@ impl [T] { /// /// assert_eq!(None, v.split_at_checked(7)); /// ``` - #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "split_at_checked", since = "1.80.0")] + #[rustc_const_stable(feature = "split_at_checked", since = "1.80.0")] #[inline] #[must_use] pub const fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])> { @@ -2121,7 +2121,7 @@ impl [T] { /// /// assert_eq!(None, v.split_at_mut_checked(7)); /// ``` - #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "split_at_checked", since = "1.80.0")] #[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")] #[inline] #[must_use] @@ -4544,7 +4544,7 @@ impl [[T; N]] { /// let empty_slice_of_arrays: &[[u32; 10]] = &[]; /// assert!(empty_slice_of_arrays.as_flattened().is_empty()); /// ``` - #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_flatten", since = "1.80.0")] #[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")] pub const fn as_flattened(&self) -> &[T] { let len = if T::IS_ZST { @@ -4581,7 +4581,7 @@ impl [[T; N]] { /// add_5_to_all(array.as_flattened_mut()); /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]); /// ``` - #[stable(feature = "slice_flatten", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "slice_flatten", since = "1.80.0")] pub fn as_flattened_mut(&mut self) -> &mut [T] { let len = if T::IS_ZST { self.len().checked_mul(N).expect("slice len overflow") diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index edda4d1b687..d860ad20d3d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -732,7 +732,7 @@ impl str { /// ``` #[inline] #[must_use] - #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "split_at_checked", since = "1.80.0")] pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { @@ -772,7 +772,7 @@ impl str { /// ``` #[inline] #[must_use] - #[stable(feature = "split_at_checked", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "split_at_checked", since = "1.80.0")] pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { @@ -2546,8 +2546,8 @@ impl str { /// ``` #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii_start(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2571,8 +2571,8 @@ impl str { /// ``` #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii_end(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2597,8 +2597,8 @@ impl str { /// ``` #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] - #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "1.80.0")] #[inline] pub const fn trim_ascii(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate diff --git a/library/core/src/time.rs b/library/core/src/time.rs index dfa58e4f46d..bc0fa3f0968 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -1090,7 +1090,7 @@ impl Duration { /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` - #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "div_duration", since = "1.80.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1111,7 +1111,7 @@ impl Duration { /// let dur2 = Duration::new(5, 400_000_000); /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` - #[stable(feature = "div_duration", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "div_duration", since = "1.80.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index f55ec1588f9..97b72f9664b 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2058,7 +2058,7 @@ pub trait Seek { /// ``` /// /// [`BufReader`]: crate::io::BufReader - #[stable(feature = "seek_seek_relative", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "seek_seek_relative", since = "1.80.0")] fn seek_relative(&mut self, offset: i64) -> Result<()> { self.seek(SeekFrom::Current(offset))?; Ok(()) diff --git a/library/std/src/prelude/common.rs b/library/std/src/prelude/common.rs index ceee3e33c3e..055ab7eb6d9 100644 --- a/library/std/src/prelude/common.rs +++ b/library/std/src/prelude/common.rs @@ -14,7 +14,7 @@ pub use crate::ops::{Drop, Fn, FnMut, FnOnce}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use crate::mem::drop; -#[stable(feature = "size_of_prelude", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "size_of_prelude", since = "1.80.0")] #[doc(no_inline)] pub use crate::mem::{align_of, align_of_val, size_of, size_of_val}; diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 7a2eed93dd4..b70c041fa42 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -64,7 +64,7 @@ union Data { /// println!("{}", *data.number); /// } /// ``` -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] pub struct LazyLock T> { once: Once, data: UnsafeCell>, @@ -85,8 +85,8 @@ impl T> LazyLock { /// assert_eq!(&*lazy, "HELLO, WORLD!"); /// ``` #[inline] - #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_const_stable(feature = "lazy_cell", since = "1.80.0")] pub const fn new(f: F) -> LazyLock { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } @@ -152,7 +152,7 @@ impl T> LazyLock { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "lazy_cell", since = "1.80.0")] pub fn force(this: &LazyLock) -> &T { this.once.call_once(|| { // SAFETY: `call_once` only runs this closure once, ever. @@ -188,7 +188,7 @@ impl LazyLock { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { @@ -201,7 +201,7 @@ impl Drop for LazyLock { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl T> Deref for LazyLock { type Target = T; @@ -216,7 +216,7 @@ impl T> Deref for LazyLock { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl Default for LazyLock { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -225,7 +225,7 @@ impl Default for LazyLock { } } -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl fmt::Debug for LazyLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_tuple("LazyLock"); @@ -239,13 +239,13 @@ impl fmt::Debug for LazyLock { // We never create a `&F` from a `&LazyLock` so it is fine // to not impl `Sync` for `F`. -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] unsafe impl Sync for LazyLock {} // auto-derived `Send` impl is OK. -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl RefUnwindSafe for LazyLock {} -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] impl UnwindSafe for LazyLock {} #[cfg(test)] diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 70e8f5f90c6..2a13b1a8ae2 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -182,7 +182,7 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "lazy_cell", since = "1.80.0")] pub use self::lazy_lock::LazyLock; #[stable(feature = "once_cell", since = "1.70.0")] pub use self::once_lock::OnceLock; From cd2ed56502b65a56c3ef4b518e3f977d2380afaa Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 11 Jun 2024 15:08:34 +0200 Subject: [PATCH 093/153] remove cfg(bootstrap) --- library/alloc/src/boxed.rs | 3 +- library/alloc/src/lib.rs | 1 - library/core/src/future/async_drop.rs | 1 - library/core/src/future/future.rs | 2 +- library/core/src/intrinsics.rs | 11 +++-- library/core/src/intrinsics/simd.rs | 1 - library/core/src/iter/traits/collect.rs | 3 +- library/core/src/num/int_macros.rs | 18 ++++----- library/core/src/ops/async_function.rs | 8 ++-- library/core/src/ptr/metadata.rs | 40 +------------------ library/std/src/env.rs | 16 -------- src/bootstrap/src/core/build_steps/compile.rs | 5 +-- src/bootstrap/src/core/build_steps/tool.rs | 5 +-- 13 files changed, 22 insertions(+), 92 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2b5141585de..01a954ed75b 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -145,8 +145,7 @@ //! to `into_iter()` for boxed slices will defer to the slice implementation on editions before //! 2024: //! -#![cfg_attr(bootstrap, doc = "```rust,edition2021,ignore")] -#![cfg_attr(not(bootstrap), doc = "```rust,edition2021")] +//! ```rust,edition2021 //! // Rust 2015, 2018, and 2021: //! //! # #![allow(boxed_slice_into_iter)] // override our `deny(warnings)` diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 4749b8880fb..895d1b8d59f 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -165,7 +165,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(exclusive_range_pattern))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs index 25138c445c4..5c3a0a98b10 100644 --- a/library/core/src/future/async_drop.rs +++ b/library/core/src/future/async_drop.rs @@ -256,7 +256,6 @@ async unsafe fn either, M: IntoFuture, T } } -#[cfg(not(bootstrap))] #[lang = "async_drop_deferred_drop_in_place"] async unsafe fn deferred_drop_in_place(to_drop: *mut T) { // SAFETY: same safety requirements as with drop_in_place (implied by diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index 86963b548b9..c80cfdcebf7 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -35,7 +35,7 @@ use crate::task::{Context, Poll}; pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] - #[cfg_attr(not(bootstrap), lang = "future_output")] + #[lang = "future_output"] type Output; /// Attempt to resolve the future to a final value, registering diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 28397fe4619..cd3534ecb12 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -986,7 +986,7 @@ pub const unsafe fn assume(b: bool) { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_nounwind] -#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +#[miri::intrinsic_fallback_is_spec] pub const fn likely(b: bool) -> bool { b } @@ -1006,7 +1006,7 @@ pub const fn likely(b: bool) -> bool { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_intrinsic] #[rustc_nounwind] -#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +#[miri::intrinsic_fallback_is_spec] pub const fn unlikely(b: bool) -> bool { b } @@ -2482,7 +2482,7 @@ extern "rust-intrinsic" { #[rustc_nounwind] #[rustc_do_not_const_check] #[inline] -#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +#[miri::intrinsic_fallback_is_spec] pub const fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8 { (ptr == other) as u8 } @@ -2747,7 +2747,7 @@ pub const fn ub_checks() -> bool { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[rustc_intrinsic] -#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +#[miri::intrinsic_fallback_is_spec] pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 { // const eval overrides this function, but runtime code for now just returns null pointers. // See . @@ -2768,7 +2768,7 @@ pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 { #[unstable(feature = "core_intrinsics", issue = "none")] #[rustc_nounwind] #[rustc_intrinsic] -#[cfg_attr(not(bootstrap), miri::intrinsic_fallback_is_spec)] +#[miri::intrinsic_fallback_is_spec] pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) { // Runtime NOP } @@ -2828,7 +2828,6 @@ impl AggregateRawPtr<*mut T> for *mut P { #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] -#[cfg(not(bootstrap))] pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { // To implement a fallback we'd have to assume the layout of the pointer, // but the whole point of this intrinsic is that we shouldn't do that. diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 820f6b2cddc..4be5e62ea5b 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -573,7 +573,6 @@ extern "rust-intrinsic" { /// /// `T` must be a vector of integers. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn simd_ctpop(x: T) -> T; /// Count the trailing zeros of each element. diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index d9d860c7b6c..61a45789013 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -311,8 +311,7 @@ where label = "`{Self}` is not an iterator", message = "`{Self}` is not an iterator" )] -#[cfg_attr(bootstrap, rustc_skip_array_during_method_dispatch)] -#[cfg_attr(not(bootstrap), rustc_skip_during_method_dispatch(array, boxed_slice))] +#[rustc_skip_during_method_dispatch(array, boxed_slice)] #[stable(feature = "rust1", since = "1.0.0")] pub trait IntoIterator { /// The type of the elements being iterated over. diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 96510ee4dca..55bb6166f10 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1165,17 +1165,13 @@ macro_rules! int_impl { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { - // ICE resolved by #125184 isn't in bootstrap compiler - #[cfg(not(bootstrap))] - { - assert_unsafe_precondition!( - check_language_ub, - concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), - ( - lhs: $SelfT = self, - ) => !lhs.overflowing_neg().1, - ); - } + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"), + ( + lhs: $SelfT = self, + ) => !lhs.overflowing_neg().1, + ); // SAFETY: this is guaranteed to be safe by the caller. unsafe { diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index f4e9d1a63ac..48d1042d9df 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -26,7 +26,7 @@ pub trait AsyncFn: AsyncFnMut { pub trait AsyncFnMut: AsyncFnOnce { /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`]. #[unstable(feature = "async_fn_traits", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "call_ref_future")] + #[lang = "call_ref_future"] type CallRefFuture<'a>: Future where Self: 'a; @@ -47,12 +47,12 @@ pub trait AsyncFnMut: AsyncFnOnce { pub trait AsyncFnOnce { /// Future returned by [`AsyncFnOnce::async_call_once`]. #[unstable(feature = "async_fn_traits", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "call_once_future")] + #[lang = "call_once_future"] type CallOnceFuture: Future; /// Output type of the called closure's future. #[unstable(feature = "async_fn_traits", issue = "none")] - #[cfg_attr(not(bootstrap), lang = "async_fn_once_output")] + #[lang = "async_fn_once_output"] type Output; /// Call the [`AsyncFnOnce`], returning a future which may move out of the called closure. @@ -146,7 +146,7 @@ mod internal_implementation_detail { // `for<'env> fn() -> (&'env T, ...)`. This allows us to represent the binder // of the closure's self-capture, and these upvar types will be instantiated with // the `'closure_env` region provided to the associated type. - #[cfg_attr(not(bootstrap), lang = "async_fn_kind_upvars")] + #[lang = "async_fn_kind_upvars"] type Upvars<'closure_env, Inputs, Upvars, BorrowedUpvarsAsFnPtr>; } } diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 78fe0c5add5..eb86bf66206 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -3,7 +3,6 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::intrinsics::aggregate_raw_ptr; -#[cfg(not(bootstrap))] use crate::intrinsics::ptr_metadata; use crate::marker::Freeze; @@ -96,17 +95,7 @@ pub trait Thin = Pointee; #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")] #[inline] pub const fn metadata(ptr: *const T) -> ::Metadata { - #[cfg(bootstrap)] - { - // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T - // and PtrComponents have the same memory layouts. Only std can make this - // guarantee. - unsafe { PtrRepr { const_ptr: ptr }.components.metadata } - } - #[cfg(not(bootstrap))] - { - ptr_metadata(ptr) - } + ptr_metadata(ptr) } /// Forms a (possibly-wide) raw pointer from a data pointer and metadata. @@ -140,33 +129,6 @@ pub const fn from_raw_parts_mut( aggregate_raw_ptr(data_pointer, metadata) } -#[repr(C)] -#[cfg(bootstrap)] -union PtrRepr { - const_ptr: *const T, - mut_ptr: *mut T, - components: PtrComponents, -} - -#[repr(C)] -#[cfg(bootstrap)] -struct PtrComponents { - data_pointer: *const (), - metadata: ::Metadata, -} - -// Manual impl needed to avoid `T: Copy` bound. -#[cfg(bootstrap)] -impl Copy for PtrComponents {} - -// Manual impl needed to avoid `T: Clone` bound. -#[cfg(bootstrap)] -impl Clone for PtrComponents { - fn clone(&self) -> Self { - *self - } -} - /// The metadata for a `Dyn = dyn SomeTrait` trait object type. /// /// It is a pointer to a vtable (virtual call table) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 4d649f8a6f1..b7b817d97c9 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -361,20 +361,12 @@ impl Error for VarError { /// } /// assert_eq!(env::var(key), Ok("VALUE".to_string())); /// ``` -#[cfg(not(bootstrap))] #[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] pub unsafe fn set_var, V: AsRef>(key: K, value: V) { _set_var(key.as_ref(), value.as_ref()) } -#[cfg(bootstrap)] -#[allow(missing_docs)] -#[stable(feature = "env", since = "1.0.0")] -pub fn set_var, V: AsRef>(key: K, value: V) { - unsafe { _set_var(key.as_ref(), value.as_ref()) } -} - unsafe fn _set_var(key: &OsStr, value: &OsStr) { os_imp::setenv(key, value).unwrap_or_else(|e| { panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}") @@ -434,20 +426,12 @@ unsafe fn _set_var(key: &OsStr, value: &OsStr) { /// } /// assert!(env::var(key).is_err()); /// ``` -#[cfg(not(bootstrap))] #[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] pub unsafe fn remove_var>(key: K) { _remove_var(key.as_ref()) } -#[cfg(bootstrap)] -#[allow(missing_docs)] -#[stable(feature = "env", since = "1.0.0")] -pub fn remove_var>(key: K) { - unsafe { _remove_var(key.as_ref()) } -} - unsafe fn _remove_var(key: &OsStr) { os_imp::unsetenv(key) .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}")) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 66692a2a2cb..a3a4d552c63 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1008,10 +1008,7 @@ pub fn rustc_cargo( // If the rustc output is piped to e.g. `head -n1` we want the process to be // killed, rather than having an error bubble up and cause a panic. - // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it. - if compiler.stage != 0 { - cargo.rustflag("-Zon-broken-pipe=kill"); - } + cargo.rustflag("-Zon-broken-pipe=kill"); // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary // and may just be a time sink. diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 9df4698f21f..47bed6269db 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -521,10 +521,7 @@ impl Step for Rustdoc { // If the rustdoc output is piped to e.g. `head -n1` we want the process // to be killed, rather than having an error bubble up and cause a // panic. - // FIXME: Synthetic #[cfg(bootstrap)]. Remove when the bootstrap compiler supports it. - if build_compiler.stage > 0 { - cargo.rustflag("-Zon-broken-pipe=kill"); - } + cargo.rustflag("-Zon-broken-pipe=kill"); let _guard = builder.msg_tool( Kind::Build, From b595e1977a6a21f9b7608e3b81e3844dea52a1f8 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 11 Jun 2024 15:43:02 +0200 Subject: [PATCH 094/153] cargo -Zcheck-cfg is now stable --- src/bootstrap/src/core/builder.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 12d2bb18ab7..d9e4cbae17d 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1566,7 +1566,6 @@ impl<'a> Builder<'a> { // features but cargo isn't involved in the #[path] process and so cannot pass the // complete list of features, so for that reason we don't enable checking of // features for std crates. - cargo.arg("-Zcheck-cfg"); if mode == Mode::Std { rustflags.arg("--check-cfg=cfg(feature,values(any()))"); } From 751143ef4031d06e718bcf859f1b3139716d043b Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 11 Jun 2024 17:12:20 +0000 Subject: [PATCH 095/153] set_env: State the conclusion upfront --- library/std/src/env.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 4d649f8a6f1..295e782639b 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -323,8 +323,10 @@ impl Error for VarError { /// This function is also always safe to call on Windows, in single-threaded /// and multi-threaded programs. /// -/// In multi-threaded programs on other operating systems, we strongly suggest -/// not using `set_var` or `remove_var` at all. The exact requirement is: you +/// In multi-threaded programs on other operating systems, the only safe option is +/// to not use `set_var` or `remove_var` at all. +/// +/// The exact requirement is: you /// must ensure that there are no other threads concurrently writing or /// *reading*(!) the environment through functions or global variables other /// than the ones in this module. The problem is that these operating systems @@ -390,8 +392,10 @@ unsafe fn _set_var(key: &OsStr, value: &OsStr) { /// This function is also always safe to call on Windows, in single-threaded /// and multi-threaded programs. /// -/// In multi-threaded programs on other operating systems, we strongly suggest -/// not using `set_var` or `remove_var` at all. The exact requirement is: you +/// In multi-threaded programs on other operating systems, the only safe option is +/// to not use `set_var` or `remove_var` at all. +/// +/// The exact requirement is: you /// must ensure that there are no other threads concurrently writing or /// *reading*(!) the environment through functions or global variables other /// than the ones in this module. The problem is that these operating systems From bbc50376b0f44c70e3a17a2db5cd16f3ad4f04f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 11 Jun 2024 16:30:47 +0000 Subject: [PATCH 096/153] ensure the self-contained linker is only enabled on nightly/dev --- src/bootstrap/src/core/build_steps/compile.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 66692a2a2cb..b16f3e5bd81 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1137,7 +1137,9 @@ pub fn rustc_cargo_env( } // Enable rustc's env var for `rust-lld` when requested. - if builder.config.lld_enabled { + if builder.config.lld_enabled + && (builder.config.channel == "dev" || builder.config.channel == "nightly") + { cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1"); } From 4038010436d18725dd5c6c8cd91f9f1fca617373 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 09:48:12 -0400 Subject: [PATCH 097/153] Get rid of PredicateObligations --- compiler/rustc_borrowck/src/type_check/relate_tys.rs | 4 ++-- compiler/rustc_hir_typeck/src/coercion.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 8 +++----- compiler/rustc_infer/src/infer/relate/combine.rs | 8 ++++---- compiler/rustc_infer/src/infer/relate/glb.rs | 4 ++-- compiler/rustc_infer/src/infer/relate/lub.rs | 4 ++-- compiler/rustc_infer/src/infer/relate/type_relating.rs | 4 ++-- compiler/rustc_infer/src/traits/mod.rs | 2 -- compiler/rustc_trait_selection/src/traits/coherence.rs | 6 ++---- .../rustc_trait_selection/src/traits/query/type_op/mod.rs | 4 ++-- 10 files changed, 20 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 2c34fc583c8..cd51d73ba55 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -3,7 +3,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; use rustc_infer::infer::NllRegionVariableOrigin; -use rustc_infer::traits::{Obligation, PredicateObligations}; +use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; @@ -560,7 +560,7 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx ); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op( self.locations, self.category, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index dbaa6e398c8..e54a07786cd 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -113,7 +113,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec( adj: Vec>, target: Ty<'tcx>, - obligations: traits::PredicateObligations<'tcx>, + obligations: Vec>, ) -> CoerceResult<'tcx> { Ok(InferOk { value: (adj, target), obligations }) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c606ab808ef..98a795e67f8 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -9,9 +9,7 @@ pub use SubregionOrigin::*; pub use ValuePairs::*; use crate::infer::relate::{CombineFields, RelateResult}; -use crate::traits::{ - self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, -}; +use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; use error_reporting::TypeErrCtxt; use free_regions::RegionRelations; use lexical_region_resolve::LexicalRegionResolutions; @@ -68,7 +66,7 @@ pub mod type_variable; #[derive(Debug)] pub struct InferOk<'tcx, T> { pub value: T, - pub obligations: PredicateObligations<'tcx>, + pub obligations: Vec>, } pub type InferResult<'tcx, T> = Result, TypeError<'tcx>>; @@ -748,7 +746,7 @@ impl<'tcx, T> InferOk<'tcx, T> { } impl<'tcx> InferOk<'tcx, ()> { - pub fn into_obligations(self) -> PredicateObligations<'tcx> { + pub fn into_obligations(self) -> Vec> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 30cb2bab900..e62ef5d4ea4 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -25,7 +25,7 @@ use super::StructurallyRelateAliases; use super::{RelateResult, TypeRelation}; use crate::infer::relate; use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; -use crate::traits::{Obligation, PredicateObligations}; +use crate::traits::{Obligation, PredicateObligation}; use rustc_middle::bug; use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -38,7 +38,7 @@ pub struct CombineFields<'infcx, 'tcx> { pub infcx: &'infcx InferCtxt<'tcx>, pub trace: TypeTrace<'tcx>, pub param_env: ty::ParamEnv<'tcx>, - pub obligations: PredicateObligations<'tcx>, + pub obligations: Vec>, pub define_opaque_types: DefineOpaqueTypes, } @@ -290,7 +290,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { Glb::new(self) } - pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + pub fn register_obligations(&mut self, obligations: Vec>) { self.obligations.extend(obligations); } @@ -315,7 +315,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { fn structurally_relate_aliases(&self) -> StructurallyRelateAliases; /// Register obligations that must hold in order for this relation to hold - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>); + fn register_obligations(&mut self, obligations: Vec>); /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 98e8f07c7a2..ca772b349d2 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -8,7 +8,7 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligations}; +use crate::traits::{ObligationCause, PredicateObligation}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -147,7 +147,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations); } diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 28dbaa94f95..0b9de8de001 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -4,7 +4,7 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligations}; +use crate::traits::{ObligationCause, PredicateObligation}; use super::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; @@ -147,7 +147,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations) } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index fd0bc9f44f7..447e4d6bfd8 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,7 +1,7 @@ use super::combine::CombineFields; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; -use crate::traits::{Obligation, PredicateObligations}; +use crate::traits::{Obligation, PredicateObligation}; use super::{ relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate, @@ -318,7 +318,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { + fn register_obligations(&mut self, obligations: Vec>) { self.fields.register_obligations(obligations); } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index ca6c6570e07..556b3bd063d 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -114,8 +114,6 @@ impl<'tcx> PolyTraitObligation<'tcx> { #[cfg(target_pointer_width = "64")] rustc_data_structures::static_assert_size!(PredicateObligation<'_>, 48); -pub type PredicateObligations<'tcx> = Vec>; - pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>; /// A callback that can be provided to `inspect_typeck`. Invoked on evaluation diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 1ef2f26cd09..fc5c71252e1 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -12,9 +12,7 @@ use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::NormalizeExt; use crate::traits::SkipLeakCheck; use crate::traits::{util, FulfillmentErrorCode}; -use crate::traits::{ - Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext, -}; +use crate::traits::{Obligation, ObligationCause, PredicateObligation, SelectionContext}; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; @@ -305,7 +303,7 @@ fn equate_impl_headers<'tcx>( param_env: ty::ParamEnv<'tcx>, impl1: &ty::ImplHeader<'tcx>, impl2: &ty::ImplHeader<'tcx>, -) -> Option> { +) -> Option>> { let result = match (impl1.trait_ref, impl2.trait_ref) { (Some(impl1_ref), Some(impl2_ref)) => infcx diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index ae4cdb9258e..c1b1bfd300b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -5,7 +5,7 @@ use crate::infer::{InferCtxt, InferOk}; use crate::traits::{ObligationCause, ObligationCtxt}; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; -use rustc_infer::traits::PredicateObligations; +use rustc_infer::traits::PredicateObligation; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; @@ -103,7 +103,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't ( Self::QueryResponse, Option>>, - PredicateObligations<'tcx>, + Vec>, Certainty, ), NoSolution, From 44a6f72a725d1e274d734473c95f95caa5c6fbb6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 10:05:47 -0400 Subject: [PATCH 098/153] Make ObligationEmittingRelation deal with Goals only --- .../src/type_check/relate_tys.rs | 38 ++++++++++---- compiler/rustc_infer/src/infer/at.rs | 52 ++++++++++--------- .../rustc_infer/src/infer/relate/combine.rs | 35 ++++++++++--- compiler/rustc_infer/src/infer/relate/glb.rs | 10 ++-- .../rustc_infer/src/infer/relate/lattice.rs | 9 +++- compiler/rustc_infer/src/infer/relate/lub.rs | 10 ++-- .../src/infer/relate/type_relating.rs | 25 +++++---- 7 files changed, 119 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index cd51d73ba55..a87b9f7a23d 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -3,7 +3,8 @@ use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; use rustc_infer::infer::NllRegionVariableOrigin; -use rustc_infer::traits::{Obligation, PredicateObligation}; +use rustc_infer::traits::solve::Goal; +use rustc_infer::traits::Obligation; use rustc_middle::mir::ConstraintCategory; use rustc_middle::span_bug; use rustc_middle::traits::query::NoSolution; @@ -154,8 +155,13 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { ), }; let cause = ObligationCause::dummy_with_span(self.span()); - let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations; - self.register_obligations(obligations); + self.register_obligations( + infcx + .handle_opaque_type(a, b, &cause, self.param_env())? + .obligations + .into_iter() + .map(Goal::from), + ); Ok(()) } @@ -550,22 +556,32 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ) { + let tcx = self.tcx(); + let param_env = self.param_env(); self.register_obligations( - obligations - .into_iter() - .map(|to_pred| { - Obligation::new(self.tcx(), ObligationCause::dummy(), self.param_env(), to_pred) - }) - .collect(), + obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)), ); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op( self.locations, self.category, InstantiateOpaqueType { - obligations, + obligations: obligations + .into_iter() + .map(|goal| { + Obligation::new( + self.tcx(), + ObligationCause::dummy_with_span(self.span()), + goal.param_env, + goal.predicate, + ) + }) + .collect(), // These fields are filled in during execution of the operation base_universe: None, region_constraints: None, diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 046d908d148..8994739f5c7 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -31,6 +31,8 @@ use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation}; use rustc_middle::bug; use rustc_middle::ty::{Const, ImplSubject}; +use crate::traits::Obligation; + /// Whether we should define opaque types or just treat them opaquely. /// /// Currently only used to prevent predicate matching from matching anything @@ -119,10 +121,8 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, define_opaque_types, ); - fields - .sup() - .relate(expected, actual) - .map(|_| InferOk { value: (), obligations: fields.obligations }) + fields.sup().relate(expected, actual)?; + Ok(InferOk { value: (), obligations: fields.into_obligations() }) } /// Makes `expected <: actual`. @@ -141,10 +141,8 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, define_opaque_types, ); - fields - .sub() - .relate(expected, actual) - .map(|_| InferOk { value: (), obligations: fields.obligations }) + fields.sub().relate(expected, actual)?; + Ok(InferOk { value: (), obligations: fields.into_obligations() }) } /// Makes `expected == actual`. @@ -163,10 +161,22 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, define_opaque_types, ); - fields - .equate(StructurallyRelateAliases::No) - .relate(expected, actual) - .map(|_| InferOk { value: (), obligations: fields.obligations }) + fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?; + Ok(InferOk { + value: (), + obligations: fields + .obligations + .into_iter() + .map(|goal| { + Obligation::new( + self.infcx.tcx, + fields.trace.cause.clone(), + goal.param_env, + goal.predicate, + ) + }) + .collect(), + }) } /// Equates `expected` and `found` while structurally relating aliases. @@ -187,10 +197,8 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, DefineOpaqueTypes::Yes, ); - fields - .equate(StructurallyRelateAliases::Yes) - .relate(expected, actual) - .map(|_| InferOk { value: (), obligations: fields.obligations }) + fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?; + Ok(InferOk { value: (), obligations: fields.into_obligations() }) } pub fn relate( @@ -237,10 +245,8 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, define_opaque_types, ); - fields - .lub() - .relate(expected, actual) - .map(|value| InferOk { value, obligations: fields.obligations }) + let value = fields.lub().relate(expected, actual)?; + Ok(InferOk { value, obligations: fields.into_obligations() }) } /// Computes the greatest-lower-bound, or mutual subtype, of two @@ -261,10 +267,8 @@ impl<'a, 'tcx> At<'a, 'tcx> { self.param_env, define_opaque_types, ); - fields - .glb() - .relate(expected, actual) - .map(|value| InferOk { value, obligations: fields.obligations }) + let value = fields.glb().relate(expected, actual)?; + Ok(InferOk { value, obligations: fields.into_obligations() }) } } diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index e62ef5d4ea4..1a0a0d10c6d 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -28,6 +28,7 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligation}; use rustc_middle::bug; use rustc_middle::infer::unify_key::EffectVarValue; +use rustc_middle::traits::solve::Goal; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast}; use rustc_middle::ty::{IntType, UintType}; @@ -38,7 +39,7 @@ pub struct CombineFields<'infcx, 'tcx> { pub infcx: &'infcx InferCtxt<'tcx>, pub trace: TypeTrace<'tcx>, pub param_env: ty::ParamEnv<'tcx>, - pub obligations: Vec>, + pub obligations: Vec>>, pub define_opaque_types: DefineOpaqueTypes, } @@ -51,6 +52,20 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { ) -> Self { Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] } } + + pub(crate) fn into_obligations(self) -> Vec> { + self.obligations + .into_iter() + .map(|goal| { + Obligation::new( + self.infcx.tcx, + self.trace.cause.clone(), + goal.param_env, + goal.predicate, + ) + }) + .collect() + } } impl<'tcx> InferCtxt<'tcx> { @@ -290,7 +305,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { Glb::new(self) } - pub fn register_obligations(&mut self, obligations: Vec>) { + pub fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.obligations.extend(obligations); } @@ -298,9 +316,11 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ) { - self.obligations.extend(obligations.into_iter().map(|to_pred| { - Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred) - })) + self.obligations.extend( + obligations + .into_iter() + .map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)), + ) } } @@ -315,7 +335,10 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { fn structurally_relate_aliases(&self) -> StructurallyRelateAliases; /// Register obligations that must hold in order for this relation to hold - fn register_obligations(&mut self, obligations: Vec>); + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ); /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index ca772b349d2..6f37995ac1e 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -1,6 +1,7 @@ //! Greatest lower bound. See [`lattice`]. -use super::{Relate, RelateResult, TypeRelation}; +use rustc_middle::traits::solve::Goal; +use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::Span; @@ -8,7 +9,7 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -147,7 +148,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations); } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index f05b984142a..8c6f1690ade 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -21,7 +21,8 @@ use super::combine::ObligationEmittingRelation; use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; -use super::RelateResult; +use rustc_middle::traits::solve::Goal; +use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -109,7 +110,11 @@ where && !this.infcx().next_trait_solver() => { this.register_obligations( - infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations, + infcx + .handle_opaque_type(a, b, this.cause(), this.param_env())? + .obligations + .into_iter() + .map(Goal::from), ); Ok(a) } diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 0b9de8de001..625cc02115a 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -4,9 +4,10 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::ObligationCause; -use super::{Relate, RelateResult, TypeRelation}; +use rustc_middle::traits::solve::Goal; +use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::Span; @@ -147,7 +148,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations) } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 447e4d6bfd8..328e4d8902f 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,11 +1,10 @@ use super::combine::CombineFields; +use crate::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; -use crate::traits::{Obligation, PredicateObligation}; - -use super::{ - relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate, - RelateResult, StructurallyRelateAliases, TypeRelation, +use rustc_middle::traits::solve::Goal; +use rustc_middle::ty::relate::{ + relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation, }; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -88,9 +87,8 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { ty::Covariant => { // can't make progress on `A <: B` if both A and B are // type variables, so record an obligation. - self.fields.obligations.push(Obligation::new( + self.fields.obligations.push(Goal::new( self.tcx(), - self.fields.trace.cause.clone(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: true, @@ -102,9 +100,8 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { ty::Contravariant => { // can't make progress on `B <: A` if both A and B are // type variables, so record an obligation. - self.fields.obligations.push(Obligation::new( + self.fields.obligations.push(Goal::new( self.tcx(), - self.fields.trace.cause.clone(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: false, @@ -153,10 +150,13 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { && def_id.is_local() && !infcx.next_trait_solver() => { + // FIXME: Don't shuttle between Goal and Obligation self.fields.obligations.extend( infcx .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? - .obligations, + .obligations + .into_iter() + .map(Goal::from), ); } @@ -318,7 +318,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations(&mut self, obligations: Vec>) { + fn register_obligations( + &mut self, + obligations: impl IntoIterator>>, + ) { self.fields.register_obligations(obligations); } From 4efb13b0c24363daf63be0ce98ab612a42fbff30 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 10:13:05 -0400 Subject: [PATCH 099/153] Rename some things --- .../src/type_check/relate_tys.rs | 12 ++++----- compiler/rustc_infer/src/infer/at.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 5 +++- .../rustc_infer/src/infer/relate/combine.rs | 27 +++++++++---------- .../src/infer/relate/generalize.rs | 6 ++--- compiler/rustc_infer/src/infer/relate/glb.rs | 8 +++--- .../rustc_infer/src/infer/relate/lattice.rs | 6 ++--- compiler/rustc_infer/src/infer/relate/lub.rs | 8 +++--- compiler/rustc_infer/src/infer/relate/mod.rs | 2 +- .../src/infer/relate/type_relating.rs | 14 +++++----- 10 files changed, 46 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index a87b9f7a23d..e9215a102c3 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; -use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; +use rustc_infer::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::solve::Goal; @@ -155,7 +155,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { ), }; let cause = ObligationCause::dummy_with_span(self.span()); - self.register_obligations( + self.register_goals( infcx .handle_opaque_type(a, b, &cause, self.param_env())? .obligations @@ -539,7 +539,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx } } -impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> { +impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> { fn span(&self) -> Span { self.locations.span(self.type_checker.body) } @@ -558,12 +558,12 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx ) { let tcx = self.tcx(); let param_env = self.param_env(); - self.register_obligations( + self.register_goals( obligations.into_iter().map(|to_pred| Goal::new(tcx, param_env, to_pred)), ); } - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ) { @@ -589,7 +589,7 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx ); } - fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { ty::Variance::Covariant => ty::PredicateKind::AliasRelate( a.into(), diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 8994739f5c7..01bd732a4cd 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -165,7 +165,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { Ok(InferOk { value: (), obligations: fields - .obligations + .goals .into_iter() .map(|goal| { Obligation::new( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 98a795e67f8..32b50053b50 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1,6 +1,9 @@ pub use at::DefineOpaqueTypes; pub use freshen::TypeFreshener; pub use lexical_region_resolve::RegionResolutionError; +pub use relate::combine::CombineFields; +pub use relate::combine::PredicateEmittingRelation; +pub use relate::StructurallyRelateAliases; pub use rustc_macros::{TypeFoldable, TypeVisitable}; pub use rustc_middle::ty::IntVarValue; pub use BoundRegionConversionTime::*; @@ -8,7 +11,7 @@ pub use RegionVariableOrigin::*; pub use SubregionOrigin::*; pub use ValuePairs::*; -use crate::infer::relate::{CombineFields, RelateResult}; +use crate::infer::relate::RelateResult; use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; use error_reporting::TypeErrCtxt; use free_regions::RegionRelations; diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 1a0a0d10c6d..0a2e85cc891 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -39,7 +39,7 @@ pub struct CombineFields<'infcx, 'tcx> { pub infcx: &'infcx InferCtxt<'tcx>, pub trace: TypeTrace<'tcx>, pub param_env: ty::ParamEnv<'tcx>, - pub obligations: Vec>>, + pub goals: Vec>>, pub define_opaque_types: DefineOpaqueTypes, } @@ -50,11 +50,11 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, define_opaque_types: DefineOpaqueTypes, ) -> Self { - Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] } + Self { infcx, trace, param_env, define_opaque_types, goals: vec![] } } pub(crate) fn into_obligations(self) -> Vec> { - self.obligations + self.goals .into_iter() .map(|goal| { Obligation::new( @@ -76,7 +76,7 @@ impl<'tcx> InferCtxt<'tcx> { b: Ty<'tcx>, ) -> RelateResult<'tcx, Ty<'tcx>> where - R: ObligationEmittingRelation<'tcx>, + R: PredicateEmittingRelation<'tcx>, { debug_assert!(!a.has_escaping_bound_vars()); debug_assert!(!b.has_escaping_bound_vars()); @@ -140,7 +140,7 @@ impl<'tcx> InferCtxt<'tcx> { relate::structurally_relate_tys(relation, a, b) } StructurallyRelateAliases::No => { - relation.register_type_relate_obligation(a, b); + relation.register_alias_relate_predicate(a, b); Ok(a) } } @@ -171,7 +171,7 @@ impl<'tcx> InferCtxt<'tcx> { b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> where - R: ObligationEmittingRelation<'tcx>, + R: PredicateEmittingRelation<'tcx>, { debug!("{}.consts({:?}, {:?})", relation.tag(), a, b); debug_assert!(!a.has_escaping_bound_vars()); @@ -309,14 +309,14 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { &mut self, obligations: impl IntoIterator>>, ) { - self.obligations.extend(obligations); + self.goals.extend(obligations); } pub fn register_predicates( &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ) { - self.obligations.extend( + self.goals.extend( obligations .into_iter() .map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)), @@ -324,7 +324,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { } } -pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { +pub trait PredicateEmittingRelation<'tcx>: TypeRelation> { fn span(&self) -> Span; fn param_env(&self) -> ty::ParamEnv<'tcx>; @@ -335,19 +335,18 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation> { fn structurally_relate_aliases(&self) -> StructurallyRelateAliases; /// Register obligations that must hold in order for this relation to hold - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ); - /// Register predicates that must hold in order for this relation to hold. Uses - /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should - /// be used if control over the obligation causes is required. + /// Register predicates that must hold in order for this relation to hold. + /// This uses the default `param_env` of the obligation. fn register_predicates( &mut self, obligations: impl IntoIterator, ty::Predicate<'tcx>>>, ); /// Register `AliasRelate` obligation(s) that both types must be related to each other. - fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>); + fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>); } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5478afda455..87a2f0b4580 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -1,7 +1,7 @@ use std::mem; use super::StructurallyRelateAliases; -use super::{ObligationEmittingRelation, Relate, RelateResult, TypeRelation}; +use super::{PredicateEmittingRelation, Relate, RelateResult, TypeRelation}; use crate::infer::relate; use crate::infer::type_variable::TypeVariableValue; use crate::infer::{InferCtxt, RegionVariableOrigin}; @@ -30,7 +30,7 @@ impl<'tcx> InferCtxt<'tcx> { /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all /// other usecases (i.e. setting the value of a type var). #[instrument(level = "debug", skip(self, relation))] - pub fn instantiate_ty_var>( + pub fn instantiate_ty_var>( &self, relation: &mut R, target_is_expected: bool, @@ -178,7 +178,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant. #[instrument(level = "debug", skip(self, relation))] - pub(super) fn instantiate_const_var>( + pub(super) fn instantiate_const_var>( &self, relation: &mut R, target_is_expected: bool, diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index 6f37995ac1e..cc17e60a79b 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -5,7 +5,7 @@ use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::Span; -use super::combine::{CombineFields, ObligationEmittingRelation}; +use super::combine::{CombineFields, PredicateEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; @@ -128,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, } } -impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } @@ -148,14 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ) { self.fields.register_obligations(obligations); } - fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate( a.into(), b.into(), diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 8c6f1690ade..c9b70608ddd 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -17,7 +17,7 @@ //! //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) -use super::combine::ObligationEmittingRelation; +use super::combine::PredicateEmittingRelation; use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; @@ -31,7 +31,7 @@ use rustc_middle::ty::{self, Ty}; /// /// GLB moves "down" the lattice (to smaller values); LUB moves /// "up" the lattice (to bigger values). -pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> { +pub trait LatticeDir<'f, 'tcx>: PredicateEmittingRelation<'tcx> { fn infcx(&self) -> &'f InferCtxt<'tcx>; fn cause(&self) -> &ObligationCause<'tcx>; @@ -109,7 +109,7 @@ where && def_id.is_local() && !this.infcx().next_trait_solver() => { - this.register_obligations( + this.register_goals( infcx .handle_opaque_type(a, b, this.cause(), this.param_env())? .obligations diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index 625cc02115a..e9d300d349c 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -1,6 +1,6 @@ //! Least upper bound. See [`lattice`]. -use super::combine::{CombineFields, ObligationEmittingRelation}; +use super::combine::{CombineFields, PredicateEmittingRelation}; use super::lattice::{self, LatticeDir}; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin}; @@ -128,7 +128,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, } } -impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } @@ -148,14 +148,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ) { self.fields.register_obligations(obligations) } - fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(ty::PredicateKind::AliasRelate( a.into(), b.into(), diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs index 627c527cba1..e7b50479b85 100644 --- a/compiler/rustc_infer/src/infer/relate/mod.rs +++ b/compiler/rustc_infer/src/infer/relate/mod.rs @@ -6,7 +6,7 @@ pub use rustc_middle::ty::relate::*; pub use self::_match::MatchAgainstFreshVars; pub use self::combine::CombineFields; -pub use self::combine::ObligationEmittingRelation; +pub use self::combine::PredicateEmittingRelation; pub mod _match; pub(super) mod combine; diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 328e4d8902f..7e64a9b936c 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -1,5 +1,5 @@ use super::combine::CombineFields; -use crate::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases}; +use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::{DefineOpaqueTypes, SubregionOrigin}; use rustc_middle::traits::solve::Goal; @@ -87,7 +87,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { ty::Covariant => { // can't make progress on `A <: B` if both A and B are // type variables, so record an obligation. - self.fields.obligations.push(Goal::new( + self.fields.goals.push(Goal::new( self.tcx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { @@ -100,7 +100,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { ty::Contravariant => { // can't make progress on `B <: A` if both A and B are // type variables, so record an obligation. - self.fields.obligations.push(Goal::new( + self.fields.goals.push(Goal::new( self.tcx(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { @@ -151,7 +151,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { && !infcx.next_trait_solver() => { // FIXME: Don't shuttle between Goal and Obligation - self.fields.obligations.extend( + self.fields.goals.extend( infcx .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? .obligations @@ -298,7 +298,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { } } -impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { +impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { fn span(&self) -> Span { self.fields.trace.span() } @@ -318,14 +318,14 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { self.fields.register_predicates(obligations); } - fn register_obligations( + fn register_goals( &mut self, obligations: impl IntoIterator>>, ) { self.fields.register_obligations(obligations); } - fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { + fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { ty::Variance::Covariant => ty::PredicateKind::AliasRelate( a.into(), From e4be97cfe763fc5550e048ae3db288fd27a1954c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 7 Jun 2024 11:51:03 -0400 Subject: [PATCH 100/153] Try not to make obligations in handle_opaque_type --- .../src/type_check/relate_tys.rs | 9 +- .../rustc_infer/src/infer/opaque_types/mod.rs | 107 +++++++++--------- compiler/rustc_infer/src/infer/projection.rs | 11 +- .../rustc_infer/src/infer/relate/lattice.rs | 9 +- .../src/infer/relate/type_relating.rs | 14 +-- .../src/solve/eval_ctxt/mod.rs | 15 ++- 6 files changed, 74 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index e9215a102c3..c531c9b209b 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -154,14 +154,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { "expected at least one opaque type in `relate_opaques`, got {a} and {b}." ), }; - let cause = ObligationCause::dummy_with_span(self.span()); - self.register_goals( - infcx - .handle_opaque_type(a, b, &cause, self.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + self.register_goals(infcx.handle_opaque_type(a, b, self.span(), self.param_env())?); Ok(()) } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 8eb3185673b..7114b888718 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -1,11 +1,11 @@ -use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::{self, PredicateObligation}; +use crate::traits::{self, Obligation}; use hir::def_id::{DefId, LocalDefId}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; +use rustc_middle::traits::solve::Goal; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; @@ -21,6 +21,8 @@ mod table; pub type OpaqueTypeMap<'tcx> = FxIndexMap, OpaqueTypeDecl<'tcx>>; pub use table::{OpaqueTypeStorage, OpaqueTypeTable}; +use super::DefineOpaqueTypes; + /// Information about the opaque types whose values we /// are inferring in this function (these are the `impl Trait` that /// appear in the return type). @@ -62,11 +64,23 @@ impl<'tcx> InferCtxt<'tcx> { { let def_span = self.tcx.def_span(def_id); let span = if span.contains(def_span) { def_span } else { span }; - let code = traits::ObligationCauseCode::OpaqueReturnType(None); - let cause = ObligationCause::new(span, body_id, code); let ty_var = self.next_ty_var(span); obligations.extend( - self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations, + self.handle_opaque_type(ty, ty_var, span, param_env) + .unwrap() + .into_iter() + .map(|goal| { + Obligation::new( + self.tcx, + ObligationCause::new( + span, + body_id, + traits::ObligationCauseCode::OpaqueReturnType(None), + ), + goal.param_env, + goal.predicate, + ) + }), ); ty_var } @@ -80,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> { &self, a: Ty<'tcx>, b: Ty<'tcx>, - cause: &ObligationCause<'tcx>, + span: Span, param_env: ty::ParamEnv<'tcx>, - ) -> InferResult<'tcx, ()> { + ) -> Result>>, TypeError<'tcx>> { let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); @@ -90,7 +104,7 @@ impl<'tcx> InferCtxt<'tcx> { // See comment on `insert_hidden_type` for why this is sufficient in coherence return Some(self.register_hidden_type( OpaqueTypeKey { def_id, args }, - cause.clone(), + span, param_env, b, )); @@ -143,18 +157,13 @@ impl<'tcx> InferCtxt<'tcx> { && self.tcx.is_type_alias_impl_trait(b_def_id) { self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag { - span: cause.span, + span, hidden_type: self.tcx.def_span(b_def_id), opaque_type: self.tcx.def_span(def_id), }); } } - Some(self.register_hidden_type( - OpaqueTypeKey { def_id, args }, - cause.clone(), - param_env, - b, - )) + Some(self.register_hidden_type(OpaqueTypeKey { def_id, args }, span, param_env, b)) } _ => None, }; @@ -464,24 +473,23 @@ impl<'tcx> InferCtxt<'tcx> { fn register_hidden_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - cause: ObligationCause<'tcx>, + span: Span, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, - ) -> InferResult<'tcx, ()> { - let mut obligations = Vec::new(); + ) -> Result>>, TypeError<'tcx>> { + let mut goals = Vec::new(); - self.insert_hidden_type(opaque_type_key, &cause, param_env, hidden_ty, &mut obligations)?; + self.insert_hidden_type(opaque_type_key, span, param_env, hidden_ty, &mut goals)?; self.add_item_bounds_for_hidden_type( opaque_type_key.def_id.to_def_id(), opaque_type_key.args, - cause, param_env, hidden_ty, - &mut obligations, + &mut goals, ); - Ok(InferOk { value: (), obligations }) + Ok(goals) } /// Insert a hidden type into the opaque type storage, making sure @@ -507,27 +515,21 @@ impl<'tcx> InferCtxt<'tcx> { pub fn insert_hidden_type( &self, opaque_type_key: OpaqueTypeKey<'tcx>, - cause: &ObligationCause<'tcx>, + span: Span, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, - obligations: &mut Vec>, + goals: &mut Vec>>, ) -> Result<(), TypeError<'tcx>> { // Ideally, we'd get the span where *this specific `ty` came // from*, but right now we just use the span from the overall // value being folded. In simple cases like `-> impl Foo`, // these are the same span, but not in cases like `-> (impl // Foo, impl Bar)`. - let span = cause.span; if self.intercrate { // During intercrate we do not define opaque types but instead always // force ambiguity unless the hidden type is known to not implement // our trait. - obligations.push(traits::Obligation::new( - self.tcx, - cause.clone(), - param_env, - ty::PredicateKind::Ambiguous, - )) + goals.push(Goal::new(self.tcx, param_env, ty::PredicateKind::Ambiguous)) } else { let prev = self .inner @@ -535,10 +537,13 @@ impl<'tcx> InferCtxt<'tcx> { .opaque_types() .register(opaque_type_key, OpaqueHiddenType { ty: hidden_ty, span }); if let Some(prev) = prev { - obligations.extend( - self.at(cause, param_env) + goals.extend( + self.at(&ObligationCause::dummy_with_span(span), param_env) .eq(DefineOpaqueTypes::Yes, prev, hidden_ty)? - .obligations, + .obligations + .into_iter() + // FIXME: Shuttling between obligations and goals is awkward. + .map(Goal::from), ); } }; @@ -550,10 +555,9 @@ impl<'tcx> InferCtxt<'tcx> { &self, def_id: DefId, args: ty::GenericArgsRef<'tcx>, - cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, - obligations: &mut Vec>, + goals: &mut Vec>>, ) { let tcx = self.tcx; // Require that the hidden type is well-formed. We have to @@ -567,12 +571,7 @@ impl<'tcx> InferCtxt<'tcx> { // type during MIR borrowck, causing us to infer the wrong // lifetime for its member constraints which then results in // unexpected region errors. - obligations.push(traits::Obligation::new( - tcx, - cause.clone(), - param_env, - ty::ClauseKind::WellFormed(hidden_ty.into()), - )); + goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into()))); let item_bounds = tcx.explicit_item_bounds(def_id); for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { @@ -588,13 +587,18 @@ impl<'tcx> InferCtxt<'tcx> { && !tcx.is_impl_trait_in_trait(projection_ty.def_id) && !self.next_trait_solver() => { - self.projection_ty_to_infer( + let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id)); + goals.push(Goal::new( + self.tcx, param_env, - projection_ty, - cause.clone(), - 0, - obligations, - ) + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + ty::ProjectionPredicate { + projection_term: projection_ty.into(), + term: ty_var.into(), + }, + )), + )); + ty_var } // Replace all other mentions of the same opaque type with the hidden type, // as the bounds must hold on the hidden type after all. @@ -611,12 +615,7 @@ impl<'tcx> InferCtxt<'tcx> { // Require that the predicate holds for the concrete type. debug!(?predicate); - obligations.push(traits::Obligation::new( - self.tcx, - cause.clone(), - param_env, - predicate, - )); + goals.push(Goal::new(self.tcx, param_env, predicate)); } } } diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 16786347980..a1ba43eb171 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -21,11 +21,12 @@ impl<'tcx> InferCtxt<'tcx> { obligations: &mut Vec>, ) -> Ty<'tcx> { debug_assert!(!self.next_trait_solver()); - let def_id = projection_ty.def_id; - let ty_var = self.next_ty_var(self.tcx.def_span(def_id)); - let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection( - ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() }, - ))); + let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id)); + let projection = + ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { + projection_term: projection_ty.into(), + term: ty_var.into(), + })); let obligation = Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection); obligations.push(obligation); diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index c9b70608ddd..6cc8d6d910a 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -21,7 +21,6 @@ use super::combine::PredicateEmittingRelation; use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; -use rustc_middle::traits::solve::Goal; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty}; @@ -109,13 +108,7 @@ where && def_id.is_local() && !this.infcx().next_trait_solver() => { - this.register_goals( - infcx - .handle_opaque_type(a, b, this.cause(), this.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + this.register_goals(infcx.handle_opaque_type(a, b, this.span(), this.param_env())?); Ok(a) } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 7e64a9b936c..f7b2f11e3d7 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -150,14 +150,12 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { && def_id.is_local() && !infcx.next_trait_solver() => { - // FIXME: Don't shuttle between Goal and Obligation - self.fields.goals.extend( - infcx - .handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())? - .obligations - .into_iter() - .map(Goal::from), - ); + self.fields.goals.extend(infcx.handle_opaque_type( + a, + b, + self.fields.trace.cause.span, + self.param_env(), + )?); } _ => { diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index b522022c206..43013a01069 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -961,15 +961,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, ) -> Result<(), NoSolution> { - let mut obligations = Vec::new(); + let mut goals = Vec::new(); self.infcx.insert_hidden_type( opaque_type_key, - &ObligationCause::dummy(), + DUMMY_SP, param_env, hidden_ty, - &mut obligations, + &mut goals, )?; - self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); + self.add_goals(GoalSource::Misc, goals); Ok(()) } @@ -980,16 +980,15 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, ) { - let mut obligations = Vec::new(); + let mut goals = Vec::new(); self.infcx.add_item_bounds_for_hidden_type( opaque_def_id, opaque_args, - ObligationCause::dummy(), param_env, hidden_ty, - &mut obligations, + &mut goals, ); - self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); + self.add_goals(GoalSource::Misc, goals); } // Do something for each opaque/hidden pair defined with `def_id` in the From 8a6bc13cfe2fe90237f76c58933d10d76fc8a29c Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sun, 9 Jun 2024 14:24:36 -0400 Subject: [PATCH 101/153] Add set_backtrace_level helper function to run_make_support --- src/tools/run-make-support/src/rustc.rs | 6 ++++ tests/run-make/short-ice/rmake.rs | 37 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index d4c00d23b8b..2538c475cae 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -100,6 +100,12 @@ impl Rustc { self } + //Adjust the backtrace level, displaying more detailed information at higher levels. + pub fn set_backtrace_level>(&mut self, level: R) -> &mut Self { + self.cmd.env("RUST_BACKTRACE", level); + self + } + /// Specify path to the output file. Equivalent to `-o`` in rustc. pub fn output>(&mut self, path: P) -> &mut Self { self.cmd.arg("-o"); diff --git a/tests/run-make/short-ice/rmake.rs b/tests/run-make/short-ice/rmake.rs index 0aa1df61dbe..81403931c78 100644 --- a/tests/run-make/short-ice/rmake.rs +++ b/tests/run-make/short-ice/rmake.rs @@ -4,26 +4,37 @@ // was shortened down to an appropriate length. // See https://github.com/rust-lang/rust/issues/107910 +//@ ignore-windows +// Reason: the assert_eq! on line 32 fails, as error output on Windows is different. + use run_make_support::rustc; -use std::env; fn main() { - env::set_var("RUST_BACKTRACE", "1"); - let mut rust_test_1 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); - env::set_var("RUST_BACKTRACE", "full"); - let mut rust_test_2 = rustc().input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); - let rust_test_log_1 = rust_test_1.stderr_utf8().push_str(&rust_test_1.stdout_utf8()).as_str(); - let rust_test_log_2 = rust_test_2.stderr_utf8().push_str(&rust_test_2.stdout_utf8()).as_str(); + let rust_test_1 = + rustc().set_backtrace_level("1").input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); + let rust_test_2 = rustc() + .set_backtrace_level("full") + .input("src/lib.rs") + .arg("-Ztreat-err-as-bug=1") + .run_fail(); + + let mut rust_test_log_1 = rust_test_1.stderr_utf8(); + rust_test_log_1.push_str(&rust_test_1.stdout_utf8()); + let rust_test_log_1 = rust_test_log_1.as_str(); + + let mut rust_test_log_2 = rust_test_2.stderr_utf8(); + rust_test_log_2.push_str(&rust_test_2.stdout_utf8()); + let rust_test_log_2 = rust_test_log_2.as_str(); let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_"); - assert!( - rust_test_log_1.lines().count() < rust_test_log_2.lines().count() - && count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace") - == count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") - && count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full - && rustc_query_count_full > 5 + assert!(rust_test_log_1.lines().count() < rust_test_log_2.lines().count()); + assert_eq!( + count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace"), + count_lines_with(rust_test_log_2, "__rust_end_short_backtrace") ); + assert!(count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full); + assert!(rustc_query_count_full > 5); } fn count_lines_with(s: &str, search: &str) -> usize { From 1a6059726551a464290117adfdf652a9e001ec75 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 11:36:48 +1000 Subject: [PATCH 102/153] Make `storage-live.rs` robust against rustc internal changes. Currently it can be made to fail by rearranging code within `compiler/rustc_mir_transform/src/lint.rs`. --- tests/ui/mir/lint/storage-live.rs | 1 + tests/ui/mir/lint/storage-live.stderr | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index 8273544b56a..d734b773642 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -5,6 +5,7 @@ //@ normalize-stderr-test "note: .*\n\n" -> "" //@ normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" //@ normalize-stderr-test "storage_live\[....\]" -> "storage_live[HASH]" +//@ normalize-stderr-test "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/mir/lint/storage-live.stderr b/tests/ui/mir/lint/storage-live.stderr index 2eb8d8e7000..7d4c3f0832a 100644 --- a/tests/ui/mir/lint/storage-live.stderr +++ b/tests/ui/mir/lint/storage-live.stderr @@ -1,12 +1,12 @@ error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (after pass CheckPackedRef) at bb0[1]: StorageLive(_1) which already has storage here - --> $DIR/storage-live.rs:22:13 + --> $DIR/storage-live.rs:23:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ | -note: delayed at compiler/rustc_mir_transform/src/lint.rs:97:26 - disabled backtrace - --> $DIR/storage-live.rs:22:13 +note: delayed at compiler/rustc_mir_transform/src/lint.rs:LL:CC - disabled backtrace + --> $DIR/storage-live.rs:23:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ From 7e7da49f2a780917909e7aa4b5b1bb2e48900c47 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Jun 2024 15:01:57 +1000 Subject: [PATCH 103/153] Update a cranelift patch file for formatting changes. PR #125443 will reformat all the use declarations in the repo. This would break a patch kept in `rustc_codegen_cranelift` that gets applied to `library/std/src/sys/pal/windows/rand.rs`. So this commit formats the use declarations in `library/std/src/sys/pal/windows/rand.rs` in advance of #125443 and updates the patch file accordingly. The motivation is that #125443 is a huge change and we want to get fiddly little changes like this out of the way so it can be nothing more than an `x fmt --all`. --- .../patches/0029-stdlib-rawdylib-processprng.patch | 6 +++--- library/std/src/sys/pal/windows/rand.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch index 6af11e54d88..584dbdb647f 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-rawdylib-processprng.patch @@ -12,7 +12,7 @@ diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/wind index ad8e01bfa9b..9ca8e4c16ce 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs -@@ -323,7 +323,7 @@ pub unsafe fn NtWriteFile( +@@ -312,7 +312,7 @@ pub unsafe fn NtWriteFile( // Use raw-dylib to import ProcessPrng as we can't rely on there being an import library. cfg_if::cfg_if! { @@ -26,8 +26,8 @@ index e427546222a..f2fe42a4d51 100644 --- a/library/std/src/sys/pal/windows/rand.rs +++ b/library/std/src/sys/pal/windows/rand.rs @@ -2,7 +2,7 @@ - use core::mem; - use core::ptr; + + use crate::sys::c; -#[cfg(not(target_vendor = "win7"))] +#[cfg(any())] diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs index e427546222a..09f527a09bf 100644 --- a/library/std/src/sys/pal/windows/rand.rs +++ b/library/std/src/sys/pal/windows/rand.rs @@ -1,6 +1,6 @@ +use core::{mem, ptr}; + use crate::sys::c; -use core::mem; -use core::ptr; #[cfg(not(target_vendor = "win7"))] #[inline] From 3203d169d34daff975dffd20d90e3074b0b40b83 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 11 Jun 2024 20:48:52 -0400 Subject: [PATCH 104/153] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index b1feb75d062..4dcbca118ab 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b1feb75d062444e2cee8b3d2aaa95309d65e9ccd +Subproject commit 4dcbca118ab7f9ffac4728004c983754bc6a04ff From 0fc18e3a17a4dd061189d83c4805e3aaf7c83cf0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 6 Jun 2024 10:08:55 -0400 Subject: [PATCH 105/153] Remove DebugWithInfcx --- compiler/rustc_middle/src/ty/list.rs | 10 +- compiler/rustc_middle/src/ty/mod.rs | 1 - .../rustc_middle/src/ty/structural_impls.rs | 103 ++---------- compiler/rustc_type_ir/src/binder.rs | 15 +- compiler/rustc_type_ir/src/const_kind.rs | 50 +----- compiler/rustc_type_ir/src/debug.rs | 146 ------------------ compiler/rustc_type_ir/src/inherent.rs | 10 +- compiler/rustc_type_ir/src/interner.rs | 10 +- compiler/rustc_type_ir/src/lib.rs | 2 - compiler/rustc_type_ir/src/predicate.rs | 32 +--- compiler/rustc_type_ir/src/region_kind.rs | 30 +--- compiler/rustc_type_ir/src/ty_kind.rs | 107 ++++--------- ...await.b-{closure#0}.coroutine_resume.0.mir | 30 ++-- .../occurs-check/associated-type.next.stderr | 8 +- .../occurs-check/associated-type.old.stderr | 16 +- .../structually-relate-aliases.stderr | 4 +- .../issue-118950-root-region.stderr | 8 +- 17 files changed, 105 insertions(+), 477 deletions(-) delete mode 100644 compiler/rustc_type_ir/src/debug.rs diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 0db541899d2..71a93cc520d 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -1,5 +1,5 @@ use super::flags::FlagComputation; -use super::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, TyCtxt, TypeFlags, WithInfcx}; +use super::{DebruijnIndex, TypeFlags}; use crate::arena::Arena; use rustc_data_structures::aligned::{align_of, Aligned}; use rustc_serialize::{Encodable, Encoder}; @@ -162,14 +162,6 @@ impl fmt::Debug for RawList { (**self).fmt(f) } } -impl<'tcx, H, T: DebugWithInfcx>> DebugWithInfcx> for RawList { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - fmt::Debug::fmt(&this.map(|this| this.as_slice()), f) - } -} impl> Encodable for RawList { #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7ff1b799822..83f8de6b6f9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -61,7 +61,6 @@ use rustc_span::{ExpnId, ExpnKind, Span}; use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx}; pub use rustc_target::abi::{ReprFlags, ReprOptions}; pub use rustc_type_ir::relate::VarianceDiagInfo; -pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, WithInfcx}; use tracing::{debug, instrument}; pub use vtable::*; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index cc6b1d57f87..71e2e3e9f99 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -13,7 +13,7 @@ use rustc_ast_ir::visit::VisitorResult; use rustc_hir::def::Namespace; use rustc_span::source_map::Spanned; use rustc_target::abi::TyAndLayout; -use rustc_type_ir::{ConstKind, DebugWithInfcx, InferCtxtLike, WithInfcx}; +use rustc_type_ir::ConstKind; use std::fmt::{self, Debug}; @@ -83,14 +83,6 @@ impl fmt::Debug for ty::LateParamRegion { } } -impl<'tcx> ty::DebugWithInfcx> for Ty<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - this.data.fmt(f) - } -} impl<'tcx> fmt::Debug for Ty<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { with_no_trimmed_paths!(fmt::Debug::fmt(self.kind(), f)) @@ -121,70 +113,33 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> { } } -impl<'tcx> DebugWithInfcx> for Pattern<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match &**this.data { - ty::PatternKind::Range { start, end, include_end } => f - .debug_struct("Pattern::Range") - .field("start", start) - .field("end", end) - .field("include_end", include_end) - .finish(), - } - } -} - impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match this.data.kind { + match self.kind { ty::ExprKind::Binop(op) => { - let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args(); - write!( - f, - "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", - &this.wrap(lhs), - &this.wrap(lhs_ty), - &this.wrap(rhs), - &this.wrap(rhs_ty), - ) + let (lhs_ty, rhs_ty, lhs, rhs) = self.binop_args(); + write!(f, "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", lhs, lhs_ty, rhs, rhs_ty,) } ty::ExprKind::UnOp(op) => { - let (rhs_ty, rhs) = this.data.unop_args(); - write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty)) + let (rhs_ty, rhs) = self.unop_args(); + write!(f, "({op:?}: ({:?}: {:?}))", rhs, rhs_ty) } ty::ExprKind::FunctionCall => { - let (func_ty, func, args) = this.data.call_args(); + let (func_ty, func, args) = self.call_args(); let args = args.collect::>(); - write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?; + write!(f, "({:?}: {:?})(", func, func_ty)?; for arg in args.iter().rev().skip(1).rev() { - write!(f, "{:?}, ", &this.wrap(arg))?; + write!(f, "{:?}, ", arg)?; } if let Some(arg) = args.last() { - write!(f, "{:?}", &this.wrap(arg))?; + write!(f, "{:?}", arg)?; } write!(f, ")") } ty::ExprKind::Cast(kind) => { - let (value_ty, value, to_ty) = this.data.cast_args(); - write!( - f, - "({kind:?}: ({:?}: {:?}), {:?})", - &this.wrap(value), - &this.wrap(value_ty), - &this.wrap(to_ty) - ) + let (value_ty, value, to_ty) = self.cast_args(); + write!(f, "({kind:?}: ({:?}: {:?}), {:?})", value, value_ty, to_ty) } } } @@ -192,20 +147,12 @@ impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { impl<'tcx> fmt::Debug for ty::Const<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl<'tcx> DebugWithInfcx> for ty::Const<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { // If this is a value, we spend some effort to make it look nice. - if let ConstKind::Value(_, _) = this.data.kind() { + if let ConstKind::Value(_, _) = self.kind() { return ty::tls::with(move |tcx| { // Somehow trying to lift the valtree results in lifetime errors, so we lift the // entire constant. - let lifted = tcx.lift(*this.data).unwrap(); + let lifted = tcx.lift(*self).unwrap(); let ConstKind::Value(ty, valtree) = lifted.kind() else { bug!("we checked that this is a valtree") }; @@ -215,7 +162,7 @@ impl<'tcx> DebugWithInfcx> for ty::Const<'tcx> { }); } // Fall back to something verbose. - write!(f, "{kind:?}", kind = &this.map(|data| data.kind())) + write!(f, "{:?}", self.kind()) } } @@ -247,32 +194,12 @@ impl<'tcx> fmt::Debug for GenericArg<'tcx> { } } } -impl<'tcx> DebugWithInfcx> for GenericArg<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match this.data.unpack() { - GenericArgKind::Lifetime(lt) => write!(f, "{:?}", &this.wrap(lt)), - GenericArgKind::Const(ct) => write!(f, "{:?}", &this.wrap(ct)), - GenericArgKind::Type(ty) => write!(f, "{:?}", &this.wrap(ty)), - } - } -} impl<'tcx> fmt::Debug for Region<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.kind()) } } -impl<'tcx> DebugWithInfcx> for Region<'tcx> { - fn fmt>>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - write!(f, "{:?}", &this.map(|data| data.kind())) - } -} /////////////////////////////////////////////////////////////////////////// // Atomic structs diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 9a2c9059967..e50d59ba5f0 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -8,12 +8,11 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_serialize::Decodable; use tracing::debug; -use crate::debug::{DebugWithInfcx, WithInfcx}; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, InferCtxtLike, Interner, SsoHashSet}; +use crate::{self as ty, Interner, SsoHashSet}; /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -56,18 +55,6 @@ where } } -impl> DebugWithInfcx for ty::Binder { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - f.debug_tuple("Binder") - .field(&this.map(|data| data.as_ref().skip_binder())) - .field(&this.data.bound_vars()) - .finish() - } -} - macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 84d48e14c24..f1683f5449f 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -5,7 +5,7 @@ use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; -use crate::{self as ty, DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; +use crate::{self as ty, DebruijnIndex, Interner}; use self::ConstKind::*; @@ -61,28 +61,19 @@ impl PartialEq for ConstKind { impl fmt::Debug for ConstKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} - -impl DebugWithInfcx for ConstKind { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { use ConstKind::*; - match this.data { + match self { Param(param) => write!(f, "{param:?}"), - Infer(var) => write!(f, "{:?}", &this.wrap(var)), + Infer(var) => write!(f, "{:?}", &var), Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var), Placeholder(placeholder) => write!(f, "{placeholder:?}"), Unevaluated(uv) => { - write!(f, "{:?}", &this.wrap(uv)) + write!(f, "{:?}", &uv) } - Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &this.wrap(ty)), + Value(ty, valtree) => write!(f, "({valtree:?}: {:?})", &ty), Error(_) => write!(f, "{{const error}}"), - Expr(expr) => write!(f, "{:?}", &this.wrap(expr)), + Expr(expr) => write!(f, "{:?}", &expr), } } } @@ -112,17 +103,9 @@ impl UnevaluatedConst { impl fmt::Debug for UnevaluatedConst { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl DebugWithInfcx for UnevaluatedConst { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { f.debug_struct("UnevaluatedConst") - .field("def", &this.data.def) - .field("args", &this.wrap(this.data.args)) + .field("def", &self.def) + .field("args", &self.args) .finish() } } @@ -175,23 +158,6 @@ impl fmt::Debug for InferConst { } } } -impl DebugWithInfcx for InferConst { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match *this.data { - InferConst::Var(vid) => match this.infcx.universe_of_ct(vid) { - None => write!(f, "{:?}", this.data), - Some(universe) => write!(f, "?{}_{}c", vid.index(), universe.index()), - }, - InferConst::EffectVar(vid) => write!(f, "?{}e", vid.index()), - InferConst::Fresh(_) => { - unreachable!() - } - } - } -} #[cfg(feature = "nightly")] impl HashStable for InferConst { diff --git a/compiler/rustc_type_ir/src/debug.rs b/compiler/rustc_type_ir/src/debug.rs deleted file mode 100644 index c206f3ccdb5..00000000000 --- a/compiler/rustc_type_ir/src/debug.rs +++ /dev/null @@ -1,146 +0,0 @@ -use crate::{ - ConstVid, EffectVid, FloatVid, InferCtxtLike, IntVid, Interner, RegionVid, TyVid, UniverseIndex, -}; - -use core::fmt; -use std::marker::PhantomData; - -pub struct NoInfcx(PhantomData); - -impl InferCtxtLike for NoInfcx { - type Interner = I; - - fn interner(&self) -> Self::Interner { - unreachable!() - } - - fn universe_of_ty(&self, _ty: TyVid) -> Option { - None - } - - fn universe_of_lt(&self, _lt: RegionVid) -> Option { - None - } - - fn universe_of_ct(&self, _ct: ConstVid) -> Option { - None - } - - fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> I::Ty { - panic!("cannot resolve {vid:?}") - } - - fn opportunistic_resolve_int_var(&self, vid: IntVid) -> I::Ty { - panic!("cannot resolve {vid:?}") - } - - fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> I::Ty { - panic!("cannot resolve {vid:?}") - } - - fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> I::Const { - panic!("cannot resolve {vid:?}") - } - - fn opportunistic_resolve_effect_var(&self, vid: EffectVid) -> I::Const { - panic!("cannot resolve {vid:?}") - } - - fn opportunistic_resolve_lt_var(&self, vid: crate::RegionVid) -> I::Region { - panic!("cannot resolve {vid:?}") - } - - fn defining_opaque_types(&self) -> I::DefiningOpaqueTypes { - Default::default() - } -} - -pub trait DebugWithInfcx: fmt::Debug { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result; -} - -impl + ?Sized> DebugWithInfcx for &'_ T { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - >::fmt(this.map(|&data| data), f) - } -} - -impl> DebugWithInfcx for [T] { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - match f.alternate() { - true => { - write!(f, "[\n")?; - for element in this.data.iter() { - write!(f, "{:?},\n", &this.wrap(element))?; - } - write!(f, "]") - } - false => { - write!(f, "[")?; - if this.data.len() > 0 { - for element in &this.data[..(this.data.len() - 1)] { - write!(f, "{:?}, ", &this.wrap(element))?; - } - if let Some(element) = this.data.last() { - write!(f, "{:?}", &this.wrap(element))?; - } - } - write!(f, "]") - } - } - } -} - -pub struct WithInfcx<'a, Infcx: InferCtxtLike, T> { - pub data: T, - pub infcx: &'a Infcx, -} - -impl Copy for WithInfcx<'_, Infcx, T> {} - -impl Clone for WithInfcx<'_, Infcx, T> { - fn clone(&self) -> Self { - Self { data: self.data.clone(), infcx: self.infcx } - } -} - -impl<'a, I: Interner, T> WithInfcx<'a, NoInfcx, T> { - pub fn with_no_infcx(data: T) -> Self { - Self { data, infcx: &NoInfcx(PhantomData) } - } -} - -impl<'a, Infcx: InferCtxtLike, T> WithInfcx<'a, Infcx, T> { - pub fn new(data: T, infcx: &'a Infcx) -> Self { - Self { data, infcx } - } - - pub fn wrap(self, u: U) -> WithInfcx<'a, Infcx, U> { - WithInfcx { data: u, infcx: self.infcx } - } - - pub fn map(self, f: impl FnOnce(T) -> U) -> WithInfcx<'a, Infcx, U> { - WithInfcx { data: f(self.data), infcx: self.infcx } - } - - pub fn as_ref(&self) -> WithInfcx<'a, Infcx, &T> { - WithInfcx { data: &self.data, infcx: self.infcx } - } -} - -impl> fmt::Debug - for WithInfcx<'_, Infcx, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - DebugWithInfcx::fmt(self.as_ref(), f) - } -} diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 205a1e5f100..2fc765f1c8f 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -12,11 +12,11 @@ use rustc_ast_ir::Mutability; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{self as ty, CollectAndApply, DebugWithInfcx, Interner, UpcastFrom}; +use crate::{self as ty, CollectAndApply, Interner, UpcastFrom}; pub trait Ty>: Copy - + DebugWithInfcx + + Debug + Hash + Eq + Into @@ -116,7 +116,7 @@ pub trait Safety>: Copy + Debug + Hash + Eq + TypeVis pub trait Region>: Copy - + DebugWithInfcx + + Debug + Hash + Eq + Into @@ -134,7 +134,7 @@ pub trait Region>: pub trait Const>: Copy - + DebugWithInfcx + + Debug + Hash + Eq + Into @@ -166,7 +166,7 @@ pub trait GenericsOf> { pub trait GenericArgs>: Copy - + DebugWithInfcx + + Debug + Hash + Eq + IntoIterator diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index ad1d2753b28..b7f412ecb8e 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -9,7 +9,7 @@ use crate::ir_print::IrPrint; use crate::relate::Relate; use crate::solve::inspect::CanonicalGoalEvaluationStep; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{self as ty, DebugWithInfcx}; +use crate::{self as ty}; pub trait Interner: Sized @@ -32,7 +32,7 @@ pub trait Interner: type GenericArgs: GenericArgs; type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref; type GenericArg: Copy - + DebugWithInfcx + + Debug + Hash + Eq + IntoKind> @@ -74,9 +74,9 @@ pub trait Interner: // Things stored inside of tys type ErrorGuaranteed: Copy + Debug + Hash + Eq; - type BoundExistentialPredicates: Copy + DebugWithInfcx + Hash + Eq + Relate; + type BoundExistentialPredicates: Copy + Debug + Hash + Eq + Relate; type AllocId: Copy + Debug + Hash + Eq; - type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx + Relate; + type Pat: Copy + Debug + Hash + Eq + Debug + Relate; type Safety: Safety + TypeFoldable + Relate; type Abi: Abi + TypeFoldable + Relate; @@ -86,7 +86,7 @@ pub trait Interner: type ParamConst: Copy + Debug + Hash + Eq + ParamLike; type BoundConst: Copy + Debug + Hash + Eq + BoundVarLike; type ValueConst: Copy + Debug + Hash + Eq; - type ExprConst: Copy + DebugWithInfcx + Hash + Eq + Relate; + type ExprConst: Copy + Debug + Hash + Eq + Relate; // Kinds of regions type Region: Region; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 73716468930..caf1afb5246 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -40,7 +40,6 @@ mod macros; mod binder; mod canonical; mod const_kind; -mod debug; mod flags; mod generic_arg; mod infcx; @@ -57,7 +56,6 @@ pub use canonical::*; #[cfg(feature = "nightly")] pub use codec::*; pub use const_kind::*; -pub use debug::{DebugWithInfcx, WithInfcx}; pub use flags::*; pub use generic_arg::*; pub use infcx::InferCtxtLike; diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 63a4c2e9d1f..c0713dc50d2 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -9,7 +9,7 @@ use crate::inherent::*; use crate::lift::Lift; use crate::upcast::Upcast; use crate::visit::TypeVisitableExt as _; -use crate::{self as ty, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; +use crate::{self as ty, Interner}; /// `A: 'region` #[derive(derivative::Derivative)] @@ -248,16 +248,6 @@ pub enum ExistentialPredicate { AutoTrait(I::DefId), } -// FIXME: Implement this the right way after -impl DebugWithInfcx for ExistentialPredicate { - fn fmt>( - this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - fmt::Debug::fmt(&this.data, f) - } -} - impl ty::Binder> { /// Given an existential predicate like `?Self: PartialEq` (e.g., derived from `dyn PartialEq`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` @@ -459,7 +449,8 @@ impl AliasTermKind { Copy(bound = ""), Hash(bound = ""), PartialEq(bound = ""), - Eq(bound = "") + Eq(bound = ""), + Debug(bound = "") )] #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] @@ -493,23 +484,6 @@ pub struct AliasTerm { _use_alias_term_new_instead: (), } -impl std::fmt::Debug for AliasTerm { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl DebugWithInfcx for AliasTerm { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - f.debug_struct("AliasTerm") - .field("args", &this.map(|data| data.args)) - .field("def_id", &this.data.def_id) - .finish() - } -} - impl AliasTerm { pub fn new( interner: I, diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 48ade273289..37c9532ad89 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -4,7 +4,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use std::fmt; -use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; +use crate::{DebruijnIndex, Interner}; use self::RegionKind::*; @@ -18,18 +18,6 @@ rustc_index::newtype_index! { pub struct RegionVid {} } -impl DebugWithInfcx for RegionVid { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match this.infcx.universe_of_lt(*this.data) { - Some(universe) => write!(f, "'?{}_{}", this.data.index(), universe.index()), - None => write!(f, "{:?}", this.data), - } - } -} - /// Representation of regions. Note that the NLL checker uses a distinct /// representation of regions. For this reason, it internally replaces all the /// regions with inference variables -- the index of the variable is then used @@ -230,12 +218,9 @@ impl PartialEq for RegionKind { } } -impl DebugWithInfcx for RegionKind { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut core::fmt::Formatter<'_>, - ) -> core::fmt::Result { - match this.data { +impl fmt::Debug for RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { ReEarlyParam(data) => write!(f, "{data:?}"), ReBound(binder_id, bound_region) => { @@ -247,7 +232,7 @@ impl DebugWithInfcx for RegionKind { ReStatic => f.write_str("'static"), - ReVar(vid) => write!(f, "{:?}", &this.wrap(vid)), + ReVar(vid) => write!(f, "{:?}", &vid), RePlaceholder(placeholder) => write!(f, "{placeholder:?}"), @@ -260,11 +245,6 @@ impl DebugWithInfcx for RegionKind { } } } -impl fmt::Debug for RegionKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} #[cfg(feature = "nightly")] // This is not a derived impl because a derive would require `I: HashStable` diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 71f3862226d..8b4ad2f5ed0 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -10,7 +10,7 @@ use std::fmt; pub use self::closure::*; use self::TyKind::*; use crate::inherent::*; -use crate::{self as ty, DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; +use crate::{self as ty, DebruijnIndex, Interner}; use rustc_ast_ir::Mutability; @@ -341,12 +341,10 @@ impl PartialEq for TyKind { } } -impl DebugWithInfcx for TyKind { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - match this.data { +// This is manually implemented because a derive would require `I: Debug` +impl fmt::Debug for TyKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { Bool => write!(f, "bool"), Char => write!(f, "char"), Int(i) => write!(f, "{i:?}"), @@ -369,27 +367,23 @@ impl DebugWithInfcx for TyKind { } Foreign(d) => f.debug_tuple("Foreign").field(d).finish(), Str => write!(f, "str"), - Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)), - Pat(t, p) => write!(f, "pattern_type!({:?} is {:?})", &this.wrap(t), &this.wrap(p)), - Slice(t) => write!(f, "[{:?}]", &this.wrap(t)), - RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), this.wrap(ty)), - Ref(r, t, m) => write!(f, "&{:?} {}{:?}", this.wrap(r), m.prefix_str(), this.wrap(t)), - FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&this.wrap(s)).finish(), - FnPtr(s) => write!(f, "{:?}", &this.wrap(s)), + Array(t, c) => write!(f, "[{:?}; {:?}]", &t, &c), + Pat(t, p) => write!(f, "pattern_type!({:?} is {:?})", &t, &p), + Slice(t) => write!(f, "[{:?}]", &t), + RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty), + Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t), + FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(), + FnPtr(s) => write!(f, "{:?}", &s), Dynamic(p, r, repr) => match repr { - DynKind::Dyn => write!(f, "dyn {:?} + {:?}", &this.wrap(p), &this.wrap(r)), + DynKind::Dyn => write!(f, "dyn {:?} + {:?}", &p, &r), DynKind::DynStar => { - write!(f, "dyn* {:?} + {:?}", &this.wrap(p), &this.wrap(r)) + write!(f, "dyn* {:?} + {:?}", &p, &r) } }, - Closure(d, s) => f.debug_tuple("Closure").field(d).field(&this.wrap(s)).finish(), - CoroutineClosure(d, s) => { - f.debug_tuple("CoroutineClosure").field(d).field(&this.wrap(s)).finish() - } - Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&this.wrap(s)).finish(), - CoroutineWitness(d, s) => { - f.debug_tuple("CoroutineWitness").field(d).field(&this.wrap(s)).finish() - } + Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(), + CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(), + Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(), + CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(), Never => write!(f, "!"), Tuple(t) => { write!(f, "(")?; @@ -398,7 +392,7 @@ impl DebugWithInfcx for TyKind { if count > 0 { write!(f, ", ")?; } - write!(f, "{:?}", &this.wrap(ty))?; + write!(f, "{:?}", &ty)?; count += 1; } // unary tuples need a trailing comma @@ -407,23 +401,16 @@ impl DebugWithInfcx for TyKind { } write!(f, ")") } - Alias(i, a) => f.debug_tuple("Alias").field(i).field(&this.wrap(a)).finish(), + Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(), Param(p) => write!(f, "{p:?}"), Bound(d, b) => crate::debug_bound_var(f, *d, b), Placeholder(p) => write!(f, "{p:?}"), - Infer(t) => write!(f, "{:?}", this.wrap(t)), + Infer(t) => write!(f, "{:?}", t), TyKind::Error(_) => write!(f, "{{type error}}"), } } } -// This is manually implemented because a derive would require `I: Debug` -impl fmt::Debug for TyKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} - /// Represents the projection of an associated, opaque, or lazy-type-alias type. /// /// * For a projection, this would be `>::N<...>`. @@ -435,7 +422,8 @@ impl fmt::Debug for TyKind { Copy(bound = ""), Hash(bound = ""), PartialEq(bound = ""), - Eq(bound = "") + Eq(bound = ""), + Debug(bound = "") )] #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] @@ -555,23 +543,6 @@ impl AliasTy { } } -impl fmt::Debug for AliasTy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl DebugWithInfcx for AliasTy { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - f.debug_struct("AliasTy") - .field("args", &this.map(|data| data.args)) - .field("def_id", &this.data.def_id) - .finish() - } -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] pub enum IntTy { @@ -968,24 +939,6 @@ impl fmt::Debug for InferTy { } } -impl DebugWithInfcx for InferTy { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - match this.data { - InferTy::TyVar(vid) => { - if let Some(universe) = this.infcx.universe_of_ty(*vid) { - write!(f, "?{}_{}t", vid.index(), universe.index()) - } else { - write!(f, "{:?}", this.data) - } - } - _ => write!(f, "{:?}", this.data), - } - } -} - #[derive(derivative::Derivative)] #[derivative( Clone(bound = ""), @@ -1078,15 +1031,7 @@ impl ty::Binder> { impl fmt::Debug for FnSig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - WithInfcx::with_no_infcx(self).fmt(f) - } -} -impl DebugWithInfcx for FnSig { - fn fmt>( - this: WithInfcx<'_, Infcx, &Self>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - let sig = this.data; + let sig = self; let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig; write!(f, "{}", safety.prefix_str())?; @@ -1100,7 +1045,7 @@ impl DebugWithInfcx for FnSig { if i > 0 { write!(f, ", ")?; } - write!(f, "{:?}", &this.wrap(ty))?; + write!(f, "{:?}", &ty)?; } if *c_variadic { if inputs.is_empty() { @@ -1113,7 +1058,7 @@ impl DebugWithInfcx for FnSig { match output.kind() { Tuple(list) if list.is_empty() => Ok(()), - _ => write!(f, " -> {:?}", &this.wrap(sig.output())), + _ => write!(f, " -> {:?}", sig.output()), } } } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index d2a0fb0cb3c..c0f16ee7ec0 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -5,12 +5,15 @@ ty: Coroutine( DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), [ - (), - std::future::ResumeTy, - (), - (), - CoroutineWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), - (), + (), + std::future::ResumeTy, + (), + (), + CoroutineWitness( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [], + ), + (), ], ), source_info: SourceInfo { @@ -23,12 +26,15 @@ ty: Coroutine( DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), [ - (), - std::future::ResumeTy, - (), - (), - CoroutineWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []), - (), + (), + std::future::ResumeTy, + (), + (), + CoroutineWitness( + DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), + [], + ), + (), ], ), source_info: SourceInfo { diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index d809a6948f3..f32bb1301da 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -1,7 +1,7 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 329086ab7df..d26f7665ee7 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,11 +1,11 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, !2_0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), _use_alias_ty_new_instead: () } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` --> $DIR/associated-type.rs:31:1 | diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 2f1dfd19c48..e1cffa0fc37 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,5 +1,5 @@ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), _use_alias_ty_new_instead: () } error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied --> $DIR/structually-relate-aliases.rs:13:36 | diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index 17da1f52479..04c44276195 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -25,10 +25,10 @@ help: this trait has no implementations, consider adding one LL | trait ToUnit<'a> { | ^^^^^^^^^^^^^^^^ - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } - WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } + WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), _use_alias_ty_new_instead: () } error[E0119]: conflicting implementations of trait `Overlap` for type `fn(_)` --> $DIR/issue-118950-root-region.rs:19:1 | From 5d8f40a63afe3999df61c2487555a540b6ff30ea Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Tue, 11 Jun 2024 17:31:06 +0800 Subject: [PATCH 106/153] No uninitalized report in a pre-returned match arm --- .../src/diagnostics/conflict_errors.rs | 21 ++++++++++++++---- .../uninitalized-in-match-arm-issue-126133.rs | 22 +++++++++++++++++++ ...nitalized-in-match-arm-issue-126133.stderr | 15 +++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.rs create mode 100644 tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 821a9036654..f32ff57fe88 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -557,8 +557,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // for the branching codepaths that aren't covered, to point at them. let map = self.infcx.tcx.hir(); let body = map.body_owned_by(self.mir_def_id()); - - let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; + let mut visitor = + ConditionVisitor { tcx: self.infcx.tcx, spans: &spans, name: &name, errors: vec![] }; visitor.visit_body(&body); let mut show_assign_sugg = false; @@ -4372,13 +4372,14 @@ impl<'hir> Visitor<'hir> for BreakFinder { /// Given a set of spans representing statements initializing the relevant binding, visit all the /// function expressions looking for branching code paths that *do not* initialize the binding. -struct ConditionVisitor<'b> { +struct ConditionVisitor<'b, 'tcx> { + tcx: TyCtxt<'tcx>, spans: &'b [Span], name: &'b str, errors: Vec<(Span, String)>, } -impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { +impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> { fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { match ex.kind { hir::ExprKind::If(cond, body, None) => { @@ -4464,6 +4465,12 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { ), )); } else if let Some(guard) = &arm.guard { + if matches!( + self.tcx.hir_node(arm.body.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) + ) { + continue; + } self.errors.push(( arm.pat.span.to(guard.span), format!( @@ -4473,6 +4480,12 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { ), )); } else { + if matches!( + self.tcx.hir_node(arm.body.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }) + ) { + continue; + } self.errors.push(( arm.pat.span, format!( diff --git a/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.rs b/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.rs new file mode 100644 index 00000000000..1974bbf9fe7 --- /dev/null +++ b/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.rs @@ -0,0 +1,22 @@ +enum E { + A, + B, + C, +} + +fn foo(e: E) { + let bar; + + match e { + E::A if true => return, + E::A => return, + E::B => {} + E::C => { + bar = 5; + } + } + + let _baz = bar; //~ ERROR E0381 +} + +fn main() {} diff --git a/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.stderr b/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.stderr new file mode 100644 index 00000000000..eb7d0f8b204 --- /dev/null +++ b/tests/ui/borrowck/uninitalized-in-match-arm-issue-126133.stderr @@ -0,0 +1,15 @@ +error[E0381]: used binding `bar` is possibly-uninitialized + --> $DIR/uninitalized-in-match-arm-issue-126133.rs:19:16 + | +LL | let bar; + | --- binding declared here but left uninitialized +... +LL | E::B => {} + | ---- if this pattern is matched, `bar` is not initialized +... +LL | let _baz = bar; + | ^^^ `bar` used here but it is possibly-uninitialized + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0381`. From 0b3fec9388d358b0b48d1ea2f83ff43468402f23 Mon Sep 17 00:00:00 2001 From: surechen Date: Sun, 9 Jun 2024 17:20:25 +0800 Subject: [PATCH 107/153] For E0277 suggest adding `Result` return type for function which using QuesionMark `?` in the body. --- compiler/rustc_hir/src/hir.rs | 1 + .../src/traits/error_reporting/suggestions.rs | 41 +++++++++ .../error_reporting/type_err_ctxt_ext.rs | 4 + ...turn-from-residual-sugg-issue-125997.fixed | 42 +++++++++ .../return-from-residual-sugg-issue-125997.rs | 34 ++++++++ ...urn-from-residual-sugg-issue-125997.stderr | 86 +++++++++++++++++++ .../ui/try-trait/try-operator-on-main.stderr | 10 +++ 7 files changed, 218 insertions(+) create mode 100644 tests/ui/return/return-from-residual-sugg-issue-125997.fixed create mode 100644 tests/ui/return/return-from-residual-sugg-issue-125997.rs create mode 100644 tests/ui/return/return-from-residual-sugg-issue-125997.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e64f7aeb11b..ff149e9750d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1010,6 +1010,7 @@ pub struct Block<'hir> { pub hir_id: HirId, /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, + /// The span includes the curly braces `{` and `}` around the block. pub span: Span, /// If true, then there may exist `break 'a` values that aim to /// break out of this block early. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9336148fd67..fddb7c263be 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4586,6 +4586,47 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { _ => "/* value */".to_string(), }) } + + fn suggest_add_result_as_return_type( + &self, + obligation: &PredicateObligation<'tcx>, + err: &mut Diag<'_>, + trait_ref: ty::PolyTraitRef<'tcx>, + ) { + if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() { + return; + } + + let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id); + if let hir::Node::Item(item) = node + && let hir::ItemKind::Fn(sig, _, body_id) = item.kind + && let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output + && self.tcx.is_diagnostic_item(sym::FromResidual, trait_ref.def_id()) + && let ty::Tuple(l) = trait_ref.skip_binder().args.type_at(0).kind() + && l.len() == 0 + && let ty::Adt(def, _) = trait_ref.skip_binder().args.type_at(1).kind() + && self.tcx.is_diagnostic_item(sym::Result, def.did()) + { + let body = self.tcx.hir().body(body_id); + let mut sugg_spans = + vec![(ret_span, " -> Result<(), Box>".to_string())]; + + if let hir::ExprKind::Block(b, _) = body.value.kind + && b.expr.is_none() + { + sugg_spans.push(( + // The span will point to the closing curly brace `}` of the block. + b.span.shrink_to_hi().with_lo(b.span.hi() - BytePos(1)), + "\n Ok(())\n}".to_string(), + )); + } + err.multipart_suggestion_verbose( + format!("consider adding return type"), + sugg_spans, + Applicability::MaybeIncorrect, + ); + } + } } /// Add a hint to add a missing borrow or remove an unnecessary one. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index da611b748da..9d1cf0e74f3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -612,6 +612,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { &mut err, trait_predicate, ); + self.suggest_add_result_as_return_type(&obligation, + &mut err, + trait_ref); + if self.suggest_add_reference_to_arg( &obligation, &mut err, diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.fixed b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed new file mode 100644 index 00000000000..b2eca69aeb9 --- /dev/null +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.fixed @@ -0,0 +1,42 @@ +//@ run-rustfix + +#![allow(unused_imports)] +#![allow(dead_code)] + +use std::fs::File; +use std::io::prelude::*; + +fn test1() -> Result<(), Box> { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + + Ok(()) +} + +fn test2() -> Result<(), Box> { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + println!(); + + Ok(()) +} + +macro_rules! mac { + () => { + fn test3() -> Result<(), Box> { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + println!(); + + Ok(()) +} + }; +} + +fn main() -> Result<(), Box> { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + mac!(); + + Ok(()) +} diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.rs b/tests/ui/return/return-from-residual-sugg-issue-125997.rs new file mode 100644 index 00000000000..dd8550a388b --- /dev/null +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.rs @@ -0,0 +1,34 @@ +//@ run-rustfix + +#![allow(unused_imports)] +#![allow(dead_code)] + +use std::fs::File; +use std::io::prelude::*; + +fn test1() { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function +} + +fn test2() { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + println!(); +} + +macro_rules! mac { + () => { + fn test3() { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + println!(); + } + }; +} + +fn main() { + let mut _file = File::create("foo.txt")?; + //~^ ERROR the `?` operator can only be used in a function + mac!(); +} diff --git a/tests/ui/return/return-from-residual-sugg-issue-125997.stderr b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr new file mode 100644 index 00000000000..ef938f0213d --- /dev/null +++ b/tests/ui/return/return-from-residual-sugg-issue-125997.stderr @@ -0,0 +1,86 @@ +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/return-from-residual-sugg-issue-125997.rs:10:44 + | +LL | fn test1() { + | ---------- this function should return `Result` or `Option` to accept `?` +LL | let mut _file = File::create("foo.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` + | + = help: the trait `FromResidual>` is not implemented for `()` +help: consider adding return type + | +LL ~ fn test1() -> Result<(), Box> { +LL | let mut _file = File::create("foo.txt")?; +LL | +LL + +LL + Ok(()) +LL + } + | + +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/return-from-residual-sugg-issue-125997.rs:15:44 + | +LL | fn test2() { + | ---------- this function should return `Result` or `Option` to accept `?` +LL | let mut _file = File::create("foo.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` + | + = help: the trait `FromResidual>` is not implemented for `()` +help: consider adding return type + | +LL ~ fn test2() -> Result<(), Box> { +LL | let mut _file = File::create("foo.txt")?; +LL | +LL | println!(); +LL + +LL + Ok(()) +LL + } + | + +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/return-from-residual-sugg-issue-125997.rs:31:44 + | +LL | fn main() { + | --------- this function should return `Result` or `Option` to accept `?` +LL | let mut _file = File::create("foo.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` + | + = help: the trait `FromResidual>` is not implemented for `()` +help: consider adding return type + | +LL ~ fn main() -> Result<(), Box> { +LL | let mut _file = File::create("foo.txt")?; +LL | +LL | mac!(); +LL + +LL + Ok(()) +LL + } + | + +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> $DIR/return-from-residual-sugg-issue-125997.rs:23:52 + | +LL | fn test3() { + | ---------- this function should return `Result` or `Option` to accept `?` +LL | let mut _file = File::create("foo.txt")?; + | ^ cannot use the `?` operator in a function that returns `()` +... +LL | mac!(); + | ------ in this macro invocation + | + = help: the trait `FromResidual>` is not implemented for `()` + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider adding return type + | +LL ~ fn test3() -> Result<(), Box> { +LL | let mut _file = File::create("foo.txt")?; +LL | +LL | println!(); +LL ~ +LL + Ok(()) +LL + } + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr index 7cd38e0cf95..ba6eacde68f 100644 --- a/tests/ui/try-trait/try-operator-on-main.stderr +++ b/tests/ui/try-trait/try-operator-on-main.stderr @@ -8,6 +8,16 @@ LL | std::fs::File::open("foo")?; | ^ cannot use the `?` operator in a function that returns `()` | = help: the trait `FromResidual>` is not implemented for `()` +help: consider adding return type + | +LL ~ fn main() -> Result<(), Box> { +LL | // error for a `Try` type on a non-`Try` fn + ... +LL | try_trait_generic::<()>(); +LL + +LL + Ok(()) +LL + } + | error[E0277]: the `?` operator can only be applied to values that implement `Try` --> $DIR/try-operator-on-main.rs:10:5 From 75b164d836ff82b459dfb05646bf0328dd23d2fd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 12 Jun 2024 13:49:36 +1000 Subject: [PATCH 108/153] Use `tidy` to sort crate attributes for all compiler crates. We already do this for a number of crates, e.g. `rustc_middle`, `rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`. For the ones we don't, in many cases the attributes are a mess. - There is no consistency about order of attribute kinds (e.g. `allow`/`deny`/`feature`). - Within attribute kind groups (e.g. the `feature` attributes), sometimes the order is alphabetical, and sometimes there is no particular order. - Sometimes the attributes of a particular kind aren't even grouped all together, e.g. there might be a `feature`, then an `allow`, then another `feature`. This commit extends the existing sorting to all compiler crates, increasing consistency. If any new attribute line is added there is now only one place it can go -- no need for arbitrary decisions. Exceptions: - `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`, because they have no crate attributes. - `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's ignored in `rustfmt.toml`). --- compiler/rustc_abi/src/lib.rs | 4 +++- compiler/rustc_arena/src/lib.rs | 18 ++++++++++-------- compiler/rustc_ast/src/lib.rs | 8 +++++--- compiler/rustc_ast_ir/src/lib.rs | 4 +++- compiler/rustc_ast_lowering/src/lib.rs | 4 +++- compiler/rustc_ast_passes/src/lib.rs | 4 +++- compiler/rustc_ast_pretty/src/lib.rs | 4 +++- compiler/rustc_attr/src/lib.rs | 4 +++- compiler/rustc_baked_icu_data/src/lib.rs | 8 +++++--- compiler/rustc_borrowck/src/lib.rs | 4 +++- compiler/rustc_builtin_macros/src/lib.rs | 6 ++++-- compiler/rustc_codegen_cranelift/src/lib.rs | 15 +++++++++------ compiler/rustc_codegen_llvm/src/lib.rs | 8 +++++--- compiler/rustc_codegen_ssa/src/lib.rs | 8 +++++--- compiler/rustc_const_eval/src/lib.rs | 8 +++++--- compiler/rustc_driver/src/lib.rs | 4 +++- compiler/rustc_driver_impl/src/lib.rs | 6 ++++-- compiler/rustc_error_codes/src/lib.rs | 6 ++++-- compiler/rustc_error_messages/src/lib.rs | 10 ++++++---- compiler/rustc_feature/src/lib.rs | 4 +++- compiler/rustc_fluent_macro/src/lib.rs | 8 +++++--- compiler/rustc_fs_util/src/lib.rs | 2 ++ compiler/rustc_graphviz/src/lib.rs | 6 ++++-- compiler/rustc_hir/src/lib.rs | 4 +++- compiler/rustc_hir_analysis/src/lib.rs | 6 ++++-- compiler/rustc_hir_pretty/src/lib.rs | 2 ++ compiler/rustc_hir_typeck/src/lib.rs | 10 ++++++---- compiler/rustc_incremental/src/lib.rs | 4 +++- compiler/rustc_index/src/lib.rs | 4 +++- compiler/rustc_index_macros/src/lib.rs | 4 +++- compiler/rustc_infer/src/lib.rs | 10 ++++++---- compiler/rustc_interface/src/lib.rs | 2 ++ compiler/rustc_lexer/src/lib.rs | 2 ++ compiler/rustc_lint/src/lib.rs | 8 +++++--- compiler/rustc_lint_defs/src/lib.rs | 2 ++ compiler/rustc_llvm/src/lib.rs | 4 +++- compiler/rustc_macros/src/lib.rs | 6 ++++-- compiler/rustc_mir_build/src/lib.rs | 2 ++ compiler/rustc_mir_dataflow/src/lib.rs | 2 ++ compiler/rustc_mir_transform/src/lib.rs | 4 +++- compiler/rustc_monomorphize/src/lib.rs | 2 ++ compiler/rustc_parse/src/lib.rs | 2 ++ compiler/rustc_parse_format/src/lib.rs | 8 +++++--- compiler/rustc_passes/src/lib.rs | 6 ++++-- compiler/rustc_pattern_analysis/src/lib.rs | 4 +++- compiler/rustc_privacy/src/lib.rs | 8 +++++--- compiler/rustc_query_impl/src/lib.rs | 8 +++++--- compiler/rustc_query_system/src/lib.rs | 6 ++++-- compiler/rustc_sanitizers/src/lib.rs | 6 +++++- compiler/rustc_serialize/src/lib.rs | 10 ++++++---- compiler/rustc_session/src/lib.rs | 8 +++++--- compiler/rustc_smir/src/lib.rs | 6 ++++-- compiler/rustc_symbol_mangling/src/lib.rs | 6 ++++-- compiler/rustc_trait_selection/src/lib.rs | 8 +++++--- compiler/rustc_traits/src/lib.rs | 2 ++ compiler/rustc_transmute/src/lib.rs | 4 +++- compiler/rustc_ty_utils/src/lib.rs | 6 ++++-- compiler/rustc_type_ir/src/lib.rs | 4 +++- 58 files changed, 226 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index b1a17d5a24b..a6662d4e0e4 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,7 +1,9 @@ -#![cfg_attr(feature = "nightly", feature(step_trait))] +// tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", doc(rust_logo))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] +#![cfg_attr(feature = "nightly", feature(step_trait))] +// tidy-alphabetical-end use std::fmt; use std::num::{NonZeroUsize, ParseIntError}; diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index bdbc59821de..810cb7a9f45 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -7,23 +7,25 @@ //! //! This crate implements several kinds of arena. +// tidy-alphabetical-start +#![allow(clippy::mut_from_ref)] // Arena allocators are one place where this pattern is fine. +#![allow(internal_features)] +#![cfg_attr(test, feature(test))] +#![deny(unsafe_op_in_unsafe_fn)] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(no_crate_inject, attr(deny(warnings))) )] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(core_intrinsics)] -#![feature(dropck_eyepatch)] -#![feature(new_uninit)] -#![feature(maybe_uninit_slice)] #![feature(decl_macro)] +#![feature(dropck_eyepatch)] +#![feature(maybe_uninit_slice)] +#![feature(new_uninit)] #![feature(rustc_attrs)] -#![cfg_attr(test, feature(test))] +#![feature(rustdoc_internals)] #![feature(strict_provenance)] -#![deny(unsafe_op_in_unsafe_fn)] -#![allow(internal_features)] -#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine. +// tidy-alphabetical-end use smallvec::SmallVec; diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 63cde3c6809..7ca950e50e6 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -4,20 +4,22 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(deny(warnings))) )] #![doc(rust_logo)] -#![allow(internal_features)] -#![feature(rustdoc_internals)] #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] -#![feature(never_type)] #![feature(negative_impls)] +#![feature(never_type)] +#![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] +// tidy-alphabetical-end pub mod util { pub mod case; diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index b1a77639b56..1d0c76f6cea 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -1,6 +1,8 @@ +// tidy-alphabetical-start +#![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(never_type))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] -#![cfg_attr(feature = "nightly", allow(internal_features))] +// tidy-alphabetical-end #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1c6b5b9af19..88f6e6c3b78 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -30,12 +30,14 @@ //! get confused if the spans from leaf AST nodes occur in multiple places //! in the HIR, especially for multiple identifiers. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(let_chains)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}; use rustc_ast::node_id::NodeMap; diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 74d0fff2734..1f4bcd59afa 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -4,13 +4,15 @@ //! //! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`. +// tidy-alphabetical-start #![allow(internal_features)] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(iter_is_partitioned)] #![feature(let_chains)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end pub mod ast_validation; mod errors; diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index b9e217a21e3..84d9ce278a2 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -1,7 +1,9 @@ +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(box_patterns)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end mod helpers; pub mod pp; diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index c61b7ea6d82..9cc53ad7ad8 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -4,10 +4,12 @@ //! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax` //! to this crate. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(let_chains)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end mod builtin; mod session_diagnostics; diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs index ffcb290685a..e964a709757 100644 --- a/compiler/rustc_baked_icu_data/src/lib.rs +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -20,10 +20,12 @@ //! --cldr-tag latest --icuexport-tag latest -o src/data //! ``` -#![allow(internal_features)] -#![feature(rustdoc_internals)] -#![doc(rust_logo)] +// tidy-alphabetical-start #![allow(elided_lifetimes_in_paths)] +#![allow(internal_features)] +#![doc(rust_logo)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end mod data { include!("data/mod.rs"); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 1d5801467da..5c9826ecca7 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,7 +1,7 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] @@ -10,8 +10,10 @@ #![feature(min_specialization)] #![feature(never_type)] #![feature(rustc_attrs)] +#![feature(rustdoc_internals)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 744c7f9d090..35b0f43d8af 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -1,12 +1,12 @@ //! This crate contains implementations of built-in macros and other code generating facilities //! injecting code into the crate before it is lowered to HIR. +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![feature(rustdoc_internals)] -#![doc(rust_logo)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] @@ -15,7 +15,9 @@ #![feature(lint_reasons)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] +#![feature(rustdoc_internals)] #![feature(try_blocks)] +// tidy-alphabetical-end extern crate proc_macro; diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 39bbad16b0c..0fea3fd4253 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,13 +1,16 @@ -#![cfg_attr(doc, allow(internal_features))] -#![cfg_attr(doc, feature(rustdoc_internals))] -#![cfg_attr(doc, doc(rust_logo))] -#![feature(rustc_private)] -// Note: please avoid adding other feature gates where possible +// tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(doc, allow(internal_features))] +#![cfg_attr(doc, doc(rust_logo))] +#![cfg_attr(doc, feature(rustdoc_internals))] +// Note: please avoid adding other feature gates where possible +#![feature(rustc_private)] +// Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] -#![warn(unused_lifetimes)] #![warn(unreachable_pub)] +#![warn(unused_lifetimes)] +// tidy-alphabetical-end extern crate jobserver; #[macro_use] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 0029ec9d09a..bb76d388393 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -4,16 +4,18 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] -#![doc(rust_logo)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![doc(rust_logo)] #![feature(exact_size_is_empty)] #![feature(extern_types)] #![feature(hash_raw_entry)] +#![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(let_chains)] -#![feature(impl_trait_in_assoc_type)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3b1921d40e6..e801af40014 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,15 +1,17 @@ -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![doc(rust_logo)] #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(negative_impls)] +#![feature(rustdoc_internals)] #![feature(strict_provenance)] #![feature(try_blocks)] +// tidy-alphabetical-end //! This crate contains codegen code that is used by all codegen backends (LLVM and others). //! The backend-agnostic functions of this crate use functions defined in various traits that diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 3a7c87c1cad..45ea3ec08f8 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,18 +1,20 @@ +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] +#![feature(if_let_guard)] #![feature(let_chains)] +#![feature(never_type)] +#![feature(rustdoc_internals)] #![feature(slice_ptr_get)] #![feature(strict_provenance)] -#![feature(never_type)] #![feature(trait_alias)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![feature(if_let_guard)] +// tidy-alphabetical-end pub mod check_consts; pub mod const_eval; diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index acd93b0b2a6..a03834c519d 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1,8 +1,10 @@ // This crate is intentionally empty and a re-export of `rustc_driver_impl` to allow the code in // `rustc_driver_impl` to be compiled in parallel with other crates. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end pub use rustc_driver_impl::*; diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index fef4ce0b471..9acff4a0a26 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -4,16 +4,18 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] #![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![allow(internal_features)] #![feature(decl_macro)] #![feature(let_chains)] #![feature(panic_backtrace_config)] #![feature(panic_update_hook)] #![feature(result_flattening)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use rustc_ast as ast; use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index f4a33a05c1b..d13d5e1bca2 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -1,10 +1,12 @@ //! This library is used to gather all error codes into one place, to make //! their maintenance easier. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] -#![doc(rust_logo)] #![deny(rustdoc::invalid_codeblock_attributes)] +#![doc(rust_logo)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end // This higher-order macro defines the error codes that are in use. It is used // in the `rustc_errors` crate. Removed error codes are listed in the comment diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 4eb4e77d69c..26a68454ab3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,8 +1,10 @@ -#![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![feature(rustc_attrs)] -#![feature(type_alias_impl_trait)] +// tidy-alphabetical-start #![allow(internal_features)] +#![doc(rust_logo)] +#![feature(rustc_attrs)] +#![feature(rustdoc_internals)] +#![feature(type_alias_impl_trait)] +// tidy-alphabetical-end use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 9db9073e2f0..fb3b7c0a127 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,9 +11,11 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. +// tidy-alphabetical-start #![allow(internal_features)] -#![feature(rustdoc_internals)] #![doc(rust_logo)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end mod accepted; mod builtin_attrs; diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs index 2303785f94e..0a04e6743a8 100644 --- a/compiler/rustc_fluent_macro/src/lib.rs +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -1,10 +1,12 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::default_hash_types)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![allow(internal_features)] -#![feature(rustdoc_internals)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] -#![allow(rustc::default_hash_types)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs index d376c24cb58..5a9b15204d5 100644 --- a/compiler/rustc_fs_util/src/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs @@ -1,7 +1,9 @@ +// tidy-alphabetical-start use std::ffi::CString; use std::fs; use std::io; use std::path::{absolute, Path, PathBuf}; +// tidy-alphabetical-end // Unfortunately, on windows, it looks like msvcrt.dll is silently translating // verbatim paths under the hood to non-verbatim paths! This manifests itself as diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 43bee5c4be0..c0fe98254f0 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -269,13 +269,15 @@ //! //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) +// tidy-alphabetical-start +#![allow(internal_features)] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] -#![feature(rustdoc_internals)] #![doc(rust_logo)] -#![allow(internal_features)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use LabelText::*; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 600a0dce03b..e517c3fd07a 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -2,13 +2,15 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html +// tidy-alphabetical-start +#![allow(internal_features)] #![feature(associated_type_defaults)] #![feature(closure_track_caller)] #![feature(let_chains)] #![feature(never_type)] #![feature(rustc_attrs)] #![feature(variant_count)] -#![allow(internal_features)] +// tidy-alphabetical-end extern crate self as rustc_hir; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 8fe81851f93..1927359421d 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -55,21 +55,23 @@ This API is completely unstable and subject to change. */ +// tidy-alphabetical-start +#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::potential_query_instability)] #![allow(rustc::untranslatable_diagnostic)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![allow(internal_features)] #![feature(control_flow_enum)] #![feature(if_let_guard)] #![feature(is_sorted)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] +#![feature(rustdoc_internals)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6f2febd86b0..d32d0183c4e 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1,7 +1,9 @@ //! HIR pretty-printing is layered on top of AST pretty-printing. A number of //! the definitions in this file have equivalents in `rustc_ast_pretty`. +// tidy-alphabetical-start #![recursion_limit = "256"] +// tidy-alphabetical-end use rustc_ast as ast; use rustc_ast::util::parser::{self, AssocOp, Fixity}; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 86fe2756b59..b0fd6de3496 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -1,11 +1,13 @@ +// tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] -#![feature(if_let_guard)] -#![feature(let_chains)] -#![feature(try_blocks)] -#![feature(never_type)] #![feature(box_patterns)] #![feature(control_flow_enum)] +#![feature(if_let_guard)] +#![feature(let_chains)] +#![feature(never_type)] +#![feature(try_blocks)] +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 960a2d012e0..76e3c0682de 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -1,10 +1,12 @@ //! Support for serializing the dep-graph and reloading it. +// tidy-alphabetical-start +#![allow(internal_features)] #![deny(missing_docs)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![allow(internal_features)] +// tidy-alphabetical-end mod assert_dep_graph; mod errors; diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 6fcb3a024ab..db6b250467e 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,9 +1,11 @@ +// tidy-alphabetical-start +#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr( feature = "nightly", feature(extend_one, min_specialization, new_uninit, step_trait, test) )] -#![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(feature = "nightly", allow(internal_features))] +// tidy-alphabetical-end pub mod bit_set; #[cfg(feature = "nightly")] diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs index 015518ae4d6..3e55dd82a6e 100644 --- a/compiler/rustc_index_macros/src/lib.rs +++ b/compiler/rustc_index_macros/src/lib.rs @@ -1,5 +1,7 @@ -#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))] +// tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] +#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))] +// tidy-alphabetical-end use proc_macro::TokenStream; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 28d908abf83..b65ac859667 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -12,22 +12,24 @@ //! //! This API is completely unstable and subject to change. -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![doc(rust_logo)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extend_one)] -#![feature(let_chains)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(iterator_try_collect)] +#![feature(let_chains)] +#![feature(rustdoc_internals)] #![feature(try_blocks)] #![feature(yeet_expr)] #![recursion_limit = "512"] // For rustdoc +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 8b1d9b706ca..0c3d4e19ef8 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -1,7 +1,9 @@ +// tidy-alphabetical-start #![feature(decl_macro)] #![feature(let_chains)] #![feature(thread_spawn_unchecked)] #![feature(try_blocks)] +// tidy-alphabetical-end mod callbacks; mod errors; diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index 6f8a9792b6c..d4efb41eed0 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -19,9 +19,11 @@ //! //! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html +// tidy-alphabetical-start // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] +// tidy-alphabetical-end mod cursor; pub mod unescape; diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index bcb714ae4ce..7dae2de7bfb 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -25,9 +25,10 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(array_windows)] #![feature(box_patterns)] #![feature(control_flow_enum)] @@ -35,9 +36,10 @@ #![feature(if_let_guard)] #![feature(iter_order_by)] #![feature(let_chains)] -#![feature(trait_upcasting)] #![feature(rustc_attrs)] -#![allow(internal_features)] +#![feature(rustdoc_internals)] +#![feature(trait_upcasting)] +// tidy-alphabetical-end mod async_fn_in_trait; pub mod builtin; diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 8bf25024afe..1ce95df3404 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -1,3 +1,4 @@ +// tidy-alphabetical-start pub use self::Level::*; use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; @@ -14,6 +15,7 @@ use rustc_span::edition::Edition; use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::{sym, symbol::Ident, Span, Symbol}; use rustc_target::spec::abi::Abi; +// tidy-alphabetical-end use serde::{Deserialize, Serialize}; diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 6a570c97c88..2b50eac8b63 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -1,7 +1,9 @@ +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![allow(internal_features)] +// tidy-alphabetical-end // NOTE: This crate only exists to allow linking on mingw targets. diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index de9c916b4f0..9d7418cd370 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,3 +1,6 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::default_hash_types)] #![feature(allow_internal_unstable)] #![feature(if_let_guard)] #![feature(let_chains)] @@ -5,8 +8,7 @@ #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] #![feature(proc_macro_tracked_env)] -#![allow(rustc::default_hash_types)] -#![allow(internal_features)] +// tidy-alphabetical-end use synstructure::decl_derive; diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index a1b8b578349..66004179b10 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -1,5 +1,6 @@ //! Construction of MIR from HIR. +// tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] @@ -7,6 +8,7 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(try_blocks)] +// tidy-alphabetical-end mod build; mod check_unsafety; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 0b397a67d45..b0808ba2067 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -1,8 +1,10 @@ +// tidy-alphabetical-start #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(exact_size_is_empty)] #![feature(let_chains)] #![feature(try_blocks)] +// tidy-alphabetical-end use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 551760f4703..3c0f4e9142b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -1,8 +1,10 @@ +// tidy-alphabetical-start #![feature(assert_matches)] #![feature(box_patterns)] #![feature(const_type_name)] #![feature(cow_is_borrowed)] #![feature(decl_macro)] +#![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(is_sorted)] #![feature(let_chains)] @@ -12,7 +14,7 @@ #![feature(round_char_boundary)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![feature(if_let_guard)] +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index eb5f8d92603..aa3b4cd5b67 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -1,5 +1,7 @@ +// tidy-alphabetical-start #![feature(array_windows)] #![feature(is_sorted)] +// tidy-alphabetical-end use rustc_hir::lang_items::LangItem; use rustc_middle::bug; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index b316327a262..25cab7252a3 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -1,5 +1,6 @@ //! The main parser interface. +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] @@ -9,6 +10,7 @@ #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(let_chains)] +// tidy-alphabetical-end use rustc_ast as ast; use rustc_ast::token; diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index ef71333d1c3..7e22644977d 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -4,14 +4,16 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. +// tidy-alphabetical-start +// We want to be able to build this crate with a stable compiler, +// so no `#![feature]` attributes should be added. +#![deny(unstable_features)] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))) )] -// We want to be able to build this crate with a stable compiler, -// so no `#![feature]` attributes should be added. -#![deny(unstable_features)] +// tidy-alphabetical-end use rustc_lexer::unescape; pub use Alignment::*; diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 045a0a1525b..a0f5f98aafc 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -4,13 +4,15 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![allow(internal_features)] #![feature(let_chains)] #![feature(map_try_insert)] +#![feature(rustdoc_internals)] #![feature(try_blocks)] +// tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 4155540886a..c9590ad06b0 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -1,7 +1,9 @@ //! Analysis of patterns, notably match exhaustiveness checking. -#![allow(rustc::untranslatable_diagnostic)] +// tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] +#![allow(rustc::untranslatable_diagnostic)] +// tidy-alphabetical-end pub mod constructor; #[cfg(feature = "rustc")] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 698b28c626d..fb57d42f6df 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1,10 +1,12 @@ +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![allow(internal_features)] #![feature(associated_type_defaults)] -#![feature(try_blocks)] #![feature(let_chains)] +#![feature(rustdoc_internals)] +#![feature(try_blocks)] +// tidy-alphabetical-end mod errors; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 85f55553af3..825c1e2e9bc 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -1,12 +1,14 @@ //! Support for serializing the dep-graph and reloading it. +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::potential_query_instability, unused_parens)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(min_specialization)] #![feature(rustc_attrs)] -#![allow(rustc::potential_query_instability, unused_parens)] -#![allow(internal_features)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index fa07877ab9f..41222e83f7c 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -1,9 +1,11 @@ +// tidy-alphabetical-start +#![allow(rustc::potential_query_instability, internal_features)] #![feature(assert_matches)] #![feature(core_intrinsics)] #![feature(hash_raw_entry)] -#![feature(min_specialization)] #![feature(let_chains)] -#![allow(rustc::potential_query_instability, internal_features)] +#![feature(min_specialization)] +// tidy-alphabetical-end pub mod cache; pub mod dep_graph; diff --git a/compiler/rustc_sanitizers/src/lib.rs b/compiler/rustc_sanitizers/src/lib.rs index 1f73e255490..e4792563e71 100644 --- a/compiler/rustc_sanitizers/src/lib.rs +++ b/compiler/rustc_sanitizers/src/lib.rs @@ -1,7 +1,11 @@ -#![feature(let_chains)] //! Sanitizers support for the Rust compiler. //! //! This crate contains the source code for providing support for the sanitizers to the Rust //! compiler. + +// tidy-alphabetical-start +#![feature(let_chains)] +// tidy-alphabetical-end + pub mod cfi; pub mod kcfi; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 532b749f913..f0e1630c650 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -1,20 +1,22 @@ //! Support code for encoding and decoding types. +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::internal)] +#![cfg_attr(test, feature(test))] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", html_playground_url = "https://play.rust-lang.org/", test(attr(allow(unused_variables), deny(warnings))) )] #![doc(rust_logo)] -#![allow(internal_features)] -#![feature(rustdoc_internals)] #![feature(const_option)] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(never_type)] #![feature(ptr_sub_ptr)] -#![cfg_attr(test, feature(test))] -#![allow(rustc::internal)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end pub use self::serialize::{Decodable, Decoder, Encodable, Encoder}; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index cb02fbdfee9..d93b3eac080 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,9 +1,11 @@ +// tidy-alphabetical-start +#![allow(internal_features)] +#![feature(iter_intersperse)] #![feature(let_chains)] +#![feature(map_many_mut)] #![feature(option_get_or_insert_default)] #![feature(rustc_attrs)] -#![feature(map_many_mut)] -#![feature(iter_intersperse)] -#![allow(internal_features)] +// tidy-alphabetical-end pub mod errors; diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index ddd5ea5510a..9f888875306 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -6,14 +6,16 @@ //! //! This API is still completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] +#![allow(rustc::usage_of_ty_tykind)] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] #![doc(rust_logo)] #![feature(rustdoc_internals)] -#![allow(internal_features)] -#![allow(rustc::usage_of_ty_tykind)] +// tidy-alphabetical-end pub mod rustc_internal; diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 745ae41085b..e65d3080a0a 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -87,11 +87,13 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] #![feature(let_chains)] -#![allow(internal_features)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 381da6f7e2a..50c618bb3bd 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -10,12 +10,12 @@ //! //! This API is completely unstable and subject to change. -#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![doc(rust_logo)] -#![feature(rustdoc_internals)] +// tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![doc(rust_logo)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] @@ -24,8 +24,10 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(never_type)] +#![feature(rustdoc_internals)] #![feature(type_alias_impl_trait)] #![recursion_limit = "512"] // For rustdoc +// tidy-alphabetical-end #[macro_use] extern crate tracing; diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index bc5436f76f1..fdeda34d294 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -1,6 +1,8 @@ //! Queries that are independent from the main solver code. +// tidy-alphabetical-start #![recursion_limit = "256"] +// tidy-alphabetical-end mod codegen; mod dropck_outlives; diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index ffebf7b0721..2b052412e6b 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,8 @@ +// tidy-alphabetical-start +#![allow(unused_variables)] #![feature(alloc_layout_extra)] #![feature(never_type)] -#![allow(unused_variables)] +// tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index bd89265d942..ad0bcbfbbc2 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -4,10 +4,10 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] -#![feature(rustdoc_internals)] -#![allow(internal_features)] #![feature(assert_matches)] #![feature(associated_type_defaults)] #![feature(box_patterns)] @@ -15,6 +15,8 @@ #![feature(iterator_try_collect)] #![feature(let_chains)] #![feature(never_type)] +#![feature(rustdoc_internals)] +// tidy-alphabetical-end use rustc_middle::query::Providers; diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 73716468930..7072b3de07d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,9 +1,11 @@ +// tidy-alphabetical-start +#![allow(rustc::usage_of_ty_tykind)] #![cfg_attr( feature = "nightly", feature(associated_type_defaults, min_specialization, never_type, rustc_attrs, negative_impls) )] -#![allow(rustc::usage_of_ty_tykind)] #![cfg_attr(feature = "nightly", allow(internal_features))] +// tidy-alphabetical-end #[cfg(feature = "nightly")] extern crate self as rustc_type_ir; From af04418a0519d45af1bc41667bffc0c2fce2cef4 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 11 Jun 2024 22:55:55 -0700 Subject: [PATCH 109/153] Make PathBuf less Ok with adding UTF-16 then `into_string` --- library/std/src/sys_common/wtf8.rs | 3 +++ library/std/tests/windows.rs | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 library/std/tests/windows.rs diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index bb1e505285b..84128a4b595 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -477,6 +477,9 @@ impl Wtf8Buf { /// Part of a hack to make PathBuf::push/pop more efficient. #[inline] pub(crate) fn as_mut_vec_for_path_buf(&mut self) -> &mut Vec { + // FIXME: this function should not even exist, as it implies violating Wtf8Buf invariants + // For now, simply assume that is about to happen. + self.is_known_utf8 = false; &mut self.bytes } } diff --git a/library/std/tests/windows.rs b/library/std/tests/windows.rs new file mode 100644 index 00000000000..9f7596f1bc2 --- /dev/null +++ b/library/std/tests/windows.rs @@ -0,0 +1,14 @@ +#![cfg(windows)] +//! An external tests + +use std::{ffi::OsString, os::windows::ffi::OsStringExt, path::PathBuf}; + +#[test] +#[should_panic] +fn os_string_must_know_it_isnt_utf8_issue_126291() { + let mut utf8 = PathBuf::from(OsString::from("utf8".to_owned())); + let non_utf8: OsString = + OsStringExt::from_wide(&[0x6e, 0x6f, 0x6e, 0xd800, 0x75, 0x74, 0x66, 0x38]); + utf8.set_extension(&non_utf8); + utf8.into_os_string().into_string().unwrap(); +} From 39e7bf6826946bea847b8680e73cbca12c8d9732 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jun 2024 14:03:00 +0000 Subject: [PATCH 110/153] Revert "Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb" This reverts commit 1e4bde1cb9736ad4b8d3b95fbfe1533015c1d165, reversing changes made to 4ee97fc3dbcddc9d69701e346a1be9e0b66855a7. --- library/core/src/internal_macros.rs | 41 +++++++++++ library/core/src/lib.rs | 1 - library/core/src/slice/ascii.rs | 9 ++- library/core/src/str/iter.rs | 6 +- library/core/src/str/mod.rs | 104 ++++++++++++++++++---------- 5 files changed, 117 insertions(+), 44 deletions(-) diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index d3a4d6aff2d..bf53b2245ac 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -80,6 +80,47 @@ macro_rules! forward_ref_op_assign { } } +/// Create a zero-size type similar to a closure type, but named. +macro_rules! impl_fn_for_zst { + ($( + $( #[$attr: meta] )* + struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty + $body: block; + )+) => { + $( + $( #[$attr] )* + struct $Name; + + impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + $body + } + } + + impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call_mut( + &mut self, + ($( $arg, )*): ($( $ArgTy, )*) + ) -> $ReturnTy { + Fn::call(&*self, ($( $arg, )*)) + } + } + + impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { + type Output = $ReturnTy; + + #[inline] + extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + Fn::call(&self, ($( $arg, )*)) + } + } + )+ + } +} + /// A macro for defining `#[cfg]` if-else statements. /// /// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 89642d6226a..ef28bc99c4f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -255,7 +255,6 @@ #![feature(trait_alias)] #![feature(transparent_unions)] #![feature(try_blocks)] -#![feature(type_alias_impl_trait)] #![feature(unboxed_closures)] #![feature(unsized_fn_params)] #![feature(with_negative_coherence)] diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 19c91ba2eb9..8ad045275ad 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -108,7 +108,7 @@ impl [u8] { without modifying the original"] #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub fn escape_ascii(&self) -> EscapeAscii<'_> { - EscapeAscii { inner: self.iter().flat_map(|byte| byte.escape_ascii()) } + EscapeAscii { inner: self.iter().flat_map(EscapeByte) } } /// Returns a byte slice with leading ASCII whitespace bytes removed. @@ -190,7 +190,12 @@ impl [u8] { } } -type EscapeByte = impl (Fn(&u8) -> ascii::EscapeDefault) + Copy; +impl_fn_for_zst! { + #[derive(Clone)] + struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault { + ascii::escape_default(*byte) + }; +} /// An iterator over the escaped version of a byte slice. /// diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index d61f04102e5..19627f28e64 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -1274,10 +1274,8 @@ pub struct SplitWhitespace<'a> { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[derive(Clone, Debug)] pub struct SplitAsciiWhitespace<'a> { - pub(super) inner: Map< - Filter, BytesIsNotEmpty<'a>>, - UnsafeBytesToStr<'a>, - >, + pub(super) inner: + Map, BytesIsNotEmpty>, UnsafeBytesToStr>, } /// An iterator over the substrings of a string, diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index edda4d1b687..669cdc92e35 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -983,7 +983,7 @@ impl str { #[cfg_attr(not(test), rustc_diagnostic_item = "str_split_whitespace")] #[inline] pub fn split_whitespace(&self) -> SplitWhitespace<'_> { - SplitWhitespace { inner: self.split(char::is_whitespace).filter(|s| !s.is_empty()) } + SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) } } /// Splits a string slice by ASCII whitespace. @@ -1032,13 +1032,8 @@ impl str { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { - let inner = self - .as_bytes() - .split(u8::is_ascii_whitespace) - .filter(|s| !s.is_empty()) - // SAFETY: the byte slice came from a string and was only split - // along character boundaries, so the resulting slices are strings. - .map(|bytes| unsafe { from_utf8_unchecked(bytes) }); + let inner = + self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr); SplitAsciiWhitespace { inner } } @@ -1090,11 +1085,7 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn lines(&self) -> Lines<'_> { - Lines(self.split_inclusive('\n').map(|line| { - let Some(line) = line.strip_suffix('\n') else { return line }; - let Some(line) = line.strip_suffix('\r') else { return line }; - line - })) + Lines(self.split_inclusive('\n').map(LinesMap)) } /// An iterator over the lines of a string. @@ -2645,19 +2636,14 @@ impl str { #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_debug(&self) -> EscapeDebug<'_> { let mut chars = self.chars(); - let first = chars - .next() - .map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL)) - .into_iter() - .flatten(); - let inner = first.chain(chars.flat_map(|c| { - c.escape_debug_ext(EscapeDebugExtArgs { - escape_grapheme_extended: false, - escape_single_quote: true, - escape_double_quote: true, - }) - })); - EscapeDebug { inner } + EscapeDebug { + inner: chars + .next() + .map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL)) + .into_iter() + .flatten() + .chain(chars.flat_map(CharEscapeDebugContinue)), + } } /// Return an iterator that escapes each char in `self` with [`char::escape_default`]. @@ -2695,7 +2681,7 @@ impl str { without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_default(&self) -> EscapeDefault<'_> { - EscapeDefault { inner: self.chars().flat_map(char::escape_default) } + EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) } } /// Return an iterator that escapes each char in `self` with [`char::escape_unicode`]. @@ -2733,7 +2719,7 @@ impl str { without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_unicode(&self) -> EscapeUnicode<'_> { - EscapeUnicode { inner: self.chars().flat_map(char::escape_unicode) } + EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) } } } @@ -2764,15 +2750,59 @@ impl Default for &mut str { } } -type LinesMap = impl (Fn(&str) -> &str) + Copy; -type CharEscapeDebugContinue = impl (FnMut(char) -> char::EscapeDebug) + Copy; -type CharEscapeUnicode = impl (Fn(char) -> char::EscapeUnicode) + Copy; -type CharEscapeDefault = impl (Fn(char) -> char::EscapeDefault) + Copy; -type IsWhitespace = impl (Fn(char) -> bool) + Copy; -type IsAsciiWhitespace = impl (Fn(&u8) -> bool) + Copy; -type IsNotEmpty = impl (Fn(&&str) -> bool) + Copy; -type BytesIsNotEmpty<'a> = impl (FnMut(&&'a [u8]) -> bool) + Copy; -type UnsafeBytesToStr<'a> = impl (FnMut(&'a [u8]) -> &'a str) + Copy; +impl_fn_for_zst! { + /// A nameable, cloneable fn type + #[derive(Clone)] + struct LinesMap impl<'a> Fn = |line: &'a str| -> &'a str { + let Some(line) = line.strip_suffix('\n') else { return line }; + let Some(line) = line.strip_suffix('\r') else { return line }; + line + }; + + #[derive(Clone)] + struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug { + c.escape_debug_ext(EscapeDebugExtArgs { + escape_grapheme_extended: false, + escape_single_quote: true, + escape_double_quote: true + }) + }; + + #[derive(Clone)] + struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode { + c.escape_unicode() + }; + #[derive(Clone)] + struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault { + c.escape_default() + }; + + #[derive(Clone)] + struct IsWhitespace impl Fn = |c: char| -> bool { + c.is_whitespace() + }; + + #[derive(Clone)] + struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool { + byte.is_ascii_whitespace() + }; + + #[derive(Clone)] + struct IsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b str| -> bool { + !s.is_empty() + }; + + #[derive(Clone)] + struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool { + !s.is_empty() + }; + + #[derive(Clone)] + struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str { + // SAFETY: not safe + unsafe { from_utf8_unchecked(bytes) } + }; +} // This is required to make `impl From<&str> for Box` and `impl From for Box` not overlap. #[stable(feature = "rust1", since = "1.0.0")] From 0bc2001879558ba0d51b6a246f5178853f9ff21e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jun 2024 16:17:38 +0000 Subject: [PATCH 111/153] Require any function with a tait in its signature to actually constrain a hidden type --- .../example/issue-72793.rs | 23 +-- .../src/obligation_forest/mod.rs | 27 +-- compiler/rustc_hir_analysis/messages.ftl | 4 + .../src/collect/type_of/opaque.rs | 15 +- compiler/rustc_hir_analysis/src/errors.rs | 11 ++ compiler/rustc_middle/src/mir/terminator.rs | 155 ++++++++++-------- library/std/src/backtrace.rs | 58 ++++--- ...adata-id-itanium-cxx-abi-const-generics.rs | 23 +-- ...e-metadata-id-itanium-cxx-abi-lifetimes.rs | 21 ++- ...-type-metadata-id-itanium-cxx-abi-paths.rs | 94 +++++------ tests/ui/const-generics/opaque_types.rs | 1 + tests/ui/const-generics/opaque_types.stderr | 43 +++-- tests/ui/consts/const-fn-cycle.rs | 28 ++++ tests/ui/consts/const-fn-cycle.stderr | 34 ++++ .../const-promoted-opaque.atomic.stderr | 71 ++++++++ tests/ui/consts/const-promoted-opaque.rs | 40 +++++ .../const-promoted-opaque.string.stderr | 71 ++++++++ tests/ui/coroutine/layout-error.rs | 25 ++- tests/ui/coroutine/layout-error.stderr | 6 +- .../metadata-sufficient-for-layout.rs | 21 +-- .../metadata-sufficient-for-layout.stderr | 8 - .../future-no-bound-vars-ice-112347.rs | 10 +- tests/ui/impl-trait/issue-108592.rs | 10 +- tests/ui/impl-trait/issues/issue-70877.rs | 31 ++-- tests/ui/impl-trait/issues/issue-70877.stderr | 22 +-- tests/ui/impl-trait/issues/issue-77987.rs | 15 +- tests/ui/impl-trait/issues/issue-86800.rs | 3 + tests/ui/impl-trait/issues/issue-86800.stderr | 52 +++++- tests/ui/impl-trait/issues/issue-89312.rs | 23 ++- .../ui/impl-trait/normalize-tait-in-const.rs | 23 +-- .../impl-trait/normalize-tait-in-const.stderr | 10 +- ...ias-impl-trait-declaration-too-subtle-2.rs | 13 +- ...alias-impl-trait-declaration-too-subtle.rs | 1 + ...s-impl-trait-declaration-too-subtle.stderr | 21 ++- ...o_tait_defining_each_other2.current.stderr | 17 +- .../two_tait_defining_each_other2.rs | 3 +- .../type-alias-impl-trait-in-fn-body.rs | 4 +- .../type-alias-impl-trait-in-fn-body.stderr | 15 ++ tests/ui/mir/issue-75053.rs | 11 +- tests/ui/mir/issue-75053.stderr | 2 +- tests/ui/self/arbitrary-self-opaque.rs | 1 + tests/ui/self/arbitrary-self-opaque.stderr | 15 +- .../type-alias-impl-trait/argument-types.rs | 20 ++- .../assoc-projection-ice.rs | 23 ++- .../bounds-are-checked-2.rs | 11 +- .../bounds-are-checked-2.stderr | 10 +- .../closure-normalization-ice-109020.rs | 12 +- .../ui/type-alias-impl-trait/closure_args.rs | 28 ++-- .../ui/type-alias-impl-trait/closure_args2.rs | 36 ++-- .../const_generic_type.no_infer.stderr | 35 +++- .../const_generic_type.rs | 2 + .../type-alias-impl-trait/constrain_inputs.rs | 2 + .../constrain_inputs.stderr | 38 ++++- .../debug-ty-with-weak.rs | 12 +- .../failed-to-normalize-ice-99945.rs | 2 + .../failed-to-normalize-ice-99945.stderr | 32 +++- .../type-alias-impl-trait/hkl_forbidden4.rs | 2 + .../hkl_forbidden4.stderr | 34 +++- ...e-failed-to-resolve-instance-for-110696.rs | 4 +- ...iled-to-resolve-instance-for-110696.stderr | 30 +++- .../type-alias-impl-trait/implied_bounds.rs | 8 +- .../implied_bounds.stderr | 2 +- .../type-alias-impl-trait/implied_bounds2.rs | 16 +- .../implied_bounds_from_types.rs | 9 +- .../implied_bounds_from_types.stderr | 17 +- .../implied_lifetime_wf_check3.rs | 62 +++++-- .../implied_lifetime_wf_check3.stderr | 44 ++--- .../implied_lifetime_wf_check4_static.rs | 17 +- .../implied_lifetime_wf_check4_static.stderr | 32 ++-- .../ui/type-alias-impl-trait/issue-101750.rs | 20 ++- .../ui/type-alias-impl-trait/issue-109054.rs | 1 + .../type-alias-impl-trait/issue-109054.stderr | 17 +- tests/ui/type-alias-impl-trait/issue-53092.rs | 14 +- .../type-alias-impl-trait/issue-53092.stderr | 33 ++-- tests/ui/type-alias-impl-trait/issue-53096.rs | 9 +- .../type-alias-impl-trait/issue-53096.stderr | 2 +- tests/ui/type-alias-impl-trait/issue-58951.rs | 10 +- tests/ui/type-alias-impl-trait/issue-60407.rs | 13 +- .../type-alias-impl-trait/issue-60407.stderr | 2 +- tests/ui/type-alias-impl-trait/issue-63355.rs | 2 +- .../type-alias-impl-trait/issue-63355.stderr | 15 ++ ...sue-65679-inst-opaque-ty-from-val-twice.rs | 24 +-- tests/ui/type-alias-impl-trait/issue-65918.rs | 11 +- tests/ui/type-alias-impl-trait/issue-72793.rs | 22 ++- .../issue-76202-trait-impl-for-tait.rs | 9 +- .../issue-84660-unsoundness.current.stderr | 17 +- .../issue-84660-unsoundness.next.stderr | 3 +- .../issue-84660-unsoundness.rs | 1 + .../nested-tait-inference3.rs | 7 +- .../nested-tait-inference3.stderr | 15 +- tests/ui/type-alias-impl-trait/nested.rs | 1 + tests/ui/type-alias-impl-trait/nested.stderr | 17 +- .../nested_type_alias_impl_trait.rs | 1 + .../nested_type_alias_impl_trait.stderr | 17 +- .../no_inferrable_concrete_type.rs | 1 + .../no_inferrable_concrete_type.stderr | 15 +- .../normalize-alias-type.rs | 35 ++-- .../outlives-bound-var.rs | 9 +- .../recursive-tait-conflicting-defn.rs | 29 ++-- .../recursive-tait-conflicting-defn.stderr | 12 +- .../rpit_tait_equality_in_canonical_query.rs | 18 +- ...rpit_tait_equality_in_canonical_query_2.rs | 15 +- .../type-alias-impl-trait/self_implication.rs | 21 +-- .../structural-match-no-leak.rs | 14 +- .../structural-match-no-leak.stderr | 2 +- .../type-alias-impl-trait/structural-match.rs | 15 +- .../structural-match.stderr | 4 +- .../type-alias-impl-trait-fns.rs | 3 +- .../type-alias-impl-trait-fns.stderr | 15 ++ .../type-alias-impl-trait-tuple.next.stderr | 15 -- .../type-alias-impl-trait-tuple.rs | 22 +-- .../unbounded_opaque_type.rs | 11 +- .../underef-index-out-of-bounds-121472.rs | 17 +- .../underef-index-out-of-bounds-121472.stderr | 24 +-- .../type-alias-impl-trait/unnameable_type.rs | 7 +- .../unnameable_type.stderr | 24 +-- 116 files changed, 1524 insertions(+), 708 deletions(-) create mode 100644 tests/ui/consts/const-fn-cycle.rs create mode 100644 tests/ui/consts/const-fn-cycle.stderr create mode 100644 tests/ui/consts/const-promoted-opaque.atomic.stderr create mode 100644 tests/ui/consts/const-promoted-opaque.rs create mode 100644 tests/ui/consts/const-promoted-opaque.string.stderr delete mode 100644 tests/ui/coroutine/metadata-sufficient-for-layout.stderr create mode 100644 tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr create mode 100644 tests/ui/type-alias-impl-trait/issue-63355.stderr create mode 100644 tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr delete mode 100644 tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr diff --git a/compiler/rustc_codegen_cranelift/example/issue-72793.rs b/compiler/rustc_codegen_cranelift/example/issue-72793.rs index 166b0060043..2e08fbca8ef 100644 --- a/compiler/rustc_codegen_cranelift/example/issue-72793.rs +++ b/compiler/rustc_codegen_cranelift/example/issue-72793.rs @@ -2,20 +2,23 @@ #![feature(type_alias_impl_trait)] -trait T { - type Item; -} +mod helper { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } -fn filter_positive<'a>() -> Alias<'a> { - &S + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } +use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index d477b86da74..3883b0736db 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -146,8 +146,6 @@ pub enum ProcessResult { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] struct ObligationTreeId(usize); -type ObligationTreeIdGenerator = impl Iterator; - pub struct ObligationForest { /// The list of obligations. In between calls to [Self::process_obligations], /// this list only contains nodes in the `Pending` or `Waiting` state. @@ -310,18 +308,25 @@ pub struct Error { pub backtrace: Vec, } -impl ObligationForest { - pub fn new() -> ObligationForest { - ObligationForest { - nodes: vec![], - done_cache: Default::default(), - active_cache: Default::default(), - reused_node_vec: vec![], - obligation_tree_id_generator: (0..).map(ObligationTreeId), - error_cache: Default::default(), +mod helper { + use super::*; + pub type ObligationTreeIdGenerator = impl Iterator; + impl ObligationForest { + pub fn new() -> ObligationForest { + ObligationForest { + nodes: vec![], + done_cache: Default::default(), + active_cache: Default::default(), + reused_node_vec: vec![], + obligation_tree_id_generator: (0..).map(ObligationTreeId), + error_cache: Default::default(), + } } } +} +use helper::*; +impl ObligationForest { /// Returns the total number of nodes in the forest that have not /// yet been fully resolved. pub fn len(&self) -> usize { diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 67959d9dfed..f697d331aa6 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -460,6 +460,10 @@ hir_analysis_static_specialize = cannot specialize on `'static` lifetime hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature .note = this item must mention the opaque type in its signature in order to be able to register hidden types +hir_analysis_tait_forward_compat2 = item does not constrain `{$opaque_type}`, but has it in its signature + .note = consider moving the opaque type's declaration and defining uses into a separate module + .opaque = this opaque type is in the signature + hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]` hir_analysis_too_large_static = extern static is too large for the current architecture diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 1bec8c496ad..2b2f07001d2 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -8,7 +8,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP}; -use crate::errors::{TaitForwardCompat, TypeOf, UnconstrainedOpaqueType}; +use crate::errors::{TaitForwardCompat, TaitForwardCompat2, TypeOf, UnconstrainedOpaqueType}; pub fn test_opaque_hidden_types(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { let mut res = Ok(()); @@ -229,13 +229,14 @@ impl TaitConstraintLocator<'_> { return; } + let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); + let mut constrained = false; for (&opaque_type_key, &hidden_type) in &tables.concrete_opaque_types { if opaque_type_key.def_id != self.def_id { continue; } constrained = true; - let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id); if !opaque_types_defined_by.contains(&self.def_id) { self.tcx.dcx().emit_err(TaitForwardCompat { @@ -259,6 +260,16 @@ impl TaitConstraintLocator<'_> { if !constrained { debug!("no constraints in typeck results"); + if opaque_types_defined_by.contains(&self.def_id) { + self.tcx.dcx().emit_err(TaitForwardCompat2 { + span: self + .tcx + .def_ident_span(item_def_id) + .unwrap_or_else(|| self.tcx.def_span(item_def_id)), + opaque_type_span: self.tcx.def_span(self.def_id), + opaque_type: self.tcx.def_path_str(self.def_id), + }); + } return; }; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 8a9d4cd4ac7..50e0e372295 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -390,6 +390,17 @@ pub struct TaitForwardCompat { pub item_span: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_tait_forward_compat2)] +#[note] +pub struct TaitForwardCompat2 { + #[primary_span] + pub span: Span, + #[note(hir_analysis_opaque)] + pub opaque_type_span: Span, + pub opaque_type: String, +} + pub struct MissingTypeParams { pub span: Span, pub def_span: Span, diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index f95afb199f7..c8c12e205e1 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -377,9 +377,6 @@ pub struct Terminator<'tcx> { pub kind: TerminatorKind<'tcx>, } -pub type Successors<'a> = impl DoubleEndedIterator + 'a; -pub type SuccessorsMut<'a> = impl DoubleEndedIterator + 'a; - impl<'tcx> Terminator<'tcx> { #[inline] pub fn successors(&self) -> Successors<'_> { @@ -407,81 +404,95 @@ impl<'tcx> TerminatorKind<'tcx> { pub fn if_(cond: Operand<'tcx>, t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> { TerminatorKind::SwitchInt { discr: cond, targets: SwitchTargets::static_if(0, f, t) } } +} - #[inline] - pub fn successors(&self) -> Successors<'_> { - use self::TerminatorKind::*; - match *self { - Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } - | Yield { resume: ref t, drop: Some(u), .. } - | Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. } - | Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. } - | FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => { - slice::from_ref(t).into_iter().copied().chain(Some(u)) +pub use helper::*; + +mod helper { + use super::*; + pub type Successors<'a> = impl DoubleEndedIterator + 'a; + pub type SuccessorsMut<'a> = impl DoubleEndedIterator + 'a; + impl<'tcx> TerminatorKind<'tcx> { + #[inline] + pub fn successors(&self) -> Successors<'_> { + use self::TerminatorKind::*; + match *self { + Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. } + | Yield { resume: ref t, drop: Some(u), .. } + | Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. } + | Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. } + | FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => { + slice::from_ref(t).into_iter().copied().chain(Some(u)) + } + Goto { target: ref t } + | Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. } + | Call { target: Some(ref t), unwind: _, .. } + | Yield { resume: ref t, drop: None, .. } + | Drop { target: ref t, unwind: _, .. } + | Assert { target: ref t, unwind: _, .. } + | FalseUnwind { real_target: ref t, unwind: _ } => { + slice::from_ref(t).into_iter().copied().chain(None) + } + UnwindResume + | UnwindTerminate(_) + | CoroutineDrop + | Return + | Unreachable + | Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None), + InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => { + targets.iter().copied().chain(Some(u)) + } + InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None), + SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None), + FalseEdge { ref real_target, imaginary_target } => { + slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target)) + } } - Goto { target: ref t } - | Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. } - | Call { target: Some(ref t), unwind: _, .. } - | Yield { resume: ref t, drop: None, .. } - | Drop { target: ref t, unwind: _, .. } - | Assert { target: ref t, unwind: _, .. } - | FalseUnwind { real_target: ref t, unwind: _ } => { - slice::from_ref(t).into_iter().copied().chain(None) - } - UnwindResume - | UnwindTerminate(_) - | CoroutineDrop - | Return - | Unreachable - | Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None), - InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => { - targets.iter().copied().chain(Some(u)) - } - InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None), - SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None), - FalseEdge { ref real_target, imaginary_target } => { - slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target)) - } - } - } - - #[inline] - pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { - use self::TerminatorKind::*; - match *self { - Call { target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. } - | Yield { resume: ref mut t, drop: Some(ref mut u), .. } - | Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } - | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } - | FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => { - slice::from_mut(t).into_iter().chain(Some(u)) - } - Goto { target: ref mut t } - | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. } - | Call { target: Some(ref mut t), unwind: _, .. } - | Yield { resume: ref mut t, drop: None, .. } - | Drop { target: ref mut t, unwind: _, .. } - | Assert { target: ref mut t, unwind: _, .. } - | FalseUnwind { real_target: ref mut t, unwind: _ } => { - slice::from_mut(t).into_iter().chain(None) - } - UnwindResume - | UnwindTerminate(_) - | CoroutineDrop - | Return - | Unreachable - | Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None), - InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => { - targets.iter_mut().chain(Some(u)) - } - InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None), - SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None), - FalseEdge { ref mut real_target, ref mut imaginary_target } => { - slice::from_mut(real_target).into_iter().chain(Some(imaginary_target)) + } + + #[inline] + pub fn successors_mut(&mut self) -> SuccessorsMut<'_> { + use self::TerminatorKind::*; + match *self { + Call { + target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), .. + } + | Yield { resume: ref mut t, drop: Some(ref mut u), .. } + | Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } + | Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. } + | FalseUnwind { + real_target: ref mut t, + unwind: UnwindAction::Cleanup(ref mut u), + } => slice::from_mut(t).into_iter().chain(Some(u)), + Goto { target: ref mut t } + | Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. } + | Call { target: Some(ref mut t), unwind: _, .. } + | Yield { resume: ref mut t, drop: None, .. } + | Drop { target: ref mut t, unwind: _, .. } + | Assert { target: ref mut t, unwind: _, .. } + | FalseUnwind { real_target: ref mut t, unwind: _ } => { + slice::from_mut(t).into_iter().chain(None) + } + UnwindResume + | UnwindTerminate(_) + | CoroutineDrop + | Return + | Unreachable + | Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None), + InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => { + targets.iter_mut().chain(Some(u)) + } + InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None), + SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None), + FalseEdge { ref mut real_target, ref mut imaginary_target } => { + slice::from_mut(real_target).into_iter().chain(Some(imaginary_target)) + } } } } +} +impl<'tcx> TerminatorKind<'tcx> { #[inline] pub fn unwind(&self) -> Option<&UnwindAction> { match *self { diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 475b3e7eb93..e3e0cde8afe 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -428,39 +428,43 @@ impl fmt::Display for Backtrace { } } -type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe; +mod helper { + use super::*; + pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe; -fn lazy_resolve(mut capture: Capture) -> LazyResolve { - move || { - // Use the global backtrace lock to synchronize this as it's a - // requirement of the `backtrace` crate, and then actually resolve - // everything. - let _lock = lock(); - for frame in capture.frames.iter_mut() { - let symbols = &mut frame.symbols; - let frame = match &frame.frame { - RawFrame::Actual(frame) => frame, - #[cfg(test)] - RawFrame::Fake => unimplemented!(), - }; - unsafe { - backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { - symbols.push(BacktraceSymbol { - name: symbol.name().map(|m| m.as_bytes().to_vec()), - filename: symbol.filename_raw().map(|b| match b { - BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()), - BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()), - }), - lineno: symbol.lineno(), - colno: symbol.colno(), + pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve { + move || { + // Use the global backtrace lock to synchronize this as it's a + // requirement of the `backtrace` crate, and then actually resolve + // everything. + let _lock = lock(); + for frame in capture.frames.iter_mut() { + let symbols = &mut frame.symbols; + let frame = match &frame.frame { + RawFrame::Actual(frame) => frame, + #[cfg(test)] + RawFrame::Fake => unimplemented!(), + }; + unsafe { + backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { + symbols.push(BacktraceSymbol { + name: symbol.name().map(|m| m.as_bytes().to_vec()), + filename: symbol.filename_raw().map(|b| match b { + BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()), + BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()), + }), + lineno: symbol.lineno(), + colno: symbol.colno(), + }); }); - }); + } } - } - capture + capture + } } } +use helper::*; impl RawFrame { fn ip(&self) -> *mut c_void { diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs index 25dba97962a..3edc68e1347 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs @@ -9,15 +9,18 @@ extern crate core; -pub type Type1 = impl Send; +mod defining_module { + pub type Type1 = impl Send; -pub fn foo() -where - Type1: 'static, -{ - pub struct Foo([T; N]); - let _: Type1 = Foo([0; 32]); + pub fn foo() + where + Type1: 'static, + { + pub struct Foo([T; N]); + let _: Type1 = Foo([0; 32]); + } } +use defining_module::*; pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} @@ -26,6 +29,6 @@ pub fn foo2(_: Type1, _: Type1) {} pub fn foo3(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}4foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EEE"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_E"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo3FooIu3i32Lu5usize32EES2_S2_E"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EEE"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo3FooIu3i32Lu5usize32EES2_S2_E"} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs index 3ef119fd905..09cfd2e10d6 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs @@ -9,17 +9,22 @@ extern crate core; -pub type Type1 = impl Send; +mod defining_module { -pub fn foo<'a>() -where - Type1: 'static, -{ - pub struct Foo<'a>(&'a i32); - pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>); - let _: Type1 = Bar; + pub type Type1 = impl Send; + + pub fn foo<'a>() + where + Type1: 'static, + { + pub struct Foo<'a>(&'a i32); + pub struct Bar<'a, 'b>(&'a i32, &'b Foo<'b>); + let _: Type1 = Bar; + } } +use defining_module::*; + pub fn foo1(_: Type1) {} // CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} pub fn foo2(_: Type1, _: Type1) {} diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs index 9870ecc69ba..ffbfe021ba3 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs @@ -9,45 +9,47 @@ extern crate core; -pub type Type1 = impl Send; -pub type Type2 = impl Send; -pub type Type3 = impl Send; -pub type Type4 = impl Send; +mod defining_module { + pub type Type1 = impl Send; + pub type Type2 = impl Send; + pub type Type3 = impl Send; + pub type Type4 = impl Send; -pub fn foo() -where - Type1: 'static, - Type2: 'static, - Type3: 'static, - Type4: 'static, -{ - // Type in extern path - extern "C" { - fn bar(); - } - let _: Type1 = bar; - - // Type in closure path - || { - pub struct Foo; - let _: Type2 = Foo; - }; - - // Type in const path - const { - pub struct Foo; - fn bar() -> Type3 { - Foo + pub fn foo() + where + Type1: 'static, + Type2: 'static, + Type4: 'static, + { + // Type in extern path + extern "C" { + fn bar(); } - }; + let _: Type1 = bar; - // Type in impl path - struct Foo; - impl Foo { - fn bar(&self) {} + // Type in closure path + || { + pub struct Foo; + let _: Type2 = Foo; + }; + + // Type in const path + const { + pub struct Foo; + fn bar() -> Type3 { + Foo + } + }; + + // Type in impl path + struct Foo; + impl Foo { + fn bar(&self) {} + } + let _: Type4 = ::bar; } - let _: Type4 = ::bar; } +use defining_module::*; // Force arguments to be passed by using a reference. Otherwise, they may end up PassMode::Ignore @@ -76,15 +78,15 @@ pub fn foo11(_: &Type4, _: &Type4) {} pub fn foo12(_: &Type4, _: &Type4, _: &Type4) {} // CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} -// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"} -// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"} -// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"} -// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"} -// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"} -// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"} -// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"} -// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"} -// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"} -// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"} -// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"} -// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvC{{[[:print:]]+}}_{{[[:print:]]+}}3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barEE"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_E"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNFNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo10{{[{}][{}]}}extern{{[}][}]}}3barES0_S0_E"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooEE"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNCNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo11{{[{}][{}]}}closure{{[}][}]}}3FooES0_S0_E"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooEE"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_E"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NtNkNvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo12{{[{}][{}]}}constant{{[}][}]}}3FooES0_S0_E"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barEE"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_E"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu{{[0-9]+}}NvNINvNtC{{[[:print:]]+}}_{{[[:print:]]+}}15defining_module3foo8{{[{}][{}]}}impl{{[}][}]}}3barES0_S0_E"} diff --git a/tests/ui/const-generics/opaque_types.rs b/tests/ui/const-generics/opaque_types.rs index ccf70f4fb37..2c7170c889f 100644 --- a/tests/ui/const-generics/opaque_types.rs +++ b/tests/ui/const-generics/opaque_types.rs @@ -6,6 +6,7 @@ type Foo = impl Sized; fn foo() {} //~^ ERROR: `Foo` is forbidden as the type of a const generic parameter +//~| ERROR: item does not constrain fn main() { foo::<42>(); diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr index f03bca69a8b..2c7384984c6 100644 --- a/tests/ui/const-generics/opaque_types.stderr +++ b/tests/ui/const-generics/opaque_types.stderr @@ -1,5 +1,18 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/opaque_types.rs:7:4 + | +LL | fn foo() {} + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/opaque_types.rs:3:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + error[E0308]: mismatched types - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | type Foo = impl Sized; | ---------- the expected opaque type @@ -22,27 +35,27 @@ note: ...which requires computing type of opaque `Foo::{opaque#0}`... LL | type Foo = impl Sized; | ^^^^^^^^^^ note: ...which requires type-checking `main`... - --> $DIR/opaque_types.rs:10:1 + --> $DIR/opaque_types.rs:11:1 | LL | fn main() { | ^^^^^^^^^ note: ...which requires evaluating type-level constant... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires const-evaluating + checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires caching mir of `main::{constant#0}` for CTFE... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires elaborating drops for `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ @@ -70,42 +83,42 @@ LL | type Foo = impl Sized; | ^^^^^^^^^^ | note: ...which requires type-checking `main`... - --> $DIR/opaque_types.rs:10:1 + --> $DIR/opaque_types.rs:11:1 | LL | fn main() { | ^^^^^^^^^ note: ...which requires evaluating type-level constant... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires const-evaluating + checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires caching mir of `main::{constant#0}` for CTFE... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires elaborating drops for `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires borrow-checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires promoting constants in MIR for `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ note: ...which requires const checking `main::{constant#0}`... - --> $DIR/opaque_types.rs:11:11 + --> $DIR/opaque_types.rs:12:11 | LL | foo::<42>(); | ^^ @@ -119,7 +132,7 @@ LL | type Foo = impl Sized; | ^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0308, E0391. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-fn-cycle.rs b/tests/ui/consts/const-fn-cycle.rs new file mode 100644 index 00000000000..5175296a53e --- /dev/null +++ b/tests/ui/consts/const-fn-cycle.rs @@ -0,0 +1,28 @@ +/// Discovered in https://github.com/rust-lang/rust/issues/112602. +/// This caused a cycle error, which made no sense. +/// Removing the `const` part of the `many` function would make the +/// test pass again. +/// The issue was that we were running const qualif checks on +/// `const fn`s, but never using them. During const qualif checks we tend +/// to end up revealing opaque types (the RPIT in `many`'s return type), +/// which can quickly lead to cycles. + +pub struct Parser(H); + +impl Parser +where + H: for<'a> Fn(&'a str) -> T, +{ + pub const fn new(handler: H) -> Parser { + Parser(handler) + } + + pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + //~^ ERROR: cycle detected + Parser::new(|_| unimplemented!()) + } +} + +fn main() { + println!("Hello, world!"); +} diff --git a/tests/ui/consts/const-fn-cycle.stderr b/tests/ui/consts/const-fn-cycle.stderr new file mode 100644 index 00000000000..c851f7342be --- /dev/null +++ b/tests/ui/consts/const-fn-cycle.stderr @@ -0,0 +1,34 @@ +error[E0391]: cycle detected when computing type of opaque `::many::{opaque#0}` + --> $DIR/const-fn-cycle.rs:20:47 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires borrow-checking `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `::many`... + --> $DIR/const-fn-cycle.rs:20:5 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `Parser<::many::{opaque#0}>` is freeze... + = note: ...which requires evaluating trait selection obligation `Parser<::many::{opaque#0}>: core::marker::Freeze`... + = note: ...which again requires computing type of opaque `::many::{opaque#0}`, completing the cycle +note: cycle used when computing type of `::many::{opaque#0}` + --> $DIR/const-fn-cycle.rs:20:47 + | +LL | pub const fn many<'s>(&'s self) -> Parser Fn(&'a str) -> Vec + 's> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr new file mode 100644 index 00000000000..a0459f4040e --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -0,0 +1,71 @@ +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/const-promoted-opaque.rs:29:25 + | +LL | let _: &'static _ = &FOO; + | ^^^^ + | + = note: see issue #80384 for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:29:26 + | +LL | let _: &'static _ = &FOO; + | ^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here + +error[E0492]: constants cannot refer to interior mutable data + --> $DIR/const-promoted-opaque.rs:34:19 + | +LL | const BAZ: &Foo = &FOO; + | ^^^^ this borrow of an interior mutable value may end up in the final value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:38:26 + | +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement + +error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:14:20 + | +LL | pub type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:21:5 + | +LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:21:5 + | +LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:21:5 + | +LL | pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + | ^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `helper::Foo` is freeze... + = note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`... + = note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `helper::Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:14:20 + | +LL | pub type Foo = impl Sized; + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/consts/const-promoted-opaque.rs b/tests/ui/consts/const-promoted-opaque.rs new file mode 100644 index 00000000000..e20823527f4 --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.rs @@ -0,0 +1,40 @@ +//@revisions: string unit atomic +#![feature(type_alias_impl_trait)] + +//! Check that we do not cause cycle errors when trying to +//! obtain information about interior mutability of an opaque type. +//! This used to happen, because when the body-analysis failed, we +//! checked the type instead, but the constant was also defining the +//! hidden type of the opaque type. Thus we ended up relying on the +//! result of our analysis to compute the result of our analysis. + +//@[unit] check-pass + +mod helper { + pub type Foo = impl Sized; + //[string,atomic]~^ ERROR cycle detected + + #[cfg(string)] + pub const FOO: Foo = String::new(); + + #[cfg(atomic)] + pub const FOO: Foo = std::sync::atomic::AtomicU8::new(42); + + #[cfg(unit)] + pub const FOO: Foo = (); +} +use helper::*; + +const BAR: () = { + let _: &'static _ = &FOO; + //[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time + //[string,atomic]~| ERROR: cannot borrow here +}; + +const BAZ: &Foo = &FOO; +//[string,atomic]~^ ERROR: constants cannot refer to interior mutable data + +fn main() { + let _: &'static _ = &FOO; + //[string,atomic]~^ ERROR: temporary value dropped while borrowed +} diff --git a/tests/ui/consts/const-promoted-opaque.string.stderr b/tests/ui/consts/const-promoted-opaque.string.stderr new file mode 100644 index 00000000000..a613d517e68 --- /dev/null +++ b/tests/ui/consts/const-promoted-opaque.string.stderr @@ -0,0 +1,71 @@ +error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability + --> $DIR/const-promoted-opaque.rs:29:25 + | +LL | let _: &'static _ = &FOO; + | ^^^^ + | + = note: see issue #80384 for more information + = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time + --> $DIR/const-promoted-opaque.rs:29:26 + | +LL | let _: &'static _ = &FOO; + | ^^^ the destructor for this type cannot be evaluated in constants +... +LL | }; + | - value is dropped here + +error[E0492]: constants cannot refer to interior mutable data + --> $DIR/const-promoted-opaque.rs:34:19 + | +LL | const BAZ: &Foo = &FOO; + | ^^^^ this borrow of an interior mutable value may end up in the final value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/const-promoted-opaque.rs:38:26 + | +LL | let _: &'static _ = &FOO; + | ---------- ^^^ creates a temporary value which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | +LL | } + | - temporary value is freed at the end of this statement + +error[E0391]: cycle detected when computing type of opaque `helper::Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:14:20 + | +LL | pub type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:18:5 + | +LL | pub const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^^^^^ +note: ...which requires promoting constants in MIR for `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:18:5 + | +LL | pub const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^^^^^ +note: ...which requires const checking `helper::FOO`... + --> $DIR/const-promoted-opaque.rs:18:5 + | +LL | pub const FOO: Foo = String::new(); + | ^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing whether `helper::Foo` is freeze... + = note: ...which requires evaluating trait selection obligation `helper::Foo: core::marker::Freeze`... + = note: ...which again requires computing type of opaque `helper::Foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `helper::Foo::{opaque#0}` + --> $DIR/const-promoted-opaque.rs:14:20 + | +LL | pub type Foo = impl Sized; + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0391, E0492, E0493, E0658, E0716. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 70a0248eabc..3e26cf17d29 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -16,13 +16,22 @@ impl Task { } } -fn main() { - async fn cb() { - let a = Foo; //~ ERROR cannot find value `Foo` in this scope - } +mod helper { + use super::*; + pub type F = impl Future; + fn foo() + where + F:, + { + async fn cb() { + let a = Foo; //~ ERROR cannot find value `Foo` in this scope + } - type F = impl Future; - // Check that statics are inhabited computes they layout. - static POOL: Task = Task::new(); - Task::spawn(&POOL, || cb()); + Task::spawn(&POOL, || cb()); + } } + +// Check that statics are inhabited computes they layout. +static POOL: Task = Task::new(); + +fn main() {} diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index 249a99e9b85..ceadb62c999 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,8 +1,8 @@ error[E0425]: cannot find value `Foo` in this scope - --> $DIR/layout-error.rs:21:17 + --> $DIR/layout-error.rs:27:21 | -LL | let a = Foo; - | ^^^ not found in this scope +LL | let a = Foo; + | ^^^ not found in this scope error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/metadata-sufficient-for-layout.rs index 23937e12c52..9c3a7e4378e 100644 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.rs +++ b/tests/ui/coroutine/metadata-sufficient-for-layout.rs @@ -4,22 +4,23 @@ // Regression test for #80998. // //@ aux-build:metadata-sufficient-for-layout.rs +//@ check-pass #![feature(type_alias_impl_trait, rustc_attrs)] #![feature(coroutine_trait)] extern crate metadata_sufficient_for_layout; -use std::ops::Coroutine; +mod helper { + use std::ops::Coroutine; + pub type F = impl Coroutine<(), Yield = (), Return = ()>; -type F = impl Coroutine<(), Yield = (), Return = ()>; - -// Static queries the layout of the coroutine. -static A: Option = None; - -fn f() -> F { - metadata_sufficient_for_layout::g() + fn f() -> F { + metadata_sufficient_for_layout::g() + } } -#[rustc_error] -fn main() {} //~ ERROR +// Static queries the layout of the coroutine. +static A: Option = None; + +fn main() {} diff --git a/tests/ui/coroutine/metadata-sufficient-for-layout.stderr b/tests/ui/coroutine/metadata-sufficient-for-layout.stderr deleted file mode 100644 index c7860fde2a9..00000000000 --- a/tests/ui/coroutine/metadata-sufficient-for-layout.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: fatal error triggered by #[rustc_error] - --> $DIR/metadata-sufficient-for-layout.rs:25:1 - | -LL | fn main() {} - | ^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs index dc4dc9e220d..af623dc7cd9 100644 --- a/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs +++ b/tests/ui/impl-trait/future-no-bound-vars-ice-112347.rs @@ -7,11 +7,15 @@ use std::future::Future; -type Fut<'a> = impl Future + 'a; +mod foo { + use std::future::Future; + pub type Fut<'a> = impl Future + 'a; -fn foo<'a>(_: &()) -> Fut<'_> { - async {} + fn foo<'a>(_: &()) -> Fut<'_> { + async {} + } } +use foo::*; trait Test { fn hello(); diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs index 624bb79006e..7db2e31549c 100644 --- a/tests/ui/impl-trait/issue-108592.rs +++ b/tests/ui/impl-trait/issue-108592.rs @@ -11,9 +11,13 @@ fn test_closure() { closure(&opaque()); } -type Opaque2 = impl Sized; -type Opaque<'a> = Opaque2; -fn define<'a>() -> Opaque<'a> {} +mod helper { + pub type Opaque2 = impl Sized; + pub type Opaque<'a> = Opaque2; + fn define<'a>() -> Opaque<'a> {} +} + +use helper::*; fn test_tait(_: &Opaque<'_>) { None::<&'static Opaque<'_>>; diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index df772298674..6ced0bbba8b 100644 --- a/tests/ui/impl-trait/issues/issue-70877.rs +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -1,10 +1,8 @@ #![feature(type_alias_impl_trait)] type FooArg<'a> = &'a dyn ToString; -type FooRet = impl std::fmt::Debug; type FooItem = Box FooRet>; -type Foo = impl Iterator; #[repr(C)] struct Bar(u8); @@ -17,19 +15,26 @@ impl Iterator for Bar { } } -fn quux(st: FooArg) -> FooRet { - Some(st.to_string()) +mod ret { + pub type FooRet = impl std::fmt::Debug; + pub fn quux(st: super::FooArg) -> FooRet { + Some(st.to_string()) + } } - -fn ham() -> Foo { - Bar(1) -} - -fn oof(_: Foo) -> impl std::fmt::Debug { - let mut bar = ham(); - let func = bar.next().unwrap(); - return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type +use ret::*; +mod foo { + pub type Foo = impl Iterator; + pub fn ham() -> Foo { + super::Bar(1) + } + pub fn oof(_: Foo) -> impl std::fmt::Debug { + //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature + let mut bar = ham(); + let func = bar.next().unwrap(); + return func(&"oof"); + } } +use foo::*; fn main() { let _ = oof(ham()); diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr index 274139f01d0..4b23a02aaee 100644 --- a/tests/ui/impl-trait/issues/issue-70877.stderr +++ b/tests/ui/impl-trait/issues/issue-70877.stderr @@ -1,19 +1,15 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/issue-70877.rs:31:12 +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/issue-70877.rs:30:12 | -LL | return func(&"oof"); - | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope +LL | pub fn oof(_: Foo) -> impl std::fmt::Debug { + | ^^^ | -note: opaque type whose hidden type is being assigned - --> $DIR/issue-70877.rs:28:19 + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-70877.rs:26:20 | -LL | fn oof(_: Foo) -> impl std::fmt::Debug { - | ^^^^^^^^^^^^^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/issue-70877.rs:4:15 - | -LL | type FooRet = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ +LL | pub type Foo = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/issues/issue-77987.rs b/tests/ui/impl-trait/issues/issue-77987.rs index b77f993effc..a7e7b067d5f 100644 --- a/tests/ui/impl-trait/issues/issue-77987.rs +++ b/tests/ui/impl-trait/issues/issue-77987.rs @@ -2,19 +2,20 @@ //@ check-pass -trait Foo {} +pub trait Foo {} impl Foo for U {} -type Scope = impl Foo<()>; +mod scope { + pub type Scope = impl super::Foo<()>; -#[allow(unused)] -fn infer_scope() -> Scope { - () + #[allow(unused)] + fn infer_scope() -> Scope { + () + } } #[allow(unused)] -fn ice() -> impl Foo -{ +fn ice() -> impl Foo { loop {} } diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index 172ab04f58d..5a6959ad7e6 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -26,6 +26,7 @@ type TransactionFuture<'__, O> = impl '__ + Future //~^ ERROR unconstrained opaque type fn execute_transaction_fut<'f, F, O>( + //~^ ERROR: item does not constrain f: F, ) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> where @@ -37,10 +38,12 @@ where impl Context { async fn do_transaction( + //~^ ERROR: item does not constrain &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> ) -> TransactionResult { //~^ ERROR expected generic lifetime parameter, found `'_` + //~| ERROR: item does not constrain let mut conn = Connection {}; let mut transaction = TestTransaction { conn: &mut conn }; f(&mut transaction).await diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index 146d2f67942..095f648143c 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -1,3 +1,48 @@ +error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature + --> $DIR/issue-86800.rs:28:4 + | +LL | fn execute_transaction_fut<'f, F, O>( + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-86800.rs:25:34 + | +LL | type TransactionFuture<'__, O> = impl '__ + Future>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature + --> $DIR/issue-86800.rs:40:14 + | +LL | async fn do_transaction( + | ^^^^^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-86800.rs:25:34 + | +LL | type TransactionFuture<'__, O> = impl '__ + Future>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature + --> $DIR/issue-86800.rs:44:5 + | +LL | / { +LL | | +LL | | +LL | | let mut conn = Connection {}; +LL | | let mut transaction = TestTransaction { conn: &mut conn }; +LL | | f(&mut transaction).await +LL | | } + | |_____^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-86800.rs:25:34 + | +LL | type TransactionFuture<'__, O> = impl '__ + Future>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/issue-86800.rs:25:34 | @@ -7,7 +52,7 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future $DIR/issue-86800.rs:34:5 + --> $DIR/issue-86800.rs:35:5 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | --- this generic parameter must be used with a generic lifetime parameter @@ -16,19 +61,20 @@ LL | f | ^ error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-86800.rs:42:5 + --> $DIR/issue-86800.rs:44:5 | LL | type TransactionFuture<'__, O> = impl '__ + Future>; | --- this generic parameter must be used with a generic lifetime parameter ... LL | / { LL | | +LL | | LL | | let mut conn = Connection {}; LL | | let mut transaction = TestTransaction { conn: &mut conn }; LL | | f(&mut transaction).await LL | | } | |_____^ -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issues/issue-89312.rs b/tests/ui/impl-trait/issues/issue-89312.rs index 4304e3bc1b4..3b0e976780b 100644 --- a/tests/ui/impl-trait/issues/issue-89312.rs +++ b/tests/ui/impl-trait/issues/issue-89312.rs @@ -2,18 +2,23 @@ //@ check-pass -trait T { type Item; } +mod helper { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} - -fn filter_positive<'a>() -> Alias<'a> { - &S + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } + + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } +use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs index 422c2e439cf..fc90139d640 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.rs +++ b/tests/ui/impl-trait/normalize-tait-in-const.rs @@ -6,20 +6,23 @@ use std::marker::Destruct; -trait T { - type Item; -} +mod foo { + trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } -const fn filter_positive<'a>() -> &'a Alias<'a> { - &&S + pub const fn filter_positive<'a>() -> &'a Alias<'a> { + &&S + } } +use foo::*; const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { fun(filter_positive()); diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index 9ea4ff7cc70..5e3c0ea054b 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -1,11 +1,11 @@ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/normalize-tait-in-const.rs:24:42 + --> $DIR/normalize-tait-in-const.rs:27:42 | LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^^^^^^^^^^^^^^^ error[E0015]: cannot call non-const closure in constant functions - --> $DIR/normalize-tait-in-const.rs:25:5 + --> $DIR/normalize-tait-in-const.rs:28:5 | LL | fun(filter_positive()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -13,15 +13,15 @@ LL | fun(filter_positive()); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants help: consider further restricting this bound | -LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&Alias<'_>)>(fun: F) { - | +++++++++++++++++++++++ +LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct + ~const Fn(&foo::Alias<'_>)>(fun: F) { + | ++++++++++++++++++++++++++++ help: add `#![feature(effects)]` to the crate attributes to enable | LL + #![feature(effects)] | error[E0493]: destructor of `F` cannot be evaluated at compile-time - --> $DIR/normalize-tait-in-const.rs:24:79 + --> $DIR/normalize-tait-in-const.rs:27:79 | LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^ the destructor for this type cannot be evaluated in constant functions diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs index b369544782c..0b29af5df5b 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs @@ -2,7 +2,14 @@ //@ check-pass -type Foo = impl PartialEq<(Foo, i32)>; +mod foo { + pub type Foo = impl PartialEq<(Foo, i32)>; + + fn foo() -> Foo { + super::Bar + } +} +use foo::Foo; struct Bar; @@ -12,8 +19,4 @@ impl PartialEq<(Foo, i32)> for Bar { } } -fn foo() -> Foo { - Bar -} - fn main() {} diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs index 91f1ed48133..dc9424c3ca7 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs @@ -9,6 +9,7 @@ mod a { impl PartialEq<(Bar, i32)> for Bar { fn eq(&self, _other: &(Foo, i32)) -> bool { //~^ ERROR: `eq` has an incompatible type for trait + //~| ERROR: item does not constrain `a::Foo::{opaque#0}` true } } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index 07ac1a37e75..4352af1c0df 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -1,3 +1,16 @@ +error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12 + | +LL | fn eq(&self, _other: &(Foo, i32)) -> bool { + | ^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 + | +LL | type Foo = impl PartialEq<(Foo, i32)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 | @@ -22,7 +35,7 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool { found signature `fn(&a::Bar, &(a::Foo, _)) -> _` error: unconstrained opaque type - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16 | LL | type Foo = impl PartialEq<(Foo, i32)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,7 +43,7 @@ LL | type Foo = impl PartialEq<(Foo, i32)>; = note: `Foo` must be used in combination with a concrete type within the same module error[E0053]: method `eq` has an incompatible type for trait - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30 | LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type @@ -44,11 +57,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { = note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _` found signature `fn(&b::Bar, &(b::Bar, _)) -> _` note: this item must have the opaque type in its signature in order to be able to register hidden types - --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12 + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12 | LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr index 6f2b2d9ca04..b70676ece0e 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr @@ -1,3 +1,16 @@ +error: item does not constrain `A::{opaque#0}`, but has it in its signature + --> $DIR/two_tait_defining_each_other2.rs:11:4 + | +LL | fn muh(x: A) -> B { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/two_tait_defining_each_other2.rs:6:10 + | +LL | type A = impl Foo; + | ^^^^^^^^ + error: unconstrained opaque type --> $DIR/two_tait_defining_each_other2.rs:6:10 | @@ -7,7 +20,7 @@ LL | type A = impl Foo; = note: `A` must be used in combination with a concrete type within the same module error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/two_tait_defining_each_other2.rs:13:5 + --> $DIR/two_tait_defining_each_other2.rs:14:5 | LL | x // B's hidden type is A (opaquely) | ^ one of the two opaque types used here has to be outside its defining scope @@ -23,5 +36,5 @@ note: opaque type being used as hidden type LL | type A = impl Foo; | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index e850736fdfa..3311c556568 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -9,7 +9,8 @@ type B = impl Foo; trait Foo {} fn muh(x: A) -> B { - //[next]~^ ERROR type annotations needed: cannot satisfy `_ == A` + //[current]~^ ERROR: item does not constrain `A::{opaque#0}` + //[next]~^^ ERROR: cannot satisfy `_ == A` x // B's hidden type is A (opaquely) //[current]~^ ERROR opaque type's hidden type cannot be another opaque type } diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs index 92699831580..4879d2db40b 100644 --- a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs +++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs @@ -1,10 +1,12 @@ -//@ build-pass (FIXME(62277): could be check-pass?) +//! Test that it is basically not possible to declare *and opaquely use* opaque types +//! in function bodies. This will work again once we have a `#[defines]` attribute #![feature(type_alias_impl_trait)] use std::fmt::Debug; fn main() { + //~^ ERROR: item does not constrain type Existential = impl Debug; fn f() -> Existential {} diff --git a/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr new file mode 100644 index 00000000000..7744fa2f2ae --- /dev/null +++ b/tests/ui/impl-trait/type-alias-impl-trait-in-fn-body.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `Existential::{opaque#0}`, but has it in its signature + --> $DIR/type-alias-impl-trait-in-fn-body.rs:8:4 + | +LL | fn main() { + | ^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/type-alias-impl-trait-in-fn-body.rs:10:24 + | +LL | type Existential = impl Debug; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/mir/issue-75053.rs b/tests/ui/mir/issue-75053.rs index e2ec4076b49..38684f3548f 100644 --- a/tests/ui/mir/issue-75053.rs +++ b/tests/ui/mir/issue-75053.rs @@ -13,10 +13,13 @@ trait MyFrom: Sized { fn my_from(value: T) -> Result; } -trait F {} -impl F for () {} -type DummyT = impl F; -fn _dummy_t() -> DummyT {} +mod f { + pub trait F {} + impl F for () {} + pub type DummyT = impl F; + fn _dummy_t() -> DummyT {} +} +use f::*; struct Phantom1(PhantomData); struct Phantom2(PhantomData); diff --git a/tests/ui/mir/issue-75053.stderr b/tests/ui/mir/issue-75053.stderr index bd37f0c92ad..a464d3266f4 100644 --- a/tests/ui/mir/issue-75053.stderr +++ b/tests/ui/mir/issue-75053.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-75053.rs:46:1 + --> $DIR/issue-75053.rs:49:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs index 3331b037b05..3c2e2d9db72 100644 --- a/tests/ui/self/arbitrary-self-opaque.rs +++ b/tests/ui/self/arbitrary-self-opaque.rs @@ -7,6 +7,7 @@ type Bar = impl Sized; impl Foo { fn foo(self: Bar) {} //~^ ERROR: invalid `self` parameter type: `Bar` + //~| ERROR: item does not constrain } fn main() {} diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index 0cbe22afac3..5ccc076bfaf 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -1,3 +1,16 @@ +error: item does not constrain `Bar::{opaque#0}`, but has it in its signature + --> $DIR/arbitrary-self-opaque.rs:8:8 + | +LL | fn foo(self: Bar) {} + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/arbitrary-self-opaque.rs:4:12 + | +LL | type Bar = impl Sized; + | ^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/arbitrary-self-opaque.rs:4:12 | @@ -15,6 +28,6 @@ LL | fn foo(self: Bar) {} = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/argument-types.rs b/tests/ui/type-alias-impl-trait/argument-types.rs index 9e4a8bb8dda..7382d4c78c7 100644 --- a/tests/ui/type-alias-impl-trait/argument-types.rs +++ b/tests/ui/type-alias-impl-trait/argument-types.rs @@ -1,13 +1,21 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] //@ check-pass -use std::fmt::Debug; -type Foo = impl Debug; +mod foo { + use std::fmt::Debug; -fn foo1(mut x: Foo) { - x = 22_u32; + pub type Foo = impl Debug; + + fn foo1(mut x: Foo) { + x = 22_u32; + } + + pub fn foo_value() -> Foo { + 11_u32 + } } +use foo::*; fn foo2(mut x: Foo) { // no constraint on x @@ -17,10 +25,6 @@ fn foo3(x: Foo) { println!("{:?}", x); } -fn foo_value() -> Foo { - 11_u32 -} - fn main() { foo3(foo_value()); } diff --git a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs index 761402582e2..9dcbc75db3f 100644 --- a/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs +++ b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs @@ -2,18 +2,23 @@ //@ build-pass -trait T { type Item; } +mod helper { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} - -fn filter_positive<'a>() -> Alias<'a> { - &S + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } + + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } +use helper::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs index 55b4dc8dc23..45f54266014 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs @@ -3,12 +3,15 @@ #![feature(type_alias_impl_trait)] -type X = impl Clone; +mod foo { + pub type X = impl Clone; -fn f(t: T) -> X { - t - //~^ ERROR the trait bound `T: Clone` is not satisfied + fn f(t: T) -> X { + t + //~^ ERROR the trait bound `T: Clone` is not satisfied + } } +use foo::X; fn g(o: Option>) -> Option> { o.clone() diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr index 20e478160c6..0c937f92253 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/bounds-are-checked-2.rs:9:5 + --> $DIR/bounds-are-checked-2.rs:10:9 | -LL | t - | ^ the trait `Clone` is not implemented for `T` +LL | t + | ^ the trait `Clone` is not implemented for `T` | help: consider restricting type parameter `T` | -LL | type X = impl Clone; - | +++++++++++++++++++ +LL | pub type X = impl Clone; + | +++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs index c5ee46024f9..0dfa1f40ae6 100644 --- a/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs +++ b/tests/ui/type-alias-impl-trait/closure-normalization-ice-109020.rs @@ -6,7 +6,14 @@ use std::marker::PhantomData; -type WithEmplacableForFn<'a> = impl EmplacableFn + 'a; +mod foo { + pub type WithEmplacableForFn<'a> = impl super::EmplacableFn + 'a; + + fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> { + () + } +} +use foo::*; fn with_emplacable_for<'a, F, R>(mut f: F) -> R where @@ -16,9 +23,6 @@ where _: &'a (), _: &mut dyn FnMut(Emplacable>) -> R, ) -> R { - fn _constrain(_: &mut ()) -> WithEmplacableForFn<'_> { - () - } loop {} } diff --git a/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs index eb5ab9d67f7..0141a01aad0 100644 --- a/tests/ui/type-alias-impl-trait/closure_args.rs +++ b/tests/ui/type-alias-impl-trait/closure_args.rs @@ -4,20 +4,24 @@ #![feature(type_alias_impl_trait)] -trait Anything {} -impl Anything for T {} -type Input = impl Anything; +mod foo { + pub trait Anything {} + impl Anything for T {} + pub type Input = impl Anything; + + fn bop(_: Input) { + super::run( + |x: u32| { + println!("{x}"); + }, + 0, + ); + } +} +use foo::Input; + fn run ()>(f: F, i: Input) { f(i); } -fn bop(_: Input) { - run( - |x: u32| { - println!("{x}"); - }, - 0, - ); -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs index 329596b19e9..13ac3d31d83 100644 --- a/tests/ui/type-alias-impl-trait/closure_args2.rs +++ b/tests/ui/type-alias-impl-trait/closure_args2.rs @@ -2,20 +2,28 @@ #![feature(type_alias_impl_trait)] -trait Foo { - // This was reachable in https://github.com/rust-lang/rust/issues/100800 - fn foo(&self) { - unreachable!() +mod foo { + pub trait Foo { + // This was reachable in https://github.com/rust-lang/rust/issues/100800 + fn foo(&self) { + unreachable!() + } + } + impl Foo for T {} + + pub struct B; + impl B { + fn foo(&self) {} + } + pub type Input = impl Foo; + fn bop() -> Input { + super::run1(|x: B| x.foo(), B); + super::run2(|x: B| x.foo(), B); + panic!() } } -impl Foo for T {} +use foo::*; -struct B; -impl B { - fn foo(&self) {} -} - -type Input = impl Foo; fn run1(f: F, i: Input) { f(i) } @@ -23,10 +31,4 @@ fn run2(f: F, i: B) { f(i) } -fn bop() -> Input { - run1(|x: B| x.foo(), B); - run2(|x: B| x.foo(), B); - panic!() -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr index 56a10201651..55a5a3d2000 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -1,3 +1,36 @@ +error: item does not constrain `Bar::{opaque#0}`, but has it in its signature + --> $DIR/const_generic_type.rs:8:10 + | +LL | async fn test() { + | ^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/const_generic_type.rs:5:12 + | +LL | type Bar = impl std::fmt::Display; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `Bar::{opaque#0}`, but has it in its signature + --> $DIR/const_generic_type.rs:8:38 + | +LL | async fn test() { + | ______________________________________^ +LL | | +LL | | +LL | | +LL | | #[cfg(infer)] +LL | | let x: u32 = N; +LL | | } + | |_^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/const_generic_type.rs:5:12 + | +LL | type Bar = impl std::fmt::Display; + | ^^^^^^^^^^^^^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/const_generic_type.rs:5:12 | @@ -14,5 +47,5 @@ LL | async fn test() { | = note: the only supported types are integers, `bool` and `char` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs index bfd06826f00..de493d04f81 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.rs +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -7,6 +7,8 @@ type Bar = impl std::fmt::Display; async fn test() { //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter + //[no_infer]~^^ ERROR item does not constrain + //[no_infer]~| ERROR item does not constrain #[cfg(infer)] let x: u32 = N; } diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.rs b/tests/ui/type-alias-impl-trait/constrain_inputs.rs index 03fb64b7b94..1391a2036b2 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs.rs +++ b/tests/ui/type-alias-impl-trait/constrain_inputs.rs @@ -5,6 +5,7 @@ mod lifetime_params { fn defining(s: &str) -> Ty<'_> { s } fn execute(ty: Ty<'_>) -> &str { todo!() } //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types + //~| ERROR item does not constrain type BadFnSig = fn(Ty<'_>) -> &str; //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types @@ -17,6 +18,7 @@ mod lifetime_params_2 { fn defining(s: &str) -> Ty<'_> { move || s } fn execute(ty: Ty<'_>) -> &str { ty() } //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types + //~| ERROR item does not constrain } // regression test for https://github.com/rust-lang/rust/issues/97104 diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr index 93953fd06d1..2468fb7480b 100644 --- a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr @@ -7,8 +7,21 @@ LL | fn execute(ty: Ty<'_>) -> &str { todo!() } = note: lifetimes appearing in an associated or opaque type are not considered constrained = note: consider introducing a named lifetime parameter +error: item does not constrain `lifetime_params::Ty::{opaque#0}`, but has it in its signature + --> $DIR/constrain_inputs.rs:6:8 + | +LL | fn execute(ty: Ty<'_>) -> &str { todo!() } + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/constrain_inputs.rs:4:19 + | +LL | type Ty<'a> = impl Sized; + | ^^^^^^^^^^ + error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:9:35 + --> $DIR/constrain_inputs.rs:10:35 | LL | type BadFnSig = fn(Ty<'_>) -> &str; | ^^^^ @@ -17,7 +30,7 @@ LL | type BadFnSig = fn(Ty<'_>) -> &str; = note: consider introducing a named lifetime parameter error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types - --> $DIR/constrain_inputs.rs:11:42 + --> $DIR/constrain_inputs.rs:12:42 | LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str; | ^^^^ @@ -26,7 +39,7 @@ LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str; = note: consider introducing a named lifetime parameter error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:18:31 + --> $DIR/constrain_inputs.rs:19:31 | LL | fn execute(ty: Ty<'_>) -> &str { ty() } | ^^^^ @@ -34,8 +47,21 @@ LL | fn execute(ty: Ty<'_>) -> &str { ty() } = note: lifetimes appearing in an associated or opaque type are not considered constrained = note: consider introducing a named lifetime parameter +error: item does not constrain `lifetime_params_2::Ty::{opaque#0}`, but has it in its signature + --> $DIR/constrain_inputs.rs:19:8 + | +LL | fn execute(ty: Ty<'_>) -> &str { ty() } + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/constrain_inputs.rs:17:19 + | +LL | type Ty<'a> = impl FnOnce() -> &'a str; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types - --> $DIR/constrain_inputs.rs:27:37 + --> $DIR/constrain_inputs.rs:29:37 | LL | type BadFnSig = fn(Ty<&str>) -> &str; | ^^^^ @@ -44,7 +70,7 @@ LL | type BadFnSig = fn(Ty<&str>) -> &str; = note: consider introducing a named lifetime parameter error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types - --> $DIR/constrain_inputs.rs:29:44 + --> $DIR/constrain_inputs.rs:31:44 | LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str; | ^^^^ @@ -52,7 +78,7 @@ LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str; = note: lifetimes appearing in an associated or opaque type are not considered constrained = note: consider introducing a named lifetime parameter -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0581, E0582. For more information about an error, try `rustc --explain E0581`. diff --git a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs index 7e743fc09dd..db9c2cc096a 100644 --- a/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs +++ b/tests/ui/type-alias-impl-trait/debug-ty-with-weak.rs @@ -3,10 +3,12 @@ #![feature(type_alias_impl_trait)] -type Debuggable = impl core::fmt::Debug; +mod bar { + pub type Debuggable = impl core::fmt::Debug; + fn foo() -> Debuggable { + 0u32 + } +} +use bar::Debuggable; static mut TEST: Option = None; - -fn foo() -> Debuggable { - 0u32 -} diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs index 023991c29d0..9ed010f2293 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.rs @@ -23,9 +23,11 @@ impl Fn(&'a ()) -> StateWidget<'a>> Widget<()> for StatefulWidget type State = (); fn make_state(&self) -> Self::State {} + //~^ ERROR item does not constrain } fn new_stateful_widget Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> { + //~^ ERROR item does not constrain StatefulWidget(build) //~^ ERROR expected generic lifetime parameter, found `'a` } diff --git a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr index 0c76feae198..9a3f4ae4c1c 100644 --- a/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr +++ b/tests/ui/type-alias-impl-trait/failed-to-normalize-ice-99945.stderr @@ -1,5 +1,31 @@ +error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature + --> $DIR/failed-to-normalize-ice-99945.rs:25:8 + | +LL | fn make_state(&self) -> Self::State {} + | ^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/failed-to-normalize-ice-99945.rs:20:24 + | +LL | type StateWidget<'a> = impl Widget<&'a ()>; + | ^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `StateWidget::{opaque#0}`, but has it in its signature + --> $DIR/failed-to-normalize-ice-99945.rs:29:4 + | +LL | fn new_stateful_widget Fn(&'a ()) -> StateWidget<'a>>(build: F) -> impl Widget<()> { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/failed-to-normalize-ice-99945.rs:20:24 + | +LL | type StateWidget<'a> = impl Widget<&'a ()>; + | ^^^^^^^^^^^^^^^^^^^ + error[E0308]: mismatched types - --> $DIR/failed-to-normalize-ice-99945.rs:34:29 + --> $DIR/failed-to-normalize-ice-99945.rs:36:29 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | ------------------- the expected opaque type @@ -11,7 +37,7 @@ LL | new_stateful_widget(|_| ()).make_state(); found unit type `()` error[E0792]: expected generic lifetime parameter, found `'a` - --> $DIR/failed-to-normalize-ice-99945.rs:29:5 + --> $DIR/failed-to-normalize-ice-99945.rs:31:5 | LL | type StateWidget<'a> = impl Widget<&'a ()>; | -- this generic parameter must be used with a generic lifetime parameter @@ -19,7 +45,7 @@ LL | type StateWidget<'a> = impl Widget<&'a ()>; LL | StatefulWidget(build) | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0792. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index 3b54fb7ea99..96c905ef3a9 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -17,10 +17,12 @@ async fn operation(_: &mut ()) -> () { } async fn call(_f: F) +//~^ ERROR item does not constrain where for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>, { //~^ ERROR: expected generic lifetime parameter, found `'any` + //~| ERROR item does not constrain } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index c41ed0642a4..7df1a08bc88 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -1,3 +1,32 @@ +error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature + --> $DIR/hkl_forbidden4.rs:19:10 + | +LL | async fn call(_f: F) + | ^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/hkl_forbidden4.rs:10:23 + | +LL | type FutNothing<'a> = impl 'a + Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: item does not constrain `FutNothing::{opaque#0}`, but has it in its signature + --> $DIR/hkl_forbidden4.rs:23:1 + | +LL | / { +LL | | +LL | | +LL | | } + | |_^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/hkl_forbidden4.rs:10:23 + | +LL | type FutNothing<'a> = impl 'a + Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/hkl_forbidden4.rs:10:23 | @@ -16,13 +45,14 @@ LL | call(operation).await | ^^^^^^^^^^^^^^^ error[E0792]: expected generic lifetime parameter, found `'any` - --> $DIR/hkl_forbidden4.rs:22:1 + --> $DIR/hkl_forbidden4.rs:23:1 | LL | type FutNothing<'a> = impl 'a + Future; | -- this generic parameter must be used with a generic lifetime parameter ... LL | / { LL | | +LL | | LL | | } | |_^ @@ -38,6 +68,6 @@ note: previous use here LL | call(operation).await | ^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs index fc71d0d61ff..0ee188d825f 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.rs @@ -6,7 +6,6 @@ use std::marker::PhantomData; - trait MyIndex { type O; fn my_index(self) -> Self::O; @@ -16,7 +15,6 @@ trait MyFrom: Sized { fn my_from(value: T) -> Result; } - trait F {} impl F for () {} type DummyT = impl F; @@ -28,6 +26,7 @@ struct Scope(Phantom2>); impl Scope { fn new() -> Self { + //~^ ERROR item does not constrain unimplemented!() } } @@ -43,6 +42,7 @@ impl>>, U> MyIndex> for Scope { //~^ ERROR the type parameter `T` is not constrained by the impl type O = T; fn my_index(self) -> Self::O { + //~^ ERROR item does not constrain MyFrom::my_from(self.0).ok().unwrap() } } diff --git a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr index a39f77ce17f..22c776e171c 100644 --- a/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr +++ b/tests/ui/type-alias-impl-trait/ice-failed-to-resolve-instance-for-110696.stderr @@ -1,9 +1,35 @@ +error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:28:8 + | +LL | fn new() -> Self { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18 + | +LL | type DummyT = impl F; + | ^^^^^^ + +error: item does not constrain `DummyT::{opaque#0}`, but has it in its signature + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:44:8 + | +LL | fn my_index(self) -> Self::O { + | ^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:20:18 + | +LL | type DummyT = impl F; + | ^^^^^^ + error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates - --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:42:6 + --> $DIR/ice-failed-to-resolve-instance-for-110696.rs:41:6 | LL | impl>>, U> MyIndex> for Scope { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.rs b/tests/ui/type-alias-impl-trait/implied_bounds.rs index 53cbf8d2290..269c0eff025 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds.rs @@ -1,7 +1,11 @@ #![feature(type_alias_impl_trait)] -type WithLifetime<'a> = impl Equals; -fn _defining_use<'a>() -> WithLifetime<'a> {} +mod foo { + use super::Equals; + pub type WithLifetime<'a> = impl Equals; + fn _defining_use<'a>() -> WithLifetime<'a> {} +} +use foo::WithLifetime; trait Convert<'a> { type Witness; diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.stderr b/tests/ui/type-alias-impl-trait/implied_bounds.stderr index 64a203fe465..23f1141e544 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds.stderr +++ b/tests/ui/type-alias-impl-trait/implied_bounds.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/implied_bounds.rs:17:9 + --> $DIR/implied_bounds.rs:21:9 | LL | impl<'a> Convert<'a> for () { | -- lifetime `'a` defined here diff --git a/tests/ui/type-alias-impl-trait/implied_bounds2.rs b/tests/ui/type-alias-impl-trait/implied_bounds2.rs index effedb954c3..845476ef974 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds2.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds2.rs @@ -2,9 +2,17 @@ #![feature(type_alias_impl_trait)] -type Ty<'a, A> = impl Sized + 'a; -fn defining<'a, A>() -> Ty<'a, A> {} -fn assert_static() {} -fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::>() } +mod helper { + pub type Ty<'a, A> = impl Sized + 'a; + fn defining<'a, A>() -> Ty<'a, A> {} + pub fn assert_static() {} +} +use helper::*; +fn test<'a, A>() +where + Ty<'a, A>: 'static, +{ + assert_static::>() +} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs index 239fcc6a5e6..76a63741e18 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs +++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs @@ -1,7 +1,11 @@ #![feature(type_alias_impl_trait)] -type WithLifetime = impl Equals; -fn _defining_use() -> WithLifetime {} +mod foo { + use super::Equals; + pub type WithLifetime = impl Equals; + fn _defining_use() -> WithLifetime {} +} +use foo::WithLifetime; trait Convert<'a> { type Witness; @@ -12,7 +16,6 @@ impl<'a> Convert<'a> for () { type Witness = WithLifetime<&'a ()>; fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T { - //~^ ERROR non-defining opaque type use // compiler used to think it gets to assume 'a: 'b here because // of the `&'b WithLifetime<&'a ()>` argument x diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr index 23dbf0e8f60..391a8a75786 100644 --- a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr +++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr @@ -1,17 +1,5 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/implied_bounds_from_types.rs:14:39 - | -LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T { - | ^^^^^^^^^^^^^^^^^^^^^^^^ argument `&'a ()` is not a generic parameter - | -note: for this opaque type - --> $DIR/implied_bounds_from_types.rs:3:24 - | -LL | type WithLifetime = impl Equals; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: lifetime may not live long enough - --> $DIR/implied_bounds_from_types.rs:18:9 + --> $DIR/implied_bounds_from_types.rs:21:9 | LL | impl<'a> Convert<'a> for () { | -- lifetime `'a` defined here @@ -24,6 +12,5 @@ LL | x | = help: consider adding the following bound: `'a: 'b` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs index 469a493b0b3..fb251e9bde1 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs @@ -1,40 +1,68 @@ #![feature(type_alias_impl_trait)] mod test_lifetime_param { - type Ty<'a> = impl Sized; - fn defining(a: &str) -> Ty<'_> { a } - fn assert_static<'a: 'static>() {} - fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } + pub type Ty<'a> = impl Sized; + fn defining(a: &str) -> Ty<'_> { + a + } + pub fn assert_static<'a: 'static>() {} +} +fn test_lifetime_param_test<'a>() +where + test_lifetime_param::Ty<'a>: 'static, +{ + test_lifetime_param::assert_static::<'a>() //~^ ERROR: lifetime may not live long enough } mod test_higher_kinded_lifetime_param { - type Ty<'a> = impl Sized; - fn defining(a: &str) -> Ty<'_> { a } - fn assert_static<'a: 'static>() {} - fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } + pub type Ty<'a> = impl Sized + 'a; + fn defining(a: &str) -> Ty<'_> { + a + } + pub fn assert_static<'a: 'static>() {} +} +fn test_higher_kinded_lifetime_param_test<'a>() +where + for<'b> test_higher_kinded_lifetime_param::Ty<'b>: 'a, +{ + test_higher_kinded_lifetime_param::assert_static::<'a>() //~^ ERROR: lifetime may not live long enough } mod test_higher_kinded_lifetime_param2 { fn assert_static<'a: 'static>() {} - fn test<'a>() { assert_static::<'a>() } - //~^ ERROR: lifetime may not live long enough + fn test<'a>() { + assert_static::<'a>() + //~^ ERROR: lifetime may not live long enough + } } mod test_type_param { - type Ty = impl Sized; - fn defining(s: A) -> Ty { s } - fn assert_static() {} - fn test() where Ty: 'static { assert_static::() } + pub type Ty = impl Sized; + fn defining(s: A) -> Ty { + s + } + pub fn assert_static() {} +} +fn test_type_param_test() +where + test_type_param::Ty: 'static, +{ + test_type_param::assert_static::() //~^ ERROR: parameter type `A` may not live long enough } mod test_implied_from_fn_sig { - type Opaque = impl Sized; - fn defining() -> Opaque {} + mod foo { + pub type Opaque = impl Sized; + fn defining() -> Opaque {} + } fn assert_static() {} - fn test(_: Opaque) { assert_static::(); } + + fn test(_: foo::Opaque) { + assert_static::(); + } } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr index d6dd20739b7..b7c9c131c7d 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -1,36 +1,42 @@ error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:7:43 + --> $DIR/implied_lifetime_wf_check3.rs:14:5 | -LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } - | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` +LL | fn test_lifetime_param_test<'a>() + | -- lifetime `'a` defined here +... +LL | test_lifetime_param::assert_static::<'a>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:15:46 + --> $DIR/implied_lifetime_wf_check3.rs:29:5 | -LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } - | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` +LL | fn test_higher_kinded_lifetime_param_test<'a>() + | -- lifetime `'a` defined here +... +LL | test_higher_kinded_lifetime_param::assert_static::<'a>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:21:21 + --> $DIR/implied_lifetime_wf_check3.rs:36:9 | -LL | fn test<'a>() { assert_static::<'a>() } - | -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | | - | lifetime `'a` defined here +LL | fn test<'a>() { + | -- lifetime `'a` defined here +LL | assert_static::<'a>() + | ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:29:41 + --> $DIR/implied_lifetime_wf_check3.rs:52:5 | -LL | fn test() where Ty: 'static { assert_static::() } - | ^^^^^^^^^^^^^^^^^^ - | | - | the parameter type `A` must be valid for the static lifetime... - | ...so that the type `A` will meet its required lifetime bounds +LL | test_type_param::assert_static::() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `A` must be valid for the static lifetime... + | ...so that the type `A` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | -LL | fn test() where Ty: 'static { assert_static::() } - | +++++++++ +LL | fn test_type_param_test() + | +++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs index 1a5daa13458..f8b09814caa 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs @@ -1,11 +1,20 @@ #![feature(type_alias_impl_trait)] mod test_type_param_static { - type Ty = impl Sized + 'static; + pub type Ty = impl Sized + 'static; //~^ ERROR: the parameter type `A` may not live long enough - fn defining(s: A) -> Ty { s } - fn assert_static() {} - fn test() where Ty: 'static { assert_static::() } + fn defining(s: A) -> Ty { + s + } + pub fn assert_static() {} +} +use test_type_param_static::*; + +fn test() +where + Ty: 'static, +{ + assert_static::() //~^ ERROR: the parameter type `A` may not live long enough } diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr index d1c06330c15..f2e5e95b96f 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr @@ -1,30 +1,30 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check4_static.rs:4:18 + --> $DIR/implied_lifetime_wf_check4_static.rs:4:22 | -LL | type Ty = impl Sized + 'static; - | ^^^^^^^^^^^^^^^^^^^^ - | | - | the parameter type `A` must be valid for the static lifetime... - | ...so that the type `A` will meet its required lifetime bounds +LL | pub type Ty = impl Sized + 'static; + | ^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `A` must be valid for the static lifetime... + | ...so that the type `A` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | -LL | type Ty = impl Sized + 'static; - | +++++++++ +LL | pub type Ty = impl Sized + 'static; + | +++++++++ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check4_static.rs:8:41 + --> $DIR/implied_lifetime_wf_check4_static.rs:17:5 | -LL | fn test() where Ty: 'static { assert_static::() } - | ^^^^^^^^^^^^^^^^^^ - | | - | the parameter type `A` must be valid for the static lifetime... - | ...so that the type `A` will meet its required lifetime bounds +LL | assert_static::() + | ^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `A` must be valid for the static lifetime... + | ...so that the type `A` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | -LL | fn test() where Ty: 'static { assert_static::() } - | +++++++++ +LL | fn test() + | +++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/issue-101750.rs b/tests/ui/type-alias-impl-trait/issue-101750.rs index 1c5261b7a79..9367be8ca07 100644 --- a/tests/ui/type-alias-impl-trait/issue-101750.rs +++ b/tests/ui/type-alias-impl-trait/issue-101750.rs @@ -2,17 +2,21 @@ //@ check-pass -trait Trait {} +mod foo { + pub trait Trait {} -type TAIT = impl Trait; + pub type TAIT = impl Trait; -struct Concrete; -impl Trait for Concrete {} + pub struct Concrete; + impl Trait for Concrete {} -fn tait() -> TAIT { - Concrete + pub fn tait() -> TAIT { + Concrete + } } +use foo::*; + trait OuterTrait { type Item; } @@ -24,9 +28,7 @@ impl OuterTrait for Dummy { } fn tait_and_impl_trait() -> impl OuterTrait { - Dummy { - t: (tait(), Concrete), - } + Dummy { t: (tait(), Concrete) } } fn tait_and_dyn_trait() -> impl OuterTrait)> { diff --git a/tests/ui/type-alias-impl-trait/issue-109054.rs b/tests/ui/type-alias-impl-trait/issue-109054.rs index 51f30779cd9..d3eb6521593 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.rs +++ b/tests/ui/type-alias-impl-trait/issue-109054.rs @@ -11,6 +11,7 @@ impl std::ops::Deref for CallMe { type Target = FnType; fn deref(&self) -> &Self::Target { + //~^ ERROR: item does not constrain `ReturnType fn inner(val: &u32) -> ReturnType { async move { *val * 2 } } diff --git a/tests/ui/type-alias-impl-trait/issue-109054.stderr b/tests/ui/type-alias-impl-trait/issue-109054.stderr index a099b7d8b8a..2a4aa63bb8c 100644 --- a/tests/ui/type-alias-impl-trait/issue-109054.stderr +++ b/tests/ui/type-alias-impl-trait/issue-109054.stderr @@ -1,5 +1,18 @@ +error: item does not constrain `ReturnType::{opaque#0}`, but has it in its signature + --> $DIR/issue-109054.rs:13:8 + | +LL | fn deref(&self) -> &Self::Target { + | ^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-109054.rs:7:23 + | +LL | type ReturnType<'a> = impl std::future::Future + 'a; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/issue-109054.rs:18:9 + --> $DIR/issue-109054.rs:19:9 | LL | type ReturnType<'a> = impl std::future::Future + 'a; | -- this generic parameter must be used with a generic lifetime parameter @@ -7,6 +20,6 @@ LL | type ReturnType<'a> = impl std::future::Future + 'a; LL | &inner | ^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/issue-53092.rs b/tests/ui/type-alias-impl-trait/issue-53092.rs index 34bab026088..83b51227aaa 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092.rs +++ b/tests/ui/type-alias-impl-trait/issue-53092.rs @@ -1,7 +1,14 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -type Bug = impl Fn(T) -> U + Copy; +mod bug { + pub type Bug = impl Fn(T) -> U + Copy; + + fn make_bug>() -> Bug { + |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied + } +} +use bug::Bug; union Moo { x: Bug, @@ -9,11 +16,6 @@ union Moo { } const CONST_BUG: Bug = unsafe { Moo { y: () }.x }; -//~^ ERROR non-defining opaque type use - -fn make_bug>() -> Bug { - |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied -} fn main() { CONST_BUG(0); diff --git a/tests/ui/type-alias-impl-trait/issue-53092.stderr b/tests/ui/type-alias-impl-trait/issue-53092.stderr index 0c4cacd6655..f04750866c7 100644 --- a/tests/ui/type-alias-impl-trait/issue-53092.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53092.stderr @@ -1,32 +1,19 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/issue-53092.rs:11:18 - | -LL | const CONST_BUG: Bug = unsafe { Moo { y: () }.x }; - | ^^^^^^^^^^^ argument `u8` is not a generic parameter - | -note: for this opaque type - --> $DIR/issue-53092.rs:4:18 - | -LL | type Bug = impl Fn(T) -> U + Copy; - | ^^^^^^^^^^^^^^^^^^^^^^ - error[E0277]: the trait bound `U: From` is not satisfied - --> $DIR/issue-53092.rs:15:5 + --> $DIR/issue-53092.rs:8:9 | -LL | |x| x.into() - | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | note: required by a bound in `make_bug` - --> $DIR/issue-53092.rs:14:19 + --> $DIR/issue-53092.rs:7:23 | -LL | fn make_bug>() -> Bug { - | ^^^^^^^ required by this bound in `make_bug` +LL | fn make_bug>() -> Bug { + | ^^^^^^^ required by this bound in `make_bug` help: consider restricting type parameter `U` | -LL | type Bug> = impl Fn(T) -> U + Copy; - | +++++++++++++++++++++++ +LL | pub type Bug> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0792. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/issue-53096.rs b/tests/ui/type-alias-impl-trait/issue-53096.rs index 007dcf3bcb6..590fce84fc9 100644 --- a/tests/ui/type-alias-impl-trait/issue-53096.rs +++ b/tests/ui/type-alias-impl-trait/issue-53096.rs @@ -1,10 +1,13 @@ #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] -type Foo = impl Fn() -> usize; -const fn bar() -> Foo { - || 0usize +mod foo { + pub type Foo = impl Fn() -> usize; + pub const fn bar() -> Foo { + || 0usize + } } +use foo::*; const BAZR: Foo = bar(); #[rustc_error] diff --git a/tests/ui/type-alias-impl-trait/issue-53096.stderr b/tests/ui/type-alias-impl-trait/issue-53096.stderr index fba1802efd2..0a744e7be9c 100644 --- a/tests/ui/type-alias-impl-trait/issue-53096.stderr +++ b/tests/ui/type-alias-impl-trait/issue-53096.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-53096.rs:11:1 + --> $DIR/issue-53096.rs:14:1 | LL | fn main() {} | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-58951.rs b/tests/ui/type-alias-impl-trait/issue-58951.rs index 8a9e586eb25..b9f27b031c7 100644 --- a/tests/ui/type-alias-impl-trait/issue-58951.rs +++ b/tests/ui/type-alias-impl-trait/issue-58951.rs @@ -2,14 +2,16 @@ #![feature(type_alias_impl_trait)] -type A = impl Iterator; +mod helper { + pub type A = impl Iterator; -fn def_a() -> A { - 0..1 + pub fn def_a() -> A { + 0..1 + } } pub fn use_a() { - def_a().map(|x| x); + helper::def_a().map(|x| x); } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-60407.rs b/tests/ui/type-alias-impl-trait/issue-60407.rs index b833429c769..6c7c76b5ac7 100644 --- a/tests/ui/type-alias-impl-trait/issue-60407.rs +++ b/tests/ui/type-alias-impl-trait/issue-60407.rs @@ -1,6 +1,13 @@ #![feature(type_alias_impl_trait, rustc_attrs)] -type Debuggable = impl core::fmt::Debug; +mod bar { + pub type Debuggable = impl core::fmt::Debug; + + pub fn foo() -> Debuggable { + 0u32 + } +} +use bar::*; static mut TEST: Option = None; @@ -9,7 +16,3 @@ fn main() { //~^ ERROR unsafe { TEST = Some(foo()) } } - -fn foo() -> Debuggable { - 0u32 -} diff --git a/tests/ui/type-alias-impl-trait/issue-60407.stderr b/tests/ui/type-alias-impl-trait/issue-60407.stderr index 583156b9f7c..bba9092e977 100644 --- a/tests/ui/type-alias-impl-trait/issue-60407.stderr +++ b/tests/ui/type-alias-impl-trait/issue-60407.stderr @@ -1,5 +1,5 @@ error: fatal error triggered by #[rustc_error] - --> $DIR/issue-60407.rs:8:1 + --> $DIR/issue-60407.rs:15:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/issue-63355.rs b/tests/ui/type-alias-impl-trait/issue-63355.rs index 0c977b30994..a0d0355b5af 100644 --- a/tests/ui/type-alias-impl-trait/issue-63355.rs +++ b/tests/ui/type-alias-impl-trait/issue-63355.rs @@ -1,5 +1,4 @@ #![feature(type_alias_impl_trait)] -//@ check-pass pub trait Foo {} @@ -39,6 +38,7 @@ impl Baz for () { } fn bar() -> Self::Bar { + //~^ ERROR: item does not constrain `FooImpl::{opaque#0}` () } } diff --git a/tests/ui/type-alias-impl-trait/issue-63355.stderr b/tests/ui/type-alias-impl-trait/issue-63355.stderr new file mode 100644 index 00000000000..6755c038056 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/issue-63355.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `FooImpl::{opaque#0}`, but has it in its signature + --> $DIR/issue-63355.rs:40:8 + | +LL | fn bar() -> Self::Bar { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-63355.rs:29:20 + | +LL | pub type FooImpl = impl Foo; + | ^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index 61251d7f6da..f98ce4a426c 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -1,19 +1,21 @@ //@ check-pass #![feature(type_alias_impl_trait, rustc_attrs)] +mod foo { + pub type T = impl Sized; + // The concrete type referred by impl-trait-type-alias(`T`) is guaranteed + // to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; + // so difference assertion should not be declared on impl-trait-type-alias's instances. + // for details, check RFC-2515: + // https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md -type T = impl Sized; -// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed -// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; -// so difference assertion should not be declared on impl-trait-type-alias's instances. -// for details, check RFC-2515: -// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md + fn bop(_: T) { + super::take(|| {}); + super::take(|| {}); + } +} +use foo::*; fn take(_: fn() -> T) {} -fn bop(_: T) { - take(|| {}); - take(|| {}); -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs index c81650876c8..275b9717cef 100644 --- a/tests/ui/type-alias-impl-trait/issue-65918.rs +++ b/tests/ui/type-alias-impl-trait/issue-65918.rs @@ -15,10 +15,13 @@ trait MyFrom: Sized { } /* MCVE starts here */ -trait F {} -impl F for () {} -type DummyT = impl F; -fn _dummy_t() -> DummyT {} +mod f { + pub trait F {} + impl F for () {} + pub type DummyT = impl F; + fn _dummy_t() -> DummyT {} +} +use f::DummyT; struct Phantom1(PhantomData); struct Phantom2(PhantomData); diff --git a/tests/ui/type-alias-impl-trait/issue-72793.rs b/tests/ui/type-alias-impl-trait/issue-72793.rs index 9389517e37b..0353b7f3787 100644 --- a/tests/ui/type-alias-impl-trait/issue-72793.rs +++ b/tests/ui/type-alias-impl-trait/issue-72793.rs @@ -3,18 +3,24 @@ #![feature(type_alias_impl_trait)] -trait T { type Item; } +mod foo { + pub trait T { + type Item; + } -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; -struct S; -impl<'a> T for &'a S { - type Item = &'a (); + struct S; + impl<'a> T for &'a S { + type Item = &'a (); + } + + pub fn filter_positive<'a>() -> Alias<'a> { + &S + } } -fn filter_positive<'a>() -> Alias<'a> { - &S -} +use foo::*; fn with_positive(fun: impl Fn(Alias<'_>)) { fun(filter_positive()); diff --git a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs index 9ceef0139f0..90ab4fd8d97 100644 --- a/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs +++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -7,11 +7,18 @@ //@ check-pass #![feature(type_alias_impl_trait)] +mod g { + pub trait Dummy {} + impl Dummy for () {} + pub type F = impl Dummy; + pub fn f() -> F {} +} +use g::*; + trait Test { fn test(self); } - impl Test for define::F { fn test(self) {} } diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr index a7ff097e8bf..2b064dcfc31 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.current.stderr @@ -1,5 +1,18 @@ +error: item does not constrain `Bar::{opaque#0}`, but has it in its signature + --> $DIR/issue-84660-unsoundness.rs:22:8 + | +LL | fn convert(_i: In) -> Self::Out { + | ^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/issue-84660-unsoundness.rs:12:12 + | +LL | type Bar = impl Foo; + | ^^^^^^^^ + error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:28:1 + --> $DIR/issue-84660-unsoundness.rs:29:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here @@ -7,6 +20,6 @@ LL | impl Trait for Out { LL | impl Trait<(), In> for Out { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr index 607f0b062ab..4c8a25edfed 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.next.stderr @@ -4,12 +4,13 @@ error[E0284]: type annotations needed: cannot satisfy `>:: LL | fn convert(_i: In) -> Self::Out { | _____________________________________^ LL | | +LL | | LL | | unreachable!(); LL | | } | |_____^ cannot satisfy `>::Out == ()` error[E0119]: conflicting implementations of trait `Trait` - --> $DIR/issue-84660-unsoundness.rs:28:1 + --> $DIR/issue-84660-unsoundness.rs:29:1 | LL | impl Trait for Out { | ------------------------------------ first implementation here diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index fd1f3c6353c..73c8deb3a4d 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -21,6 +21,7 @@ impl Trait for Out { type Out = Out; fn convert(_i: In) -> Self::Out { //[next]~^ ERROR: cannot satisfy `>::Out == ()` + //[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature unreachable!(); } } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs index b0ebdd1bfab..a7d824c5a6a 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs @@ -6,12 +6,13 @@ use std::fmt::Debug; type FooX = impl Debug; //~^ ERROR unconstrained opaque type -trait Foo { } +trait Foo {} -impl Foo for () { } +impl Foo for () {} fn foo() -> impl Foo { + //~^ ERROR: item does not constrain () } -fn main() { } +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr index ce5d3037053..9ccd9544896 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr @@ -1,3 +1,16 @@ +error: item does not constrain `FooX::{opaque#0}`, but has it in its signature + --> $DIR/nested-tait-inference3.rs:13:4 + | +LL | fn foo() -> impl Foo { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/nested-tait-inference3.rs:6:13 + | +LL | type FooX = impl Debug; + | ^^^^^^^^^^ + error: unconstrained opaque type --> $DIR/nested-tait-inference3.rs:6:13 | @@ -6,5 +19,5 @@ LL | type FooX = impl Debug; | = note: `FooX` must be used in combination with a concrete type within the same module -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/nested.rs b/tests/ui/type-alias-impl-trait/nested.rs index 6b866be7d17..524703939f1 100644 --- a/tests/ui/type-alias-impl-trait/nested.rs +++ b/tests/ui/type-alias-impl-trait/nested.rs @@ -8,6 +8,7 @@ trait Trait {} impl Trait for U {} fn bar() -> Bar { + //~^ ERROR: item does not constrain 42 } diff --git a/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr index a19d4c4eb71..ca1cf6058ea 100644 --- a/tests/ui/type-alias-impl-trait/nested.stderr +++ b/tests/ui/type-alias-impl-trait/nested.stderr @@ -1,5 +1,18 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/nested.rs:10:4 + | +LL | fn bar() -> Bar { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/nested.rs:3:12 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + error[E0277]: `Bar` doesn't implement `Debug` - --> $DIR/nested.rs:15:22 + --> $DIR/nested.rs:16:22 | LL | println!("{:?}", bar()); | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -7,6 +20,6 @@ LL | println!("{:?}", bar()); = help: the trait `Debug` is not implemented for `Bar` = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 07607516cc4..4def8948708 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -11,6 +11,7 @@ mod my_mod { } pub fn get_foot(_: Foo) -> Foot { + //~^ ERROR: item does not constrain `Foo::{opaque#0}`, but has it in its signature get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type } } diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr index 3e67a162f0f..889cff1ba09 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr @@ -1,5 +1,18 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/nested_type_alias_impl_trait.rs:13:12 + | +LL | pub fn get_foot(_: Foo) -> Foot { + | ^^^^^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/nested_type_alias_impl_trait.rs:6:20 + | +LL | pub type Foo = impl Debug; + | ^^^^^^^^^^ + error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/nested_type_alias_impl_trait.rs:14:9 + --> $DIR/nested_type_alias_impl_trait.rs:15:9 | LL | get_foo() | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope @@ -15,5 +28,5 @@ note: opaque type being used as hidden type LL | pub type Foo = impl Debug; | ^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs index 6431cf37df7..3954672500b 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -9,6 +9,7 @@ mod foo { // make compiler happy about using 'Foo' pub fn bar(x: Foo) -> Foo { + //~^ ERROR: item does not constrain `Foo::{opaque#0}` x } } diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index fabc80c0a4f..d95a4a8a727 100644 --- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,3 +1,16 @@ +error: item does not constrain `Foo::{opaque#0}`, but has it in its signature + --> $DIR/no_inferrable_concrete_type.rs:11:12 + | +LL | pub fn bar(x: Foo) -> Foo { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/no_inferrable_concrete_type.rs:7:20 + | +LL | pub type Foo = impl Copy; + | ^^^^^^^^^ + error: unconstrained opaque type --> $DIR/no_inferrable_concrete_type.rs:7:20 | @@ -6,5 +19,5 @@ LL | pub type Foo = impl Copy; | = note: `Foo` must be used in combination with a concrete type within the same module -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs index 60579926038..9fcf42e188c 100644 --- a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs +++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs @@ -8,25 +8,32 @@ pub trait Tr { impl Tr for (u32,) { #[inline] - fn get(&self) -> u32 { self.0 } + fn get(&self) -> u32 { + self.0 + } } pub fn tr1() -> impl Tr { (32,) } -pub fn tr2() -> impl Tr { - struct Inner { - x: X, - } - type X = impl Tr; - impl Tr for Inner { - fn get(&self) -> u32 { - self.x.get() - } - } - - Inner { - x: tr1(), +struct Inner { + x: helper::X, +} +impl Tr for Inner { + fn get(&self) -> u32 { + self.x.get() + } +} + +mod helper { + pub use super::*; + pub type X = impl Tr; + + pub fn tr2() -> impl Tr + where + X:, + { + Inner { x: tr1() } } } diff --git a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs index 0ae2c9600ce..2c6f44d5416 100644 --- a/tests/ui/type-alias-impl-trait/outlives-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs @@ -5,8 +5,11 @@ //@ check-pass #![feature(type_alias_impl_trait)] -type Ty<'a> = impl Sized + 'a; -fn define<'a>() -> Ty<'a> {} +mod tait { + pub type Ty<'a> = impl Sized + 'a; + fn define<'a>() -> Ty<'a> {} +} +use tait::Ty; // Ty<'^0>: 'static fn test1(_: &'static fn(Ty<'_>)) {} @@ -15,4 +18,4 @@ fn test2() { None::<&fn(Ty<'_>)>; } -fn main() { } +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs index e221f4f3f55..38fb493b498 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs @@ -9,26 +9,29 @@ struct A; impl Test for A {} struct B { - inner: T, + inner: T, } impl Test for B {} -type TestImpl = impl Test; +mod helper { + use super::*; + pub type TestImpl = impl Test; -fn test() -> TestImpl { - A + pub fn test() -> TestImpl { + A + } + + fn make_option2() -> Option { + let inner = make_option().unwrap(); + + Some(B { inner }) + //~^ ERROR concrete type differs from previous defining opaque type use + } } -fn make_option() -> Option { - Some(test()) -} - -fn make_option2() -> Option { - let inner = make_option().unwrap(); - - Some(B { inner }) - //~^ ERROR concrete type differs from previous defining opaque type use +fn make_option() -> Option { + Some(helper::test()) } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr index 05825e68625..252c5d7dfa7 100644 --- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr +++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr @@ -1,14 +1,14 @@ error: concrete type differs from previous defining opaque type use - --> $DIR/recursive-tait-conflicting-defn.rs:30:3 + --> $DIR/recursive-tait-conflicting-defn.rs:28:9 | -LL | Some(B { inner }) - | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` +LL | Some(B { inner }) + | ^^^^^^^^^^^^^^^^^ expected `A`, got `B` | note: previous use here - --> $DIR/recursive-tait-conflicting-defn.rs:20:3 + --> $DIR/recursive-tait-conflicting-defn.rs:22:9 | -LL | A - | ^ +LL | A + | ^ error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs index 6f50703aca2..37d84feee4b 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.rs @@ -12,15 +12,19 @@ #![feature(type_alias_impl_trait)] -type Opaque = impl Sized; +mod helper { + pub type Opaque = impl Sized; -fn get_rpit() -> impl Clone {} + pub fn get_rpit() -> impl Clone {} + + fn test() -> Opaque { + super::query(get_rpit); + get_rpit() + } +} + +use helper::*; fn query(_: impl FnOnce() -> Opaque) {} -fn test() -> Opaque { - query(get_rpit); - get_rpit() -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs index 9cb0316b7a3..80f1b1502d3 100644 --- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs +++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query_2.rs @@ -5,14 +5,17 @@ #![feature(type_alias_impl_trait)] -type Opaque = impl Sized; +mod helper { + pub type Opaque = impl Sized; -fn get_rpit() -> impl Sized {} + pub fn get_rpit() -> impl Sized {} + + fn test(_: Opaque) { + super::query(get_rpit); + } +} +use helper::*; fn query(_: impl FnOnce() -> Opaque) {} -fn test(_: Opaque) { - query(get_rpit); -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self_implication.rs b/tests/ui/type-alias-impl-trait/self_implication.rs index eed13933a03..56464af96ed 100644 --- a/tests/ui/type-alias-impl-trait/self_implication.rs +++ b/tests/ui/type-alias-impl-trait/self_implication.rs @@ -16,17 +16,18 @@ fn foo() { let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live } +struct Foo<'a> { + x: &'a mut u8, +} +// desugared +mod foo { + pub type FooX = impl Sized; + impl<'a> super::Foo<'a> { + pub fn foo(&self) -> FooX {} + } +} + fn bar() { - struct Foo<'a> { - x: &'a mut u8, - } - - // desugared - type FooX = impl Sized; - impl<'a> Foo<'a> { - fn foo(&self) -> FooX {} - } - // use site let mut x = 5; let y = Foo { x: &mut x }; diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs index c2ab6a9d10a..27f5799c380 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -1,13 +1,15 @@ #![feature(type_alias_impl_trait)] -type Bar = impl Send; +mod bar { + pub type Bar = impl Send; -// While i32 is structural-match, we do not want to leak this information. -// (See https://github.com/rust-lang/rust/issues/72156) -const fn leak_free() -> Bar { - 7i32 + // While i32 is structural-match, we do not want to leak this information. + // (See https://github.com/rust-lang/rust/issues/72156) + pub const fn leak_free() -> Bar { + 7i32 + } } -const LEAK_FREE: Bar = leak_free(); +const LEAK_FREE: bar::Bar = bar::leak_free(); fn leak_free_test() { match LEAK_FREE { diff --git a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr index b1ccd5cc402..98d71aa9a17 100644 --- a/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr @@ -1,5 +1,5 @@ error: `Bar` cannot be used in patterns - --> $DIR/structural-match-no-leak.rs:14:9 + --> $DIR/structural-match-no-leak.rs:16:9 | LL | LEAK_FREE => (), | ^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/structural-match.rs b/tests/ui/type-alias-impl-trait/structural-match.rs index 7cc9ccaabdc..50259591539 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.rs +++ b/tests/ui/type-alias-impl-trait/structural-match.rs @@ -1,19 +1,22 @@ #![feature(type_alias_impl_trait)] -type Foo = impl Send; +mod foo { + pub type Foo = impl Send; -// This is not structural-match -struct A; + // This is not structural-match + struct A; -const fn value() -> Foo { - A + pub const fn value() -> Foo { + A + } } +use foo::*; const VALUE: Foo = value(); fn test() { match VALUE { VALUE => (), - //~^ `Foo` cannot be used in patterns + //~^ `foo::Foo` cannot be used in patterns _ => (), } } diff --git a/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr index b0415db0e55..c7478b0a135 100644 --- a/tests/ui/type-alias-impl-trait/structural-match.stderr +++ b/tests/ui/type-alias-impl-trait/structural-match.stderr @@ -1,5 +1,5 @@ -error: `Foo` cannot be used in patterns - --> $DIR/structural-match.rs:15:9 +error: `foo::Foo` cannot be used in patterns + --> $DIR/structural-match.rs:18:9 | LL | VALUE => (), | ^^^^^ diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs index bd580a78984..cbd91066c49 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs @@ -1,5 +1,3 @@ -//@ check-pass - #![feature(type_alias_impl_trait)] // Regression test for issue #61863 @@ -18,6 +16,7 @@ fn bla() -> TE { } fn bla2() -> TE { + //~^ ERROR: item does not constrain `TE::{opaque#0}`, but has it in its signature bla() } diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr new file mode 100644 index 00000000000..819bde02183 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `TE::{opaque#0}`, but has it in its signature + --> $DIR/type-alias-impl-trait-fns.rs:18:4 + | +LL | fn bla2() -> TE { + | ^^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/type-alias-impl-trait-fns.rs:23:11 + | +LL | type TE = impl MyTrait; + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr deleted file mode 100644 index 036ab66f79d..00000000000 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/type-alias-impl-trait-tuple.rs:22:24 - | -LL | Blah { my_foo: make_foo(), my_u8: 12 } - | ^^^^^^^^^^ cannot satisfy `Foo == _` - -error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/type-alias-impl-trait-tuple.rs:26:10 - | -LL | (self.my_foo, self.my_u8, make_foo()) - | ^^^^^^^^^^^ cannot satisfy `Foo == _` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs index fadb92ab440..8e90f969953 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -1,16 +1,24 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[current] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] #![allow(dead_code)] -pub trait MyTrait {} +mod foo { + pub trait MyTrait {} -impl MyTrait for bool {} + impl MyTrait for bool {} -type Foo = impl MyTrait; + pub type Foo = impl MyTrait; + + pub fn make_foo() -> Foo { + true + } +} + +use foo::*; struct Blah { my_foo: Foo, @@ -20,16 +28,10 @@ struct Blah { impl Blah { fn new() -> Blah { Blah { my_foo: make_foo(), my_u8: 12 } - //[next]~^ ERROR type annotations needed: cannot satisfy `Foo == _` } fn into_inner(self) -> (Foo, u8, Foo) { (self.my_foo, self.my_u8, make_foo()) - //[next]~^ ERROR type annotations needed: cannot satisfy `Foo == _` } } -fn make_foo() -> Foo { - true -} - fn main() {} diff --git a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs index 03afec859d2..09ff006acbd 100644 --- a/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs +++ b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs @@ -1,10 +1,15 @@ //@ check-pass #![feature(type_alias_impl_trait)] -type Opaque = impl Sized; -fn defining() -> Opaque {} -struct Ss<'a, T>(&'a Opaque); +mod opaque { + pub type Opaque = impl Sized; + fn defining() -> Opaque {} +} + +use opaque::Opaque; + +struct Ss<'a, T>(&'a Opaque); fn test<'a, T>(_: Ss<'a, T>) { // test that we have an implied bound `Opaque: 'a` from fn signature diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs index 37e0d89efc7..56d975355c3 100644 --- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs +++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.rs @@ -1,16 +1,21 @@ // test for ICE #121472 index out of bounds un_derefer.rs #![feature(type_alias_impl_trait)] -trait T {} +mod foo { + pub trait T {} -type Alias<'a> = impl T; + pub type Alias<'a> = impl T; + fn bar() { + super::with_positive(|&n| ()); + //~^ ERROR mismatched types + } +} + +use foo::*; struct S; impl<'a> T for &'a S {} fn with_positive(fun: impl Fn(Alias<'_>)) {} -fn main() { - with_positive(|&n| ()); - //~^ ERROR mismatched types -} +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr index a224bab0705..279bd3bca5a 100644 --- a/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr +++ b/tests/ui/type-alias-impl-trait/underef-index-out-of-bounds-121472.stderr @@ -1,21 +1,21 @@ error[E0308]: mismatched types - --> $DIR/underef-index-out-of-bounds-121472.rs:14:20 + --> $DIR/underef-index-out-of-bounds-121472.rs:9:31 | -LL | type Alias<'a> = impl T; - | ------ the expected opaque type -... -LL | with_positive(|&n| ()); - | ^^ - | | - | expected opaque type, found `&_` - | expected due to this +LL | pub type Alias<'a> = impl T; + | ------ the expected opaque type +LL | fn bar() { +LL | super::with_positive(|&n| ()); + | ^^ + | | + | expected opaque type, found `&_` + | expected due to this | - = note: expected opaque type `Alias<'_>` + = note: expected opaque type `foo::Alias<'_>` found reference `&_` help: consider removing `&` from the pattern | -LL - with_positive(|&n| ()); -LL + with_positive(|n| ()); +LL - super::with_positive(|&n| ()); +LL + super::with_positive(|n| ()); | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.rs b/tests/ui/type-alias-impl-trait/unnameable_type.rs index 1739ab0063f..5813f529dea 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.rs +++ b/tests/ui/type-alias-impl-trait/unnameable_type.rs @@ -15,10 +15,11 @@ use private::Trait; // downstream type MyPrivate = impl Sized; -//~^ ERROR: unconstrained opaque type impl Trait for u32 { - fn dont_define_this(_private: MyPrivate) {} - //~^ ERROR: incompatible type for trait + fn dont_define_this(private: MyPrivate) { + //~^ ERROR: incompatible type for trait + let _: () = private; + } } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr index e9032433494..f567b01d29a 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -1,22 +1,14 @@ -error: unconstrained opaque type - --> $DIR/unnameable_type.rs:17:18 - | -LL | type MyPrivate = impl Sized; - | ^^^^^^^^^^ - | - = note: `MyPrivate` must be used in combination with a concrete type within the same module - error[E0053]: method `dont_define_this` has an incompatible type for trait - --> $DIR/unnameable_type.rs:20:35 + --> $DIR/unnameable_type.rs:19:34 | LL | type MyPrivate = impl Sized; | ---------- the found opaque type -... -LL | fn dont_define_this(_private: MyPrivate) {} - | ^^^^^^^^^ - | | - | expected `Private`, found opaque type - | help: change the parameter type to match the trait: `Private` +LL | impl Trait for u32 { +LL | fn dont_define_this(private: MyPrivate) { + | ^^^^^^^^^ + | | + | expected `Private`, found opaque type + | help: change the parameter type to match the trait: `Private` | note: type in trait --> $DIR/unnameable_type.rs:10:39 @@ -26,6 +18,6 @@ LL | fn dont_define_this(_private: Private) {} = note: expected signature `fn(Private)` found signature `fn(MyPrivate)` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0053`. From 85f2ecab576d3f02619b4d4976a6d7827c65ed4b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 15:32:38 +0000 Subject: [PATCH 112/153] Add a `fn main() {}` to a doctest to prevent the test from being wrapped in a `fn main() {}` body --- compiler/rustc_error_codes/src/error_codes/E0792.md | 4 ++++ compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/compiler/rustc_error_codes/src/error_codes/E0792.md b/compiler/rustc_error_codes/src/error_codes/E0792.md index bad2b5abfe4..5e3dcc4aa72 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0792.md +++ b/compiler/rustc_error_codes/src/error_codes/E0792.md @@ -39,6 +39,8 @@ type Foo = impl std::fmt::Debug; fn foo() -> Foo { 5u32 } + +fn main() {} ``` This means that no matter the generic parameter to `foo`, @@ -57,4 +59,6 @@ type Foo = impl Debug; fn foo() -> Foo { Vec::::new() } + +fn main() {} ``` diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 6098da990c0..7aef6321eeb 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -46,6 +46,8 @@ declare_lint! { /// fn test() -> impl Trait { /// 42 /// } + /// + /// fn main() {} /// ``` /// /// {{produces}} From f2cce98149b78e2880e2e81e03c2cc94ff5a29a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Jun 2024 10:52:44 +0200 Subject: [PATCH 113/153] Migrate `run-make/prefer-rlib` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/prefer-rlib/Makefile | 9 --------- tests/run-make/prefer-rlib/rmake.rs | 16 ++++++++++++++++ 3 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/prefer-rlib/Makefile create mode 100644 tests/run-make/prefer-rlib/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 448d4887d32..ac89a30f353 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -175,7 +175,6 @@ run-make/pgo-gen/Makefile run-make/pgo-indirect-call-promotion/Makefile run-make/pgo-use/Makefile run-make/pointer-auth-link-with-c/Makefile -run-make/prefer-rlib/Makefile run-make/pretty-print-to-file/Makefile run-make/pretty-print-with-dep-file/Makefile run-make/print-calling-conventions/Makefile diff --git a/tests/run-make/prefer-rlib/Makefile b/tests/run-make/prefer-rlib/Makefile deleted file mode 100644 index 2e86b9c1dd7..00000000000 --- a/tests/run-make/prefer-rlib/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) bar.rs --crate-type=dylib --crate-type=rlib - ls $(TMPDIR)/$(call RLIB_GLOB,bar) - $(RUSTC) foo.rs - rm $(TMPDIR)/*bar* - $(call RUN,foo) diff --git a/tests/run-make/prefer-rlib/rmake.rs b/tests/run-make/prefer-rlib/rmake.rs new file mode 100644 index 00000000000..1d336a07903 --- /dev/null +++ b/tests/run-make/prefer-rlib/rmake.rs @@ -0,0 +1,16 @@ +// Check that `foo.rs` prefers to link to `bar` statically, and can be executed even if the `bar` +// library artifacts are removed. + +//@ ignore-cross-compile + +use run_make_support::{dynamic_lib_name, path, run, rust_lib_name, rustc}; +use std::fs::remove_file; + +fn main() { + rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").run(); + assert!(path(rust_lib_name("bar")).exists()); + rustc().input("foo.rs").run(); + remove_file(rust_lib_name("bar")).unwrap(); + remove_file(dynamic_lib_name("bar")).unwrap(); + run("foo"); +} From d79aeaf8981f331f16295e119d4a226842feaf3c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Jun 2024 10:53:06 +0200 Subject: [PATCH 114/153] Remove unused import in `run-make/prefer-dylib/rmake.rs` --- tests/run-make/prefer-dylib/rmake.rs | 1 - tests/run-make/prefer-rlib/rmake.rs | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/run-make/prefer-dylib/rmake.rs b/tests/run-make/prefer-dylib/rmake.rs index ad9fd8a15a2..5b2b0649673 100644 --- a/tests/run-make/prefer-dylib/rmake.rs +++ b/tests/run-make/prefer-dylib/rmake.rs @@ -2,7 +2,6 @@ use run_make_support::{cwd, dynamic_lib_name, read_dir, run, run_fail, rustc}; use std::fs::remove_file; -use std::process::Command; fn main() { rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").arg("-Cprefer-dynamic").run(); diff --git a/tests/run-make/prefer-rlib/rmake.rs b/tests/run-make/prefer-rlib/rmake.rs index 1d336a07903..96861a264e6 100644 --- a/tests/run-make/prefer-rlib/rmake.rs +++ b/tests/run-make/prefer-rlib/rmake.rs @@ -3,14 +3,13 @@ //@ ignore-cross-compile -use run_make_support::{dynamic_lib_name, path, run, rust_lib_name, rustc}; -use std::fs::remove_file; +use run_make_support::{dynamic_lib_name, fs_wrapper, path, run, rust_lib_name, rustc}; fn main() { rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").run(); assert!(path(rust_lib_name("bar")).exists()); rustc().input("foo.rs").run(); - remove_file(rust_lib_name("bar")).unwrap(); - remove_file(dynamic_lib_name("bar")).unwrap(); + fs_wrapper::remove_file(rust_lib_name("bar")); + fs_wrapper::remove_file(dynamic_lib_name("bar")); run("foo"); } From bbc55091bb05c11d6770de3e396d81b6221de8d0 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 12 Jun 2024 11:44:52 +0200 Subject: [PATCH 115/153] fix RELEASES: we do not support upcasting to auto traits --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index c1311ab14c5..2297924c7f3 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -147,7 +147,7 @@ Language - [Split `refining_impl_trait` lint into `_reachable`, `_internal` variants](https://github.com/rust-lang/rust/pull/121720/) - [Remove unnecessary type inference when using associated types inside of higher ranked `where`-bounds](https://github.com/rust-lang/rust/pull/119849) - [Weaken eager detection of cyclic types during type inference](https://github.com/rust-lang/rust/pull/119989) -- [`trait Trait: Auto {}`: allow upcasting from `dyn Trait` to `dyn Auto`](https://github.com/rust-lang/rust/pull/119338) +- [`trait Trait: Auto {}`: allow upcasting from `dyn Trait` to `dyn Trait + Auto`](https://github.com/rust-lang/rust/pull/119338) From 3bbd480f07dcc3a8b9516232d041eada63b10a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 12 Jun 2024 11:45:52 +0200 Subject: [PATCH 116/153] Update `rustc-perf` submodule To integrate https://github.com/rust-lang/rustc-perf/pull/1926. --- src/tools/rustc-perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf index 72daa50ce23..c64bb60dd16 160000 --- a/src/tools/rustc-perf +++ b/src/tools/rustc-perf @@ -1 +1 @@ -Subproject commit 72daa50ce2350f5a9b5ae6dc3ad6babccd14ec0a +Subproject commit c64bb60dd1636922b1ccbb82867bed934a99dbcb From 45a9bd5d40d1674af33287088dbc24bd092541ac Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 12 Jun 2024 11:46:05 +0200 Subject: [PATCH 117/153] Use `fs_wrapper` in `run-make/prefer-dylib` --- tests/run-make/prefer-dylib/rmake.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/run-make/prefer-dylib/rmake.rs b/tests/run-make/prefer-dylib/rmake.rs index 5b2b0649673..6b3b3ad6d3b 100644 --- a/tests/run-make/prefer-dylib/rmake.rs +++ b/tests/run-make/prefer-dylib/rmake.rs @@ -1,7 +1,6 @@ //@ ignore-cross-compile -use run_make_support::{cwd, dynamic_lib_name, read_dir, run, run_fail, rustc}; -use std::fs::remove_file; +use run_make_support::{cwd, dynamic_lib_name, fs_wrapper, read_dir, run, run_fail, rustc}; fn main() { rustc().input("bar.rs").crate_type("dylib").crate_type("rlib").arg("-Cprefer-dynamic").run(); @@ -9,7 +8,7 @@ fn main() { run("foo"); - remove_file(dynamic_lib_name("bar")).unwrap(); + fs_wrapper::remove_file(dynamic_lib_name("bar")); // This time the command should fail. run_fail("foo"); } From 9e58c5e0270246b956e55bb8ccb4c2c72dc352d0 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Wed, 12 Jun 2024 10:59:41 +0100 Subject: [PATCH 118/153] Update download-ci-llvm-stamp --- src/bootstrap/download-ci-llvm-stamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index bd1f9699c3c..e4dbd3a13fe 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/120761 +Last change is for: https://github.com/rust-lang/rust/pull/125141 From 185a48d4b266722d550474a620c0e37e28b1c6d6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 08:55:48 +0000 Subject: [PATCH 119/153] Bump tracing-tree and allow rendering lines again --- compiler/rustc_log/Cargo.toml | 2 +- compiler/rustc_log/src/lib.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 3ff86f700a5..fe399bc77e3 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" tracing = "0.1.28" tracing-core = "=0.1.30" # FIXME(Nilstrieb) tracing has a deadlock: https://github.com/tokio-rs/tracing/issues/2635 tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } -tracing-tree = "0.3.0" +tracing-tree = "0.3.1" # tidy-alphabetical-end [dev-dependencies] diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 41b26ecce3c..01b6e342df0 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -58,6 +58,7 @@ pub struct LoggerConfig { pub verbose_thread_ids: Result, pub backtrace: Result, pub wraptree: Result, + pub lines: Result, } impl LoggerConfig { @@ -69,6 +70,7 @@ impl LoggerConfig { verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")), backtrace: env::var(format!("{env}_BACKTRACE")), wraptree: env::var(format!("{env}_WRAPTREE")), + lines: env::var(format!("{env}_LINES")), } } } @@ -101,6 +103,11 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { Err(_) => false, }; + let lines = match cfg.lines { + Ok(v) => &v == "1", + Err(_) => false, + }; + let mut layer = tracing_tree::HierarchicalLayer::default() .with_writer(io::stderr) .with_ansi(color_logs) @@ -108,6 +115,7 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> { .with_verbose_exit(verbose_entry_exit) .with_verbose_entry(verbose_entry_exit) .with_indent_amount(2) + .with_indent_lines(lines) .with_thread_ids(verbose_thread_ids) .with_thread_names(verbose_thread_ids); From 3da92891fd3f1eecb6b16d080da6ac3447f5bd9b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 09:49:32 +0000 Subject: [PATCH 120/153] Avoid a bunch of booleans in favor of `Result<(), ErrorGuaranteed>` as that more robustly proves that an error has been emitted --- compiler/rustc_hir_typeck/src/expr.rs | 16 +++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 7 ++- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 10 ++-- .../rustc_hir_typeck/src/method/suggest.rs | 46 ++++++++----------- 4 files changed, 35 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5b27ebe3416..d77d898f3bd 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1341,16 +1341,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Ok(method) } - Err(error) => { - if segment.ident.name != kw::Empty { - if let Some(err) = - self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) - { - err.emit(); - } + Err(error) => Err(if segment.ident.name == kw::Empty { + self.dcx().span_delayed_bug(rcvr.span, "empty method name") + } else { + match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { + Ok(diag) => diag.emit(), + Err(guar) => guar, } - Err(()) - } + }), }; // Call the generic checker. diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e354e1ec59c..421ed9954e0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -846,15 +846,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if item_name.name != kw::Empty { - if let Some(e) = self.report_method_error( + self.report_method_error( hir_id, ty.normalized, error, Expectation::NoExpectation, trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - ) { - e.emit(); - } + )? + .emit(); } result diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8333d47493..b8ae21594fd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -113,16 +113,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, sp: Span, expr: &'tcx hir::Expr<'tcx>, - method: Result, ()>, + method: Result, ErrorGuaranteed>, args_no_rcvr: &'tcx [hir::Expr<'tcx>], tuple_arguments: TupleArgumentsFlag, expected: Expectation<'tcx>, ) -> Ty<'tcx> { let has_error = match method { - Ok(method) => method.args.references_error() || method.sig.references_error(), - Err(_) => true, + Ok(method) => method.args.error_reported().and(method.sig.error_reported()), + Err(guar) => Err(guar), }; - if has_error { + if let Err(guar) = has_error { let err_inputs = self.err_args(args_no_rcvr.len()); let err_inputs = match tuple_arguments { @@ -140,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, method.ok().map(|method| method.def_id), ); - return Ty::new_misc_error(self.tcx); + return Ty::new_error(self.tcx, guar); } let method = method.unwrap(); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 803d1554324..4e2b36f2d9e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -33,7 +33,7 @@ use rustc_middle::ty::IsSuggestable; use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span}; +use rustc_span::{edit_distance, ErrorGuaranteed, ExpnKind, FileName, MacroKind, Span}; use rustc_span::{Symbol, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote; @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> Result, ErrorGuaranteed> { let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), @@ -226,9 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Avoid suggestions when we don't know what's going on. - if rcvr_ty.references_error() { - return None; - } + rcvr_ty.error_reported()?; match error { MethodError::NoMatch(mut no_match_data) => { @@ -265,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut sources, Some(sugg_span), ); - err.emit(); + return Err(err.emit()); } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { @@ -286,7 +284,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); - err.emit(); + return Err(err.emit()); } MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { @@ -343,12 +341,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); + return Err(err.emit()); } MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), } - None } fn suggest_missing_writer(&self, rcvr_ty: Ty<'tcx>, rcvr_expr: &hir::Expr<'tcx>) -> Diag<'_> { @@ -576,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Option> { + ) -> Result, ErrorGuaranteed> { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); @@ -608,14 +605,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if self.suggest_wrapping_range_with_parens( + self.suggest_wrapping_range_with_parens( tcx, rcvr_ty, source, span, item_name, &short_ty_str, - ) || self.suggest_constraining_numerical_ty( + )?; + self.suggest_constraining_numerical_ty( tcx, rcvr_ty, source, @@ -623,9 +621,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, &short_ty_str, - ) { - return None; - } + )?; span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -881,7 +877,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(span.shrink_to_lo(), format!("into_iter()."))], Applicability::MaybeIncorrect, ); - return Some(err); + return Ok(err); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in // `::method` because otherwise the machinery will look for blanket @@ -1606,7 +1602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); - Some(err) + Ok(err) } /// If an appropriate error source is not found, check method chain for possible candidates @@ -2259,7 +2255,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { if let SelfSource::MethodCall(expr) = source { for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) { if let Node::Expr(parent_expr) = parent { @@ -2316,7 +2312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - tcx.dcx().emit_err(errors::MissingParenthesesInRange { + return Err(tcx.dcx().emit_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), @@ -2325,13 +2321,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { left: range_span.shrink_to_lo(), right: range_span.shrink_to_hi(), }), - }); - return true; + })); } } } } - false + Ok(()) } fn suggest_constraining_numerical_ty( @@ -2343,7 +2338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind: &str, item_name: Ident, ty_str: &str, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { let found_candidate = all_traits(self.tcx) .into_iter() .any(|info| self.associated_value(info.def_id, item_name).is_some()); @@ -2447,10 +2442,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => {} } - err.emit(); - return true; + return Err(err.emit()); } - false + Ok(()) } /// For code `rect::area(...)`, From 48e614a84b1bfb9e35e8f48fcb0d572a8ac287a2 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 12 Jun 2024 12:15:52 +0200 Subject: [PATCH 121/153] applease clippy --- src/bootstrap/src/core/build_steps/dist.rs | 6 +++--- src/bootstrap/src/core/build_steps/doc.rs | 4 ++-- src/bootstrap/src/core/build_steps/format.rs | 2 +- src/bootstrap/src/core/build_steps/test.rs | 6 +++--- src/bootstrap/src/core/build_steps/tool.rs | 2 +- src/bootstrap/src/lib.rs | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 60b1ff3e441..f651f751441 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -78,7 +78,7 @@ impl Step for Docs { let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); tarball.set_product_name("Rust Documentation"); - tarball.add_bulk_dir(&builder.doc_out(host), dest); + tarball.add_bulk_dir(builder.doc_out(host), dest); tarball.add_file(builder.src.join("src/doc/robots.txt"), dest, 0o644); Some(tarball.generate()) } @@ -117,7 +117,7 @@ impl Step for JsonDocs { let mut tarball = Tarball::new(builder, "rust-docs-json", &host.triple); tarball.set_product_name("Rust Documentation In JSON Format"); tarball.is_preview(true); - tarball.add_bulk_dir(&builder.json_doc_out(host), dest); + tarball.add_bulk_dir(builder.json_doc_out(host), dest); Some(tarball.generate()) } } @@ -148,7 +148,7 @@ impl Step for RustcDocs { let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); tarball.set_product_name("Rustc Documentation"); - tarball.add_bulk_dir(&builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); + tarball.add_bulk_dir(builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); Some(tarball.generate()) } } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index b37b2b5bcef..6748625f132 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -378,7 +378,7 @@ impl Step for Standalone { .arg(&favicon) .arg("--markdown-no-toc") .arg("--index-page") - .arg(&builder.src.join("src/doc/index.md")) + .arg(builder.src.join("src/doc/index.md")) .arg("--markdown-playground-url") .arg("https://play.rust-lang.org/") .arg("-o") @@ -482,7 +482,7 @@ impl Step for Releases { .arg("--markdown-css") .arg("rust.css") .arg("--index-page") - .arg(&builder.src.join("src/doc/index.md")) + .arg(builder.src.join("src/doc/index.md")) .arg("--markdown-playground-url") .arg("https://play.rust-lang.org/") .arg("-o") diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 0caa39d78ac..2deb9168df2 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -15,7 +15,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F let mut cmd = Command::new(rustfmt); // Avoid the submodule config paths from coming into play. We only allow a single global config // for the workspace for now. - cmd.arg("--config-path").arg(&src.canonicalize().unwrap()); + cmd.arg("--config-path").arg(src.canonicalize().unwrap()); cmd.arg("--edition").arg("2021"); cmd.arg("--unstable-features"); cmd.arg("--skip-children"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 29cd90222b2..7556a19c90c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -308,7 +308,7 @@ impl Step for Cargo { // Forcibly disable tests using nightly features since any changes to // those features won't be able to land. cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1"); - cargo.env("PATH", &path_for_cargo(builder, compiler)); + cargo.env("PATH", path_for_cargo(builder, compiler)); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -2559,7 +2559,7 @@ fn prepare_cargo_test( cargo.arg("-p").arg(krate); } - cargo.arg("--").args(&builder.config.test_args()).args(libtest_args); + cargo.arg("--").args(builder.config.test_args()).args(libtest_args); if !builder.config.verbose_tests { cargo.arg("--quiet"); } @@ -3108,7 +3108,7 @@ impl Step for TierCheck { &[], ); cargo.arg(builder.src.join("src/doc/rustc/src/platform-support.md")); - cargo.arg(&builder.rustc(self.compiler)); + cargo.arg(builder.rustc(self.compiler)); if builder.is_verbose() { cargo.arg("--verbose"); } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 47bed6269db..6cf31f2e61e 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -199,7 +199,7 @@ pub fn prepare_tool_cargo( cargo.env("CFG_COMMIT_DATE", date); } if !features.is_empty() { - cargo.arg("--features").arg(&features.join(", ")); + cargo.arg("--features").arg(features.join(", ")); } // Enable internal lints for clippy and rustdoc diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index cde090637e0..1cab02e8c31 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -624,7 +624,7 @@ impl Build { self.config .git() .args(["config", "--file"]) - .arg(&self.config.src.join(".gitmodules")) + .arg(self.config.src.join(".gitmodules")) .args(["--get-regexp", "path"]), ); for line in output.lines() { From be464b800c5875d23549afb744dcd3cf428ed539 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 10:26:12 +0000 Subject: [PATCH 122/153] Upgrade a span_delayed_bug into a span_bug, as we have no tests hitting it. --- compiler/rustc_hir_typeck/src/expr.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d77d898f3bd..cf2bf0d8f8b 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1341,14 +1341,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_method_call_and_enforce_effects(expr.hir_id, expr.span, method); Ok(method) } - Err(error) => Err(if segment.ident.name == kw::Empty { - self.dcx().span_delayed_bug(rcvr.span, "empty method name") - } else { - match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { - Ok(diag) => diag.emit(), - Err(guar) => guar, + Err(error) => { + if segment.ident.name == kw::Empty { + span_bug!(rcvr.span, "empty method name") + } else { + match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { + Ok(diag) => Err(diag.emit()), + Err(guar) => Err(guar), + } } - }), + } }; // Call the generic checker. From 4a06a5bc7ad259023e4373e794687adfce252dac Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 12 Jun 2024 12:39:09 +0200 Subject: [PATCH 123/153] Adjust LoongArch64 data layouts for LLVM update The data layout was changed in LLVM 19: llvm/llvm-project#93814 --- compiler/rustc_codegen_llvm/src/context.rs | 8 ++++++++ .../src/spec/targets/loongarch64_unknown_linux_gnu.rs | 2 +- .../src/spec/targets/loongarch64_unknown_linux_musl.rs | 2 +- .../src/spec/targets/loongarch64_unknown_none.rs | 2 +- .../spec/targets/loongarch64_unknown_none_softfloat.rs | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 53a098d178e..7d92888feee 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -142,6 +142,14 @@ pub unsafe fn create_module<'ll>( } } + if llvm_version < (19, 0, 0) { + if sess.target.arch == "loongarch64" { + // LLVM 19 updates the LoongArch64 data layout. + // See https://github.com/llvm/llvm-project/pull/93814 + target_data_layout = target_data_layout.replace("-n32:64", "-n64"); + } + } + // Ensure the data-layout values hardcoded remain the defaults. { let tm = crate::back::write::create_informational_target_machine(tcx.sess); diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs index f15a8798940..3e88180012e 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs @@ -10,7 +10,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs index 032a29708d1..c45bc438350 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_musl.rs @@ -10,7 +10,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs index b2bfc8e4272..69533e82c3c 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs index 02e44c187ab..bc4c5bcde5e 100644 --- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_none_softfloat.rs @@ -11,7 +11,7 @@ pub fn target() -> Target { std: None, }, pointer_width: 64, - data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(), + data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "loongarch64".into(), options: TargetOptions { cpu: "generic".into(), From cae18fa7b0a773e967e5b8ef6fbccdaa7e0b6eed Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Jun 2024 13:15:02 +0200 Subject: [PATCH 124/153] Clarify doc comment. --- library/core/src/panic/panic_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index df8f441bf35..a593abc8605 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -72,7 +72,7 @@ impl<'a> PanicInfo<'a> { /// Returns the payload associated with the panic. /// - /// On `core::panic::PanicInfo`, this method never returns anything useful. + /// On this type, `core::panic::PanicInfo`, this method never returns anything useful. /// It only exists because of compatibility with [`std::panic::PanicHookInfo`], /// which used to be the same type. /// From 1dc795230320d231c8c870ffd25ae17c2f7ea8ed Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Jun 2024 13:15:17 +0200 Subject: [PATCH 125/153] Fix deprecation version. --- library/core/src/panic/panic_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index a593abc8605..1925f8e8eac 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -80,7 +80,7 @@ impl<'a> PanicInfo<'a> { /// /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload - #[deprecated(since = "1.77.0", note = "this never returns anything useful")] + #[deprecated(since = "CURRENT_RUSTC_VERSION", note = "this never returns anything useful")] #[stable(feature = "panic_hooks", since = "1.10.0")] #[allow(deprecated, deprecated_in_future)] pub fn payload(&self) -> &(dyn crate::any::Any + Send) { From 2944eab5e67b732f994df4fdefaa43e9ef225682 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Jun 2024 13:15:29 +0200 Subject: [PATCH 126/153] Use payload_as_str instead of two downcasts. --- library/std/src/panic.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 5282c00fcca..c5d1a893ee8 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -202,10 +202,7 @@ impl fmt::Display for PanicHookInfo<'_> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { formatter.write_str("panicked at ")?; self.location.fmt(formatter)?; - if let Some(payload) = self.payload.downcast_ref::<&'static str>() { - formatter.write_str(":\n")?; - formatter.write_str(payload)?; - } else if let Some(payload) = self.payload.downcast_ref::() { + if let Some(payload) = self.payload_as_str() { formatter.write_str(":\n")?; formatter.write_str(payload)?; } From 9afc91349e508121a2cc1d15402736b09a2527b6 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Jun 2024 13:17:42 +0200 Subject: [PATCH 127/153] Update doc comment on PanicInfo::message(). --- library/core/src/panic/panic_info.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index 1925f8e8eac..c8e507c690e 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -29,9 +29,8 @@ impl<'a> PanicInfo<'a> { PanicInfo { location, message, can_unwind, force_no_backtrace } } - /// If the `panic!` macro from the `core` crate (not from `std`) - /// was used with a formatting string and some additional arguments, - /// returns that message ready to be used for example with [`fmt::write`] + /// The message that was given to the `panic!` macro, + /// ready to be formatted with e.g. [`fmt::write`]. #[must_use] #[unstable(feature = "panic_info_message", issue = "66745")] pub fn message(&self) -> fmt::Arguments<'_> { From 749a685626be4bd42eb1772eb497b6006f48cb14 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 12 Jun 2024 13:23:21 +0200 Subject: [PATCH 128/153] Fix deprecated version. --- library/core/src/panic/panic_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index c8e507c690e..78cf1d2e98e 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -79,7 +79,7 @@ impl<'a> PanicInfo<'a> { /// /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload - #[deprecated(since = "CURRENT_RUSTC_VERSION", note = "this never returns anything useful")] + #[deprecated(since = "1.81.0", note = "this never returns anything useful")] #[stable(feature = "panic_hooks", since = "1.10.0")] #[allow(deprecated, deprecated_in_future)] pub fn payload(&self) -> &(dyn crate::any::Any + Send) { From dc6def3042074f38e7c6bdaba3038fb2b1f0e2aa Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 11 Jun 2024 22:13:40 +1000 Subject: [PATCH 129/153] coverage: Add `tests/coverage/assert-ne.rs` This test extracts a fragment of `issue-84561.rs` that has historically proven troublesome when trying to modify how spans are extracted from MIR. --- tests/coverage/assert-ne.cov-map | 13 +++++++++++++ tests/coverage/assert-ne.coverage | 23 +++++++++++++++++++++++ tests/coverage/assert-ne.rs | 22 ++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/coverage/assert-ne.cov-map create mode 100644 tests/coverage/assert-ne.coverage create mode 100644 tests/coverage/assert-ne.rs diff --git a/tests/coverage/assert-ne.cov-map b/tests/coverage/assert-ne.cov-map new file mode 100644 index 00000000000..6d9906fd7f5 --- /dev/null +++ b/tests/coverage/assert-ne.cov-map @@ -0,0 +1,13 @@ +Function name: assert_ne::main +Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 08, 01, 03, 1c, 05, 04, 0d, 00, 13, 02, 02, 0d, 00, 13, 09, 03, 05, 01, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 1 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 4 +- Code(Counter(0)) at (prev + 8, 1) to (start + 3, 28) +- Code(Counter(1)) at (prev + 4, 13) to (start + 0, 19) +- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(2)) at (prev + 3, 5) to (start + 1, 2) + diff --git a/tests/coverage/assert-ne.coverage b/tests/coverage/assert-ne.coverage new file mode 100644 index 00000000000..236a8fd1385 --- /dev/null +++ b/tests/coverage/assert-ne.coverage @@ -0,0 +1,23 @@ + LL| |//@ edition: 2021 + LL| | + LL| |use core::hint::black_box; + LL| | + LL| |#[derive(Debug, PartialEq)] + LL| |struct Foo(u32); + LL| | + LL| 1|fn main() { + LL| 1| assert_ne!( + LL| 1| Foo(5), // Make sure this expression's span isn't lost. + LL| 1| if black_box(false) { + LL| 0| Foo(0) // + LL| | } else { + LL| 1| Foo(1) // + LL| | } + LL| | ); + LL| 1| () + LL| 1|} + LL| | + LL| |// This test is a short fragment extracted from `issue-84561.rs`, highlighting + LL| |// a particular span of code that can easily be lost if overlapping spans are + LL| |// processed incorrectly. + diff --git a/tests/coverage/assert-ne.rs b/tests/coverage/assert-ne.rs new file mode 100644 index 00000000000..8a8fe089804 --- /dev/null +++ b/tests/coverage/assert-ne.rs @@ -0,0 +1,22 @@ +//@ edition: 2021 + +use core::hint::black_box; + +#[derive(Debug, PartialEq)] +struct Foo(u32); + +fn main() { + assert_ne!( + Foo(5), // Make sure this expression's span isn't lost. + if black_box(false) { + Foo(0) // + } else { + Foo(1) // + } + ); + () +} + +// This test is a short fragment extracted from `issue-84561.rs`, highlighting +// a particular span of code that can easily be lost if overlapping spans are +// processed incorrectly. From 0bfdb8d33dd89099fc2b573d3df4c2347ffa2dbb Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 12 Jun 2024 22:48:11 +1000 Subject: [PATCH 130/153] coverage: Add `tests/coverage/loop-break.rs` This is a modified copy of `tests/mir-opt/coverage/instrument_coverage.rs`. --- tests/coverage/loop-break.cov-map | 14 ++++++++++++++ tests/coverage/loop-break.coverage | 14 ++++++++++++++ tests/coverage/loop-break.rs | 13 +++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 tests/coverage/loop-break.cov-map create mode 100644 tests/coverage/loop-break.coverage create mode 100644 tests/coverage/loop-break.rs diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map new file mode 100644 index 00000000000..98df0fdab6b --- /dev/null +++ b/tests/coverage/loop-break.cov-map @@ -0,0 +1,14 @@ +Function name: loop_break::main +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 01, 05, 01, 27, 01, 02, 0d, 00, 12, 05, 01, 0a, 00, 0b, 01, 02, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 1 +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +Number of file 0 mappings: 5 +- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11) +- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 39) + = (c0 + c1) +- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18) +- Code(Counter(1)) at (prev + 1, 10) to (start + 0, 11) +- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) + diff --git a/tests/coverage/loop-break.coverage b/tests/coverage/loop-break.coverage new file mode 100644 index 00000000000..cea7dee83f1 --- /dev/null +++ b/tests/coverage/loop-break.coverage @@ -0,0 +1,14 @@ + LL| |//@ edition: 2021 + LL| | + LL| 1|fn main() { + LL| 1| loop { + LL| 1| if core::hint::black_box(true) { + LL| 1| break; + LL| 0| } + LL| | } + LL| 1|} + LL| | + LL| |// This test is a lightly-modified version of `tests/mir-opt/coverage/instrument_coverage.rs`. + LL| |// If this test needs to be blessed, then the mir-opt version probably needs to + LL| |// be blessed too! + diff --git a/tests/coverage/loop-break.rs b/tests/coverage/loop-break.rs new file mode 100644 index 00000000000..9a842225e83 --- /dev/null +++ b/tests/coverage/loop-break.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +fn main() { + loop { + if core::hint::black_box(true) { + break; + } + } +} + +// This test is a lightly-modified version of `tests/mir-opt/coverage/instrument_coverage.rs`. +// If this test needs to be blessed, then the mir-opt version probably needs to +// be blessed too! From 4d72c42ddf05def4ade2bbe38712ebc8a1f2dcf4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 12:54:32 +0000 Subject: [PATCH 131/153] Eagerly emit the diagnostic instead of leaving it to all callers --- compiler/rustc_hir_typeck/src/expr.rs | 5 +-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 +- .../rustc_hir_typeck/src/method/suggest.rs | 32 +++++++++++-------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index cf2bf0d8f8b..3321f029c8d 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1345,10 +1345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if segment.ident.name == kw::Empty { span_bug!(rcvr.span, "empty method name") } else { - match self.report_method_error(expr.hir_id, rcvr_t, error, expected, false) { - Ok(diag) => Err(diag.emit()), - Err(guar) => Err(guar), - } + Err(self.report_method_error(expr.hir_id, rcvr_t, error, expected, false)) } } }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 421ed9954e0..2b32a93bbbe 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -852,8 +852,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, Expectation::NoExpectation, trait_missing_method && span.edition().at_least_rust_2021(), // emits missing method for trait only after edition 2021 - )? - .emit(); + ); } result diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4e2b36f2d9e..bffefe36256 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Result, ErrorGuaranteed> { + ) -> ErrorGuaranteed { let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), @@ -226,7 +226,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Avoid suggestions when we don't know what's going on. - rcvr_ty.error_reported()?; + if let Err(guar) = rcvr_ty.error_reported() { + return guar; + } match error { MethodError::NoMatch(mut no_match_data) => { @@ -263,7 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut sources, Some(sugg_span), ); - return Err(err.emit()); + return err.emit(); } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { @@ -284,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| self.tcx.def_span(def_id)); err.span_label(sp, format!("private {kind} defined here")); self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true); - return Err(err.emit()); + return err.emit(); } MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => { @@ -341,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - return Err(err.emit()); + return err.emit(); } MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"), @@ -561,7 +563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn report_no_match_method_error( + fn report_no_match_method_error( &self, mut span: Span, rcvr_ty: Ty<'tcx>, @@ -573,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, trait_missing_method: bool, - ) -> Result, ErrorGuaranteed> { + ) -> ErrorGuaranteed { let mode = no_match_data.mode; let tcx = self.tcx; let rcvr_ty = self.resolve_vars_if_possible(rcvr_ty); @@ -605,15 +607,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - self.suggest_wrapping_range_with_parens( + if let Err(guar) = self.suggest_wrapping_range_with_parens( tcx, rcvr_ty, source, span, item_name, &short_ty_str, - )?; - self.suggest_constraining_numerical_ty( + ) { + return guar; + } + if let Err(guar) = self.suggest_constraining_numerical_ty( tcx, rcvr_ty, source, @@ -621,7 +625,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, &short_ty_str, - )?; + ) { + return guar; + } span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). @@ -877,7 +883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(span.shrink_to_lo(), format!("into_iter()."))], Applicability::MaybeIncorrect, ); - return Ok(err); + return err.emit(); } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) { // We special case the situation where we are looking for `_` in // `::method` because otherwise the machinery will look for blanket @@ -1602,7 +1608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected); - Ok(err) + err.emit() } /// If an appropriate error source is not found, check method chain for possible candidates From 9065889ee639d8dd7c0dd098fee82a867e471be7 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 12:56:56 +0000 Subject: [PATCH 132/153] Rename some functions --- compiler/rustc_hir_typeck/src/method/suggest.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index bffefe36256..28d738c11c8 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -607,7 +607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We could pass the file for long types into these two, but it isn't strictly necessary // given how targeted they are. - if let Err(guar) = self.suggest_wrapping_range_with_parens( + if let Err(guar) = self.report_failed_method_call_on_range_end( tcx, rcvr_ty, source, @@ -617,7 +617,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { return guar; } - if let Err(guar) = self.suggest_constraining_numerical_ty( + if let Err(guar) = self.report_failed_method_call_on_numerical_infer_var( tcx, rcvr_ty, source, @@ -2253,7 +2253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Suggest possible range with adding parentheses, for example: /// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`. - fn suggest_wrapping_range_with_parens( + fn report_failed_method_call_on_range_end( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, @@ -2335,7 +2335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(()) } - fn suggest_constraining_numerical_ty( + fn report_failed_method_call_on_numerical_infer_var( &self, tcx: TyCtxt<'tcx>, actual: Ty<'tcx>, From 2fa78f3a2a87a7522d3c95bd9c53aaeede63996e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 10 Jun 2024 01:33:33 +1000 Subject: [PATCH 133/153] coverage: Replace the old span refiner with a single function As more and more of the span refiner's functionality has been pulled out into separate early passes, it has finally reached the point where we can remove the rest of the old `SpansRefiner` code, and replace it with a single modestly-sized function. --- .../rustc_mir_transform/src/coverage/spans.rs | 237 +++--------------- tests/coverage/loop-break.cov-map | 6 +- tests/coverage/loop-break.coverage | 2 +- ...ment_coverage.main.InstrumentCoverage.diff | 2 +- 4 files changed, 40 insertions(+), 207 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 743f1cc24be..bb6a666ff73 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,6 +1,5 @@ -use rustc_middle::bug; use rustc_middle::mir; -use rustc_span::{BytePos, Span}; +use rustc_span::Span; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; use crate::coverage::mappings; @@ -23,7 +22,7 @@ pub(super) fn extract_refined_covspans( let sorted_span_buckets = from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks); for bucket in sorted_span_buckets { - let refined_spans = SpansRefiner::refine_sorted_spans(bucket); + let refined_spans = refine_sorted_spans(bucket); code_mappings.extend(refined_spans.into_iter().map(|RefinedCovspan { span, bcb }| { // Each span produced by the refiner represents an ordinary code region. mappings::CodeMapping { span, bcb } @@ -31,58 +30,6 @@ pub(super) fn extract_refined_covspans( } } -#[derive(Debug)] -struct CurrCovspan { - span: Span, - bcb: BasicCoverageBlock, -} - -impl CurrCovspan { - fn new(span: Span, bcb: BasicCoverageBlock) -> Self { - Self { span, bcb } - } - - fn into_prev(self) -> PrevCovspan { - let Self { span, bcb } = self; - PrevCovspan { span, bcb, merged_spans: vec![span] } - } -} - -#[derive(Debug)] -struct PrevCovspan { - span: Span, - bcb: BasicCoverageBlock, - /// List of all the original spans from MIR that have been merged into this - /// span. Mainly used to precisely skip over gaps when truncating a span. - merged_spans: Vec, -} - -impl PrevCovspan { - fn is_mergeable(&self, other: &CurrCovspan) -> bool { - self.bcb == other.bcb - } - - fn merge_from(&mut self, other: &CurrCovspan) { - debug_assert!(self.is_mergeable(other)); - self.span = self.span.to(other.span); - self.merged_spans.push(other.span); - } - - fn cutoff_statements_at(mut self, cutoff_pos: BytePos) -> Option { - self.merged_spans.retain(|span| span.hi() <= cutoff_pos); - if let Some(max_hi) = self.merged_spans.iter().map(|span| span.hi()).max() { - self.span = self.span.with_hi(max_hi); - } - - if self.merged_spans.is_empty() { None } else { Some(self.into_refined()) } - } - - fn into_refined(self) -> RefinedCovspan { - let Self { span, bcb, merged_spans: _ } = self; - RefinedCovspan { span, bcb } - } -} - #[derive(Debug)] struct RefinedCovspan { span: Span, @@ -100,164 +47,50 @@ impl RefinedCovspan { } } -/// Converts the initial set of coverage spans (one per MIR `Statement` or `Terminator`) into a -/// minimal set of coverage spans, using the BCB CFG to determine where it is safe and useful to: -/// -/// * Remove duplicate source code coverage regions -/// * Merge spans that represent continuous (both in source code and control flow), non-branching -/// execution -struct SpansRefiner { - /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative - /// dominance between the `BasicCoverageBlock`s of equal `Span`s. - sorted_spans_iter: std::vec::IntoIter, +/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines" +/// those spans by removing spans that overlap in unwanted ways, and by merging +/// compatible adjacent spans. +#[instrument(level = "debug")] +fn refine_sorted_spans(sorted_spans: Vec) -> Vec { + // Holds spans that have been read from the input vector, but haven't yet + // been committed to the output vector. + let mut pending = vec![]; + let mut refined = vec![]; - /// The current coverage span to compare to its `prev`, to possibly merge, discard, - /// or cause `prev` to be modified or discarded. - /// If `curr` is not discarded or merged, it becomes `prev` for the next iteration. - some_curr: Option, - - /// The coverage span from a prior iteration; typically assigned from that iteration's `curr`. - /// If that `curr` was discarded, `prev` retains its value from the previous iteration. - some_prev: Option, - - /// The final coverage spans to add to the coverage map. A `Counter` or `Expression` - /// will also be injected into the MIR for each BCB that has associated spans. - refined_spans: Vec, -} - -impl SpansRefiner { - /// Takes the initial list of (sorted) spans extracted from MIR, and "refines" - /// them by merging compatible adjacent spans, removing redundant spans, - /// and carving holes in spans when they overlap in unwanted ways. - fn refine_sorted_spans(sorted_spans: Vec) -> Vec { - let sorted_spans_len = sorted_spans.len(); - let this = Self { - sorted_spans_iter: sorted_spans.into_iter(), - some_curr: None, - some_prev: None, - refined_spans: Vec::with_capacity(sorted_spans_len), - }; - - this.to_refined_spans() - } - - /// Iterate through the sorted coverage spans, and return the refined list of merged and - /// de-duplicated spans. - fn to_refined_spans(mut self) -> Vec { - while self.next_coverage_span() { - // For the first span we don't have `prev` set, so most of the - // span-processing steps don't make sense yet. - if self.some_prev.is_none() { - debug!(" initial span"); - continue; - } - - // The remaining cases assume that `prev` and `curr` are set. - let prev = self.prev(); - let curr = self.curr(); - - if prev.is_mergeable(curr) { - debug!(?prev, "curr will be merged into prev"); - let curr = self.take_curr(); - self.prev_mut().merge_from(&curr); - } else if prev.span.hi() <= curr.span.lo() { - debug!( - " different bcbs and disjoint spans, so keep curr for next iter, and add prev={prev:?}", - ); - let prev = self.take_prev().into_refined(); - self.refined_spans.push(prev); - } else { - self.cutoff_prev_at_overlapping_curr(); - } - } - - // There is usually a final span remaining in `prev` after the loop ends, - // so add it to the output as well. - if let Some(prev) = self.some_prev.take() { - debug!(" AT END, adding last prev={prev:?}"); - self.refined_spans.push(prev.into_refined()); - } - - // Do one last merge pass, to simplify the output. - self.refined_spans.dedup_by(|b, a| { - if a.is_mergeable(b) { - debug!(?a, ?b, "merging list-adjacent refined spans"); - a.merge_from(b); - true - } else { + for curr in sorted_spans { + pending.retain(|prev: &SpanFromMir| { + if prev.span.hi() <= curr.span.lo() { + // There's no overlap between the previous/current covspans, + // so move the previous one into the refined list. + refined.push(RefinedCovspan { span: prev.span, bcb: prev.bcb }); false + } else { + // Otherwise, retain the previous covspan only if it has the + // same BCB. This tends to discard long outer spans that enclose + // smaller inner spans with different control flow. + prev.bcb == curr.bcb } }); - - self.refined_spans + pending.push(curr); } - #[track_caller] - fn curr(&self) -> &CurrCovspan { - self.some_curr.as_ref().unwrap_or_else(|| bug!("some_curr is None (curr)")) + // Drain the rest of the pending list into the refined list. + for prev in pending { + refined.push(RefinedCovspan { span: prev.span, bcb: prev.bcb }); } - /// If called, then the next call to `next_coverage_span()` will *not* update `prev` with the - /// `curr` coverage span. - #[track_caller] - fn take_curr(&mut self) -> CurrCovspan { - self.some_curr.take().unwrap_or_else(|| bug!("some_curr is None (take_curr)")) - } - - #[track_caller] - fn prev(&self) -> &PrevCovspan { - self.some_prev.as_ref().unwrap_or_else(|| bug!("some_prev is None (prev)")) - } - - #[track_caller] - fn prev_mut(&mut self) -> &mut PrevCovspan { - self.some_prev.as_mut().unwrap_or_else(|| bug!("some_prev is None (prev_mut)")) - } - - #[track_caller] - fn take_prev(&mut self) -> PrevCovspan { - self.some_prev.take().unwrap_or_else(|| bug!("some_prev is None (take_prev)")) - } - - /// Advance `prev` to `curr` (if any), and `curr` to the next coverage span in sorted order. - fn next_coverage_span(&mut self) -> bool { - if let Some(curr) = self.some_curr.take() { - self.some_prev = Some(curr.into_prev()); - } - if let Some(SpanFromMir { span, bcb, .. }) = self.sorted_spans_iter.next() { - // This code only sees sorted spans after hole-carving, so there should - // be no way for `curr` to start before `prev`. - if let Some(prev) = &self.some_prev { - debug_assert!(prev.span.lo() <= span.lo()); - } - self.some_curr = Some(CurrCovspan::new(span, bcb)); - debug!(?self.some_prev, ?self.some_curr, "next_coverage_span"); + // Do one last merge pass, to simplify the output. + debug!(?refined, "before merge"); + refined.dedup_by(|b, a| { + if a.is_mergeable(b) { + debug!(?a, ?b, "merging list-adjacent refined spans"); + a.merge_from(b); true } else { false } - } + }); + debug!(?refined, "after merge"); - /// `curr` overlaps `prev`. If `prev`s span extends left of `curr`s span, keep _only_ - /// statements that end before `curr.lo()` (if any), and add the portion of the - /// combined span for those statements. Any other statements have overlapping spans - /// that can be ignored because `curr` and/or other upcoming statements/spans inside - /// the overlap area will produce their own counters. This disambiguation process - /// avoids injecting multiple counters for overlapping spans, and the potential for - /// double-counting. - fn cutoff_prev_at_overlapping_curr(&mut self) { - debug!( - " different bcbs, overlapping spans, so ignore/drop pending and only add prev \ - if it has statements that end before curr; prev={:?}", - self.prev() - ); - - let curr_span = self.curr().span; - if let Some(prev) = self.take_prev().cutoff_statements_at(curr_span.lo()) { - debug!("after cutoff, adding {prev:?}"); - self.refined_spans.push(prev); - } else { - debug!("prev was eliminated by cutoff"); - } - } + refined } diff --git a/tests/coverage/loop-break.cov-map b/tests/coverage/loop-break.cov-map index 98df0fdab6b..890d5d84539 100644 --- a/tests/coverage/loop-break.cov-map +++ b/tests/coverage/loop-break.cov-map @@ -1,14 +1,14 @@ Function name: loop_break::main -Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 01, 05, 01, 27, 01, 02, 0d, 00, 12, 05, 01, 0a, 00, 0b, 01, 02, 01, 00, 02] +Raw bytes (31): 0x[01, 01, 01, 01, 05, 05, 01, 03, 01, 00, 0b, 03, 02, 0c, 00, 27, 01, 01, 0d, 00, 12, 05, 01, 0a, 00, 0b, 01, 02, 01, 00, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 1 - expression 0 operands: lhs = Counter(0), rhs = Counter(1) Number of file 0 mappings: 5 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 11) -- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 39) +- Code(Expression(0, Add)) at (prev + 2, 12) to (start + 0, 39) = (c0 + c1) -- Code(Counter(0)) at (prev + 2, 13) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 18) - Code(Counter(1)) at (prev + 1, 10) to (start + 0, 11) - Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2) diff --git a/tests/coverage/loop-break.coverage b/tests/coverage/loop-break.coverage index cea7dee83f1..1b7c64fb68d 100644 --- a/tests/coverage/loop-break.coverage +++ b/tests/coverage/loop-break.coverage @@ -1,7 +1,7 @@ LL| |//@ edition: 2021 LL| | LL| 1|fn main() { - LL| 1| loop { + LL| | loop { LL| 1| if core::hint::black_box(true) { LL| 1| break; LL| 0| } diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff index 01876b494c5..a594c44c316 100644 --- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff @@ -9,7 +9,7 @@ + coverage ExpressionId(0) => Expression { lhs: Counter(0), op: Add, rhs: Counter(1) }; + coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:10:1 - 10:11; -+ coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:11:5 - 12:17; ++ coverage Code(Expression(0)) => $DIR/instrument_coverage.rs:12:12 - 12:17; + coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:13:13 - 13:18; + coverage Code(Counter(1)) => $DIR/instrument_coverage.rs:14:10 - 14:11; + coverage Code(Counter(0)) => $DIR/instrument_coverage.rs:16:1 - 16:2; From 17b07716f823cd7cbbd848216002c1fee53707f9 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 15 May 2024 11:58:06 -0400 Subject: [PATCH 134/153] rewrite pgo-branch-weights to rmake --- src/tools/run-make-support/src/lib.rs | 8 +- src/tools/run-make-support/src/llvm.rs | 127 ++++++++++++++++++ src/tools/run-make-support/src/run.rs | 23 +++- src/tools/run-make-support/src/rustc.rs | 18 +++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/pgo-branch-weights/Makefile | 35 ----- tests/run-make/pgo-branch-weights/rmake.rs | 45 +++++++ 7 files changed, 215 insertions(+), 42 deletions(-) create mode 100644 src/tools/run-make-support/src/llvm.rs delete mode 100644 tests/run-make/pgo-branch-weights/Makefile create mode 100644 tests/run-make/pgo-branch-weights/rmake.rs diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index b920f9a07db..b7a936a1e11 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -9,7 +9,7 @@ mod command; pub mod diff; mod drop_bomb; pub mod fs_wrapper; -pub mod llvm_readobj; +pub mod llvm; pub mod run; pub mod rustc; pub mod rustdoc; @@ -29,8 +29,10 @@ pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; pub use diff::{diff, Diff}; -pub use llvm_readobj::{llvm_readobj, LlvmReadobj}; -pub use run::{cmd, run, run_fail}; +pub use llvm::{ + llvm_filecheck, llvm_profdata, llvm_readobj, LlvmFilecheck, LlvmProfdata, LlvmReadobj, +}; +pub use run::{cmd, run, run_fail, run_with_args}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs new file mode 100644 index 00000000000..414251abda2 --- /dev/null +++ b/src/tools/run-make-support/src/llvm.rs @@ -0,0 +1,127 @@ +use std::path::{Path, PathBuf}; + +use crate::{env_var, Command}; + +/// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available +/// at `$LLVM_BIN_DIR/llvm-readobj`. +pub fn llvm_readobj() -> LlvmReadobj { + LlvmReadobj::new() +} + +/// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available +/// at `$LLVM_BIN_DIR/llvm-profdata`. +pub fn llvm_profdata() -> LlvmProfdata { + LlvmProfdata::new() +} + +/// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available +/// at `$LLVM_FILECHECK`. +pub fn llvm_filecheck() -> LlvmFilecheck { + LlvmFilecheck::new() +} + +/// A `llvm-readobj` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmReadobj { + cmd: Command, +} + +/// A `llvm-profdata` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmProfdata { + cmd: Command, +} + +/// A `llvm-filecheck` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmFilecheck { + cmd: Command, +} + +crate::impl_common_helpers!(LlvmReadobj); +crate::impl_common_helpers!(LlvmProfdata); +crate::impl_common_helpers!(LlvmFilecheck); + +/// Generate the path to the bin directory of LLVM. +#[must_use] +pub fn llvm_bin_dir() -> PathBuf { + let llvm_bin_dir = env_var("LLVM_BIN_DIR"); + PathBuf::from(llvm_bin_dir) +} + +impl LlvmReadobj { + /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available + /// at `$LLVM_BIN_DIR/llvm-readobj`. + pub fn new() -> Self { + let llvm_readobj = llvm_bin_dir().join("llvm-readobj"); + let cmd = Command::new(llvm_readobj); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Pass `--file-header` to display file headers. + pub fn file_header(&mut self) -> &mut Self { + self.cmd.arg("--file-header"); + self + } +} + +impl LlvmProfdata { + /// Construct a new `llvm-profdata` invocation. This assumes that `llvm-profdata` is available + /// at `$LLVM_BIN_DIR/llvm-profdata`. + pub fn new() -> Self { + let llvm_profdata = llvm_bin_dir().join("llvm-profdata"); + let cmd = Command::new(llvm_profdata); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Specify the output file path. + pub fn output>(&mut self, path: P) -> &mut Self { + self.cmd.arg("-o"); + self.cmd.arg(path.as_ref()); + self + } + + /// Take several profile data files generated by PGO instrumentation and merge them + /// together into a single indexed profile data file. + pub fn merge(&mut self) -> &mut Self { + self.cmd.arg("merge"); + self + } +} + +impl LlvmFilecheck { + /// Construct a new `llvm-filecheck` invocation. This assumes that `llvm-filecheck` is available + /// at `$LLVM_FILECHECK`. + pub fn new() -> Self { + let llvm_filecheck = env_var("LLVM_FILECHECK"); + let cmd = Command::new(llvm_filecheck); + Self { cmd } + } + + /// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call. + pub fn stdin>(&mut self, input: I) -> &mut Self { + self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); + self + } + + /// Provide the patterns that need to be matched. + pub fn patterns>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } +} diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 6fa1a75363c..54730bb7de7 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -9,12 +9,17 @@ use crate::{cwd, env_var, is_windows, set_host_rpath}; use super::handle_failed_output; #[track_caller] -fn run_common(name: &str) -> Command { +fn run_common(name: &str, args: Option<&[&str]>) -> Command { let mut bin_path = PathBuf::new(); bin_path.push(cwd()); bin_path.push(name); let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR"); let mut cmd = Command::new(bin_path); + if let Some(args) = args { + for arg in args { + cmd.arg(arg); + } + } cmd.env(&ld_lib_path_envvar, { let mut paths = vec![]; paths.push(cwd()); @@ -43,7 +48,19 @@ fn run_common(name: &str) -> Command { #[track_caller] pub fn run(name: &str) -> CompletedProcess { let caller = panic::Location::caller(); - let mut cmd = run_common(name); + let mut cmd = run_common(name, None); + let output = cmd.run(); + if !output.status().success() { + handle_failed_output(&cmd, output, caller.line()); + } + output +} + +/// Run a built binary with one or more argument(s) and make sure it succeeds. +#[track_caller] +pub fn run_with_args(name: &str, args: &[&str]) -> CompletedProcess { + let caller = panic::Location::caller(); + let mut cmd = run_common(name, Some(args)); let output = cmd.run(); if !output.status().success() { handle_failed_output(&cmd, output, caller.line()); @@ -55,7 +72,7 @@ pub fn run(name: &str) -> CompletedProcess { #[track_caller] pub fn run_fail(name: &str) -> CompletedProcess { let caller = panic::Location::caller(); - let mut cmd = run_common(name); + let mut cmd = run_common(name, None); let output = cmd.run_fail(); if output.status().success() { handle_failed_output(&cmd, output, caller.line()); diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 32fa5018d80..4a47ac2ed68 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -146,6 +146,24 @@ impl Rustc { self } + /// Specify directory path used for profile generation + pub fn profile_generate>(&mut self, path: P) -> &mut Self { + let mut arg = OsString::new(); + arg.push("-Cprofile-generate="); + arg.push(path.as_ref()); + self.cmd.arg(&arg); + self + } + + /// Specify directory path used for profile usage + pub fn profile_use>(&mut self, path: P) -> &mut Self { + let mut arg = OsString::new(); + arg.push("-Cprofile-use="); + arg.push(path.as_ref()); + self.cmd.arg(&arg); + self + } + /// Specify error format to use pub fn error_format(&mut self, format: &str) -> &mut Self { self.cmd.arg(format!("--error-format={format}")); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index b07e012a1b8..912895fecd4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -168,7 +168,6 @@ run-make/pass-linker-flags/Makefile run-make/pass-non-c-like-enum-to-c/Makefile run-make/pdb-alt-path/Makefile run-make/pdb-buildinfo-cl-cmd/Makefile -run-make/pgo-branch-weights/Makefile run-make/pgo-gen-lto/Makefile run-make/pgo-gen-no-imp-symbols/Makefile run-make/pgo-gen/Makefile diff --git a/tests/run-make/pgo-branch-weights/Makefile b/tests/run-make/pgo-branch-weights/Makefile deleted file mode 100644 index 4c9f8b2493a..00000000000 --- a/tests/run-make/pgo-branch-weights/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# needs-profiler-support -# ignore-windows-gnu -# ignore-cross-compile - -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - -include ../tools.mk - -# For some very small programs GNU ld seems to not properly handle -# instrumentation sections correctly. Neither Gold nor LLD have that problem. -ifeq ($(UNAME),Linux) -ifneq (,$(findstring x86,$(TARGET))) -COMMON_FLAGS=-Clink-args=-fuse-ld=gold -endif -endif - - -all: - # We don't compile `opaque` with either optimizations or instrumentation. - $(RUSTC) $(COMMON_FLAGS) opaque.rs || exit 1 - # Compile the test program with instrumentation - mkdir -p "$(TMPDIR)/prof_data_dir" || exit 1 - $(RUSTC) $(COMMON_FLAGS) interesting.rs \ - -Cprofile-generate="$(TMPDIR)/prof_data_dir" -O -Ccodegen-units=1 || exit 1 - $(RUSTC) $(COMMON_FLAGS) main.rs -Cprofile-generate="$(TMPDIR)/prof_data_dir" -O || exit 1 - # The argument below generates to the expected branch weights - $(call RUN,main aaaaaaaaaaaa2bbbbbbbbbbbb2bbbbbbbbbbbbbbbbcc) || exit 1 - "$(LLVM_BIN_DIR)/llvm-profdata" merge \ - -o "$(TMPDIR)/prof_data_dir/merged.profdata" \ - "$(TMPDIR)/prof_data_dir" || exit 1 - $(RUSTC) $(COMMON_FLAGS) interesting.rs \ - -Cprofile-use="$(TMPDIR)/prof_data_dir/merged.profdata" -O \ - -Ccodegen-units=1 --emit=llvm-ir || exit 1 - cat "$(TMPDIR)/interesting.ll" | "$(LLVM_FILECHECK)" filecheck-patterns.txt diff --git a/tests/run-make/pgo-branch-weights/rmake.rs b/tests/run-make/pgo-branch-weights/rmake.rs new file mode 100644 index 00000000000..55f6e7e56c5 --- /dev/null +++ b/tests/run-make/pgo-branch-weights/rmake.rs @@ -0,0 +1,45 @@ +// This test generates an instrumented binary - a program which +// will keep track of how many times it calls each function, a useful +// feature for optimization. Then, an argument (aaaaaaaaaaaa2bbbbbbbbbbbb2bbbbbbbbbbbbbbbbcc) +// is passed into the instrumented binary, which should react with a number of function calls +// fully known in advance. (For example, the letter 'a' results in calling f1()) + +// If the test passes, the expected function call count was added to the use-phase LLVM-IR. +// See https://github.com/rust-lang/rust/pull/66631 + +//@ needs-profiler-support +//@ ignore-cross-compile + +// FIXME(Oneirical): This test has problems generating profdata on mingw. +// For more information, see https://github.com/rust-lang/rust/pull/122613 +//@ ignore-windows-gnu + +use run_make_support::{fs_wrapper, llvm_filecheck, llvm_profdata, run_with_args, rustc}; +use std::path::Path; + +fn main() { + let path_prof_data_dir = Path::new("prof_data_dir"); + let path_merged_profdata = path_prof_data_dir.join("merged.profdata"); + rustc().input("opaque.rs").run(); + fs_wrapper::create_dir_all(&path_prof_data_dir); + rustc() + .input("interesting.rs") + .profile_generate(&path_prof_data_dir) + .opt() + .codegen_units(1) + .run(); + rustc().input("main.rs").profile_generate(&path_prof_data_dir).opt().run(); + run_with_args("main", &["aaaaaaaaaaaa2bbbbbbbbbbbb2bbbbbbbbbbbbbbbbcc"]); + llvm_profdata().merge().output(&path_merged_profdata).input(path_prof_data_dir).run(); + rustc() + .input("interesting.rs") + .profile_use(path_merged_profdata) + .opt() + .codegen_units(1) + .emit("llvm-ir") + .run(); + llvm_filecheck() + .patterns("filecheck-patterns.txt") + .stdin(fs_wrapper::read("interesting.ll")) + .run(); +} From b1ace388c0c493e01b9ee1295dea406588afda11 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 13 May 2024 13:47:45 +0200 Subject: [PATCH 135/153] Extend SCC construction to enable extra functionality This patch has been extracted from #123720. It specifically enhances `Sccs` to allow tracking arbitrary commutative properties of SCCs, including - reachable values (max/min) - SCC-internal values (max/min) This helps with among other things universe computation: we can now identify SCC universes as a straightforward "find max/min" operation during SCC construction. It's also more or less zero-cost; don't use the new features, don't pay for them. This commit also vastly extends the documentation of the SCCs module, which I had a very hard time following. --- .../rustc_borrowck/src/constraints/mod.rs | 104 ++++- .../rustc_borrowck/src/region_infer/mod.rs | 261 +++--------- .../src/region_infer/opaque_types.rs | 4 +- .../src/graph/scc/mod.rs | 387 ++++++++++++------ .../src/graph/scc/tests.rs | 214 +++++++++- .../infer/region_constraints/leak_check.rs | 2 +- 6 files changed, 630 insertions(+), 342 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 97408fa20d7..b1d6fd89e27 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -1,15 +1,99 @@ -use rustc_data_structures::graph::scc::Sccs; +use crate::region_infer::RegionDefinition; +use crate::type_check::Locations; +use rustc_data_structures::graph::scc::{self, Sccs}; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo}; +use rustc_middle::ty::{RegionVid, TyCtxt, UniverseIndex, VarianceDiagInfo}; use rustc_span::Span; use std::fmt; use std::ops::Index; -use crate::type_check::Locations; - pub(crate) mod graph; +pub type ConstraintSccs = Sccs; + +/// An annotation for region graph SCCs that tracks +/// the values of its elements. +#[derive(Copy, Debug, Clone)] +pub struct RegionTracker { + /// The largest universe of a placeholder reached from this SCC. + /// This includes placeholders within this SCC. + max_placeholder_universe_reached: UniverseIndex, + + /// The smallest universe index reachable form the nodes of this SCC. + min_reachable_universe: UniverseIndex, + + /// The representative Region Variable Id for this SCC. We prefer + /// placeholders over existentially quantified variables, otherwise + /// it's the one with the smallest Region Variable ID. + pub representative: RegionVid, + + /// Is the current representative a placeholder? + representative_is_placeholder: bool, + + /// Is the current representative existentially quantified? + representative_is_existential: bool, +} + +impl scc::Annotation for RegionTracker { + fn merge_scc(mut self, mut other: Self) -> Self { + // Prefer any placeholder over any existential + if other.representative_is_placeholder && self.representative_is_existential { + other.merge_min_max_seen(&self); + return other; + } + + if self.representative_is_placeholder && other.representative_is_existential + || (self.representative <= other.representative) + { + self.merge_min_max_seen(&other); + return self; + } + other.merge_min_max_seen(&self); + other + } + + fn merge_reached(mut self, other: Self) -> Self { + // No update to in-component values, only add seen values. + self.merge_min_max_seen(&other); + self + } +} + +impl RegionTracker { + pub fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { + let placeholder_universe = + if definition.is_placeholder() { definition.universe } else { UniverseIndex::ROOT }; + + Self { + max_placeholder_universe_reached: placeholder_universe, + min_reachable_universe: definition.universe, + representative: rvid, + representative_is_placeholder: definition.is_placeholder(), + representative_is_existential: definition.is_existential(), + } + } + pub fn universe(self) -> UniverseIndex { + self.min_reachable_universe + } + + fn merge_min_max_seen(&mut self, other: &Self) { + self.max_placeholder_universe_reached = std::cmp::max( + self.max_placeholder_universe_reached, + other.max_placeholder_universe_reached, + ); + + self.min_reachable_universe = + std::cmp::min(self.min_reachable_universe, other.min_reachable_universe); + } + + /// Returns `true` if during the annotated SCC reaches a placeholder + /// with a universe larger than the smallest reachable one, `false` otherwise. + pub fn has_incompatible_universes(&self) -> bool { + self.universe().cannot_name(self.max_placeholder_universe_reached) + } +} + /// A set of NLL region constraints. These include "outlives" /// constraints of the form `R1: R2`. Each constraint is identified by /// a unique `OutlivesConstraintIndex` and you can index into the set @@ -45,18 +129,6 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { graph::ConstraintGraph::new(graph::Reverse, self, num_region_vars) } - /// Computes cycles (SCCs) in the graph of regions. In particular, - /// find all regions R1, R2 such that R1: R2 and R2: R1 and group - /// them into an SCC, and find the relationships between SCCs. - pub(crate) fn compute_sccs( - &self, - constraint_graph: &graph::NormalConstraintGraph, - static_region: RegionVid, - ) -> Sccs { - let region_graph = &constraint_graph.region_graph(self, static_region); - Sccs::new(region_graph) - } - pub(crate) fn outlives( &self, ) -> &IndexSlice> { diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 0e3140ca98b..b2a91a58e5c 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -4,10 +4,9 @@ use std::rc::Rc; use rustc_data_structures::binary_search_util; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diag; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::IndexVec; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; @@ -19,11 +18,12 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex}; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph}; +use crate::constraints::{ConstraintSccs, RegionTracker}; use crate::dataflow::BorrowIndex; use crate::{ constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet}, @@ -72,7 +72,7 @@ pub struct RegionInferenceContext<'tcx> { /// The SCC computed from `constraints` and the constraint /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. - constraint_sccs: Rc>, + pub constraint_sccs: Rc, /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required @@ -91,22 +91,6 @@ pub struct RegionInferenceContext<'tcx> { /// Map universe indexes to information on why we created it. universe_causes: FxIndexMap>, - /// Contains the minimum universe of any variable within the same - /// SCC. We will ensure that no SCC contains values that are not - /// visible from this index. - scc_universes: IndexVec, - - /// Contains the "representative" region of each SCC. - /// It is defined as the one with the minimal RegionVid, favoring - /// free regions, then placeholders, then existential regions. - /// - /// It is a hacky way to manage checking regions for equality, - /// since we can 'canonicalize' each region to the representative - /// of its SCC and be sure that -- if they have the same repr -- - /// they *must* be equal (though not having the same repr does not - /// mean they are unequal). - scc_representatives: IndexVec, - /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, /// you first find which scc it is a part of. @@ -151,7 +135,7 @@ pub(crate) struct AppliedMemberConstraint { } #[derive(Debug)] -pub(crate) struct RegionDefinition<'tcx> { +pub struct RegionDefinition<'tcx> { /// What kind of variable is this -- a free region? existential /// variable? etc. (See the `NllRegionVariableOrigin` for more /// info.) @@ -250,7 +234,7 @@ pub enum ExtraConstraintInfo { } #[instrument(skip(infcx, sccs), level = "debug")] -fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: Rc>) { +fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) { use crate::renumber::RegionCtxt; let var_to_origin = infcx.reg_var_to_origin.borrow(); @@ -264,7 +248,7 @@ fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: Rc(infcx: &BorrowckInferCtxt<'tcx>, sccs: Rc>(); + let edge_representatives = sccs + .successors(*scc_idx) + .iter() + .map(|scc_idx| components_representatives[scc_idx]) + .collect::>(); scc_node_to_edges.insert((scc_idx, repr), edge_representatives); } @@ -320,7 +305,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// The `outlives_constraints` and `type_tests` are an initial set /// of constraints produced by the MIR type check. pub(crate) fn new( - _infcx: &BorrowckInferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'tcx>, var_infos: VarInfos, universal_regions: Rc>, placeholder_indices: Rc, @@ -343,13 +328,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { .map(|info| RegionDefinition::new(info.universe, info.origin)) .collect(); + let fr_static = universal_regions.fr_static; let constraints = Frozen::freeze(outlives_constraints); let constraint_graph = Frozen::freeze(constraints.graph(definitions.len())); - let fr_static = universal_regions.fr_static; - let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static)); + let constraint_sccs = { + let constraint_graph = constraints.graph(definitions.len()); + let region_graph = &constraint_graph.region_graph(&constraints, fr_static); + let sccs = ConstraintSccs::new_with_annotation(®ion_graph, |r| { + RegionTracker::new(r, &definitions[r]) + }); + Rc::new(sccs) + }; if cfg!(debug_assertions) { - sccs_info(_infcx, constraint_sccs.clone()); + sccs_info(infcx, &constraint_sccs); } let mut scc_values = @@ -360,10 +352,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { scc_values.merge_liveness(scc, region, &liveness_constraints); } - let scc_universes = Self::compute_scc_universes(&constraint_sccs, &definitions); - - let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions); - let member_constraints = Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r))); @@ -378,8 +366,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { member_constraints, member_constraints_applied: Vec::new(), universe_causes, - scc_universes, - scc_representatives, scc_values, type_tests, universal_regions, @@ -391,123 +377,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { result } - /// Each SCC is the combination of many region variables which - /// have been equated. Therefore, we can associate a universe with - /// each SCC which is minimum of all the universes of its - /// constituent regions -- this is because whatever value the SCC - /// takes on must be a value that each of the regions within the - /// SCC could have as well. This implies that the SCC must have - /// the minimum, or narrowest, universe. - fn compute_scc_universes( - constraint_sccs: &Sccs, - definitions: &IndexSlice>, - ) -> IndexVec { - let num_sccs = constraint_sccs.num_sccs(); - let mut scc_universes = IndexVec::from_elem_n(ty::UniverseIndex::MAX, num_sccs); - - debug!("compute_scc_universes()"); - - // For each region R in universe U, ensure that the universe for the SCC - // that contains R is "no bigger" than U. This effectively sets the universe - // for each SCC to be the minimum of the regions within. - for (region_vid, region_definition) in definitions.iter_enumerated() { - let scc = constraint_sccs.scc(region_vid); - let scc_universe = &mut scc_universes[scc]; - let scc_min = std::cmp::min(region_definition.universe, *scc_universe); - if scc_min != *scc_universe { - *scc_universe = scc_min; - debug!( - "compute_scc_universes: lowered universe of {scc:?} to {scc_min:?} \ - because it contains {region_vid:?} in {region_universe:?}", - scc = scc, - scc_min = scc_min, - region_vid = region_vid, - region_universe = region_definition.universe, - ); - } - } - - // Walk each SCC `A` and `B` such that `A: B` - // and ensure that universe(A) can see universe(B). - // - // This serves to enforce the 'empty/placeholder' hierarchy - // (described in more detail on `RegionKind`): - // - // ``` - // static -----+ - // | | - // empty(U0) placeholder(U1) - // | / - // empty(U1) - // ``` - // - // In particular, imagine we have variables R0 in U0 and R1 - // created in U1, and constraints like this; - // - // ``` - // R1: !1 // R1 outlives the placeholder in U1 - // R1: R0 // R1 outlives R0 - // ``` - // - // Here, we wish for R1 to be `'static`, because it - // cannot outlive `placeholder(U1)` and `empty(U0)` any other way. - // - // Thanks to this loop, what happens is that the `R1: R0` - // constraint lowers the universe of `R1` to `U0`, which in turn - // means that the `R1: !1` constraint will (later) cause - // `R1` to become `'static`. - for scc_a in constraint_sccs.all_sccs() { - for &scc_b in constraint_sccs.successors(scc_a) { - let scc_universe_a = scc_universes[scc_a]; - let scc_universe_b = scc_universes[scc_b]; - let scc_universe_min = std::cmp::min(scc_universe_a, scc_universe_b); - if scc_universe_a != scc_universe_min { - scc_universes[scc_a] = scc_universe_min; - - debug!( - "compute_scc_universes: lowered universe of {scc_a:?} to {scc_universe_min:?} \ - because {scc_a:?}: {scc_b:?} and {scc_b:?} is in universe {scc_universe_b:?}", - scc_a = scc_a, - scc_b = scc_b, - scc_universe_min = scc_universe_min, - scc_universe_b = scc_universe_b - ); - } - } - } - - debug!("compute_scc_universes: scc_universe = {:#?}", scc_universes); - - scc_universes - } - - /// For each SCC, we compute a unique `RegionVid`. See the - /// `scc_representatives` field of `RegionInferenceContext` for - /// more details. - fn compute_scc_representatives( - constraints_scc: &Sccs, - definitions: &IndexSlice>, - ) -> IndexVec { - let num_sccs = constraints_scc.num_sccs(); - let mut scc_representatives = IndexVec::from_elem_n(RegionVid::MAX, num_sccs); - - // Iterate over all RegionVids *in-order* and pick the least RegionVid as the - // representative of its SCC. This naturally prefers free regions over others. - for (vid, def) in definitions.iter_enumerated() { - let repr = &mut scc_representatives[constraints_scc.scc(vid)]; - if *repr == ty::RegionVid::MAX { - *repr = vid; - } else if matches!(def.origin, NllRegionVariableOrigin::Placeholder(_)) - && matches!(definitions[*repr].origin, NllRegionVariableOrigin::Existential { .. }) - { - // Pick placeholders over existentials even if they have a greater RegionVid. - *repr = vid; - } - } - - scc_representatives - } - /// Initializes the region variables for each universally /// quantified region (lifetime parameter). The first N variables /// always correspond to the regions appearing in the function @@ -533,7 +402,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // This iterator has unstable order but we collect it all into an IndexVec for (external_name, variable) in self.universal_regions.named_universal_regions() { debug!( - "init_universal_regions: region {:?} has external name {:?}", + "init_free_and_bound_regions: region {:?} has external name {:?}", variable, external_name ); self.definitions[variable].external_name = Some(external_name); @@ -559,7 +428,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // its universe `ui` and its extensions. So we // can't just add it into `scc` unless the // universe of the scc can name this region. - let scc_universe = self.scc_universes[scc]; + let scc_universe = self.scc_universe(scc); if scc_universe.can_name(placeholder.universe) { self.scc_values.add_element(scc, placeholder); } else { @@ -640,8 +509,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Returns access to the value of `r` for debugging purposes. pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex { - let scc = self.constraint_sccs.scc(r); - self.scc_universes[scc] + self.scc_universe(self.constraint_sccs.scc(r)) } /// Once region solving has completed, this function will return the member constraints that @@ -737,8 +605,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // SCC. For each SCC, we visit its successors and compute // their values, then we union all those values to get our // own. - let constraint_sccs = self.constraint_sccs.clone(); - for scc in constraint_sccs.all_sccs() { + for scc in self.constraint_sccs.all_sccs() { self.compute_value_for_scc(scc); } @@ -817,20 +684,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { // if one exists. for c_r in &mut choice_regions { let scc = self.constraint_sccs.scc(*c_r); - *c_r = self.scc_representatives[scc]; + *c_r = self.scc_representative(scc); } // If the member region lives in a higher universe, we currently choose // the most conservative option by leaving it unchanged. - if self.scc_universes[scc] != ty::UniverseIndex::ROOT { + + if !self.constraint_sccs().annotation(scc).universe().is_root() { return; } - debug_assert!( - self.scc_values.placeholders_contained_in(scc).next().is_none(), - "scc {:?} in a member constraint has placeholder value: {:?}", - scc, - self.scc_values.region_value_str(scc), - ); // The existing value for `scc` is a lower-bound. This will // consist of some set `{P} + {LB}` of points `{P}` and @@ -900,12 +762,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// in `scc_a`. Used during constraint propagation, and only once /// the value of `scc_b` has been computed. fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool { - let universe_a = self.scc_universes[scc_a]; + let universe_a = self.constraint_sccs().annotation(scc_a).universe(); + let universe_b = self.constraint_sccs().annotation(scc_b).universe(); // Quick check: if scc_b's declared universe is a subset of // scc_a's declared universe (typically, both are ROOT), then // it cannot contain any problematic universe elements. - if universe_a.can_name(self.scc_universes[scc_b]) { + if universe_a.can_name(universe_b) { return true; } @@ -1033,7 +896,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!( "lower_bound = {:?} r_scc={:?} universe={:?}", - lower_bound, r_scc, self.scc_universes[r_scc] + lower_bound, + r_scc, + self.constraint_sccs.annotation(r_scc).universe() ); // If the type test requires that `T: 'a` where `'a` is a @@ -1321,7 +1186,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { tcx.fold_regions(value, |r, _db| { let vid = self.to_region_vid(r); let scc = self.constraint_sccs.scc(vid); - let repr = self.scc_representatives[scc]; + let repr = self.scc_representative(scc); ty::Region::new_var(tcx, repr) }) } @@ -1547,6 +1412,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + fn scc_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex { + self.constraint_sccs().annotation(scc).universe() + } /// Checks the final value for the free region `fr` to see if it /// grew too large. In particular, examine what `end(X)` points /// wound up in `fr`'s final value; for each `end(X)` where `X != @@ -1566,8 +1434,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Because this free region must be in the ROOT universe, we // know it cannot contain any bound universes. - assert!(self.scc_universes[longer_fr_scc].is_root()); - debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none()); + assert!(self.scc_universe(longer_fr_scc).is_root()); // Only check all of the relations for the main representative of each // SCC, otherwise just check that we outlive said representative. This @@ -1575,7 +1442,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // closures. // Note that the representative will be a universal region if there is // one in this SCC, so we will always check the representative here. - let representative = self.scc_representatives[longer_fr_scc]; + let representative = self.scc_representative(longer_fr_scc); if representative != longer_fr { if let RegionRelationCheckResult::Error = self.check_universal_region_relation( longer_fr, @@ -1776,36 +1643,27 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// that cannot be named by `fr1`; in that case, we will require /// that `fr1: 'static` because it is the only way to `fr1: r` to /// be satisfied. (See `add_incompatible_universe`.) + #[instrument(skip(self), ret)] pub(crate) fn provides_universal_region( &self, r: RegionVid, fr1: RegionVid, fr2: RegionVid, ) -> bool { - debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); - let result = { - r == fr2 || { - fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) - } - }; - debug!("provides_universal_region: result = {:?}", result); - result + let fr2_is_static = fr2 == self.universal_regions.fr_static; + r == fr2 || (fr2_is_static && self.cannot_name_placeholder(fr1, r)) } /// If `r2` represents a placeholder region, then this returns /// `true` if `r1` cannot name that placeholder in its /// value; otherwise, returns `false`. + #[instrument(skip(self), ret)] pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { - debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); - match self.definitions[r2].origin { NllRegionVariableOrigin::Placeholder(placeholder) => { - let universe1 = self.definitions[r1].universe; - debug!( - "cannot_name_value_of: universe1={:?} placeholder={:?}", - universe1, placeholder - ); - universe1.cannot_name(placeholder.universe) + let r1_universe = self.definitions[r1].universe; + debug!(?placeholder, ?r1_universe); + r1_universe.cannot_name(placeholder.universe) } NllRegionVariableOrigin::FreeRegion | NllRegionVariableOrigin::Existential { .. } => { @@ -1835,6 +1693,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// Returns: a series of constraints as well as the region `R` /// that passed the target test. + #[instrument(skip(self, target_test), ret)] pub(crate) fn find_constraint_paths_between_regions( &self, from_region: RegionVid, @@ -1932,7 +1791,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { #[instrument(skip(self), level = "trace", ret)] pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, location: Location) -> RegionVid { trace!(scc = ?self.constraint_sccs.scc(fr1)); - trace!(universe = ?self.scc_universes[self.constraint_sccs.scc(fr1)]); + trace!(universe = ?self.region_universe(fr1)); self.find_constraint_paths_between_regions(fr1, |r| { // First look for some `r` such that `fr1: r` and `r` is live at `location` trace!(?r, liveness_constraints=?self.liveness_constraints.pretty_print_live_points(r)); @@ -2252,8 +2111,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// This can be used to quickly under-approximate the regions which are equal to each other /// and their relative orderings. // This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`. - pub fn constraint_sccs(&self) -> &Sccs { - self.constraint_sccs.as_ref() + pub fn constraint_sccs(&self) -> &ConstraintSccs { + &self.constraint_sccs } /// Access to the region graph, built from the outlives constraints. @@ -2282,6 +2141,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { let point = self.liveness_constraints.point_from_location(location); self.liveness_constraints.is_loan_live_at(loan_idx, point) } + + /// Returns the representative `RegionVid` for a given SCC. + /// See `RegionTracker` for how a region variable ID is chosen. + fn scc_representative(&self, scc: ConstraintSccIndex) -> RegionVid { + self.constraint_sccs.annotation(scc).representative + } } impl<'tcx> RegionDefinition<'tcx> { @@ -2297,6 +2162,14 @@ impl<'tcx> RegionDefinition<'tcx> { Self { origin, universe, external_name: None } } + + pub fn is_placeholder(&self) -> bool { + matches!(self.origin, NllRegionVariableOrigin::Placeholder(_)) + } + + pub fn is_existential(&self) -> bool { + matches!(self.origin, NllRegionVariableOrigin::Existential { .. }) + } } #[derive(Clone, Debug)] diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 06adb686ed4..51c3648d730 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -85,7 +85,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Use the SCC representative instead of directly using `region`. // See [rustc-dev-guide chapter] § "Strict lifetime equality". let scc = self.constraint_sccs.scc(region.as_var()); - let vid = self.scc_representatives[scc]; + let vid = self.scc_representative(scc); let named = match self.definitions[vid].origin { // Iterate over all universal regions in a consistent order and find the // *first* equal region. This makes sure that equal lifetimes will have @@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let scc = self.constraint_sccs.scc(vid); // Special handling of higher-ranked regions. - if !self.scc_universes[scc].is_root() { + if !self.scc_universe(scc).is_root() { match self.scc_values.placeholders_contained_in(scc).enumerate().last() { // If the region contains a single placeholder then they're equal. Some((0, placeholder)) => { diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 7f36e4ca16d..fb8d727d67e 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -4,54 +4,111 @@ //! node in the graph. This uses [Tarjan's algorithm]( //! https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm) //! that completes in *O*(*n*) time. +//! Optionally, also annotate the SCC nodes with some commutative data. +//! Typical examples would include: minimum element in SCC, maximum element +//! reachable from it, etc. use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, NumEdges, Successors}; use rustc_index::{Idx, IndexSlice, IndexVec}; +use std::fmt::Debug; use std::ops::Range; use tracing::{debug, instrument}; #[cfg(test)] mod tests; +/// An annotation for an SCC. This can be a representative, +/// or the max/min element of the SCC, or all of the above. +pub trait Annotation: Debug + Copy { + /// Merge two existing annotations into one during + /// path compression. + fn merge_scc(self, other: Self) -> Self; + + /// Merge a successor into this annotation. + fn merge_reached(self, other: Self) -> Self; + + fn update_scc(&mut self, other: Self) { + *self = self.merge_scc(other) + } + + fn update_reachable(&mut self, other: Self) { + *self = self.merge_reached(other) + } +} + +/// The empty annotation, which does nothing. +impl Annotation for () { + fn merge_reached(self, _other: Self) -> Self { + () + } + fn merge_scc(self, _other: Self) -> Self { + () + } +} + /// Strongly connected components (SCC) of a graph. The type `N` is /// the index type for the graph nodes and `S` is the index type for /// the SCCs. We can map from each node to the SCC that it /// participates in, and we also have the successors of each SCC. -pub struct Sccs { +pub struct Sccs { /// For each node, what is the SCC index of the SCC to which it /// belongs. scc_indices: IndexVec, - /// Data about each SCC. - scc_data: SccData, + /// Data about all the SCCs. + scc_data: SccData, } -pub struct SccData { - /// For each SCC, the range of `all_successors` where its +/// Information about an invidividual SCC node. +struct SccDetails { + /// For this SCC, the range of `all_successors` where its /// successors can be found. - ranges: IndexVec>, + range: Range, + + /// User-specified metadata about the SCC. + annotation: A, +} + +// The name of this struct should discourage you from making it public and leaking +// its representation. This message was left here by one who came before you, +// who learnt the hard way that making even small changes in representation is difficult when it's publicly inspectable. Obey the law of Demeter! +struct SccData { + /// Maps SCC indices to their metadata, including + /// offsets into `all_successors`. + scc_details: IndexVec>, /// Contains the successors for all the Sccs, concatenated. The /// range of indices corresponding to a given SCC is found in its - /// SccData. + /// `scc_details.range`. all_successors: Vec, } -impl Sccs { +impl Sccs { + /// Compute SCCs without annotations. pub fn new(graph: &impl Successors) -> Self { - SccsConstruction::construct(graph) + Self::new_with_annotation(graph, |_| ()) + } +} + +impl Sccs { + /// Compute SCCs and annotate them with a user-supplied annotation + pub fn new_with_annotation A>( + graph: &impl Successors, + to_annotation: F, + ) -> Self { + SccsConstruction::construct(graph, to_annotation) + } + + pub fn annotation(&self, scc: S) -> A { + self.scc_data.annotation(scc) } pub fn scc_indices(&self) -> &IndexSlice { &self.scc_indices } - pub fn scc_data(&self) -> &SccData { - &self.scc_data - } - /// Returns the number of SCCs in the graph. pub fn num_sccs(&self) -> usize { self.scc_data.len() @@ -90,7 +147,7 @@ impl Sccs { } } -impl DirectedGraph for Sccs { +impl DirectedGraph for Sccs { type Node = S; fn num_nodes(&self) -> usize { @@ -98,43 +155,33 @@ impl DirectedGraph for Sccs { } } -impl NumEdges for Sccs { +impl NumEdges for Sccs { fn num_edges(&self) -> usize { self.scc_data.all_successors.len() } } -impl Successors for Sccs { +impl Successors for Sccs { fn successors(&self, node: S) -> impl Iterator { self.successors(node).iter().cloned() } } -impl SccData { +impl SccData { /// Number of SCCs, fn len(&self) -> usize { - self.ranges.len() - } - - pub fn ranges(&self) -> &IndexSlice> { - &self.ranges - } - - pub fn all_successors(&self) -> &Vec { - &self.all_successors + self.scc_details.len() } /// Returns the successors of the given SCC. fn successors(&self, scc: S) -> &[S] { - // Annoyingly, `range` does not implement `Copy`, so we have - // to do `range.start..range.end`: - let range = &self.ranges[scc]; - &self.all_successors[range.start..range.end] + &self.all_successors[self.scc_details[scc].range.clone()] } /// Creates a new SCC with `successors` as its successors and + /// the maximum weight of its internal nodes `scc_max_weight` and /// returns the resulting index. - fn create_scc(&mut self, successors: impl IntoIterator) -> S { + fn create_scc(&mut self, successors: impl IntoIterator, annotation: A) -> S { // Store the successors on `scc_successors_vec`, remembering // the range of indices. let all_successors_start = self.all_successors.len(); @@ -142,22 +189,35 @@ impl SccData { let all_successors_end = self.all_successors.len(); debug!( - "create_scc({:?}) successors={:?}", - self.ranges.len(), + "create_scc({:?}) successors={:?}, annotation={:?}", + self.len(), &self.all_successors[all_successors_start..all_successors_end], + annotation ); - self.ranges.push(all_successors_start..all_successors_end) + let range = all_successors_start..all_successors_end; + let metadata = SccDetails { range, annotation }; + self.scc_details.push(metadata) + } + + fn annotation(&self, scc: S) -> A { + self.scc_details[scc].annotation } } -struct SccsConstruction<'c, G: DirectedGraph + Successors, S: Idx> { +struct SccsConstruction<'c, G, S, A, F> +where + G: DirectedGraph + Successors, + S: Idx, + A: Annotation, + F: Fn(G::Node) -> A, +{ graph: &'c G, /// The state of each node; used during walk to record the stack /// and after walk to record what cycle each node ended up being /// in. - node_states: IndexVec>, + node_states: IndexVec>, /// The stack of nodes that we are visiting as part of the DFS. node_stack: Vec, @@ -174,26 +234,34 @@ struct SccsConstruction<'c, G: DirectedGraph + Successors, S: Idx> { /// around between successors to amortize memory allocation costs. duplicate_set: FxHashSet, - scc_data: SccData, + scc_data: SccData, + + /// A function that constructs an initial SCC annotation + /// out of a single node. + to_annotation: F, } #[derive(Copy, Clone, Debug)] -enum NodeState { +enum NodeState { /// This node has not yet been visited as part of the DFS. /// /// After SCC construction is complete, this state ought to be /// impossible. NotVisited, - /// This node is currently being walk as part of our DFS. It is on - /// the stack at the depth `depth`. + /// This node is currently being walked as part of our DFS. It is on + /// the stack at the depth `depth` and the heaviest node on the way + /// there is `max_weigth_on_path`. /// /// After SCC construction is complete, this state ought to be /// impossible. - BeingVisited { depth: usize }, + BeingVisited { depth: usize, annotation: A }, - /// Indicates that this node is a member of the given cycle. - InCycle { scc_index: S }, + /// Indicates that this node is a member of the given cycle where + /// the weight of the heaviest node is `cycle_max_weight`. + /// Note that an SCC can have several cycles, so the max + /// weight of an SCC is the max weight of all its cycles. + InCycle { scc_index: S, annotation: A }, /// Indicates that this node is a member of whatever cycle /// `parent` is a member of. This state is transient: whenever we @@ -203,16 +271,27 @@ enum NodeState { InCycleWith { parent: N }, } +/// The state of walking a given node. #[derive(Copy, Clone, Debug)] -enum WalkReturn { - Cycle { min_depth: usize }, - Complete { scc_index: S }, +enum WalkReturn { + /// The walk found a cycle, but the entire component is not known to have + /// been fully walked yet. We only know the minimum depth of this + /// component in a minimum spanning tree of the graph. This component + /// is tentatively represented by the state of the first node of this + /// cycle we met, which is at `min_depth`. + Cycle { min_depth: usize, annotation: A }, + /// The SCC and everything reachable from it have been fully walked. + /// At this point we know what is inside the SCC as we have visited every + /// node reachable from it. The SCC can now be fully represented by its ID. + Complete { scc_index: S, annotation: A }, } -impl<'c, G, S> SccsConstruction<'c, G, S> +impl<'c, G, S, A, F> SccsConstruction<'c, G, S, A, F> where G: DirectedGraph + Successors, S: Idx, + F: Fn(G::Node) -> A, + A: Annotation, { /// Identifies SCCs in the graph `G` and computes the resulting /// DAG. This uses a variant of [Tarjan's @@ -225,8 +304,12 @@ where /// D' (i.e., D' < D), we know that N, N', and all nodes in /// between them on the stack are part of an SCC. /// + /// Additionally, we keep track of a representative of the SCC with the highest + /// reachable weight for all SCCs, for some arbitrary ordering function that assigns + /// a weight to nodes. + /// /// [wikipedia]: https://bit.ly/2EZIx84 - fn construct(graph: &'c G) -> Sccs { + fn construct(graph: &'c G, to_annotation: F) -> Sccs { let num_nodes = graph.num_nodes(); let mut this = Self { @@ -234,15 +317,16 @@ where node_states: IndexVec::from_elem_n(NodeState::NotVisited, num_nodes), node_stack: Vec::with_capacity(num_nodes), successors_stack: Vec::new(), - scc_data: SccData { ranges: IndexVec::new(), all_successors: Vec::new() }, + scc_data: SccData { scc_details: IndexVec::new(), all_successors: Vec::new() }, duplicate_set: FxHashSet::default(), + to_annotation, }; let scc_indices = (0..num_nodes) .map(G::Node::new) .map(|node| match this.start_walk_from(node) { - WalkReturn::Complete { scc_index } => scc_index, - WalkReturn::Cycle { min_depth } => { + WalkReturn::Complete { scc_index, .. } => scc_index, + WalkReturn::Cycle { min_depth, .. } => { panic!("`start_walk_node({node:?})` returned cycle with depth {min_depth:?}") } }) @@ -251,12 +335,8 @@ where Sccs { scc_indices, scc_data: this.scc_data } } - fn start_walk_from(&mut self, node: G::Node) -> WalkReturn { - if let Some(result) = self.inspect_node(node) { - result - } else { - self.walk_unvisited_node(node) - } + fn start_walk_from(&mut self, node: G::Node) -> WalkReturn { + self.inspect_node(node).unwrap_or_else(|| self.walk_unvisited_node(node)) } /// Inspect a node during the DFS. We first examine its current @@ -271,11 +351,15 @@ where /// Otherwise, we are looking at a node that has already been /// completely visited. We therefore return `WalkReturn::Complete` /// with its associated SCC index. - fn inspect_node(&mut self, node: G::Node) -> Option> { + fn inspect_node(&mut self, node: G::Node) -> Option> { Some(match self.find_state(node) { - NodeState::InCycle { scc_index } => WalkReturn::Complete { scc_index }, + NodeState::InCycle { scc_index, annotation } => { + WalkReturn::Complete { scc_index, annotation } + } - NodeState::BeingVisited { depth: min_depth } => WalkReturn::Cycle { min_depth }, + NodeState::BeingVisited { depth: min_depth, annotation } => { + WalkReturn::Cycle { min_depth, annotation } + } NodeState::NotVisited => return None, @@ -290,7 +374,7 @@ where /// of `r2` (and updates `r` to reflect current result). This is /// basically the "find" part of a standard union-find algorithm /// (with path compression). - fn find_state(&mut self, mut node: G::Node) -> NodeState { + fn find_state(&mut self, mut node: G::Node) -> NodeState { // To avoid recursion we temporarily reuse the `parent` of each // InCycleWith link to encode a downwards link while compressing // the path. After we have found the root or deepest node being @@ -306,24 +390,42 @@ where // found the initial self-loop. let mut previous_node = node; - // Ultimately assigned by the parent when following + // Ultimately propagated to all the transitive parents when following // `InCycleWith` upwards. - let node_state = loop { - debug!("find_state(r = {:?} in state {:?})", node, self.node_states[node]); - match self.node_states[node] { - NodeState::InCycle { scc_index } => break NodeState::InCycle { scc_index }, - NodeState::BeingVisited { depth } => break NodeState::BeingVisited { depth }, - NodeState::NotVisited => break NodeState::NotVisited, - NodeState::InCycleWith { parent } => { - // We test this, to be extremely sure that we never - // ever break our termination condition for the - // reverse iteration loop. - assert!(node != parent, "Node can not be in cycle with itself"); - // Store the previous node as an inverted list link - self.node_states[node] = NodeState::InCycleWith { parent: previous_node }; - // Update to parent node. - previous_node = node; - node = parent; + // This loop performs the downward link encoding mentioned above. Details below! + let node_state = { + let mut annotation = (self.to_annotation)(node); + + loop { + debug!("find_state(r = {node:?} in state {:?})", self.node_states[node]); + match self.node_states[node] { + NodeState::NotVisited => break NodeState::NotVisited, + NodeState::BeingVisited { depth, annotation: previous_annotation } => { + break NodeState::BeingVisited { + depth, + annotation: previous_annotation.merge_scc(annotation), + }; + } + NodeState::InCycleWith { parent } => { + // We test this, to be extremely sure that we never + // ever break our termination condition for the + // reverse iteration loop. + assert!(node != parent, "Node can not be in cycle with itself"); + + annotation = annotation.merge_scc((self.to_annotation)(node)); + + // Store the previous node as an inverted list link + self.node_states[node] = NodeState::InCycleWith { parent: previous_node }; + // Update to parent node. + previous_node = node; + node = parent; + } + NodeState::InCycle { scc_index, annotation: previous_annotation } => { + break NodeState::InCycle { + scc_index, + annotation: previous_annotation.merge_scc(annotation), + }; + } } } }; @@ -369,6 +471,8 @@ where if previous_node == node { return node_state; } + debug!("Compressing {node:?} down to {previous_node:?} with state {node_state:?}"); + // Update to previous node in the link. match self.node_states[previous_node] { NodeState::InCycleWith { parent: previous } => { @@ -381,29 +485,20 @@ where debug!("find_state: parent_state = {:?}", node_state); - // Update the node state from the parent state. The assigned - // state is actually a loop invariant but it will only be - // evaluated if there is at least one backlink to follow. - // Fully trusting llvm here to find this loop optimization. - match node_state { - // Path compression, make current node point to the same root. - NodeState::InCycle { .. } => { - self.node_states[node] = node_state; - } - // Still visiting nodes, compress to cycle to the node + let new_state = match node_state { + // Still visiting nodes, compress the cycle to the root node // at that depth. - NodeState::BeingVisited { depth } => { - self.node_states[node] = - NodeState::InCycleWith { parent: self.node_stack[depth] }; + NodeState::BeingVisited { depth, .. } => { + let parent = self.node_stack[depth]; + NodeState::InCycleWith { parent } } - // These are never allowed as parent nodes. InCycleWith - // should have been followed to a real parent and - // NotVisited can not be part of a cycle since it should - // have instead gotten explored. - NodeState::NotVisited | NodeState::InCycleWith { .. } => { - panic!("invalid parent state: {node_state:?}") - } - } + // Already fully visited; we just transfer the state of the parent. + s @ NodeState::InCycle { .. } => s, + // These cannot be the root nodes of a path being compressed + NodeState::NotVisited | NodeState::InCycleWith { .. } => unreachable!(), + }; + + self.node_states[node] = new_state; } } @@ -413,30 +508,37 @@ where /// caller decide avoids mutual recursion between the two methods and allows /// us to maintain an allocated stack for nodes on the path between calls. #[instrument(skip(self, initial), level = "debug")] - fn walk_unvisited_node(&mut self, initial: G::Node) -> WalkReturn { - struct VisitingNodeFrame { + fn walk_unvisited_node(&mut self, initial: G::Node) -> WalkReturn { + debug!("Walk unvisited node: {initial:?}"); + struct VisitingNodeFrame { node: G::Node, - iter: Option, + successors: Option, depth: usize, min_depth: usize, successors_len: usize, min_cycle_root: G::Node, successor_node: G::Node, + /// The annotation for the SCC starting in `node`. It may or may + /// not contain other nodes. + current_component_annotation: A, } // Move the stack to a local variable. We want to utilize the existing allocation and // mutably borrow it without borrowing self at the same time. let mut successors_stack = core::mem::take(&mut self.successors_stack); + debug_assert_eq!(successors_stack.len(), 0); - let mut stack: Vec> = vec![VisitingNodeFrame { + let mut stack: Vec> = vec![VisitingNodeFrame { node: initial, depth: 0, min_depth: 0, - iter: None, + successors: None, successors_len: 0, min_cycle_root: initial, successor_node: initial, + // Strictly speaking not necessary, but assumed to be idempotent: + current_component_annotation: (self.to_annotation)(initial), }]; let mut return_value = None; @@ -445,18 +547,24 @@ where let VisitingNodeFrame { node, depth, - iter, + successors, successors_len, min_depth, min_cycle_root, successor_node, + current_component_annotation, } = frame; - let node = *node; let depth = *depth; - let successors = match iter { - Some(iter) => iter, + // node is definitely in the current component, add it to the annotation. + current_component_annotation.update_scc((self.to_annotation)(node)); + debug!( + "Visiting {node:?} at depth {depth:?}, annotation: {current_component_annotation:?}" + ); + + let successors = match successors { + Some(successors) => successors, None => { // This None marks that we still have the initialize this node's frame. debug!(?depth, ?node); @@ -464,7 +572,8 @@ where debug_assert!(matches!(self.node_states[node], NodeState::NotVisited)); // Push `node` onto the stack. - self.node_states[node] = NodeState::BeingVisited { depth }; + self.node_states[node] = + NodeState::BeingVisited { depth, annotation: (self.to_annotation)(node) }; self.node_stack.push(node); // Walk each successor of the node, looking to see if any of @@ -472,11 +581,11 @@ where // so, that means they can also reach us. *successors_len = successors_stack.len(); // Set and return a reference, this is currently empty. - iter.get_or_insert(self.graph.successors(node)) + successors.get_or_insert(self.graph.successors(node)) } }; - // Now that iter is initialized, this is a constant for this frame. + // Now that the successors iterator is initialized, this is a constant for this frame. let successors_len = *successors_len; // Construct iterators for the nodes and walk results. There are two cases: @@ -489,10 +598,17 @@ where debug!(?node, ?successor_node); (successor_node, self.inspect_node(successor_node)) }); - for (successor_node, walk) in returned_walk.chain(successor_walk) { match walk { - Some(WalkReturn::Cycle { min_depth: successor_min_depth }) => { + // The starting node `node` leads to a cycle whose earliest node, + // `successor_node`, is at `min_depth`. There may be more cycles. + Some(WalkReturn::Cycle { + min_depth: successor_min_depth, + annotation: successor_annotation, + }) => { + debug!( + "Cycle found from {node:?}, minimum depth: {successor_min_depth:?}, annotation: {successor_annotation:?}" + ); // Track the minimum depth we can reach. assert!(successor_min_depth <= depth); if successor_min_depth < *min_depth { @@ -500,41 +616,56 @@ where *min_depth = successor_min_depth; *min_cycle_root = successor_node; } + current_component_annotation.update_scc(successor_annotation); } - - Some(WalkReturn::Complete { scc_index: successor_scc_index }) => { + // The starting node `node` is succeeded by a fully identified SCC + // which is now added to the set under `scc_index`. + Some(WalkReturn::Complete { + scc_index: successor_scc_index, + annotation: successor_annotation, + }) => { + debug!( + "Complete; {node:?} is root of complete-visited SCC idx {successor_scc_index:?} with annotation {successor_annotation:?}" + ); // Push the completed SCC indices onto // the `successors_stack` for later. debug!(?node, ?successor_scc_index); successors_stack.push(successor_scc_index); + current_component_annotation.update_reachable(successor_annotation); } - + // `node` has no more (direct) successors; search recursively. None => { let depth = depth + 1; + debug!("Recursing down into {successor_node:?} at depth {depth:?}"); debug!(?depth, ?successor_node); // Remember which node the return value will come from. frame.successor_node = successor_node; - // Start a new stack frame the step into it. + // Start a new stack frame, then step into it. stack.push(VisitingNodeFrame { node: successor_node, depth, - iter: None, + successors: None, successors_len: 0, min_depth: depth, min_cycle_root: successor_node, successor_node, + current_component_annotation: (self.to_annotation)(successor_node), }); continue 'recurse; } } } + debug!("Finished walk from {node:?} with annotation: {current_component_annotation:?}"); + // Completed walk, remove `node` from the stack. let r = self.node_stack.pop(); debug_assert_eq!(r, Some(node)); // Remove the frame, it's done. let frame = stack.pop().unwrap(); + let current_component_annotation = frame.current_component_annotation; + debug_assert_eq!(frame.node, node); // If `min_depth == depth`, then we are the root of the // cycle: we can't reach anyone further down the stack. @@ -543,6 +674,8 @@ where // We return one frame at a time so there can't be another return value. debug_assert!(return_value.is_none()); return_value = Some(if frame.min_depth == depth { + // We are at the head of the component. + // Note that successor stack may have duplicates, so we // want to remove those: let deduplicated_successors = { @@ -552,15 +685,25 @@ where .drain(successors_len..) .filter(move |&i| duplicate_set.insert(i)) }; - let scc_index = self.scc_data.create_scc(deduplicated_successors); - self.node_states[node] = NodeState::InCycle { scc_index }; - WalkReturn::Complete { scc_index } + + debug!("Creating SCC rooted in {node:?} with successor {:?}", frame.successor_node); + + let scc_index = + self.scc_data.create_scc(deduplicated_successors, current_component_annotation); + + self.node_states[node] = + NodeState::InCycle { scc_index, annotation: current_component_annotation }; + + WalkReturn::Complete { scc_index, annotation: current_component_annotation } } else { // We are not the head of the cycle. Return back to our // caller. They will take ownership of the // `self.successors` data that we pushed. self.node_states[node] = NodeState::InCycleWith { parent: frame.min_cycle_root }; - WalkReturn::Cycle { min_depth: frame.min_depth } + WalkReturn::Cycle { + min_depth: frame.min_depth, + annotation: current_component_annotation, + } }); } diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs index 513df666d0d..373f87bfdbc 100644 --- a/compiler/rustc_data_structures/src/graph/scc/tests.rs +++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs @@ -3,10 +3,53 @@ extern crate test; use super::*; use crate::graph::tests::TestGraph; +#[derive(Copy, Clone, Debug)] +struct MaxReached(usize); +type UsizeSccs = Sccs; +type MaxReachedSccs = Sccs; + +impl Annotation for MaxReached { + fn merge_scc(self, other: Self) -> Self { + Self(std::cmp::max(other.0, self.0)) + } + + fn merge_reached(self, other: Self) -> Self { + self.merge_scc(other) + } +} + +impl PartialEq for MaxReached { + fn eq(&self, other: &usize) -> bool { + &self.0 == other + } +} + +impl MaxReached { + fn from_usize(nr: usize) -> Self { + Self(nr) + } +} + +#[derive(Copy, Clone, Debug)] +struct MinMaxIn { + min: usize, + max: usize, +} + +impl Annotation for MinMaxIn { + fn merge_scc(self, other: Self) -> Self { + Self { min: std::cmp::min(self.min, other.min), max: std::cmp::max(self.max, other.max) } + } + + fn merge_reached(self, _other: Self) -> Self { + self + } +} + #[test] fn diamond() { let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3)]); - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 4); assert_eq!(sccs.num_sccs(), 4); } @@ -34,7 +77,7 @@ fn test_big_scc() { +-- 2 <--+ */ let graph = TestGraph::new(0, &[(0, 1), (1, 2), (1, 3), (2, 0), (3, 2)]); - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 1); } @@ -50,7 +93,7 @@ fn test_three_sccs() { +-- 2 <--+ */ let graph = TestGraph::new(0, &[(0, 1), (1, 2), (2, 1), (3, 2)]); - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 3); assert_eq!(sccs.scc(0), 1); assert_eq!(sccs.scc(1), 0); @@ -106,7 +149,7 @@ fn test_find_state_2() { // 2 InCycleWith { 1 } // 3 InCycleWith { 0 } - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 1); assert_eq!(sccs.scc(0), 0); assert_eq!(sccs.scc(1), 0); @@ -130,7 +173,7 @@ fn test_find_state_3() { */ let graph = TestGraph::new(0, &[(0, 1), (0, 4), (1, 2), (1, 3), (2, 1), (3, 0), (4, 2), (5, 2)]); - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 2); assert_eq!(sccs.scc(0), 0); assert_eq!(sccs.scc(1), 0); @@ -165,7 +208,7 @@ fn test_deep_linear() { nodes.push((i - 1, i)); } let graph = TestGraph::new(0, nodes.as_slice()); - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), NR_NODES); assert_eq!(sccs.scc(0), NR_NODES - 1); assert_eq!(sccs.scc(NR_NODES - 1), 0); @@ -210,7 +253,164 @@ fn bench_sccc(b: &mut test::Bencher) { graph[21] = (7, 4); let graph = TestGraph::new(0, &graph[..]); b.iter(|| { - let sccs: Sccs<_, usize> = Sccs::new(&graph); + let sccs: UsizeSccs = Sccs::new(&graph); assert_eq!(sccs.num_sccs(), 3); }); } + +#[test] +fn test_max_self_loop() { + let graph = TestGraph::new(0, &[(0, 0)]); + let sccs: MaxReachedSccs = + Sccs::new_with_annotation(&graph, |n| if n == 0 { MaxReached(17) } else { MaxReached(0) }); + assert_eq!(sccs.annotation(0), 17); +} + +#[test] +fn test_max_branch() { + let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 4)]); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, MaxReached::from_usize); + assert_eq!(sccs.annotation(sccs.scc(0)), 4); + assert_eq!(sccs.annotation(sccs.scc(1)), 3); + assert_eq!(sccs.annotation(sccs.scc(2)), 4); +} +#[test] +fn test_single_cycle_max() { + let graph = TestGraph::new(0, &[(0, 2), (2, 3), (2, 4), (4, 1), (1, 2)]); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, MaxReached::from_usize); + assert_eq!(sccs.annotation(sccs.scc(2)), 4); + assert_eq!(sccs.annotation(sccs.scc(0)), 4); +} + +#[test] +fn test_simple_cycle_max() { + let graph = TestGraph::new(0, &[(0, 1), (1, 2), (2, 0)]); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, MaxReached::from_usize); + assert_eq!(sccs.num_sccs(), 1); +} + +#[test] +fn test_double_cycle_max() { + let graph = + TestGraph::new(0, &[(0, 1), (1, 2), (1, 4), (2, 3), (2, 4), (3, 5), (4, 1), (5, 4)]); + let sccs: MaxReachedSccs = + Sccs::new_with_annotation(&graph, |n| if n == 5 { MaxReached(2) } else { MaxReached(1) }); + + assert_eq!(sccs.annotation(sccs.scc(0)).0, 2); +} + +#[test] +fn test_bug_minimised() { + let graph = TestGraph::new(0, &[(0, 3), (0, 1), (3, 2), (2, 3), (1, 4), (4, 5), (5, 4)]); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |n| match n { + 3 => MaxReached(1), + _ => MaxReached(0), + }); + assert_eq!(sccs.annotation(sccs.scc(2)), 1); + assert_eq!(sccs.annotation(sccs.scc(1)), 0); + assert_eq!(sccs.annotation(sccs.scc(4)), 0); +} + +#[test] +fn test_bug_max_leak_minimised() { + let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (3, 0), (3, 4), (4, 3)]); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w { + 4 => MaxReached(1), + _ => MaxReached(0), + }); + + assert_eq!(sccs.annotation(sccs.scc(2)), 0); + assert_eq!(sccs.annotation(sccs.scc(3)), 1); + assert_eq!(sccs.annotation(sccs.scc(0)), 1); +} + +#[test] +fn test_bug_max_leak() { + let graph = TestGraph::new( + 8, + &[ + (0, 0), + (0, 18), + (0, 19), + (0, 1), + (0, 2), + (0, 7), + (0, 8), + (0, 23), + (18, 0), + (18, 12), + (19, 0), + (19, 25), + (12, 18), + (12, 3), + (12, 5), + (3, 12), + (3, 21), + (3, 22), + (5, 13), + (21, 3), + (22, 3), + (13, 5), + (13, 4), + (4, 13), + (4, 0), + (2, 11), + (7, 6), + (6, 20), + (20, 6), + (8, 17), + (17, 9), + (9, 16), + (16, 26), + (26, 15), + (15, 10), + (10, 14), + (14, 27), + (23, 24), + ], + ); + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w { + 22 => MaxReached(1), + 24 => MaxReached(2), + 27 => MaxReached(2), + _ => MaxReached(0), + }); + + assert_eq!(sccs.annotation(sccs.scc(2)), 0); + assert_eq!(sccs.annotation(sccs.scc(7)), 0); + assert_eq!(sccs.annotation(sccs.scc(8)), 2); + assert_eq!(sccs.annotation(sccs.scc(23)), 2); + assert_eq!(sccs.annotation(sccs.scc(3)), 2); + assert_eq!(sccs.annotation(sccs.scc(0)), 2); +} + +#[test] +fn test_bug_max_zero_stick_shape() { + let graph = TestGraph::new(0, &[(0, 1), (1, 2), (2, 3), (3, 2), (3, 4)]); + + let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w { + 4 => MaxReached(1), + _ => MaxReached(0), + }); + + assert_eq!(sccs.annotation(sccs.scc(0)), 1); + assert_eq!(sccs.annotation(sccs.scc(1)), 1); + assert_eq!(sccs.annotation(sccs.scc(2)), 1); + assert_eq!(sccs.annotation(sccs.scc(3)), 1); + assert_eq!(sccs.annotation(sccs.scc(4)), 1); +} + +#[test] +fn test_min_max_in() { + let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (3, 0), (3, 4), (4, 3), (3, 5)]); + let sccs: Sccs = + Sccs::new_with_annotation(&graph, |w| MinMaxIn { min: w, max: w }); + + assert_eq!(sccs.annotation(sccs.scc(2)).min, 2); + assert_eq!(sccs.annotation(sccs.scc(2)).max, 2); + assert_eq!(sccs.annotation(sccs.scc(0)).min, 0); + assert_eq!(sccs.annotation(sccs.scc(0)).max, 4); + assert_eq!(sccs.annotation(sccs.scc(3)).min, 0); + assert_eq!(sccs.annotation(sccs.scc(3)).max, 4); + assert_eq!(sccs.annotation(sccs.scc(5)).min, 5); +} diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 5b159d62731..89b3dfc46f7 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -360,7 +360,7 @@ struct MiniGraph<'tcx> { /// Map from node index to SCC, and stores the successors of each SCC. All /// the regions in the same SCC are equal to one another, and if `S1 -> S2`, /// then `S1: S2`. - sccs: Sccs, + sccs: Sccs, } impl<'tcx> MiniGraph<'tcx> { From d2a01760bcc82302464632e38d2108e06c2a8dd9 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 13 May 2024 14:02:14 +0200 Subject: [PATCH 136/153] Documentation fixes --- .../rustc_data_structures/src/graph/scc/mod.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index fb8d727d67e..68a055553a1 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -250,17 +250,17 @@ enum NodeState { NotVisited, /// This node is currently being walked as part of our DFS. It is on - /// the stack at the depth `depth` and the heaviest node on the way - /// there is `max_weigth_on_path`. + /// the stack at the depth `depth` and its current annotation is + /// `annotation`. /// /// After SCC construction is complete, this state ought to be /// impossible. BeingVisited { depth: usize, annotation: A }, /// Indicates that this node is a member of the given cycle where - /// the weight of the heaviest node is `cycle_max_weight`. - /// Note that an SCC can have several cycles, so the max - /// weight of an SCC is the max weight of all its cycles. + /// the merged annotation is `annotation`. + /// Note that an SCC can have several cycles, so its final annotation + /// is the merged value of all its member annotations. InCycle { scc_index: S, annotation: A }, /// Indicates that this node is a member of whatever cycle @@ -304,9 +304,8 @@ where /// D' (i.e., D' < D), we know that N, N', and all nodes in /// between them on the stack are part of an SCC. /// - /// Additionally, we keep track of a representative of the SCC with the highest - /// reachable weight for all SCCs, for some arbitrary ordering function that assigns - /// a weight to nodes. + /// Additionally, we keep track of a representative annotation of the + /// SCC. /// /// [wikipedia]: https://bit.ly/2EZIx84 fn construct(graph: &'c G, to_annotation: F) -> Sccs { From 905db03b2869d6c53893ccddd84d8b2fd3c48273 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Fri, 17 May 2024 15:11:59 +0200 Subject: [PATCH 137/153] Simplify path compression logic --- .../rustc_borrowck/src/constraints/mod.rs | 13 ++++++++++--- .../rustc_borrowck/src/region_infer/mod.rs | 2 ++ .../src/graph/scc/mod.rs | 19 ++----------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index b1d6fd89e27..ecb05eb09a4 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -62,15 +62,22 @@ impl scc::Annotation for RegionTracker { impl RegionTracker { pub fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { + let (representative_is_placeholder, representative_is_existential) = match definition.origin { + rustc_infer::infer::NllRegionVariableOrigin::FreeRegion => (false, false), + rustc_infer::infer::NllRegionVariableOrigin::Placeholder(_) => (true, false), + rustc_infer::infer::NllRegionVariableOrigin::Existential { .. } => (false, true), + }; + let placeholder_universe = - if definition.is_placeholder() { definition.universe } else { UniverseIndex::ROOT }; + if representative_is_placeholder { definition.universe } else { UniverseIndex::ROOT }; + Self { max_placeholder_universe_reached: placeholder_universe, min_reachable_universe: definition.universe, representative: rvid, - representative_is_placeholder: definition.is_placeholder(), - representative_is_existential: definition.is_existential(), + representative_is_placeholder, + representative_is_existential, } } pub fn universe(self) -> UniverseIndex { diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b2a91a58e5c..2f387e345ed 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2163,10 +2163,12 @@ impl<'tcx> RegionDefinition<'tcx> { Self { origin, universe, external_name: None } } + #[inline(always)] pub fn is_placeholder(&self) -> bool { matches!(self.origin, NllRegionVariableOrigin::Placeholder(_)) } + #[inline(always)] pub fn is_existential(&self) -> bool { matches!(self.origin, NllRegionVariableOrigin::Existential { .. }) } diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 68a055553a1..1426aa2baa4 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -393,38 +393,23 @@ where // `InCycleWith` upwards. // This loop performs the downward link encoding mentioned above. Details below! let node_state = { - let mut annotation = (self.to_annotation)(node); - loop { debug!("find_state(r = {node:?} in state {:?})", self.node_states[node]); match self.node_states[node] { - NodeState::NotVisited => break NodeState::NotVisited, - NodeState::BeingVisited { depth, annotation: previous_annotation } => { - break NodeState::BeingVisited { - depth, - annotation: previous_annotation.merge_scc(annotation), - }; - } + s @ (NodeState::NotVisited | NodeState::BeingVisited{..} | NodeState::InCycle { .. }) => break s, NodeState::InCycleWith { parent } => { // We test this, to be extremely sure that we never // ever break our termination condition for the // reverse iteration loop. assert!(node != parent, "Node can not be in cycle with itself"); - annotation = annotation.merge_scc((self.to_annotation)(node)); - // Store the previous node as an inverted list link self.node_states[node] = NodeState::InCycleWith { parent: previous_node }; // Update to parent node. previous_node = node; node = parent; } - NodeState::InCycle { scc_index, annotation: previous_annotation } => { - break NodeState::InCycle { - scc_index, - annotation: previous_annotation.merge_scc(annotation), - }; - } + } } }; From 582c613be80f7b308972290773b23cac39c4b7d7 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Fri, 17 May 2024 15:12:31 +0200 Subject: [PATCH 138/153] Formatting, weird because I just did that --- compiler/rustc_borrowck/src/constraints/mod.rs | 4 ++-- compiler/rustc_data_structures/src/graph/scc/mod.rs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index ecb05eb09a4..111a62aa6af 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -62,7 +62,8 @@ impl scc::Annotation for RegionTracker { impl RegionTracker { pub fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { - let (representative_is_placeholder, representative_is_existential) = match definition.origin { + let (representative_is_placeholder, representative_is_existential) = match definition.origin + { rustc_infer::infer::NllRegionVariableOrigin::FreeRegion => (false, false), rustc_infer::infer::NllRegionVariableOrigin::Placeholder(_) => (true, false), rustc_infer::infer::NllRegionVariableOrigin::Existential { .. } => (false, true), @@ -71,7 +72,6 @@ impl RegionTracker { let placeholder_universe = if representative_is_placeholder { definition.universe } else { UniverseIndex::ROOT }; - Self { max_placeholder_universe_reached: placeholder_universe, min_reachable_universe: definition.universe, diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 1426aa2baa4..e7ec2f97505 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -396,7 +396,9 @@ where loop { debug!("find_state(r = {node:?} in state {:?})", self.node_states[node]); match self.node_states[node] { - s @ (NodeState::NotVisited | NodeState::BeingVisited{..} | NodeState::InCycle { .. }) => break s, + s @ (NodeState::NotVisited + | NodeState::BeingVisited { .. } + | NodeState::InCycle { .. }) => break s, NodeState::InCycleWith { parent } => { // We test this, to be extremely sure that we never // ever break our termination condition for the @@ -409,7 +411,6 @@ where previous_node = node; node = parent; } - } } }; From 14c10ec88e3766868b9fe94458385fad3c3f8a7e Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Fri, 17 May 2024 16:55:38 +0200 Subject: [PATCH 139/153] Docstring for for `Annotation` Note that this changes no executing code. The change is 100% in documentation. --- .../rustc_data_structures/src/graph/scc/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index e7ec2f97505..5fb99e7ada4 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -20,10 +20,20 @@ use tracing::{debug, instrument}; mod tests; /// An annotation for an SCC. This can be a representative, -/// or the max/min element of the SCC, or all of the above. +/// the max/min element of the SCC, or all of the above. +/// +/// Concretely, the following properties must hold (where `merge` +/// is `merge_scc` and `merge_reached`): +/// - idempotency: `a.merge(a) = a` +/// - commutativity: `a.merge(b) = b.merge(a)` +/// +/// This is rather limiting and precludes, for example, counting. +/// In general, what you want is probably always min/max according +/// to some ordering, potentially with side constraints (min x such +/// that P holds). pub trait Annotation: Debug + Copy { /// Merge two existing annotations into one during - /// path compression. + /// path compression.o fn merge_scc(self, other: Self) -> Self; /// Merge a successor into this annotation. From b1add7bc046bce3dd1d31175486d160d8af52674 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 20 May 2024 13:01:35 +0200 Subject: [PATCH 140/153] Slightly faster version of `find_state` This version shaves off ca 2% of the cycles in my experiments and makes the control flow easier to follow for me and hopefully others, including the compiler. Someone gave me a working profiler and by God I'm using it. --- .../src/graph/scc/mod.rs | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 5fb99e7ada4..2ce155bb316 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -402,13 +402,25 @@ where // Ultimately propagated to all the transitive parents when following // `InCycleWith` upwards. // This loop performs the downward link encoding mentioned above. Details below! - let node_state = { + // Note that there are two different states being assigned: the root state, and + // a potentially derived version of the root state for non-root nodes in the chain. + let (root_state, assigned_state) = { loop { debug!("find_state(r = {node:?} in state {:?})", self.node_states[node]); match self.node_states[node] { - s @ (NodeState::NotVisited - | NodeState::BeingVisited { .. } - | NodeState::InCycle { .. }) => break s, + // This must have been the first and only state since it is unexplored*; + // no update needed! * Unless there is a bug :') + s @ NodeState::NotVisited => return s, + // We are in a completely discovered SCC; every node on our path is in that SCC: + s @ NodeState::InCycle { .. } => break (s, s), + // The Interesting Third Base Case: we are a path back to a root node + // still being explored. Now we need that node to keep its state and + // every other node to be recorded as being in whatever component that + // ends up in. + s @ NodeState::BeingVisited { depth, .. } => { + break (s, NodeState::InCycleWith { parent: self.node_stack[depth] }); + } + // We are not at the head of a path; keep compressing it! NodeState::InCycleWith { parent } => { // We test this, to be extremely sure that we never // ever break our termination condition for the @@ -462,11 +474,13 @@ where // Move backwards until we found the node where we started. We // will know when we hit the state where previous_node == node. loop { - // Back at the beginning, we can return. + // Back at the beginning, we can return. Note that we return the root state. + // This is becuse for components being explored, we would otherwise get a + // `node_state[n] = InCycleWith{ parent: n }` and that's wrong. if previous_node == node { - return node_state; + return root_state; } - debug!("Compressing {node:?} down to {previous_node:?} with state {node_state:?}"); + debug!("Compressing {node:?} down to {previous_node:?} with state {assigned_state:?}"); // Update to previous node in the link. match self.node_states[previous_node] { @@ -475,25 +489,14 @@ where previous_node = previous; } // Only InCycleWith nodes were added to the reverse linked list. - other => panic!("Invalid previous link while compressing cycle: {other:?}"), + other => unreachable!("Invalid previous link while compressing cycle: {other:?}"), } - debug!("find_state: parent_state = {:?}", node_state); - - let new_state = match node_state { - // Still visiting nodes, compress the cycle to the root node - // at that depth. - NodeState::BeingVisited { depth, .. } => { - let parent = self.node_stack[depth]; - NodeState::InCycleWith { parent } - } - // Already fully visited; we just transfer the state of the parent. - s @ NodeState::InCycle { .. } => s, - // These cannot be the root nodes of a path being compressed - NodeState::NotVisited | NodeState::InCycleWith { .. } => unreachable!(), - }; - - self.node_states[node] = new_state; + // Update the node state to the (potentially derived) state. + // If the root is still being explored, this is + // `InCycleWith{ parent: }`, otherwise + // `assigned_state == root_state`. + self.node_states[node] = assigned_state; } } From aee846224cfaf6679acbf30986e6d2bb0de769ea Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Mon, 20 May 2024 13:25:55 +0200 Subject: [PATCH 141/153] Remove a few unnecessary constructions This shaves off ca 6% of the cycles in `start_walk_from()` in my experiments. --- compiler/rustc_data_structures/src/graph/scc/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 2ce155bb316..22b029c2bd4 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -535,7 +535,6 @@ where successors_len: 0, min_cycle_root: initial, successor_node: initial, - // Strictly speaking not necessary, but assumed to be idempotent: current_component_annotation: (self.to_annotation)(initial), }]; @@ -556,7 +555,9 @@ where let depth = *depth; // node is definitely in the current component, add it to the annotation. - current_component_annotation.update_scc((self.to_annotation)(node)); + if node != initial { + current_component_annotation.update_scc((self.to_annotation)(node)); + } debug!( "Visiting {node:?} at depth {depth:?}, annotation: {current_component_annotation:?}" ); @@ -570,8 +571,10 @@ where debug_assert!(matches!(self.node_states[node], NodeState::NotVisited)); // Push `node` onto the stack. - self.node_states[node] = - NodeState::BeingVisited { depth, annotation: (self.to_annotation)(node) }; + self.node_states[node] = NodeState::BeingVisited { + depth, + annotation: *current_component_annotation, + }; self.node_stack.push(node); // Walk each successor of the node, looking to see if any of From 7782d2023bd3fbaf28f4ecc66d51bb33b1e18491 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Tue, 21 May 2024 10:18:44 +0200 Subject: [PATCH 142/153] Roll back a few `#[instrument]` Apparently this interferes with inlining and murders performance on `wg-grammar`. --- .../rustc_borrowck/src/region_infer/mod.rs | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 2f387e345ed..91dbbfb4973 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1643,26 +1643,33 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// that cannot be named by `fr1`; in that case, we will require /// that `fr1: 'static` because it is the only way to `fr1: r` to /// be satisfied. (See `add_incompatible_universe`.) - #[instrument(skip(self), ret)] pub(crate) fn provides_universal_region( &self, r: RegionVid, fr1: RegionVid, fr2: RegionVid, ) -> bool { - let fr2_is_static = fr2 == self.universal_regions.fr_static; - r == fr2 || (fr2_is_static && self.cannot_name_placeholder(fr1, r)) + debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); + let result = { + r == fr2 || { + fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) + } + }; + debug!("provides_universal_region: result = {:?}", result); + result } /// If `r2` represents a placeholder region, then this returns /// `true` if `r1` cannot name that placeholder in its /// value; otherwise, returns `false`. - #[instrument(skip(self), ret)] pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { match self.definitions[r2].origin { NllRegionVariableOrigin::Placeholder(placeholder) => { let r1_universe = self.definitions[r1].universe; - debug!(?placeholder, ?r1_universe); + debug!( + "cannot_name_value_of: universe1={r1_universe:?} placeholder={:?}", + placeholder + ); r1_universe.cannot_name(placeholder.universe) } @@ -2162,16 +2169,6 @@ impl<'tcx> RegionDefinition<'tcx> { Self { origin, universe, external_name: None } } - - #[inline(always)] - pub fn is_placeholder(&self) -> bool { - matches!(self.origin, NllRegionVariableOrigin::Placeholder(_)) - } - - #[inline(always)] - pub fn is_existential(&self) -> bool { - matches!(self.origin, NllRegionVariableOrigin::Existential { .. }) - } } #[derive(Clone, Debug)] From e6eb63d4b9c384296233ec46c37a7ffebe526ea3 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Tue, 21 May 2024 10:42:36 +0200 Subject: [PATCH 143/153] Resurrect some comments, remove a `pub` This commit addresses @lqd's code review and resurrects a lost comment and removes some dead code. --- .../rustc_borrowck/src/region_infer/mod.rs | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 91dbbfb4973..6f2fe8bddb2 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -72,7 +72,7 @@ pub struct RegionInferenceContext<'tcx> { /// The SCC computed from `constraints` and the constraint /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. - pub constraint_sccs: Rc, + constraint_sccs: Rc, /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required @@ -397,6 +397,39 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// and (b) any universally quantified regions that it outlives, /// which in this case is just itself. R1 (`'b`) in contrast also /// outlives `'a` and hence contains R0 and R1. + /// + /// This bit of logic also handles invalid universe relations + /// for higher-kinded types. + /// + // We Walk each SCC `A` and `B` such that `A: B` + // and ensure that universe(A) can see universe(B). + // + // This serves to enforce the 'empty/placeholder' hierarchy + // (described in more detail on `RegionKind`): + // + // ``` + // static -----+ + // | | + // empty(U0) placeholder(U1) + // | / + // empty(U1) + // ``` + // + // In particular, imagine we have variables R0 in U0 and R1 + // created in U1, and constraints like this; + // + // ``` + // R1: !1 // R1 outlives the placeholder in U1 + // R1: R0 // R1 outlives R0 + // ``` + // + // Here, we wish for R1 to be `'static`, because it + // cannot outlive `placeholder(U1)` and `empty(U0)` any other way. + // + // Thanks to this loop, what happens is that the `R1: R0` + // constraint has lowered the universe of `R1` to `U0`, which in turn + // means that the `R1: !1` constraint here will cause + // `R1` to become `'static`. fn init_free_and_bound_regions(&mut self) { // Update the names (if any) // This iterator has unstable order but we collect it all into an IndexVec @@ -1412,6 +1445,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + /// The minimum universe of any variable reachable from this + /// SCC, inside or outside of it. fn scc_universe(&self, scc: ConstraintSccIndex) -> UniverseIndex { self.constraint_sccs().annotation(scc).universe() } @@ -2151,6 +2186,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Returns the representative `RegionVid` for a given SCC. /// See `RegionTracker` for how a region variable ID is chosen. + /// + /// It is a hacky way to manage checking regions for equality, + /// since we can 'canonicalize' each region to the representative + /// of its SCC and be sure that -- if they have the same repr -- + /// they *must* be equal (though not having the same repr does not + /// mean they are unequal). fn scc_representative(&self, scc: ConstraintSccIndex) -> RegionVid { self.constraint_sccs.annotation(scc).representative } From 3bdcb9d4368c2404955499c0e66c991a706ca4a4 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Tue, 21 May 2024 10:57:32 +0200 Subject: [PATCH 144/153] Revise documentation after @lqd's comments --- compiler/rustc_data_structures/src/graph/scc/mod.rs | 12 ++++-------- .../src/infer/region_constraints/leak_check.rs | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 22b029c2bd4..40d1d8d11d3 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -22,12 +22,9 @@ mod tests; /// An annotation for an SCC. This can be a representative, /// the max/min element of the SCC, or all of the above. /// -/// Concretely, the following properties must hold (where `merge` -/// is `merge_scc` and `merge_reached`): -/// - idempotency: `a.merge(a) = a` -/// - commutativity: `a.merge(b) = b.merge(a)` +/// Concretely, the both merge operations must commute, e.g. where `merge` +/// is `merge_scc` and `merge_reached`: `a.merge(b) == b.merge(a)` /// -/// This is rather limiting and precludes, for example, counting. /// In general, what you want is probably always min/max according /// to some ordering, potentially with side constraints (min x such /// that P holds). @@ -62,7 +59,7 @@ impl Annotation for () { /// the index type for the graph nodes and `S` is the index type for /// the SCCs. We can map from each node to the SCC that it /// participates in, and we also have the successors of each SCC. -pub struct Sccs { +pub struct Sccs { /// For each node, what is the SCC index of the SCC to which it /// belongs. scc_indices: IndexVec, @@ -314,8 +311,7 @@ where /// D' (i.e., D' < D), we know that N, N', and all nodes in /// between them on the stack are part of an SCC. /// - /// Additionally, we keep track of a representative annotation of the - /// SCC. + /// Additionally, we keep track of a current annotation of the SCC. /// /// [wikipedia]: https://bit.ly/2EZIx84 fn construct(graph: &'c G, to_annotation: F) -> Sccs { diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 89b3dfc46f7..5b159d62731 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -360,7 +360,7 @@ struct MiniGraph<'tcx> { /// Map from node index to SCC, and stores the successors of each SCC. All /// the regions in the same SCC are equal to one another, and if `S1 -> S2`, /// then `S1: S2`. - sccs: Sccs, + sccs: Sccs, } impl<'tcx> MiniGraph<'tcx> { From 2e1e119ba1189eeff2d76ed84248845f06fef1f8 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Tue, 21 May 2024 16:57:00 +0200 Subject: [PATCH 145/153] Move `RegionTracker` to `region_infer` In terms of code organisation, this is a lot cleaner and allows tighter access modifiers. --- .../rustc_borrowck/src/constraints/mod.rs | 95 +------------------ .../rustc_borrowck/src/region_infer/mod.rs | 93 +++++++++++++++++- 2 files changed, 93 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 111a62aa6af..b54e05b2b34 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -1,106 +1,13 @@ -use crate::region_infer::RegionDefinition; use crate::type_check::Locations; -use rustc_data_structures::graph::scc::{self, Sccs}; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{RegionVid, TyCtxt, UniverseIndex, VarianceDiagInfo}; +use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo}; use rustc_span::Span; use std::fmt; use std::ops::Index; pub(crate) mod graph; -pub type ConstraintSccs = Sccs; - -/// An annotation for region graph SCCs that tracks -/// the values of its elements. -#[derive(Copy, Debug, Clone)] -pub struct RegionTracker { - /// The largest universe of a placeholder reached from this SCC. - /// This includes placeholders within this SCC. - max_placeholder_universe_reached: UniverseIndex, - - /// The smallest universe index reachable form the nodes of this SCC. - min_reachable_universe: UniverseIndex, - - /// The representative Region Variable Id for this SCC. We prefer - /// placeholders over existentially quantified variables, otherwise - /// it's the one with the smallest Region Variable ID. - pub representative: RegionVid, - - /// Is the current representative a placeholder? - representative_is_placeholder: bool, - - /// Is the current representative existentially quantified? - representative_is_existential: bool, -} - -impl scc::Annotation for RegionTracker { - fn merge_scc(mut self, mut other: Self) -> Self { - // Prefer any placeholder over any existential - if other.representative_is_placeholder && self.representative_is_existential { - other.merge_min_max_seen(&self); - return other; - } - - if self.representative_is_placeholder && other.representative_is_existential - || (self.representative <= other.representative) - { - self.merge_min_max_seen(&other); - return self; - } - other.merge_min_max_seen(&self); - other - } - - fn merge_reached(mut self, other: Self) -> Self { - // No update to in-component values, only add seen values. - self.merge_min_max_seen(&other); - self - } -} - -impl RegionTracker { - pub fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { - let (representative_is_placeholder, representative_is_existential) = match definition.origin - { - rustc_infer::infer::NllRegionVariableOrigin::FreeRegion => (false, false), - rustc_infer::infer::NllRegionVariableOrigin::Placeholder(_) => (true, false), - rustc_infer::infer::NllRegionVariableOrigin::Existential { .. } => (false, true), - }; - - let placeholder_universe = - if representative_is_placeholder { definition.universe } else { UniverseIndex::ROOT }; - - Self { - max_placeholder_universe_reached: placeholder_universe, - min_reachable_universe: definition.universe, - representative: rvid, - representative_is_placeholder, - representative_is_existential, - } - } - pub fn universe(self) -> UniverseIndex { - self.min_reachable_universe - } - - fn merge_min_max_seen(&mut self, other: &Self) { - self.max_placeholder_universe_reached = std::cmp::max( - self.max_placeholder_universe_reached, - other.max_placeholder_universe_reached, - ); - - self.min_reachable_universe = - std::cmp::min(self.min_reachable_universe, other.min_reachable_universe); - } - - /// Returns `true` if during the annotated SCC reaches a placeholder - /// with a universe larger than the smallest reachable one, `false` otherwise. - pub fn has_incompatible_universes(&self) -> bool { - self.universe().cannot_name(self.max_placeholder_universe_reached) - } -} - /// A set of NLL region constraints. These include "outlives" /// constraints of the form `R1: R2`. Each constraint is identified by /// a unique `OutlivesConstraintIndex` and you can index into the set diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 6f2fe8bddb2..971f5a2a7ec 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -4,6 +4,7 @@ use std::rc::Rc; use rustc_data_structures::binary_search_util; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::graph::scc::{self, Sccs}; use rustc_errors::Diag; use rustc_hir::def_id::CRATE_DEF_ID; use rustc_index::IndexVec; @@ -23,7 +24,6 @@ use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::Span; use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph}; -use crate::constraints::{ConstraintSccs, RegionTracker}; use crate::dataflow::BorrowIndex; use crate::{ constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet}, @@ -46,6 +46,97 @@ mod reverse_sccs; pub mod values; +pub type ConstraintSccs = Sccs; + +/// An annotation for region graph SCCs that tracks +/// the values of its elements. +#[derive(Copy, Debug, Clone)] +pub struct RegionTracker { + /// The largest universe of a placeholder reached from this SCC. + /// This includes placeholders within this SCC. + max_placeholder_universe_reached: UniverseIndex, + + /// The smallest universe index reachable form the nodes of this SCC. + min_reachable_universe: UniverseIndex, + + /// The representative Region Variable Id for this SCC. We prefer + /// placeholders over existentially quantified variables, otherwise + /// it's the one with the smallest Region Variable ID. + representative: RegionVid, + + /// Is the current representative a placeholder? + representative_is_placeholder: bool, + + /// Is the current representative existentially quantified? + representative_is_existential: bool, +} + +impl scc::Annotation for RegionTracker { + fn merge_scc(mut self, mut other: Self) -> Self { + // Prefer any placeholder over any existential + if other.representative_is_placeholder && self.representative_is_existential { + other.merge_min_max_seen(&self); + return other; + } + + if self.representative_is_placeholder && other.representative_is_existential + || (self.representative <= other.representative) + { + self.merge_min_max_seen(&other); + return self; + } + other.merge_min_max_seen(&self); + other + } + + fn merge_reached(mut self, other: Self) -> Self { + // No update to in-component values, only add seen values. + self.merge_min_max_seen(&other); + self + } +} + +impl RegionTracker { + fn new(rvid: RegionVid, definition: &RegionDefinition<'_>) -> Self { + let (representative_is_placeholder, representative_is_existential) = match definition.origin + { + rustc_infer::infer::NllRegionVariableOrigin::FreeRegion => (false, false), + rustc_infer::infer::NllRegionVariableOrigin::Placeholder(_) => (true, false), + rustc_infer::infer::NllRegionVariableOrigin::Existential { .. } => (false, true), + }; + + let placeholder_universe = + if representative_is_placeholder { definition.universe } else { UniverseIndex::ROOT }; + + Self { + max_placeholder_universe_reached: placeholder_universe, + min_reachable_universe: definition.universe, + representative: rvid, + representative_is_placeholder, + representative_is_existential, + } + } + fn universe(self) -> UniverseIndex { + self.min_reachable_universe + } + + fn merge_min_max_seen(&mut self, other: &Self) { + self.max_placeholder_universe_reached = std::cmp::max( + self.max_placeholder_universe_reached, + other.max_placeholder_universe_reached, + ); + + self.min_reachable_universe = + std::cmp::min(self.min_reachable_universe, other.min_reachable_universe); + } + + /// Returns `true` if during the annotated SCC reaches a placeholder + /// with a universe larger than the smallest reachable one, `false` otherwise. + pub fn has_incompatible_universes(&self) -> bool { + self.universe().cannot_name(self.max_placeholder_universe_reached) + } +} + pub struct RegionInferenceContext<'tcx> { pub var_infos: VarInfos, From d63708b9074ebdc69e21bee8588d28db497e9ccd Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Wed, 12 Jun 2024 15:40:01 +0200 Subject: [PATCH 146/153] Address code review comments on the comments --- .../rustc_borrowck/src/region_infer/mod.rs | 58 +++++++++---------- .../src/graph/scc/mod.rs | 5 +- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 971f5a2a7ec..40b58500598 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -492,35 +492,35 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// This bit of logic also handles invalid universe relations /// for higher-kinded types. /// - // We Walk each SCC `A` and `B` such that `A: B` - // and ensure that universe(A) can see universe(B). - // - // This serves to enforce the 'empty/placeholder' hierarchy - // (described in more detail on `RegionKind`): - // - // ``` - // static -----+ - // | | - // empty(U0) placeholder(U1) - // | / - // empty(U1) - // ``` - // - // In particular, imagine we have variables R0 in U0 and R1 - // created in U1, and constraints like this; - // - // ``` - // R1: !1 // R1 outlives the placeholder in U1 - // R1: R0 // R1 outlives R0 - // ``` - // - // Here, we wish for R1 to be `'static`, because it - // cannot outlive `placeholder(U1)` and `empty(U0)` any other way. - // - // Thanks to this loop, what happens is that the `R1: R0` - // constraint has lowered the universe of `R1` to `U0`, which in turn - // means that the `R1: !1` constraint here will cause - // `R1` to become `'static`. + /// We Walk each SCC `A` and `B` such that `A: B` + /// and ensure that universe(A) can see universe(B). + /// + /// This serves to enforce the 'empty/placeholder' hierarchy + /// (described in more detail on `RegionKind`): + /// + /// ```ignore (illustrative) + /// static -----+ + /// | | + /// empty(U0) placeholder(U1) + /// | / + /// empty(U1) + /// ``` + /// + /// In particular, imagine we have variables R0 in U0 and R1 + /// created in U1, and constraints like this; + /// + /// ```ignore (illustrative) + /// R1: !1 // R1 outlives the placeholder in U1 + /// R1: R0 // R1 outlives R0 + /// ``` + /// + /// Here, we wish for R1 to be `'static`, because it + /// cannot outlive `placeholder(U1)` and `empty(U0)` any other way. + /// + /// Thanks to this loop, what happens is that the `R1: R0` + /// constraint has lowered the universe of `R1` to `U0`, which in turn + /// means that the `R1: !1` constraint here will cause + /// `R1` to become `'static`. fn init_free_and_bound_regions(&mut self) { // Update the names (if any) // This iterator has unstable order but we collect it all into an IndexVec diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 40d1d8d11d3..8b96b36a851 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -80,7 +80,10 @@ struct SccDetails { // The name of this struct should discourage you from making it public and leaking // its representation. This message was left here by one who came before you, -// who learnt the hard way that making even small changes in representation is difficult when it's publicly inspectable. Obey the law of Demeter! +// who learnt the hard way that making even small changes in representation +// is difficult when it's publicly inspectable. +// +// Obey the law of Demeter! struct SccData { /// Maps SCC indices to their metadata, including /// offsets into `all_successors`. From 62990713cece662d36a192e2713a30cd7cfb115b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 14:25:34 +0000 Subject: [PATCH 147/153] Avoid a Ty::new_misc_error when an ErrorGuaranteed is available --- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 4 ++-- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2b32a93bbbe..94e879ae9c3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -660,8 +660,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - pub(crate) fn err_args(&self, len: usize) -> Vec> { - let ty_error = Ty::new_misc_error(self.tcx); + pub(crate) fn err_args(&self, len: usize, guar: ErrorGuaranteed) -> Vec> { + let ty_error = Ty::new_error(self.tcx, guar); vec![ty_error; len] } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8ae21594fd..e20a6ef7c13 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -123,7 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(guar) => Err(guar), }; if let Err(guar) = has_error { - let err_inputs = self.err_args(args_no_rcvr.len()); + let err_inputs = self.err_args(args_no_rcvr.len(), guar); let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, @@ -237,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => { // Otherwise, there's a mismatch, so clear out what we're expecting, and set // our input types to err_args so we don't blow up the error messages - struct_span_code_err!( + let guar = struct_span_code_err!( tcx.dcx(), call_span, E0059, @@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for the function trait is neither a tuple nor unit" ) .emit(); - (self.err_args(provided_args.len()), None) + (self.err_args(provided_args.len(), guar), None) } } } else { From af106617f17d7d4bdfe70158265f352b13511382 Mon Sep 17 00:00:00 2001 From: r0cky Date: Wed, 12 Jun 2024 23:31:27 +0800 Subject: [PATCH 148/153] Detect pub structs never constructed even though they impl pub trait with assoc constants --- compiler/rustc_passes/src/dead.rs | 4 +- ...sed-adt-impl-pub-trait-with-assoc-const.rs | 52 +++++++++++++++++++ ...adt-impl-pub-trait-with-assoc-const.stderr | 26 ++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs create mode 100644 tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 2cb3c5d8965..a72fbdb9021 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -472,7 +472,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { && let ItemKind::Impl(impl_ref) = self.tcx.hir().expect_item(local_impl_id).kind { - if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) + if !matches!(trait_item.kind, hir::TraitItemKind::Type(..)) && !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty) .ty_and_all_fields_are_public { @@ -802,7 +802,7 @@ fn check_item<'tcx>( // And we access the Map here to get HirId from LocalDefId for local_def_id in local_def_ids { // check the function may construct Self - let mut may_construct_self = true; + let mut may_construct_self = false; if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(tcx.local_def_id_to_hir_id(local_def_id)) { diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs new file mode 100644 index 00000000000..bf2fc243e81 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.rs @@ -0,0 +1,52 @@ +#![deny(dead_code)] + +struct T1; //~ ERROR struct `T1` is never constructed +pub struct T2(i32); //~ ERROR struct `T2` is never constructed +struct T3; + +trait Trait1 { //~ ERROR trait `Trait1` is never used + const UNUSED: i32; + fn unused(&self) {} + fn construct_self() -> Self; +} + +pub trait Trait2 { + const USED: i32; + fn used(&self) {} +} + +pub trait Trait3 { + const USED: i32; + fn construct_self() -> Self; +} + +impl Trait1 for T1 { + const UNUSED: i32 = 0; + fn construct_self() -> Self { + Self + } +} + +impl Trait1 for T2 { + const UNUSED: i32 = 0; + fn construct_self() -> Self { + T2(0) + } +} + +impl Trait2 for T1 { + const USED: i32 = 0; +} + +impl Trait2 for T2 { + const USED: i32 = 0; +} + +impl Trait3 for T3 { + const USED: i32 = 0; + fn construct_self() -> Self { + Self + } +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr new file mode 100644 index 00000000000..174096d9398 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-adt-impl-pub-trait-with-assoc-const.stderr @@ -0,0 +1,26 @@ +error: struct `T1` is never constructed + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:3:8 + | +LL | struct T1; + | ^^ + | +note: the lint level is defined here + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: struct `T2` is never constructed + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12 + | +LL | pub struct T2(i32); + | ^^ + +error: trait `Trait1` is never used + --> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7 + | +LL | trait Trait1 { + | ^^^^^^ + +error: aborting due to 3 previous errors + From 39c3b86eaa756cf3b8a8957abae7fd029196f90d Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 11 Jun 2024 19:34:53 +0200 Subject: [PATCH 149/153] Add a `ignore-tidy-todo` to ignore the tidy TODO comment check --- src/tools/tidy/src/style.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 64cc2277620..2d3888ec75f 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -444,7 +444,9 @@ pub fn check(path: &Path, bad: &mut bool) { suppressible_tidy_err!(err, skip_cr, "CR character"); } if filename != "style.rs" { - if trimmed.contains("TODO") { + // Allow using TODO in diagnostic suggestions by marking the + // relevant line with `// ignore-tidy-todo`. + if trimmed.contains("TODO") && !trimmed.contains("ignore-tidy-todo") { err( "TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME", ) From 4f5fb3126f24e2dbe401430c2b6961941be181f9 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 5 Jun 2024 11:06:41 +0200 Subject: [PATCH 150/153] Add TODO comment to unsafe env modification Addresses https://github.com/rust-lang/rust/pull/124636#issuecomment-2132119534. I think that the diff display regresses a little, because it's no longer showing the `+` to show where the `unsafe {}` is added. I think it's still fine. --- compiler/rustc_mir_build/src/check_unsafety.rs | 3 +++ compiler/rustc_mir_build/src/errors.rs | 5 +++++ tests/ui/rust-2024/unsafe-env-suggestion.fixed | 2 ++ tests/ui/rust-2024/unsafe-env-suggestion.stderr | 10 ++++++---- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index d781fb1c297..a65586ccdb7 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -97,6 +97,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { if !span.at_least_rust_2024() && self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) => { + let sm = self.tcx.sess.source_map(); self.tcx.emit_node_span_lint( DEPRECATED_SAFE, self.hir_context, @@ -105,6 +106,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { span, function: with_no_trimmed_paths!(self.tcx.def_path_str(id)), sub: CallToDeprecatedSafeFnRequiresUnsafeSub { + indent: sm.indentation_before(span).unwrap_or_default(), + start_of_line: sm.span_extend_to_line(span).shrink_to_lo(), left: span.shrink_to_lo(), right: span.shrink_to_hi(), }, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index cf324c03dc9..3bd2e47976b 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -33,6 +33,11 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { #[derive(Subdiagnostic)] #[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")] pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { + pub(crate) indent: String, + #[suggestion_part( + code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo + )] + pub(crate) start_of_line: Span, #[suggestion_part(code = "unsafe {{ ")] pub(crate) left: Span, #[suggestion_part(code = " }}")] diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.fixed b/tests/ui/rust-2024/unsafe-env-suggestion.fixed index d9c738edfac..1f3d2dc0a31 100644 --- a/tests/ui/rust-2024/unsafe-env-suggestion.fixed +++ b/tests/ui/rust-2024/unsafe-env-suggestion.fixed @@ -6,9 +6,11 @@ use std::env; #[deny(unused_unsafe)] fn main() { + // TODO: Audit that the environment access only happens in single-threaded code. unsafe { env::set_var("FOO", "BAR") }; //~^ ERROR call to deprecated safe function //~| WARN this is accepted in the current edition + // TODO: Audit that the environment access only happens in single-threaded code. unsafe { env::remove_var("FOO") }; //~^ ERROR call to deprecated safe function //~| WARN this is accepted in the current edition diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.stderr b/tests/ui/rust-2024/unsafe-env-suggestion.stderr index 90c91c2a474..7c12f4aa5ed 100644 --- a/tests/ui/rust-2024/unsafe-env-suggestion.stderr +++ b/tests/ui/rust-2024/unsafe-env-suggestion.stderr @@ -13,8 +13,9 @@ LL | #![deny(deprecated_safe)] | ^^^^^^^^^^^^^^^ help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code | -LL | unsafe { env::set_var("FOO", "BAR") }; - | ++++++++ + +LL + // TODO: Audit that the environment access only happens in single-threaded code. +LL ~ unsafe { env::set_var("FOO", "BAR") }; + | error: call to deprecated safe function `std::env::remove_var` is unsafe and requires unsafe block --> $DIR/unsafe-env-suggestion.rs:12:5 @@ -26,8 +27,9 @@ LL | env::remove_var("FOO"); = note: for more information, see issue #27970 help: you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code | -LL | unsafe { env::remove_var("FOO") }; - | ++++++++ + +LL + // TODO: Audit that the environment access only happens in single-threaded code. +LL ~ unsafe { env::remove_var("FOO") }; + | error: aborting due to 2 previous errors From 54429cf27928f8aa9039dc019a73a372dcc6306d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 12 Jun 2024 16:19:25 +0000 Subject: [PATCH 151/153] Fix outdated predacates_of.rs comments --- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 40204961e9c..3421c8da4e9 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -169,12 +169,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen predicates.insert((trait_ref.upcast(tcx), tcx.def_span(def_id))); } - // Collect the predicates that were written inline by the user on each - // type parameter (e.g., ``). Also add `ConstArgHasType` predicates - // for each const parameter. + // Add implicit predicates that should be treated as if the user has written them, + // including the implicit `T: Sized` for all generic parameters, and `ConstArgHasType` + // for const params. for param in hir_generics.params { match param.kind { - // We already dealt with early bound lifetimes above. GenericParamKind::Lifetime { .. } => (), GenericParamKind::Type { .. } => { let param_ty = icx.lowerer().lower_ty_param(param.hir_id); @@ -204,7 +203,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen } trace!(?predicates); - // Add in the bounds that appear in the where-clause. + // Add inline `` bounds and bounds in the where clause. for predicate in hir_generics.predicates { match predicate { hir::WherePredicate::BoundPredicate(bound_pred) => { From 2c41b1c6841a2098afc28d2365a50039de5276f2 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 13 Jun 2024 05:04:31 +0000 Subject: [PATCH 152/153] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 7f8fd86b561..e49680ba75a 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -fa1681c9f6a66f0240c46c98bfef6209c9d6df23 +f6b4b71ef10307201b52c17b0f9dcf9557cd90ba From a49c65976cf3d8c705b328ef61d205a4501d3685 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 13 Jun 2024 05:13:16 +0000 Subject: [PATCH 153/153] fmt --- .../miri/tests/fail/validity/invalid_enum_cast.rs | 14 ++++++++++---- .../tests/fail/validity/invalid_enum_cast.stderr | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs index faf5fb699a6..ed451a435b9 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.rs @@ -3,11 +3,17 @@ #[derive(Copy, Clone)] #[allow(unused)] -enum E {A, B, C } +enum E { + A, + B, + C, +} -fn cast(ptr: *const E) { unsafe { - let _val = *ptr as u32; //~ERROR: enum value has invalid tag -}} +fn cast(ptr: *const E) { + unsafe { + let _val = *ptr as u32; //~ERROR: enum value has invalid tag + } +} pub fn main() { let v = u32::MAX; diff --git a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr index d8988876045..30afb5e8087 100644 --- a/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr +++ b/src/tools/miri/tests/fail/validity/invalid_enum_cast.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: enum value has invalid tag: 0xff --> $DIR/invalid_enum_cast.rs:LL:CC | -LL | let _val = *ptr as u32; - | ^^^^^^^^^^^ enum value has invalid tag: 0xff +LL | let _val = *ptr as u32; + | ^^^^^^^^^^^ enum value has invalid tag: 0xff | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information