From b8615aa3f5cde84aa7277e549c2a30fa5e4ac5d5 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 24 Sep 2024 11:32:33 +0200 Subject: [PATCH 001/118] Move existing rfc3627 tests to a dedicated folder --- .../auxiliary/migration_lint_macros.rs} | 0 .../migration_lint.fixed} | 6 ++-- .../migration_lint.rs} | 6 ++-- .../migration_lint.stderr} | 30 +++++++++---------- 4 files changed, 21 insertions(+), 21 deletions(-) rename tests/ui/pattern/{auxiliary/match_ergonomics_2024_macros.rs => rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs} (100%) rename tests/ui/pattern/{match_ergonomics_2024.fixed => rfc-3627-match-ergonomics-2024/migration_lint.fixed} (91%) rename tests/ui/pattern/{match_ergonomics_2024.rs => rfc-3627-match-ergonomics-2024/migration_lint.rs} (91%) rename tests/ui/pattern/{match_ergonomics_2024.stderr => rfc-3627-match-ergonomics-2024/migration_lint.stderr} (80%) diff --git a/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs similarity index 100% rename from tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/auxiliary/migration_lint_macros.rs diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed similarity index 91% rename from tests/ui/pattern/match_ergonomics_2024.fixed rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 1ec2b5a214bf..253c9589a552 100644 --- a/tests/ui/pattern/match_ergonomics_2024.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -1,12 +1,12 @@ //@ edition: 2021 //@ run-rustfix //@ rustfix-only-machine-applicable -//@ aux-build:match_ergonomics_2024_macros.rs +//@ aux-build:migration_lint_macros.rs #![feature(mut_ref, ref_pat_eat_one_layer_2024)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] -extern crate match_ergonomics_2024_macros; +extern crate migration_lint_macros; struct Foo(u8); @@ -47,7 +47,7 @@ fn main() { match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. - (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { //~^ WARN: the semantics of this pattern will change in edition 2024 _x = 4; _y = &7; diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs similarity index 91% rename from tests/ui/pattern/match_ergonomics_2024.rs rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index c9f992c12d4a..1406db779cc7 100644 --- a/tests/ui/pattern/match_ergonomics_2024.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -1,12 +1,12 @@ //@ edition: 2021 //@ run-rustfix //@ rustfix-only-machine-applicable -//@ aux-build:match_ergonomics_2024_macros.rs +//@ aux-build:migration_lint_macros.rs #![feature(mut_ref, ref_pat_eat_one_layer_2024)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] -extern crate match_ergonomics_2024_macros; +extern crate migration_lint_macros; struct Foo(u8); @@ -47,7 +47,7 @@ fn main() { match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. - (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { //~^ WARN: the semantics of this pattern will change in edition 2024 _x = 4; _y = &7; diff --git a/tests/ui/pattern/match_ergonomics_2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr similarity index 80% rename from tests/ui/pattern/match_ergonomics_2024.stderr rename to tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 11844434ad21..4d7230120247 100644 --- a/tests/ui/pattern/match_ergonomics_2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,5 +1,5 @@ error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:14:9 + --> $DIR/migration_lint.rs:14:9 | LL | let Foo(mut a) = &Foo(0); | -^^^^^^^^^ @@ -7,13 +7,13 @@ LL | let Foo(mut a) = &Foo(0); | help: desugar the match ergonomics: `&` | note: the lint level is defined here - --> $DIR/match_ergonomics_2024.rs:7:9 + --> $DIR/migration_lint.rs:7:9 | LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:18:9 + --> $DIR/migration_lint.rs:18:9 | LL | let Foo(mut a) = &mut Foo(0); | -^^^^^^^^^ @@ -21,7 +21,7 @@ LL | let Foo(mut a) = &mut Foo(0); | help: desugar the match ergonomics: `&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:22:12 + --> $DIR/migration_lint.rs:22:12 | LL | if let Some(&_) = &&&&&Some(&0u8) {} | -^^^^^^^ @@ -29,7 +29,7 @@ LL | if let Some(&_) = &&&&&Some(&0u8) {} | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:25:12 + --> $DIR/migration_lint.rs:25:12 | LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {} | -^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {} | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:28:12 + --> $DIR/migration_lint.rs:28:12 | LL | if let Some(&_) = &&&&&mut Some(&0u8) {} | -^^^^^^^ @@ -45,7 +45,7 @@ LL | if let Some(&_) = &&&&&mut Some(&0u8) {} | help: desugar the match ergonomics: `&&&&&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:31:12 + --> $DIR/migration_lint.rs:31:12 | LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut So | ++++ ++++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:34:12 + --> $DIR/migration_lint.rs:34:12 | LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Som | ++++ ++++ +++++++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:43:9 + --> $DIR/migration_lint.rs:43:9 | LL | let Struct { a, mut b, c } = &s; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -78,20 +78,20 @@ LL | let &Struct { ref a, mut b, ref c } = &s; | + +++ +++ warning: the semantics of this pattern will change in edition 2024 - --> $DIR/match_ergonomics_2024.rs:50:9 + --> $DIR/migration_lint.rs:50:9 | -LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/match_ergonomics_2024.rs:46:12 + --> $DIR/migration_lint.rs:46:12 | LL | #[warn(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: desugar the match ergonomics | -LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => { - | + +++ +LL | &(Some(mut _x), migration_lint_macros::mixed_edition_pat!(ref _y)) => { + | + +++ error: aborting due to 8 previous errors; 1 warning emitted From c22588b700a62a1d93ff7bc30fd49583efab4ad2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Fri, 20 Sep 2024 19:47:30 +0200 Subject: [PATCH 002/118] Add `min_match_ergonomics_2024` feature gate --- compiler/rustc_feature/src/unstable.rs | 3 +++ compiler/rustc_span/src/symbol.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fa3a7049f4a0..5fff81d3e1cd 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -516,6 +516,9 @@ declare_features! ( (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), + /// A very restricted form of match ergonomics used over the 2024 edition transition to give + /// more time for T-lang to decide the final form of RFC3627. + (incomplete, min_match_ergonomics_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization /// are fixed. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 402232a1720b..81ae66ccf680 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1218,6 +1218,7 @@ symbols! { min_const_generics, min_const_unsafe_fn, min_exhaustive_patterns, + min_match_ergonomics_2024, min_specialization, min_type_alias_impl_trait, minnumf128, From 94ab726c7856cd7716d2a33db3e1915faed99008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Wed, 25 Sep 2024 11:35:01 +0200 Subject: [PATCH 003/118] Add 'from_ref' and 'from_mut' constructors to 'core::ptr::NonNull'; --- library/core/src/lib.rs | 1 + library/core/src/ptr/non_null.rs | 28 ++++++++++--- ...ated_loop.PreCodegen.after.panic-abort.mir | 40 ++++++++++--------- ...ted_loop.PreCodegen.after.panic-unwind.mir | 20 +++++----- ...ward_loop.PreCodegen.after.panic-abort.mir | 16 ++++---- ...ard_loop.PreCodegen.after.panic-unwind.mir | 16 ++++---- ...erse_loop.PreCodegen.after.panic-abort.mir | 22 +++++----- ...rse_loop.PreCodegen.after.panic-unwind.mir | 22 +++++----- 8 files changed, 97 insertions(+), 68 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 01cadd78cc09..53d11ebb5d62 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -174,6 +174,7 @@ #![feature(isqrt)] #![feature(lazy_get)] #![feature(link_cfg)] +#![feature(non_null_from_ref)] #![feature(offset_of_enum)] #![feature(panic_internals)] #![feature(ptr_alignment_type)] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index daa40b3c9d2e..44936d69bc96 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -230,6 +230,24 @@ impl NonNull { } } + /// Converts a reference to a `NonNull` pointer. + #[unstable(feature = "non_null_from_ref", issue = "130823")] + #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")] + #[inline] + pub const fn from_ref(r: &T) -> Self { + // SAFETY: A reference cannot be null. + unsafe { NonNull { pointer: r as *const T } } + } + + /// Converts a mutable reference to a `NonNull` pointer. + #[unstable(feature = "non_null_from_ref", issue = "130823")] + #[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")] + #[inline] + pub const fn from_mut(r: &mut T) -> Self { + // SAFETY: A mutable reference cannot be null. + unsafe { NonNull { pointer: r as *mut T } } + } + /// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a /// `NonNull` pointer is returned, as opposed to a raw `*const` pointer. /// @@ -1753,9 +1771,8 @@ impl From<&mut T> for NonNull { /// /// This conversion is safe and infallible since references cannot be null. #[inline] - fn from(reference: &mut T) -> Self { - // SAFETY: A mutable reference cannot be null. - unsafe { NonNull { pointer: reference as *mut T } } + fn from(r: &mut T) -> Self { + NonNull::from_mut(r) } } @@ -1765,8 +1782,7 @@ impl From<&T> for NonNull { /// /// This conversion is safe and infallible since references cannot be null. #[inline] - fn from(reference: &T) -> Self { - // SAFETY: A reference cannot be null. - unsafe { NonNull { pointer: reference as *const T } } + fn from(r: &T) -> Self { + NonNull::from_ref(r) } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index 3aa483ed1aef..bd56ab67e002 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug i => _22; debug x => _23; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; let mut _15: std::option::Option<&T>; let mut _19: (usize, bool); let mut _20: (usize, &T); - scope 18 { + scope 19 { let _18: usize; - scope 23 { + scope 24 { } } - scope 19 { - scope 20 { - scope 26 (inlined as FromResidual>>::from_residual) { + scope 20 { + scope 21 { + scope 27 (inlined as FromResidual>>::from_residual) { } } } - scope 21 { - scope 22 { + scope 22 { + scope 23 { } } - scope 24 (inlined as Try>::branch) { + scope 25 (inlined as Try>::branch) { let mut _16: isize; let _17: &T; - scope 25 { + scope 26 { } } } @@ -59,29 +59,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::enumerate) { - scope 15 (inlined Enumerate::>::new) { + scope 15 (inlined as Iterator>::enumerate) { + scope 16 (inlined Enumerate::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 4cc0aa0ed788..57f09a4631b5 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -34,29 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::enumerate) { - scope 15 (inlined Enumerate::>::new) { + scope 15 (inlined as Iterator>::enumerate) { + scope 16 (inlined Enumerate::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 507afa63c688..4050304f4698 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as IntoIterator>::into_iter) { + scope 15 (inlined as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index a25f12edc28e..2c3d7ab1e4a8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as IntoIterator>::into_iter) { + scope 15 (inlined as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index 1b397a4e4cdd..a6ccd435c40e 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _17; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; } } @@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::rev) { - scope 15 (inlined Rev::>::new) { + scope 15 (inlined as Iterator>::rev) { + scope 16 (inlined Rev::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index 77689dd9b513..df11c8e3b496 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _17; } - scope 17 (inlined > as Iterator>::next) { + scope 18 (inlined > as Iterator>::next) { let mut _14: &mut std::slice::Iter<'_, T>; } } @@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _9: *const T; scope 7 { } - scope 11 (inlined without_provenance::) { + scope 12 (inlined without_provenance::) { } - scope 12 (inlined NonNull::::as_ptr) { + scope 13 (inlined NonNull::::as_ptr) { } - scope 13 (inlined std::ptr::mut_ptr::::add) { + scope 14 (inlined std::ptr::mut_ptr::::add) { } } scope 8 (inlined as From<&[T]>>::from) { - let mut _4: *const [T]; + scope 9 (inlined NonNull::<[T]>::from_ref) { + let mut _4: *const [T]; + } } - scope 9 (inlined NonNull::<[T]>::cast::) { + scope 10 (inlined NonNull::<[T]>::cast::) { let mut _5: *const T; - scope 10 (inlined NonNull::<[T]>::as_ptr) { + scope 11 (inlined NonNull::<[T]>::as_ptr) { } } } } } - scope 14 (inlined as Iterator>::rev) { - scope 15 (inlined Rev::>::new) { + scope 15 (inlined as Iterator>::rev) { + scope 16 (inlined Rev::>::new) { } } - scope 16 (inlined > as IntoIterator>::into_iter) { + scope 17 (inlined > as IntoIterator>::into_iter) { } bb0: { From e9047612313496f0cad1b0feb200072e0fd78027 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 1 Oct 2024 16:23:04 +0200 Subject: [PATCH 004/118] Use environment variables instead of command line arguments for merged doctests --- src/librustdoc/doctest.rs | 3 +-- src/librustdoc/doctest/runner.rs | 42 ++++++++++++-------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 3ee6b24ac92c..e8bd36dffc77 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -644,8 +644,7 @@ fn run_test( } else { cmd = Command::new(&output_file); if doctest.is_multiple_tests { - cmd.arg("*doctest-bin-path"); - cmd.arg(&output_file); + cmd.env("RUSTDOC_DOCTEST_BIN_PATH", &output_file); } } if let Some(run_directory) = &rustdoc_options.test_run_directory { diff --git a/src/librustdoc/doctest/runner.rs b/src/librustdoc/doctest/runner.rs index 326ca4ee1e68..176008ae7a2c 100644 --- a/src/librustdoc/doctest/runner.rs +++ b/src/librustdoc/doctest/runner.rs @@ -112,8 +112,7 @@ mod __doctest_mod {{ use std::path::PathBuf; pub static BINARY_PATH: OnceLock = OnceLock::new(); - pub const RUN_OPTION: &str = \"*doctest-inner-test\"; - pub const BIN_OPTION: &str = \"*doctest-bin-path\"; + pub const RUN_OPTION: &str = \"RUSTDOC_DOCTEST_RUN_NB_TEST\"; #[allow(unused)] pub fn doctest_path() -> Option<&'static PathBuf> {{ @@ -123,8 +122,8 @@ mod __doctest_mod {{ #[allow(unused)] pub fn doctest_runner(bin: &std::path::Path, test_nb: usize) -> Result<(), String> {{ let out = std::process::Command::new(bin) - .arg(self::RUN_OPTION) - .arg(test_nb.to_string()) + .env(self::RUN_OPTION, test_nb.to_string()) + .args(std::env::args().skip(1).collect::>()) .output() .expect(\"failed to run command\"); if !out.status.success() {{ @@ -138,36 +137,27 @@ mod __doctest_mod {{ #[rustc_main] fn main() -> std::process::ExitCode {{ const TESTS: [test::TestDescAndFn; {nb_tests}] = [{ids}]; -let bin_marker = std::ffi::OsStr::new(__doctest_mod::BIN_OPTION); let test_marker = std::ffi::OsStr::new(__doctest_mod::RUN_OPTION); let test_args = &[{test_args}]; +const ENV_BIN: &'static str = \"RUSTDOC_DOCTEST_BIN_PATH\"; -let mut args = std::env::args_os().skip(1); -while let Some(arg) = args.next() {{ - if arg == bin_marker {{ - let Some(binary) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::BIN_OPTION); - }}; - if crate::__doctest_mod::BINARY_PATH.set(binary.into()).is_err() {{ - panic!(\"`{{}}` option was used more than once\", bin_marker.to_string_lossy()); - }} - return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); - }} else if arg == test_marker {{ - let Some(nb_test) = args.next() else {{ - panic!(\"missing argument after `{{}}`\", __doctest_mod::RUN_OPTION); - }}; - if let Some(nb_test) = nb_test.to_str().and_then(|nb| nb.parse::().ok()) {{ - if let Some(test) = TESTS.get(nb_test) {{ - if let test::StaticTestFn(f) = test.testfn {{ - return std::process::Termination::report(f()); - }} +if let Ok(binary) = std::env::var(ENV_BIN) {{ + let _ = crate::__doctest_mod::BINARY_PATH.set(binary.into()); + unsafe {{ std::env::remove_var(ENV_BIN); }} + return std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)); +}} else if let Ok(nb_test) = std::env::var(__doctest_mod::RUN_OPTION) {{ + if let Ok(nb_test) = nb_test.parse::() {{ + if let Some(test) = TESTS.get(nb_test) {{ + if let test::StaticTestFn(f) = test.testfn {{ + return std::process::Termination::report(f()); }} }} - panic!(\"Unexpected value after `{{}}`\", __doctest_mod::RUN_OPTION); }} + panic!(\"Unexpected value for `{{}}`\", __doctest_mod::RUN_OPTION); }} -eprintln!(\"WARNING: No argument provided so doctests will be run in the same process\"); +eprintln!(\"WARNING: No rustdoc doctest environment variable provided so doctests will be run in \ +the same process\"); std::process::Termination::report(test::test_main(test_args, Vec::from(TESTS), None)) }}", nb_tests = self.nb_tests, From 302551388b1942bb4216bb5a15d9d55cee3643a8 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Fri, 20 Sep 2024 12:27:51 +0300 Subject: [PATCH 005/118] Implemented FromStr for CString and TryFrom for String --- library/alloc/src/ffi/c_str.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index e32676a65432..15b0506023d0 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -7,7 +7,7 @@ use core::borrow::Borrow; use core::ffi::{c_char, CStr}; use core::num::NonZero; use core::slice::memchr; -use core::str::{self, Utf8Error}; +use core::str::{self, FromStr, Utf8Error}; use core::{fmt, mem, ops, ptr, slice}; use crate::borrow::{Cow, ToOwned}; @@ -815,6 +815,30 @@ impl From>> for CString { } } +impl FromStr for CString { + type Err = NulError; + + /// Converts a string `s` into a [`CString`]. + /// + /// This method is equivalent to [`CString::new`]. + #[inline] + fn from_str(s: &str) -> Result { + Self::new(s) + } +} + +impl TryFrom for String { + type Error = IntoStringError; + + /// Converts a [`CString`] into a [`String`] if it contains valid UTF-8 data. + /// + /// This method is equivalent to [`CString::into_string`]. + #[inline] + fn try_from(value: CString) -> Result { + value.into_string() + } +} + #[cfg(not(test))] #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box { From 5fef4621c3fd3a2b460dbacd35fbef52537d8889 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 1 Oct 2024 21:04:22 -0700 Subject: [PATCH 006/118] Add 1.82 release notes --- RELEASES.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index b49470c30756..b9d58d6b757b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,100 @@ +Version 1.82.0 (2024-10-17) +========================== + + + +Language +-------- +- [Don't make statement nonterminals match pattern nonterminals](https://github.com/rust-lang/rust/pull/120221/) +- [Implement lint against ambiguous negative literals](https://github.com/rust-lang/rust/pull/121364/) +- [Patterns matching empty types can now be omitted in common cases](https://github.com/rust-lang/rust/pull/122792) +- [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/) +- [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/) +- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672) +- [Stabilize explicit opt-in to unsafe attributes](https://github.com/rust-lang/rust/pull/128771) + + + + +Compiler +-------- +- [Promote riscv64gc-unknown-linux-musl to tier 2](https://github.com/rust-lang/rust/pull/122049) +- [Improved diagnostics to explain why a pattern is unreachable](https://github.com/rust-lang/rust/pull/128034) +- [The compiler now triggers the unreachable code warning properly for async functions that don't return/are `-> !`](https://github.com/rust-lang/rust/pull/128443) +- [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/) + + + + +Libraries +--------- +- [Implement DoubleEnded and ExactSize for Take and Take](https://github.com/rust-lang/rust/pull/106943/) +- [Stabilize Wasm relaxed SIMD](https://github.com/rust-lang/rust/pull/117468/) +- [Stabilize const `{integer}::from_str_radix` i.e. `const_int_from_str`](https://github.com/rust-lang/rust/pull/124941/) +- [CommandExt::before_exec: deprecate safety in edition 2024](https://github.com/rust-lang/rust/pull/125970/) +- [CloneToUninit impls](https://github.com/rust-lang/rust/pull/126877/) +- [impl `Default` for collection iterators that don't already have it](https://github.com/rust-lang/rust/pull/128261/) + + + + +Stabilized APIs +--------------- + + + +Cargo +----- +- [feat: Add `info` cargo subcommand](https://github.com/rust-lang/cargo/pull/14141/) + + + +Compatibility Notes +------------------- +- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) + - We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead. +- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679) +- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921) +- The standard library has a new implementation of `binary_search` which is significantly improves performance (#128254). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. +- [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets. +- [Stabilize offset_of_nested](https://github.com/rust-lang/rust/pull/128284) +- [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400) +- The WebAssembly target features `multivalue` and `reference-types` are now + both enabled by default. These two features both have subtle changes implied + for generated WebAssembly binaries. For the `multivalue` feature, WebAssembly + target support has changed when upgrading to LLVM 19. Support for generating + functions with multiple returns no longer works and + `-Ctarget-feature=+multivalue` has a different meaning than it did in LLVM 18 + and prior. There is no longer any supported means to generate a module that has + a function with multiple returns in WebAssembly from Rust source code. For the + `reference-types` feature the encoding of immediates in the `call_indirect`, a + commonly used instruction by the WebAssembly backend, has changed. Validators + and parsers which don't understand the `reference-types` proposal will no + longer accept modules produced by LLVM due to this change in encoding of + immediates. Additionally these features being enabled are encoded in the + `target_features` custom section and may affect downstream tooling such as + `wasm-opt` consuming the module. Generating a WebAssembly module that disables + default features requires `-Zbuild-std` support from Cargo and more information + can be found at + [rust-lang/rust#128511](https://github.com/rust-lang/rust/pull/128511). +- [Stabilize `const` arguments to inline asm](https://github.com/rust-lang/rust/pull/128570) +- [Promote aarch64-apple-darwin to Tier 1](https://github.com/rust-lang/rust/pull/128592) +- [stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596) +- [float types: document NaN bit pattern guarantees](https://github.com/rust-lang/rust/pull/129559) +- [Rust now raises unsafety errors for union patterns in parameter-position](https://github.com/rust-lang/rust/pull/130531) + + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Update to LLVM 19](https://github.com/rust-lang/rust/pull/127513) + Version 1.81.0 (2024-09-05) ========================== From a0e687f0348af5d269c8ba0ac9bbb52308850c6a Mon Sep 17 00:00:00 2001 From: ismailarilik Date: Sun, 6 Oct 2024 15:57:23 +0300 Subject: [PATCH 007/118] Remove unnecessary sorts in `rustc_hir_analysis`. This is an attempt to gain the performance loss after the PR #131140. Here the related objects are `IndexSet` so do not require a sort to stay stable. --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 5 +---- .../src/coherence/inherent_impls_overlap.rs | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3a9d2640eee9..3079fd71b0c2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -531,7 +531,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { debug!(?required_bounds); let param_env = tcx.param_env(gat_def_id); - let mut unsatisfied_bounds: Vec<_> = required_bounds + let unsatisfied_bounds: Vec<_> = required_bounds .into_iter() .filter(|clause| match clause.kind().skip_binder() { ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => { @@ -552,9 +552,6 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) { .map(|clause| clause.to_string()) .collect(); - // We sort so that order is predictable - unsatisfied_bounds.sort(); - if !unsatisfied_bounds.is_empty() { let plural = pluralize!(unsatisfied_bounds.len()); let suggestion = format!( diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index d1c888a185ed..5127e73d9784 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -319,9 +319,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { // List of connected regions is built. Now, run the overlap check // for each pair of impl blocks in the same connected region. for region in connected_regions.into_iter().flatten() { - let mut impl_blocks = - region.impl_blocks.into_iter().collect::>(); - impl_blocks.sort_unstable(); + let impl_blocks = region.impl_blocks.into_iter().collect::>(); for (i, &impl1_items_idx) in impl_blocks.iter().enumerate() { let &(&impl1_def_id, impl_items1) = &impls_items[impl1_items_idx]; res = res.and(self.check_for_duplicate_items_in_impl(impl1_def_id)); From 2bd0d070ed7733a827ef46d3e4a2430a7a5aaed3 Mon Sep 17 00:00:00 2001 From: Andreas Molzer Date: Sun, 6 Oct 2024 21:32:04 +0200 Subject: [PATCH 008/118] Expand set_ptr_value / with_metadata_of docs Rewrite these blobs to explicitly mention the case of a sized operand. The previous made that seem wrong instead of emphasizing it is nothing but a simple cast. Instead, the explanation now emphasizes that the address portion of the argument, together with its provenance, is discarded which previously had to be inferred by the reader. Then an example demonstrates a simple line of incorrect usage based on this idea of provenance. --- library/core/src/ptr/const_ptr.rs | 41 +++++++++++++++++++++++-------- library/core/src/ptr/mut_ptr.rs | 40 ++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 332c5e904d7e..7b91b1bcb3b8 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -63,21 +63,22 @@ impl *const T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thing depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -91,6 +92,26 @@ impl *const T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let x = 0u32; + /// let y = 1u32; + /// + /// let x = (&x) as *const u32; + /// let y = (&y) as *const u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); + /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 287073497f82..e1a181158afc 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -45,21 +45,22 @@ impl *mut T { self as _ } - /// Uses the pointer value in a new pointer of another type. + /// Uses the address value in a new pointer of another type. /// - /// In case `meta` is a (fat) pointer to an unsized type, this operation - /// will ignore the pointer part, whereas for (thin) pointers to sized - /// types, this has the same effect as a simple cast. + /// This operation will ignore the address part of its `meta` operand and discard existing + /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect + /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address + /// with new metadata such as slice lengths or `dyn`-vtable. /// - /// The resulting pointer will have provenance of `self`, i.e., for a fat - /// pointer, this operation is semantically the same as creating a new - /// fat pointer with the data pointer value of `self` but the metadata of - /// `meta`. + /// The resulting pointer will have provenance of `self`. This operation is semantically the + /// same as creating a new pointer with the data pointer value of `self` but the metadata of + /// `meta`, being fat or thing depending on the `meta` operand. /// /// # Examples /// - /// This function is primarily useful for allowing byte-wise pointer - /// arithmetic on potentially fat pointers: + /// This function is primarily useful for enabling pointer arithmetic on potentially fat + /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then + /// recombined with its own original metadata. /// /// ``` /// #![feature(set_ptr_value)] @@ -73,6 +74,25 @@ impl *mut T { /// println!("{:?}", &*ptr); // will print "3" /// } /// ``` + /// + /// # *Incorrect* usage + /// + /// The provenance from pointers is *not* combined. The result must only be used to refer to the + /// address allowed by `self`. + /// + /// ```rust,no_run + /// #![feature(set_ptr_value)] + /// let mut x = 0u32; + /// let mut y = 1u32; + /// + /// let x = (&mut x) as *mut u32; + /// let y = (&mut y) as *mut u32; + /// + /// let offset = (x as usize - y as usize) / 4; + /// let bad = x.wrapping_add(offset).with_metadata_of(y); + /// + /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. + /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] #[must_use = "returns a new pointer rather than modifying its argument"] From ae698f819935aae8623f41aa3837cc0a07903c1a Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 Sep 2024 12:09:18 -0700 Subject: [PATCH 009/118] Add sugar for &pin (const|mut) types --- compiler/rustc_ast/src/ast.rs | 11 +++- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/util/classify.rs | 4 +- compiler/rustc_ast/src/visit.rs | 3 +- compiler/rustc_ast_ir/src/lib.rs | 7 +++ compiler/rustc_ast_lowering/src/expr.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 51 ++++++++++++++++--- .../src/lifetime_collector.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_pretty/src/pprust/state.rs | 6 +++ compiler/rustc_hir/src/hir.rs | 5 +- compiler/rustc_parse/src/parser/ty.rs | 39 ++++++++++++-- compiler/rustc_passes/src/hir_stats.rs | 50 +++++++++--------- compiler/rustc_resolve/src/late.rs | 4 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 3 ++ src/tools/rustfmt/src/types.rs | 5 +- tests/ui/async-await/pin-sugar-ambiguity.rs | 15 ++++++ tests/ui/async-await/pin-sugar-no-const.rs | 8 +++ .../ui/async-await/pin-sugar-no-const.stderr | 15 ++++++ tests/ui/async-await/pin-sugar.rs | 51 +++++++++++++++++++ .../feature-gate-pin_ergonomics.rs | 11 ++-- .../feature-gate-pin_ergonomics.stderr | 47 ++++++++++++++--- 23 files changed, 284 insertions(+), 63 deletions(-) create mode 100644 tests/ui/async-await/pin-sugar-ambiguity.rs create mode 100644 tests/ui/async-await/pin-sugar-no-const.rs create mode 100644 tests/ui/async-await/pin-sugar-no-const.stderr create mode 100644 tests/ui/async-await/pin-sugar.rs diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f2b52eea12f2..88db97b66e49 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -23,7 +23,7 @@ use std::{cmp, fmt, mem}; pub use GenericArgs::*; pub use UnsafeSource::*; -pub use rustc_ast_ir::{Movability, Mutability}; +pub use rustc_ast_ir::{Movability, Mutability, Pinnedness}; use rustc_data_structures::packed::Pu128; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -2161,6 +2161,10 @@ pub enum TyKind { Ptr(MutTy), /// A reference (`&'a T` or `&'a mut T`). Ref(Option, MutTy), + /// A pinned reference (`&'a pin const T` or `&'a pin mut T`). + /// + /// Desugars into `Pin<&'a T>` or `Pin<&'a mut T>`. + PinnedRef(Option, MutTy), /// A bare function (e.g., `fn(usize) -> bool`). BareFn(P), /// The never type (`!`). @@ -2509,7 +2513,10 @@ impl Param { if ident.name == kw::SelfLower { return match self.ty.kind { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => { + TyKind::Ref(lt, MutTy { ref ty, mutbl }) + | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl }) + if ty.kind.is_implicit_self() => + { Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) } _ => Some(respan( diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 6ce23a1479d0..1c57dd948fc8 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -485,7 +485,7 @@ pub fn walk_ty(vis: &mut T, ty: &mut P) { } TyKind::Slice(ty) => vis.visit_ty(ty), TyKind::Ptr(mt) => vis.visit_mt(mt), - TyKind::Ref(lt, mt) => { + TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => { visit_opt(lt, |lt| vis.visit_lifetime(lt)); vis.visit_mt(mt); } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 1a80a9ccdbf5..8fdaf9958508 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -247,7 +247,9 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { break (mac.args.delim == Delimiter::Brace).then_some(mac); } - ast::TyKind::Ptr(mut_ty) | ast::TyKind::Ref(_, mut_ty) => { + ast::TyKind::Ptr(mut_ty) + | ast::TyKind::Ref(_, mut_ty) + | ast::TyKind::PinnedRef(_, mut_ty) => { ty = &mut_ty.ty; } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9f9c3d8c3923..1ab88e8c02ef 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -499,7 +499,8 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { match kind { TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)), TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)), - TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) => { + TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) + | TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => { visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref); try_visit!(visitor.visit_ty(ty)); } diff --git a/compiler/rustc_ast_ir/src/lib.rs b/compiler/rustc_ast_ir/src/lib.rs index eeed5d361513..ff9d940ce9f2 100644 --- a/compiler/rustc_ast_ir/src/lib.rs +++ b/compiler/rustc_ast_ir/src/lib.rs @@ -79,3 +79,10 @@ impl Mutability { matches!(self, Self::Not) } } + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] +pub enum Pinnedness { + Not, + Pinned, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 52372bbf991c..ae1e1b3f8a21 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -640,7 +640,8 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_span(span), Some(self.allow_gen_future.clone()), ); - let resume_ty = self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span); + let resume_ty = + self.make_lang_item_qpath(hir::LangItem::ResumeTy, unstable_span, None); let input_ty = hir::Ty { hir_id: self.next_id(), kind: hir::TyKind::Path(resume_ty), @@ -2065,7 +2066,7 @@ impl<'hir> LoweringContext<'_, 'hir> { lang_item: hir::LangItem, name: Symbol, ) -> hir::Expr<'hir> { - let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span)); + let qpath = self.make_lang_item_qpath(lang_item, self.lower_span(span), None); let path = hir::ExprKind::Path(hir::QPath::TypeRelative( self.arena.alloc(self.ty(span, hir::TyKind::Path(qpath))), self.arena.alloc(hir::PathSegment::new( diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b26797f42032..bd20a70f325e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,8 +55,8 @@ use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, StashKey}; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::{ - self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName, - TraitCandidate, + self as hir, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem, MissingLifetimeKind, + ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -765,8 +765,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { res } - fn make_lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> { - hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, None)) + fn make_lang_item_qpath( + &mut self, + lang_item: hir::LangItem, + span: Span, + args: Option<&'hir hir::GenericArgs<'hir>>, + ) -> hir::QPath<'hir> { + hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args)) } fn make_lang_item_path( @@ -1317,6 +1322,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let lifetime = self.lower_lifetime(®ion); hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)) } + TyKind::PinnedRef(region, mt) => { + let region = region.unwrap_or_else(|| { + let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = + self.resolver.get_lifetime_res(t.id) + { + debug_assert_eq!(start.plus(1), end); + start + } else { + self.next_node_id() + }; + let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi(); + Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } + }); + let lifetime = self.lower_lifetime(®ion); + let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx)); + let span = self.lower_span(t.span); + let arg = hir::Ty { kind, span, hir_id: self.next_id() }; + let args = self.arena.alloc(hir::GenericArgs { + args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]), + constraints: &[], + parenthesized: hir::GenericArgsParentheses::No, + span_ext: span, + }); + let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args)); + hir::TyKind::Path(path) + } TyKind::BareFn(f) => { let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params); hir::TyKind::BareFn(self.arena.alloc(hir::BareFnTy { @@ -1882,10 +1913,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Given we are only considering `ImplicitSelf` types, we needn't consider // the case where we have a mutable pattern to a reference as that would // no longer be an `ImplicitSelf`. - TyKind::Ref(_, mt) if mt.ty.kind.is_implicit_self() => match mt.mutbl { - hir::Mutability::Not => hir::ImplicitSelfKind::RefImm, - hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut, - }, + TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt) + if mt.ty.kind.is_implicit_self() => + { + match mt.mutbl { + hir::Mutability::Not => hir::ImplicitSelfKind::RefImm, + hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut, + } + } _ => hir::ImplicitSelfKind::None, } }), diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 1e82ba5db8a2..fe64160fb4dc 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -95,7 +95,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { visit::walk_ty(self, t); self.current_binders.pop(); } - TyKind::Ref(None, _) => { + TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => { self.record_elided_anchor(t.id, t.span); visit::walk_ty(self, t); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 42d1ef5c558b..5daaa840e13b 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -547,6 +547,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(mut_ref, "mutable by-reference bindings are experimental"); gate_all!(global_registration, "global registration is experimental"); gate_all!(return_type_notation, "return type notation is experimental"); + gate_all!(pin_ergonomics, "pinned reference syntax is experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 884cc413bd58..8b3653ab097c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1163,6 +1163,12 @@ impl<'a> State<'a> { self.print_opt_lifetime(lifetime); self.print_mt(mt, false); } + ast::TyKind::PinnedRef(lifetime, mt) => { + self.word("&"); + self.print_opt_lifetime(lifetime); + self.word("pin "); + self.print_mt(mt, true); + } ast::TyKind::Never => { self.word("!"); } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2ef6fa53f4ed..bc5ed249559a 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1,10 +1,9 @@ use std::fmt; -use rustc_ast as ast; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ - Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, LitKind, - TraitObjectSyntax, UintTy, + self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label, + LitKind, TraitObjectSyntax, UintTy, }; pub use rustc_ast::{ BinOp, BinOpKind, BindingMode, BorrowKind, ByRef, CaptureBy, ImplPolarity, IsAuto, Movability, diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a8ed8b5df9c0..ccd6dfda7970 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, - PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, + self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; @@ -529,7 +527,10 @@ impl<'a> Parser<'a> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { let and_span = self.prev_token.span; let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime()); - let mut mutbl = self.parse_mutability(); + let (pinned, mut mutbl) = match self.parse_pin_and_mut() { + Some(pin_mut) => pin_mut, + None => (Pinnedness::Not, self.parse_mutability()), + }; if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires // it to be followed by a plus, but we disallow plus in the pointee type. @@ -565,7 +566,35 @@ impl<'a> Parser<'a> { self.bump_with((dyn_tok, dyn_tok_sp)); } let ty = self.parse_ty_no_plus()?; - Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl })) + Ok(match pinned { + Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }), + Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }), + }) + } + + /// Parses `pin` and `mut` annotations on references. + /// + /// It must be either `pin const` or `pin mut`. + pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> { + if self.token.is_ident_named(sym::pin) { + let result = self.look_ahead(1, |token| { + if token.is_keyword(kw::Const) { + Some((Pinnedness::Pinned, Mutability::Not)) + } else if token.is_keyword(kw::Mut) { + Some((Pinnedness::Pinned, Mutability::Mut)) + } else { + None + } + }); + if result.is_some() { + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); + self.bump(); + } + result + } else { + None + } } // Parses the `typeof(EXPR)`. diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 8ad14b6eb74b..fc9d548d1fbe 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -574,29 +574,33 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_ty(&mut self, t: &'v ast::Ty) { - record_variants!((self, t, t.kind, Id::None, ast, Ty, TyKind), [ - Slice, - Array, - Ptr, - Ref, - BareFn, - Never, - Tup, - AnonStruct, - AnonUnion, - Path, - Pat, - TraitObject, - ImplTrait, - Paren, - Typeof, - Infer, - ImplicitSelf, - MacCall, - CVarArgs, - Dummy, - Err - ]); + record_variants!( + (self, t, t.kind, Id::None, ast, Ty, TyKind), + [ + Slice, + Array, + Ptr, + Ref, + PinnedRef, + BareFn, + Never, + Tup, + AnonStruct, + AnonUnion, + Path, + Pat, + TraitObject, + ImplTrait, + Paren, + Typeof, + Infer, + ImplicitSelf, + MacCall, + CVarArgs, + Dummy, + Err + ] + ); ast_visit::walk_ty(self, t) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 66c1ff93ce1c..b84cbf9c6294 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -779,7 +779,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r let prev = self.diag_metadata.current_trait_object; let prev_ty = self.diag_metadata.current_type_path; match &ty.kind { - TyKind::Ref(None, _) => { + TyKind::Ref(None, _) | TyKind::PinnedRef(None, _) => { // Elided lifetime in reference: we resolve as if there was some lifetime `'_` with // NodeId `ty.id`. // This span will be used in case of elision failure. @@ -2326,7 +2326,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> { fn visit_ty(&mut self, ty: &'ra Ty) { trace!("FindReferenceVisitor considering ty={:?}", ty); - if let TyKind::Ref(lt, _) = ty.kind { + if let TyKind::Ref(lt, _) | TyKind::PinnedRef(lt, _) = ty.kind { // See if anything inside the &thing contains Self let mut visitor = SelfVisitor { r: self.r, impl_self: self.impl_self, self_found: false }; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fce5ec36c661..aced05ca351a 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3482,7 +3482,7 @@ struct LifetimeFinder<'ast> { impl<'ast> Visitor<'ast> for LifetimeFinder<'ast> { fn visit_ty(&mut self, t: &'ast Ty) { - if let TyKind::Ref(_, mut_ty) = &t.kind { + if let TyKind::Ref(_, mut_ty) | TyKind::PinnedRef(_, mut_ty) = &t.kind { self.seen.push(t); if t.span.lo() == self.lifetime.lo() { self.found = Some(&mut_ty.ty); diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 68f74e52ed7b..187f7fb44176 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -753,6 +753,9 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Ref(ll, l), Ref(rl, r)) => { both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) }, + (PinnedRef(ll, l), PinnedRef(rl, r)) => { + both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty) + }, (BareFn(l), BareFn(r)) => { l.safety == r.safety && eq_ext(&l.ext, &r.ext) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 07b483b2b372..b64e069e0966 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -827,7 +827,8 @@ impl Rewrite for ast::Ty { rewrite_unary_prefix(context, prefix, &*mt.ty, shape) } - ast::TyKind::Ref(ref lifetime, ref mt) => { + ast::TyKind::Ref(ref lifetime, _pinned, ref mt) => { + // FIXME: format pinnedness let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); @@ -1262,7 +1263,7 @@ pub(crate) fn can_be_overflowed_type( ) -> bool { match ty.kind { ast::TyKind::Tup(..) => context.use_block_indent() && len == 1, - ast::TyKind::Ref(_, ref mutty) | ast::TyKind::Ptr(ref mutty) => { + ast::TyKind::Ref(_, _, ref mutty) | ast::TyKind::Ptr(ref mutty) => { can_be_overflowed_type(context, &*mutty.ty, len) } _ => false, diff --git a/tests/ui/async-await/pin-sugar-ambiguity.rs b/tests/ui/async-await/pin-sugar-ambiguity.rs new file mode 100644 index 000000000000..d183000931ec --- /dev/null +++ b/tests/ui/async-await/pin-sugar-ambiguity.rs @@ -0,0 +1,15 @@ +//@ check-pass +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +// Handle the case where there's ambiguity between pin as a contextual keyword and pin as a path. + +struct Foo; + +mod pin { + pub struct Foo; +} + +fn main() { + let _x: &pin ::Foo = &pin::Foo; +} diff --git a/tests/ui/async-await/pin-sugar-no-const.rs b/tests/ui/async-await/pin-sugar-no-const.rs new file mode 100644 index 000000000000..dd6456b60348 --- /dev/null +++ b/tests/ui/async-await/pin-sugar-no-const.rs @@ -0,0 +1,8 @@ +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +// Makes sure we don't accidentally accept `&pin Foo` without the `const` keyword. + +fn main() { + let _x: &pin i32 = todo!(); //~ ERROR found `i32` +} diff --git a/tests/ui/async-await/pin-sugar-no-const.stderr b/tests/ui/async-await/pin-sugar-no-const.stderr new file mode 100644 index 000000000000..5f01156c1f0a --- /dev/null +++ b/tests/ui/async-await/pin-sugar-no-const.stderr @@ -0,0 +1,15 @@ +error: expected one of `!`, `(`, `::`, `;`, `<`, or `=`, found `i32` + --> $DIR/pin-sugar-no-const.rs:7:18 + | +LL | let _x: &pin i32 = todo!(); + | - ^^^ expected one of `!`, `(`, `::`, `;`, `<`, or `=` + | | + | while parsing the type for `_x` + | +help: there is a keyword `in` with a similar name + | +LL | let _x: &in i32 = todo!(); + | ~~ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/pin-sugar.rs b/tests/ui/async-await/pin-sugar.rs new file mode 100644 index 000000000000..8dbdec418b1f --- /dev/null +++ b/tests/ui/async-await/pin-sugar.rs @@ -0,0 +1,51 @@ +//@ check-pass + +#![feature(pin_ergonomics)] +#![allow(dead_code, incomplete_features)] + +// Makes sure we can handle `&pin mut T` and `&pin const T` as sugar for `Pin<&mut T>` and +// `Pin<&T>`. + +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn baz(self: &pin mut Self) { + } + + fn baz_const(self: &pin const Self) { + } + + fn baz_lt<'a>(self: &'a pin mut Self) { + } + + fn baz_const_lt(self: &'_ pin const Self) { + } +} + +fn foo(_: &pin mut Foo) { +} + +fn foo_const(x: &pin const Foo) { +} + +fn bar(x: &pin mut Foo) { + foo(x); + foo(x); // for this to work we need to automatically reborrow, + // as if the user had written `foo(x.as_mut())`. + + Foo::baz(x); + Foo::baz(x); + + // make sure we can reborrow &mut as &. + foo_const(x); + Foo::baz_const(x); + + let x: &pin const _ = Pin::new(&Foo); + + foo_const(x); // make sure reborrowing from & to & works. + foo_const(x); +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs index 3382504af9d6..4624faf1e53c 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs @@ -1,4 +1,4 @@ -#![allow(dead_code, incomplete_features)] +#![allow(dead_code)] use std::pin::Pin; @@ -9,10 +9,13 @@ impl Foo { } } -fn foo(_: Pin<&mut Foo>) { +fn foo(x: Pin<&mut Foo>) { + let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental } -fn bar(mut x: Pin<&mut Foo>) { +fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental + +fn bar(x: Pin<&mut Foo>) { foo(x); foo(x); //~ ERROR use of moved value: `x` } @@ -22,4 +25,6 @@ fn baz(mut x: Pin<&mut Foo>) { x.foo(); //~ ERROR use of moved value: `x` } +fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental + fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr index 430b78662414..dd93a7be1ada 100644 --- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr +++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr @@ -1,8 +1,38 @@ -error[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:17:9 +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:13:14 | -LL | fn bar(mut x: Pin<&mut Foo>) { - | ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait +LL | let _y: &pin mut Foo = x; + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:16:18 + | +LL | fn foo_sugar(_: &pin mut Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: pinned reference syntax is experimental + --> $DIR/feature-gate-pin_ergonomics.rs:28:18 + | +LL | fn baz_sugar(_: &pin const Foo) {} + | ^^^ + | + = note: see issue #130494 for more information + = help: add `#![feature(pin_ergonomics)]` 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[E0382]: use of moved value: `x` + --> $DIR/feature-gate-pin_ergonomics.rs:20:9 + | +LL | fn bar(x: Pin<&mut Foo>) { + | - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait LL | foo(x); | - value moved here LL | foo(x); @@ -11,13 +41,13 @@ LL | foo(x); note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary --> $DIR/feature-gate-pin_ergonomics.rs:12:11 | -LL | fn foo(_: Pin<&mut Foo>) { +LL | fn foo(x: Pin<&mut Foo>) { | --- ^^^^^^^^^^^^^ this parameter takes ownership of the value | | | in this function error[E0382]: use of moved value: `x` - --> $DIR/feature-gate-pin_ergonomics.rs:22:5 + --> $DIR/feature-gate-pin_ergonomics.rs:25:5 | LL | fn baz(mut x: Pin<&mut Foo>) { | ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait @@ -36,6 +66,7 @@ help: consider reborrowing the `Pin` instead of moving it LL | x.as_mut().foo(); | +++++++++ -error: aborting due to 2 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0382`. +Some errors have detailed explanations: E0382, E0658. +For more information about an error, try `rustc --explain E0382`. From b490bf56b7da3a689f0ea7a46f56d7cd2339efb0 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 20 Sep 2024 15:44:43 -0700 Subject: [PATCH 010/118] Fix clippy and rustfmt compilation --- compiler/rustc_parse/src/parser/ty.rs | 5 ++- compiler/rustc_passes/src/hir_stats.rs | 51 ++++++++++++-------------- src/tools/rustfmt/src/types.rs | 11 +++--- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index ccd6dfda7970..b0ff033cf801 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,7 +2,10 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID + self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, + GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, + Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, + TyKind, }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index fc9d548d1fbe..daf1bd8b19d0 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -574,33 +574,30 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { } fn visit_ty(&mut self, t: &'v ast::Ty) { - record_variants!( - (self, t, t.kind, Id::None, ast, Ty, TyKind), - [ - Slice, - Array, - Ptr, - Ref, - PinnedRef, - BareFn, - Never, - Tup, - AnonStruct, - AnonUnion, - Path, - Pat, - TraitObject, - ImplTrait, - Paren, - Typeof, - Infer, - ImplicitSelf, - MacCall, - CVarArgs, - Dummy, - Err - ] - ); + record_variants!((self, t, t.kind, Id::None, ast, Ty, TyKind), [ + Slice, + Array, + Ptr, + Ref, + PinnedRef, + BareFn, + Never, + Tup, + AnonStruct, + AnonUnion, + Path, + Pat, + TraitObject, + ImplTrait, + Paren, + Typeof, + Infer, + ImplicitSelf, + MacCall, + CVarArgs, + Dummy, + Err + ]); ast_visit::walk_ty(self, t) } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index b64e069e0966..999deb5dd4aa 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -827,8 +827,9 @@ impl Rewrite for ast::Ty { rewrite_unary_prefix(context, prefix, &*mt.ty, shape) } - ast::TyKind::Ref(ref lifetime, _pinned, ref mt) => { - // FIXME: format pinnedness + ast::TyKind::Ref(ref lifetime, ref mt) + | ast::TyKind::PinnedRef(ref lifetime, ref mt) => { + // FIXME(pin_ergonomics): correctly format pinned reference syntax let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); @@ -1263,9 +1264,9 @@ pub(crate) fn can_be_overflowed_type( ) -> bool { match ty.kind { ast::TyKind::Tup(..) => context.use_block_indent() && len == 1, - ast::TyKind::Ref(_, _, ref mutty) | ast::TyKind::Ptr(ref mutty) => { - can_be_overflowed_type(context, &*mutty.ty, len) - } + ast::TyKind::Ref(_, ref mutty) + | ast::TyKind::PinnedRef(_, ref mutty) + | ast::TyKind::Ptr(ref mutty) => can_be_overflowed_type(context, &*mutty.ty, len), _ => false, } } From 3aabe1e4a3518f943a20b692a0db90189fc5898c Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 23 Sep 2024 16:07:31 -0700 Subject: [PATCH 011/118] Add basic pin sugar support to rustfmt --- src/tools/rustfmt/src/types.rs | 8 +++++++- src/tools/rustfmt/tests/source/pin_sugar.rs | 10 ++++++++++ src/tools/rustfmt/tests/target/pin_sugar.rs | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/tools/rustfmt/tests/source/pin_sugar.rs create mode 100644 src/tools/rustfmt/tests/target/pin_sugar.rs diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 999deb5dd4aa..f7177c7f8546 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -829,7 +829,6 @@ impl Rewrite for ast::Ty { } ast::TyKind::Ref(ref lifetime, ref mt) | ast::TyKind::PinnedRef(ref lifetime, ref mt) => { - // FIXME(pin_ergonomics): correctly format pinned reference syntax let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); @@ -863,6 +862,13 @@ impl Rewrite for ast::Ty { cmnt_lo = lifetime.ident.span.hi(); } + if let ast::TyKind::PinnedRef(..) = self.kind { + result.push_str("pin "); + if ast::Mutability::Not == mt.mutbl { + result.push_str("const "); + } + } + if ast::Mutability::Mut == mt.mutbl { let mut_hi = context.snippet_provider.span_after(self.span(), "mut"); let before_mut_span = mk_sp(cmnt_lo, mut_hi - BytePos::from_usize(3)); diff --git a/src/tools/rustfmt/tests/source/pin_sugar.rs b/src/tools/rustfmt/tests/source/pin_sugar.rs new file mode 100644 index 000000000000..0eb3c0770c48 --- /dev/null +++ b/src/tools/rustfmt/tests/source/pin_sugar.rs @@ -0,0 +1,10 @@ +// See #130494 + +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +fn f(x: &pin const i32) {} +fn g<'a>(x: & 'a pin const i32) {} +fn h<'a>(x: & 'a pin +mut i32) {} +fn i(x: &pin mut i32) {} diff --git a/src/tools/rustfmt/tests/target/pin_sugar.rs b/src/tools/rustfmt/tests/target/pin_sugar.rs new file mode 100644 index 000000000000..c9fa883e238f --- /dev/null +++ b/src/tools/rustfmt/tests/target/pin_sugar.rs @@ -0,0 +1,9 @@ +// See #130494 + +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] + +fn f(x: &pin const i32) {} +fn g<'a>(x: &'a pin const i32) {} +fn h<'a>(x: &'a pin mut i32) {} +fn i(x: &pin mut i32) {} From 005a6298f75b309cb0ab07f36d2888961ffa602f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2024 14:20:27 -0400 Subject: [PATCH 012/118] re-sync with latest tracking issue changes --- RELEASES.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index b9d58d6b757b..4bdee5f66ed0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,12 +6,19 @@ Version 1.82.0 (2024-10-17) Language -------- - [Don't make statement nonterminals match pattern nonterminals](https://github.com/rust-lang/rust/pull/120221/) -- [Implement lint against ambiguous negative literals](https://github.com/rust-lang/rust/pull/121364/) - [Patterns matching empty types can now be omitted in common cases](https://github.com/rust-lang/rust/pull/122792) +- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) - [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/) - [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/) - [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672) +- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679) +- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921) +- [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284) +- [Do not require `T` to be live when dropping `[T; 0]`](https://github.com/rust-lang/rust/pull/128438) +- [Stabilize `const` operands in inline assembly](https://github.com/rust-lang/rust/pull/128570) +- [Stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596) - [Stabilize explicit opt-in to unsafe attributes](https://github.com/rust-lang/rust/pull/128771) +- [Document NaN bit patterns guarantees](https://github.com/rust-lang/rust/pull/129559) @@ -19,8 +26,11 @@ Language Compiler -------- - [Promote riscv64gc-unknown-linux-musl to tier 2](https://github.com/rust-lang/rust/pull/122049) +- [Promote Mac Catalyst targets `aarch64-apple-ios-macabi` and `x86_64-apple-ios-macabi` to Tier 2, and ship them with rustup](https://github.com/rust-lang/rust/pull/126450) - [Improved diagnostics to explain why a pattern is unreachable](https://github.com/rust-lang/rust/pull/128034) - [The compiler now triggers the unreachable code warning properly for async functions that don't return/are `-> !`](https://github.com/rust-lang/rust/pull/128443) +- [Promote `aarch64-apple-darwin` to Tier 1](https://github.com/rust-lang/rust/pull/128592) +- [Add Trusty OS target `aarch64-unknown-trusty` and `armv7-unknown-trusty` as tier 3 targets](https://github.com/rust-lang/rust/pull/129490) - [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/) @@ -31,7 +41,6 @@ Libraries - [Implement DoubleEnded and ExactSize for Take and Take](https://github.com/rust-lang/rust/pull/106943/) - [Stabilize Wasm relaxed SIMD](https://github.com/rust-lang/rust/pull/117468/) - [Stabilize const `{integer}::from_str_radix` i.e. `const_int_from_str`](https://github.com/rust-lang/rust/pull/124941/) -- [CommandExt::before_exec: deprecate safety in edition 2024](https://github.com/rust-lang/rust/pull/125970/) - [CloneToUninit impls](https://github.com/rust-lang/rust/pull/126877/) - [impl `Default` for collection iterators that don't already have it](https://github.com/rust-lang/rust/pull/128261/) @@ -51,13 +60,9 @@ Cargo Compatibility Notes ------------------- -- [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) - We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead. -- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679) -- [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921) - The standard library has a new implementation of `binary_search` which is significantly improves performance (#128254). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. - [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets. -- [Stabilize offset_of_nested](https://github.com/rust-lang/rust/pull/128284) - [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400) - The WebAssembly target features `multivalue` and `reference-types` are now both enabled by default. These two features both have subtle changes implied @@ -77,10 +82,6 @@ Compatibility Notes default features requires `-Zbuild-std` support from Cargo and more information can be found at [rust-lang/rust#128511](https://github.com/rust-lang/rust/pull/128511). -- [Stabilize `const` arguments to inline asm](https://github.com/rust-lang/rust/pull/128570) -- [Promote aarch64-apple-darwin to Tier 1](https://github.com/rust-lang/rust/pull/128592) -- [stabilize floating-point arithmetic in `const fn`](https://github.com/rust-lang/rust/pull/128596) -- [float types: document NaN bit pattern guarantees](https://github.com/rust-lang/rust/pull/129559) - [Rust now raises unsafety errors for union patterns in parameter-position](https://github.com/rust-lang/rust/pull/130531) From 4abbdfa1c9cd3e2f3181608fb60539755f3a8068 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 6 Oct 2024 20:05:27 +0200 Subject: [PATCH 013/118] Prepare tests --- .../migration_lint.fixed | 113 ++++++++++++++---- .../migration_lint.rs | 113 ++++++++++++++---- .../migration_lint.stderr | 113 ++++++++++++------ 3 files changed, 262 insertions(+), 77 deletions(-) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 253c9589a552..528d274c0ac2 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -8,49 +8,120 @@ extern crate migration_lint_macros; -struct Foo(u8); +struct Foo(T); + +// Tests type equality in a way that avoids coercing `&&T` to `&T`. +trait Eq {} +impl Eq for T {} +fn assert_type_eq>(_: T, _: U) {} fn main() { - let &Foo(mut a) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 - a = 42; + let Foo(x) = &Foo(0); + assert_type_eq(x, &0u8); - let &mut Foo(mut a) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 - a = 42; + let Foo(x) = &mut Foo(0); + assert_type_eq(x, &mut 0u8); - if let &&&&&Some(&_) = &&&&&Some(&0u8) {} + let &Foo(mut x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {} + let &mut Foo(mut x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {} + let Foo(ref x) = &Foo(0); + assert_type_eq(x, &0u8); + + let Foo(ref x) = &mut Foo(0); + assert_type_eq(x, &0u8); + + let &Foo(x) = &Foo(0); + assert_type_eq(x, 0u8); + + let &mut Foo(x) = &mut Foo(0); + assert_type_eq(x, 0u8); + + let &Foo(x) = &Foo(&0); + assert_type_eq(x, &0u8); + + let &mut Foo(x) = &mut Foo(&0); + assert_type_eq(x, &0u8); + + let &Foo(&x) = &Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + let &Foo(&mut x) = &Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + let &mut Foo(&x) = &mut Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - struct Struct { - a: u32, - b: u32, - c: u32, + let &mut Foo(&mut x) = &mut Foo(&mut 0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + + if let Some(x) = &&&&&Some(&0u8) { + assert_type_eq(x, &&0u8); } - let s = Struct { a: 0, b: 0, c: 0 }; - let &Struct { ref a, mut b, ref c } = &s; + + if let &&&&&Some(&x) = &&&&&Some(&0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, &mut 0u8); + } + + struct Struct { + a: A, + b: B, + c: C, + } + + let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(a, &0u32); + assert_type_eq(b, 0u32); + + let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &&0u32); + assert_type_eq(c, &&0u32); + + if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = + //~^ ERROR: the semantics of this pattern will change in edition 2024 + &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) + { + assert_type_eq(a, &0u32); + assert_type_eq(b, 0u32); + assert_type_eq(c, &&0u32); + } #[warn(rust_2024_incompatible_pat)] match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. - (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { + (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { //~^ WARN: the semantics of this pattern will change in edition 2024 - _x = 4; - _y = &7; + assert_type_eq(x, 0u32); + assert_type_eq(y, &0u32); } _ => {} } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 1406db779cc7..0c5be2c761d1 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -8,49 +8,120 @@ extern crate migration_lint_macros; -struct Foo(u8); +struct Foo(T); + +// Tests type equality in a way that avoids coercing `&&T` to `&T`. +trait Eq {} +impl Eq for T {} +fn assert_type_eq>(_: T, _: U) {} fn main() { - let Foo(mut a) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 - a = 42; + let Foo(x) = &Foo(0); + assert_type_eq(x, &0u8); - let Foo(mut a) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 - a = 42; + let Foo(x) = &mut Foo(0); + assert_type_eq(x, &mut 0u8); - if let Some(&_) = &&&&&Some(&0u8) {} + let Foo(mut x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let Some(&mut _) = &&&&&Some(&mut 0u8) {} + let Foo(mut x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let Some(&_) = &&&&&mut Some(&0u8) {} + let Foo(ref x) = &Foo(0); + assert_type_eq(x, &0u8); + + let Foo(ref x) = &mut Foo(0); + assert_type_eq(x, &0u8); + + let &Foo(x) = &Foo(0); + assert_type_eq(x, 0u8); + + let &mut Foo(x) = &mut Foo(0); + assert_type_eq(x, 0u8); + + let &Foo(x) = &Foo(&0); + assert_type_eq(x, &0u8); + + let &mut Foo(x) = &mut Foo(&0); + assert_type_eq(x, &0u8); + + let Foo(&x) = &Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + let Foo(&mut x) = &Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + let Foo(&x) = &mut Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); - struct Struct { - a: u32, - b: u32, - c: u32, + let Foo(&mut x) = &mut Foo(&mut 0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + + if let Some(x) = &&&&&Some(&0u8) { + assert_type_eq(x, &&0u8); } - let s = Struct { a: 0, b: 0, c: 0 }; - let Struct { a, mut b, c } = &s; + + if let Some(&x) = &&&&&Some(&0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let Some(&mut x) = &&&&&Some(&mut 0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let Some(&x) = &&&&&mut Some(&0u8) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, 0u8); + } + + if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(x, &mut 0u8); + } + + struct Struct { + a: A, + b: B, + c: C, + } + + let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(a, &0u32); + assert_type_eq(b, 0u32); + + let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &&0u32); + assert_type_eq(c, &&0u32); + + if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = + //~^ ERROR: the semantics of this pattern will change in edition 2024 + &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) + { + assert_type_eq(a, &0u32); + assert_type_eq(b, 0u32); + assert_type_eq(c, &&0u32); + } #[warn(rust_2024_incompatible_pat)] match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. - (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { + (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { //~^ WARN: the semantics of this pattern will change in edition 2024 - _x = 4; - _y = &7; + assert_type_eq(x, 0u32); + assert_type_eq(y, &0u32); } _ => {} } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 4d7230120247..29e9183acc3b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,7 +1,7 @@ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:14:9 + --> $DIR/migration_lint.rs:25:9 | -LL | let Foo(mut a) = &Foo(0); +LL | let Foo(mut x) = &Foo(0); | -^^^^^^^^^ | | | help: desugar the match ergonomics: `&` @@ -13,85 +13,128 @@ LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:18:9 + --> $DIR/migration_lint.rs:29:9 | -LL | let Foo(mut a) = &mut Foo(0); +LL | let Foo(mut x) = &mut Foo(0); | -^^^^^^^^^ | | | help: desugar the match ergonomics: `&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:22:12 + --> $DIR/migration_lint.rs:51:9 | -LL | if let Some(&_) = &&&&&Some(&0u8) {} +LL | let Foo(&x) = &Foo(&0); + | -^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:55:9 + | +LL | let Foo(&mut x) = &Foo(&mut 0); + | -^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:59:9 + | +LL | let Foo(&x) = &mut Foo(&0); + | -^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:63:9 + | +LL | let Foo(&mut x) = &mut Foo(&mut 0); + | -^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:71:12 + | +LL | if let Some(&x) = &&&&&Some(&0u8) { | -^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:25:12 + --> $DIR/migration_lint.rs:76:12 | -LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {} +LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | -^^^^^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:28:12 + --> $DIR/migration_lint.rs:81:12 | -LL | if let Some(&_) = &&&&&mut Some(&0u8) {} +LL | if let Some(&x) = &&&&&mut Some(&0u8) { | -^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:31:12 + --> $DIR/migration_lint.rs:86:12 | -LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} +LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ^^^^^^^^^^^^^^^^^^^^^^^^ | help: desugar the match ergonomics | -LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} - | ++++ ++++ - -error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:34:12 - | -LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: desugar the match ergonomics - | -LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} +LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ++++ ++++ +++++++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:43:9 + --> $DIR/migration_lint.rs:97:9 | -LL | let Struct { a, mut b, c } = &s; +LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^ | help: desugar the match ergonomics | -LL | let &Struct { ref a, mut b, ref c } = &s; +LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; | + +++ +++ -warning: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:50:9 +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:102:9 | -LL | (Some(mut _x), migration_lint_macros::mixed_edition_pat!(_y)) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; + | + +++ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:108:12 + | +LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = + | + + + +++ + +warning: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:121:9 + | +LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/migration_lint.rs:46:12 + --> $DIR/migration_lint.rs:117:12 | LL | #[warn(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: desugar the match ergonomics | -LL | &(Some(mut _x), migration_lint_macros::mixed_edition_pat!(ref _y)) => { - | + +++ +LL | &(Some(mut x), migration_lint_macros::mixed_edition_pat!(ref y)) => { + | + +++ -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 13 previous errors; 1 warning emitted From 4107322766523afa7d1968acc0dfee4fd06e8ad8 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 6 Oct 2024 20:47:06 +0200 Subject: [PATCH 014/118] Error on resetted binding mode in edition 2024 --- compiler/rustc_hir_typeck/src/pat.rs | 15 +- compiler/rustc_hir_typeck/src/writeback.rs | 6 +- compiler/rustc_lint_defs/src/builtin.rs | 4 +- .../rustc_middle/src/ty/typeck_results.rs | 15 +- compiler/rustc_mir_build/src/errors.rs | 2 + .../rustc_mir_build/src/thir/pattern/mod.rs | 28 +++- .../migration_lint.fixed | 9 +- .../migration_lint.rs | 7 +- .../migration_lint.stderr | 20 +-- .../min_match_ergonomics_fail.rs | 49 ++++++ .../min_match_ergonomics_fail.stderr | 144 ++++++++++++++++++ .../min_match_ergonomics_success.rs | 19 +++ 12 files changed, 270 insertions(+), 48 deletions(-) create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr create mode 100644 tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 45a6efc7a6a3..8eb3118fb8ad 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -692,10 +692,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(def_br, Mutability::Mut) } else { // `mut` resets binding mode on edition <= 2021 - self.typeck_results + *self + .typeck_results .borrow_mut() .rust_2024_migration_desugared_pats_mut() - .insert(pat_info.top_info.hir_id); + .entry(pat_info.top_info.hir_id) + .or_default() |= pat.span.at_least_rust_2024(); BindingMode(ByRef::No, Mutability::Mut) } } @@ -2206,14 +2208,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Reset binding mode on old editions - if pat_info.binding_mode != ByRef::No { pat_info.binding_mode = ByRef::No; - - self.typeck_results + *self + .typeck_results .borrow_mut() .rust_2024_migration_desugared_pats_mut() - .insert(pat_info.top_info.hir_id); + .entry(pat_info.top_info.hir_id) + .or_default() |= pat.span.at_least_rust_2024(); } } @@ -2264,6 +2266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (err, err) } }; + self.check_pat(inner, inner_ty, pat_info); ref_ty } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index c2555d2bb47d..8164c7377529 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -640,7 +640,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) { - if self + if let Some(is_hard_error) = self .fcx .typeck_results .borrow_mut() @@ -650,7 +650,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { debug!( "node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint" ); - self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id); + self.typeck_results + .rust_2024_migration_desugared_pats_mut() + .insert(hir_id, is_hard_error); } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9b6d63c2ef48..06e63bd73411 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1650,7 +1650,7 @@ declare_lint! { /// ### Example /// /// ```rust,edition2021 - /// #![feature(ref_pat_eat_one_layer_2024)] + /// #![feature(min_match_ergonomics_2024)] /// #![warn(rust_2024_incompatible_pat)] /// /// if let Some(&a) = &Some(&0u8) { @@ -1671,7 +1671,7 @@ declare_lint! { pub RUST_2024_INCOMPATIBLE_PAT, Allow, "detects patterns whose meaning will change in Rust 2024", - @feature_gate = ref_pat_eat_one_layer_2024; + @feature_gate = min_match_ergonomics_2024; // FIXME uncomment below upon stabilization /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index a92bdb2eae0d..c13d229ebdcb 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -79,9 +79,10 @@ pub struct TypeckResults<'tcx> { /// Stores the actual binding mode for all instances of [`BindingMode`]. pat_binding_modes: ItemLocalMap, - /// Top-level patterns whose match ergonomics need to be desugared - /// by the Rust 2021 -> 2024 migration lint. - rust_2024_migration_desugared_pats: ItemLocalSet, + /// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024 + /// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error + /// (if any of the incompatible pattern elements are in edition 2024). + rust_2024_migration_desugared_pats: ItemLocalMap, /// Stores the types which were implicitly dereferenced in pattern binding modes /// for later usage in THIR lowering. For example, @@ -437,15 +438,15 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } - pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> { - LocalSetInContext { + pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> { + LocalTableInContext { hir_owner: self.hir_owner, data: &self.rust_2024_migration_desugared_pats, } } - pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> { - LocalSetInContextMut { + pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> { + LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.rust_2024_migration_desugared_pats, } diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 411e9420914d..7f905d5b90b7 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat { pub(crate) struct Rust2024IncompatiblePatSugg { pub(crate) suggestion: Vec<(Span, String)>, + /// Whether the incompatibility is a hard error because a relevant span is in edition 2024. + pub(crate) is_hard_error: bool, } impl Subdiagnostic for Rust2024IncompatiblePatSugg { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index d78e1f5da09f..90355d7fce69 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -48,18 +48,30 @@ pub(super) fn pat_from_hir<'a, 'tcx>( typeck_results, rust_2024_migration_suggestion: typeck_results .rust_2024_migration_desugared_pats() - .contains(pat.hir_id) - .then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }), + .get(pat.hir_id) + .map(|&is_hard_error| Rust2024IncompatiblePatSugg { + suggestion: Vec::new(), + is_hard_error, + }), }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(sugg) = pcx.rust_2024_migration_suggestion { - tcx.emit_node_span_lint( - lint::builtin::RUST_2024_INCOMPATIBLE_PAT, - pat.hir_id, - pat.span, - Rust2024IncompatiblePat { sugg }, - ); + if tcx.features().min_match_ergonomics_2024 && sugg.is_hard_error { + let mut err = tcx.dcx().struct_span_err( + pat.span, + "patterns are not allowed to reset the default binding mode in rust 2024", + ); + err.subdiagnostic(sugg); + err.emit(); + } else { + tcx.emit_node_span_lint( + lint::builtin::RUST_2024_INCOMPATIBLE_PAT, + pat.hir_id, + pat.span, + Rust2024IncompatiblePat { sugg }, + ); + } } result } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 528d274c0ac2..63c84ae5b997 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -2,7 +2,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ aux-build:migration_lint_macros.rs -#![feature(mut_ref, ref_pat_eat_one_layer_2024)] +#![feature(mut_ref, min_match_ergonomics_2024)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] @@ -114,14 +114,13 @@ fn main() { assert_type_eq(c, &&0u32); } - #[warn(rust_2024_incompatible_pat)] match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. - (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - //~^ WARN: the semantics of this pattern will change in edition 2024 + &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { + //~^ ERROR: patterns are not allowed to reset the default binding mode assert_type_eq(x, 0u32); - assert_type_eq(y, &0u32); + assert_type_eq(y, 0u32); } _ => {} } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 0c5be2c761d1..f2a83c1266bf 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -2,7 +2,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ aux-build:migration_lint_macros.rs -#![feature(mut_ref, ref_pat_eat_one_layer_2024)] +#![feature(mut_ref, min_match_ergonomics_2024)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] @@ -114,14 +114,13 @@ fn main() { assert_type_eq(c, &&0u32); } - #[warn(rust_2024_incompatible_pat)] match &(Some(0), Some(0)) { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - //~^ WARN: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode assert_type_eq(x, 0u32); - assert_type_eq(y, &0u32); + assert_type_eq(y, 0u32); } _ => {} } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 29e9183acc3b..5e42e03d6685 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -120,21 +120,13 @@ help: desugar the match ergonomics LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = | + + + +++ -warning: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:121:9 +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/migration_lint.rs:120:9 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/migration_lint.rs:117:12 - | -LL | #[warn(rust_2024_incompatible_pat)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: desugar the match ergonomics - | -LL | &(Some(mut x), migration_lint_macros::mixed_edition_pat!(ref y)) => { - | + +++ + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` -error: aborting due to 13 previous errors; 1 warning emitted +error: aborting due to 14 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs new file mode 100644 index 000000000000..283666fdf4ca --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -0,0 +1,49 @@ +//@ check-fail +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +// gate-test-min_match_ergonomics_2024 +#![feature(min_match_ergonomics_2024)] +#![allow(incomplete_features)] +#![deny(rust_2024_incompatible_pat)] + +fn main() {} + +#[derive(Copy, Clone)] +struct T; + +struct Foo { + f: &'static (u8,), +} + +macro_rules! test_pat_on_type { + ($($tt:tt)*) => { + const _: () = { + // Define a new function to ensure all cases are tested independently. + fn foo($($tt)*) {} + }; + }; +} + +test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types +test_pat_on_type![(&x,): &(&T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types +test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types +test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types +test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types +test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types +test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(ref x,): &(T,)]; +test_pat_on_type![(ref mut x,): &mut (T,)]; + +fn get() -> X { + unimplemented!() +} + +// Make sure this works even when the underlying type is inferred. This test passes on rust stable. +fn infer() -> X { + match &get() { + (&x,) => x, //~ ERROR patterns are not allowed to reset the default binding mode + } +} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr new file mode 100644 index 000000000000..22247847def2 --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -0,0 +1,144 @@ +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:27:20 + | +LL | test_pat_on_type![(&x,): &(T,)]; + | ^^ ----- expected due to this + | | + | expected `T`, found `&_` + | + = note: expected struct `T` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - test_pat_on_type![(&x,): &(T,)]; +LL + test_pat_on_type![(x,): &(T,)]; + | + +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:29:20 + | +LL | test_pat_on_type![(&x,): &(&mut T,)]; + | ^^ ---------- expected due to this + | | + | types differ in mutability + | + = note: expected mutable reference `&mut T` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - test_pat_on_type![(&x,): &(&mut T,)]; +LL + test_pat_on_type![(x,): &(&mut T,)]; + | + +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:30:20 + | +LL | test_pat_on_type![(&mut x,): &(&T,)]; + | ^^^^^^ ------ expected due to this + | | + | types differ in mutability + | + = note: expected reference `&T` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/min_match_ergonomics_fail.rs:30:20 + | +LL | test_pat_on_type![(&mut x,): &(&T,)]; + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL - test_pat_on_type![(&mut x,): &(&T,)]; +LL + test_pat_on_type![(x,): &(&T,)]; + | + +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:32:20 + | +LL | test_pat_on_type![(&x,): &&mut &(T,)]; + | ^^ ----------- expected due to this + | | + | expected `T`, found `&_` + | + = note: expected struct `T` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - test_pat_on_type![(&x,): &&mut &(T,)]; +LL + test_pat_on_type![(x,): &&mut &(T,)]; + | + +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:33:29 + | +LL | test_pat_on_type![Foo { f: (&x,) }: Foo]; + | ^^ --- expected due to this + | | + | expected `u8`, found `&_` + | + = note: expected type `u8` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - test_pat_on_type![Foo { f: (&x,) }: Foo]; +LL + test_pat_on_type![Foo { f: (x,) }: Foo]; + | + +error[E0308]: mismatched types + --> $DIR/min_match_ergonomics_fail.rs:34:29 + | +LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; + | ^^ -------- expected due to this + | | + | expected `u8`, found `&_` + | + = note: expected type `u8` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; +LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; + | + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:28:19 + | +LL | test_pat_on_type![(&x,): &(&T,)]; + | -^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:31:19 + | +LL | test_pat_on_type![(&mut x,): &(&mut T,)]; + | -^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:35:19 + | +LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; + | -^^^^^^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:36:19 + | +LL | test_pat_on_type![(mut x,): &(T,)]; + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:47:9 + | +LL | (&x,) => x, + | -^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: aborting due to 11 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs new file mode 100644 index 000000000000..8dbbd7cfbb0c --- /dev/null +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs @@ -0,0 +1,19 @@ +//@ revisions: normal min_match_ergonomics +//@ check-pass +#![cfg_attr(min_match_ergonomics, feature(min_match_ergonomics_2024))] +#![allow(incomplete_features)] + +fn main() {} + +// Tests type equality in a way that avoids coercing `&&T` to `&T`. +trait Eq {} +impl Eq for T {} +fn assert_type_eq>(_: T, _: U) {} + +#[derive(Copy, Clone)] +struct T; + +fn test() { + let (x,) = &(&T,); + assert_type_eq(x, &&T); +} From 575033c50cf3f530bb054211e3dae968d373037f Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 7 Oct 2024 23:39:33 +0200 Subject: [PATCH 015/118] Also disallow `ref`/`ref mut` overriding the binding mode --- compiler/rustc_hir_typeck/src/pat.rs | 15 ++++++- .../migration_lint.fixed | 6 ++- .../migration_lint.rs | 2 + .../migration_lint.stderr | 42 +++++++++++++------ .../min_match_ergonomics_fail.rs | 4 +- .../min_match_ergonomics_fail.stderr | 18 +++++++- 6 files changed, 67 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 8eb3118fb8ad..9ac5367d5d99 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -691,7 +691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { BindingMode(def_br, Mutability::Mut) } else { - // `mut` resets binding mode on edition <= 2021 + // `mut` resets the binding mode on edition <= 2021 *self .typeck_results .borrow_mut() @@ -702,7 +702,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => user_bind_annot, + BindingMode(ByRef::Yes(_), _) => { + if matches!(def_br, ByRef::Yes(_)) { + // `ref`/`ref mut` overrides the binding mode on edition <= 2021 + *self + .typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .entry(pat_info.top_info.hir_id) + .or_default() |= pat.span.at_least_rust_2024(); + } + user_bind_annot + } }; if bm.0 == ByRef::Yes(Mutability::Mut) diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 63c84ae5b997..a0fc34826a2f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -30,10 +30,12 @@ fn main() { //~^ ERROR: the semantics of this pattern will change in edition 2024 assert_type_eq(x, 0u8); - let Foo(ref x) = &Foo(0); + let &Foo(ref x) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 assert_type_eq(x, &0u8); - let Foo(ref x) = &mut Foo(0); + let &mut Foo(ref x) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 assert_type_eq(x, &0u8); let &Foo(x) = &Foo(0); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index f2a83c1266bf..6fdea065dc0f 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -31,9 +31,11 @@ fn main() { assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 assert_type_eq(x, &0u8); let &Foo(x) = &Foo(0); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 5e42e03d6685..f429b96010d7 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -21,7 +21,23 @@ LL | let Foo(mut x) = &mut Foo(0); | help: desugar the match ergonomics: `&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:51:9 + --> $DIR/migration_lint.rs:33:9 + | +LL | let Foo(ref x) = &Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:37:9 + | +LL | let Foo(ref x) = &mut Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/migration_lint.rs:53:9 | LL | let Foo(&x) = &Foo(&0); | -^^^^^^ @@ -29,7 +45,7 @@ LL | let Foo(&x) = &Foo(&0); | help: desugar the match ergonomics: `&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:55:9 + --> $DIR/migration_lint.rs:57:9 | LL | let Foo(&mut x) = &Foo(&mut 0); | -^^^^^^^^^^ @@ -37,7 +53,7 @@ LL | let Foo(&mut x) = &Foo(&mut 0); | help: desugar the match ergonomics: `&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:59:9 + --> $DIR/migration_lint.rs:61:9 | LL | let Foo(&x) = &mut Foo(&0); | -^^^^^^ @@ -45,7 +61,7 @@ LL | let Foo(&x) = &mut Foo(&0); | help: desugar the match ergonomics: `&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:63:9 + --> $DIR/migration_lint.rs:65:9 | LL | let Foo(&mut x) = &mut Foo(&mut 0); | -^^^^^^^^^^ @@ -53,7 +69,7 @@ LL | let Foo(&mut x) = &mut Foo(&mut 0); | help: desugar the match ergonomics: `&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:71:12 + --> $DIR/migration_lint.rs:73:12 | LL | if let Some(&x) = &&&&&Some(&0u8) { | -^^^^^^^ @@ -61,7 +77,7 @@ LL | if let Some(&x) = &&&&&Some(&0u8) { | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:76:12 + --> $DIR/migration_lint.rs:78:12 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | -^^^^^^^^^^^ @@ -69,7 +85,7 @@ LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | help: desugar the match ergonomics: `&&&&&` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:81:12 + --> $DIR/migration_lint.rs:83:12 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { | -^^^^^^^ @@ -77,7 +93,7 @@ LL | if let Some(&x) = &&&&&mut Some(&0u8) { | help: desugar the match ergonomics: `&&&&&mut` error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:86:12 + --> $DIR/migration_lint.rs:88:12 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -88,7 +104,7 @@ LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some | ++++ ++++ +++++++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:97:9 + --> $DIR/migration_lint.rs:99:9 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^ @@ -99,7 +115,7 @@ LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; | + +++ +++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:102:9 + --> $DIR/migration_lint.rs:104:9 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +126,7 @@ LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | + +++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:108:12 + --> $DIR/migration_lint.rs:110:12 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,12 +137,12 @@ LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = | + + + +++ error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/migration_lint.rs:120:9 + --> $DIR/migration_lint.rs:122:9 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | help: desugar the match ergonomics: `&` -error: aborting due to 14 previous errors +error: aborting due to 16 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index 283666fdf4ca..c5d2199852ba 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -34,8 +34,8 @@ test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode -test_pat_on_type![(ref x,): &(T,)]; -test_pat_on_type![(ref mut x,): &mut (T,)]; +test_pat_on_type![(ref x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode +test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR patterns are not allowed to reset the default binding mode fn get() -> X { unimplemented!() diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 22247847def2..8f189e1cf079 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -131,6 +131,22 @@ LL | test_pat_on_type![(mut x,): &(T,)]; | | | help: desugar the match ergonomics: `&` +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:37:19 + | +LL | test_pat_on_type![(ref x,): &(T,)]; + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + +error: patterns are not allowed to reset the default binding mode in rust 2024 + --> $DIR/min_match_ergonomics_fail.rs:38:19 + | +LL | test_pat_on_type![(ref mut x,): &mut (T,)]; + | -^^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + error: patterns are not allowed to reset the default binding mode in rust 2024 --> $DIR/min_match_ergonomics_fail.rs:47:9 | @@ -139,6 +155,6 @@ LL | (&x,) => x, | | | help: desugar the match ergonomics: `&` -error: aborting due to 11 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0308`. From 4aaada42d0b59c3294908f9996277c60d9e13917 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 7 Oct 2024 23:47:21 +0200 Subject: [PATCH 016/118] Stabilize `min_match_ergonomics_2024` --- compiler/rustc_feature/src/unstable.rs | 3 - compiler/rustc_lint_defs/src/builtin.rs | 7 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 - .../migration_lint.fixed | 17 ++++- .../migration_lint.rs | 17 ++++- .../migration_lint.stderr | 70 +++++++++++++++---- .../min_match_ergonomics_fail.rs | 3 - .../min_match_ergonomics_fail.stderr | 28 ++++---- .../min_match_ergonomics_success.rs | 2 - 10 files changed, 104 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 5fff81d3e1cd..fa3a7049f4a0 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -516,9 +516,6 @@ declare_features! ( (unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)), /// Allows `#[marker]` on certain traits allowing overlapping implementations. (unstable, marker_trait_attr, "1.30.0", Some(29864)), - /// A very restricted form of match ergonomics used over the 2024 edition transition to give - /// more time for T-lang to decide the final form of RFC3627. - (incomplete, min_match_ergonomics_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// A minimal, sound subset of specialization intended to be used by the /// standard library until the soundness issues with specialization /// are fixed. diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 06e63bd73411..b73ceb91c400 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1650,7 +1650,6 @@ declare_lint! { /// ### Example /// /// ```rust,edition2021 - /// #![feature(min_match_ergonomics_2024)] /// #![warn(rust_2024_incompatible_pat)] /// /// if let Some(&a) = &Some(&0u8) { @@ -1671,12 +1670,10 @@ declare_lint! { pub RUST_2024_INCOMPATIBLE_PAT, Allow, "detects patterns whose meaning will change in Rust 2024", - @feature_gate = min_match_ergonomics_2024; - // FIXME uncomment below upon stabilization - /*@future_incompatible = FutureIncompatibleInfo { + @future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), reference: "123076", - };*/ + }; } declare_lint! { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 90355d7fce69..bb02ee37733c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -57,7 +57,7 @@ pub(super) fn pat_from_hir<'a, 'tcx>( let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(sugg) = pcx.rust_2024_migration_suggestion { - if tcx.features().min_match_ergonomics_2024 && sugg.is_hard_error { + if sugg.is_hard_error { let mut err = tcx.dcx().struct_span_err( pat.span, "patterns are not allowed to reset the default binding mode in rust 2024", diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 81ae66ccf680..402232a1720b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1218,7 +1218,6 @@ symbols! { min_const_generics, min_const_unsafe_fn, min_exhaustive_patterns, - min_match_ergonomics_2024, min_specialization, min_type_alias_impl_trait, minnumf128, diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index a0fc34826a2f..90c35b5a6972 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -2,7 +2,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ aux-build:migration_lint_macros.rs -#![feature(mut_ref, min_match_ergonomics_2024)] +#![feature(mut_ref)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] @@ -24,18 +24,22 @@ fn main() { let &Foo(mut x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(mut x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(ref x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &mut Foo(ref x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &Foo(x) = &Foo(0); @@ -52,18 +56,22 @@ fn main() { let &Foo(&x) = &Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(&mut x) = &Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&x) = &mut Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&mut x) = &mut Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); if let Some(x) = &&&&&Some(&0u8) { @@ -72,21 +80,25 @@ fn main() { if let &&&&&Some(&x) = &&&&&Some(&0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -98,17 +110,20 @@ fn main() { let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { assert_type_eq(a, &0u32); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 6fdea065dc0f..04d547f30186 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -2,7 +2,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ aux-build:migration_lint_macros.rs -#![feature(mut_ref, min_match_ergonomics_2024)] +#![feature(mut_ref)] #![allow(incomplete_features, unused)] #![deny(rust_2024_incompatible_pat)] @@ -24,18 +24,22 @@ fn main() { let Foo(mut x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(mut x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &Foo(x) = &Foo(0); @@ -52,18 +56,22 @@ fn main() { let Foo(&x) = &Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&x) = &mut Foo(&0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &mut Foo(&mut 0); //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); if let Some(x) = &&&&&Some(&0u8) { @@ -72,21 +80,25 @@ fn main() { if let Some(&x) = &&&&&Some(&0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut x) = &&&&&Some(&mut 0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&x) = &&&&&mut Some(&0u8) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -98,17 +110,20 @@ fn main() { let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { assert_type_eq(a, &0u32); diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index f429b96010d7..4881748f71ad 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -6,6 +6,8 @@ LL | let Foo(mut x) = &Foo(0); | | | help: desugar the match ergonomics: `&` | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 note: the lint level is defined here --> $DIR/migration_lint.rs:7:9 | @@ -13,131 +15,169 @@ LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:29:9 + --> $DIR/migration_lint.rs:30:9 | LL | let Foo(mut x) = &mut Foo(0); | -^^^^^^^^^ | | | help: desugar the match ergonomics: `&mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:33:9 + --> $DIR/migration_lint.rs:35:9 | LL | let Foo(ref x) = &Foo(0); | -^^^^^^^^^ | | | help: desugar the match ergonomics: `&` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:37:9 + --> $DIR/migration_lint.rs:40:9 | LL | let Foo(ref x) = &mut Foo(0); | -^^^^^^^^^ | | | help: desugar the match ergonomics: `&mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:53:9 + --> $DIR/migration_lint.rs:57:9 | LL | let Foo(&x) = &Foo(&0); | -^^^^^^ | | | help: desugar the match ergonomics: `&` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:57:9 + --> $DIR/migration_lint.rs:62:9 | LL | let Foo(&mut x) = &Foo(&mut 0); | -^^^^^^^^^^ | | | help: desugar the match ergonomics: `&` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:61:9 + --> $DIR/migration_lint.rs:67:9 | LL | let Foo(&x) = &mut Foo(&0); | -^^^^^^ | | | help: desugar the match ergonomics: `&mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:65:9 + --> $DIR/migration_lint.rs:72:9 | LL | let Foo(&mut x) = &mut Foo(&mut 0); | -^^^^^^^^^^ | | | help: desugar the match ergonomics: `&mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:73:12 + --> $DIR/migration_lint.rs:81:12 | LL | if let Some(&x) = &&&&&Some(&0u8) { | -^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:78:12 + --> $DIR/migration_lint.rs:87:12 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { | -^^^^^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:83:12 + --> $DIR/migration_lint.rs:93:12 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { | -^^^^^^^ | | | help: desugar the match ergonomics: `&&&&&mut` + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:88:12 + --> $DIR/migration_lint.rs:99:12 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 help: desugar the match ergonomics | LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ++++ ++++ +++++++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:99:9 + --> $DIR/migration_lint.rs:111:9 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 help: desugar the match ergonomics | LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; | + +++ +++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:104:9 + --> $DIR/migration_lint.rs:117:9 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 help: desugar the match ergonomics | LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | + +++ error: the semantics of this pattern will change in edition 2024 - --> $DIR/migration_lint.rs:110:12 + --> $DIR/migration_lint.rs:124:12 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 help: desugar the match ergonomics | LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = | + + + +++ error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/migration_lint.rs:122:9 + --> $DIR/migration_lint.rs:137:9 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index c5d2199852ba..a822c90ab6e5 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -1,9 +1,6 @@ //@ check-fail //@ edition: 2024 //@ compile-flags: -Zunstable-options -// gate-test-min_match_ergonomics_2024 -#![feature(min_match_ergonomics_2024)] -#![allow(incomplete_features)] #![deny(rust_2024_incompatible_pat)] fn main() {} diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 8f189e1cf079..ca34ad8d0ece 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:27:20 + --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(T,)]; | ^^ ----- expected due to this @@ -15,7 +15,7 @@ LL + test_pat_on_type![(x,): &(T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:29:20 + --> $DIR/min_match_ergonomics_fail.rs:26:20 | LL | test_pat_on_type![(&x,): &(&mut T,)]; | ^^ ---------- expected due to this @@ -31,7 +31,7 @@ LL + test_pat_on_type![(x,): &(&mut T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:30:20 + --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&T,)]; | ^^^^^^ ------ expected due to this @@ -41,7 +41,7 @@ LL | test_pat_on_type![(&mut x,): &(&T,)]; = note: expected reference `&T` found mutable reference `&mut _` note: to declare a mutable binding use: `mut x` - --> $DIR/min_match_ergonomics_fail.rs:30:20 + --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&T,)]; | ^^^^^^ @@ -52,7 +52,7 @@ LL + test_pat_on_type![(x,): &(&T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:32:20 + --> $DIR/min_match_ergonomics_fail.rs:29:20 | LL | test_pat_on_type![(&x,): &&mut &(T,)]; | ^^ ----------- expected due to this @@ -68,7 +68,7 @@ LL + test_pat_on_type![(x,): &&mut &(T,)]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:33:29 + --> $DIR/min_match_ergonomics_fail.rs:30:29 | LL | test_pat_on_type![Foo { f: (&x,) }: Foo]; | ^^ --- expected due to this @@ -84,7 +84,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: Foo]; | error[E0308]: mismatched types - --> $DIR/min_match_ergonomics_fail.rs:34:29 + --> $DIR/min_match_ergonomics_fail.rs:31:29 | LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; | ^^ -------- expected due to this @@ -100,7 +100,7 @@ LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:28:19 + --> $DIR/min_match_ergonomics_fail.rs:25:19 | LL | test_pat_on_type![(&x,): &(&T,)]; | -^^^^ @@ -108,7 +108,7 @@ LL | test_pat_on_type![(&x,): &(&T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:31:19 + --> $DIR/min_match_ergonomics_fail.rs:28:19 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | -^^^^^^^^ @@ -116,7 +116,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:35:19 + --> $DIR/min_match_ergonomics_fail.rs:32:19 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | -^^^^^^^^^^^^^^^ @@ -124,7 +124,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:36:19 + --> $DIR/min_match_ergonomics_fail.rs:33:19 | LL | test_pat_on_type![(mut x,): &(T,)]; | -^^^^^^^ @@ -132,7 +132,7 @@ LL | test_pat_on_type![(mut x,): &(T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:37:19 + --> $DIR/min_match_ergonomics_fail.rs:34:19 | LL | test_pat_on_type![(ref x,): &(T,)]; | -^^^^^^^ @@ -140,7 +140,7 @@ LL | test_pat_on_type![(ref x,): &(T,)]; | help: desugar the match ergonomics: `&` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:38:19 + --> $DIR/min_match_ergonomics_fail.rs:35:19 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | -^^^^^^^^^^^ @@ -148,7 +148,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | help: desugar the match ergonomics: `&mut` error: patterns are not allowed to reset the default binding mode in rust 2024 - --> $DIR/min_match_ergonomics_fail.rs:47:9 + --> $DIR/min_match_ergonomics_fail.rs:44:9 | LL | (&x,) => x, | -^^^^ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs index 8dbbd7cfbb0c..0fb448afca9c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_success.rs @@ -1,6 +1,4 @@ -//@ revisions: normal min_match_ergonomics //@ check-pass -#![cfg_attr(min_match_ergonomics, feature(min_match_ergonomics_2024))] #![allow(incomplete_features)] fn main() {} From 2ef0a8fdfd5142e8a524f4dc9fff8c65d0bd7cc2 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 8 Oct 2024 00:14:35 +0200 Subject: [PATCH 017/118] Change error message --- compiler/rustc_mir_build/messages.ftl | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 7 ++-- .../migration_lint.fixed | 30 ++++++++--------- .../migration_lint.rs | 30 ++++++++--------- .../migration_lint.stderr | 32 +++++++++---------- .../min_match_ergonomics_fail.stderr | 14 ++++---- 6 files changed, 57 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 1c4e9fd11cbd..55149570dbc4 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future -mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024 +mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024 mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .attributes = no other attributes may be applied diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index bb02ee37733c..16b7cac4e4d5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -25,6 +25,7 @@ use tracing::{debug, instrument}; pub(crate) use self::check_match::check_match; use crate::errors::*; +use crate::fluent_generated as fluent; use crate::thir::util::UserAnnotatedTyHelpers; struct PatCtxt<'a, 'tcx> { @@ -58,10 +59,8 @@ pub(super) fn pat_from_hir<'a, 'tcx>( debug!("pat_from_hir({:?}) = {:?}", pat, result); if let Some(sugg) = pcx.rust_2024_migration_suggestion { if sugg.is_hard_error { - let mut err = tcx.dcx().struct_span_err( - pat.span, - "patterns are not allowed to reset the default binding mode in rust 2024", - ); + let mut err = + tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat); err.subdiagnostic(sugg); err.emit(); } else { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index 90c35b5a6972..086671e69cba 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let &Foo(mut x) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(mut x) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(ref x) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &mut Foo(ref x) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); @@ -55,22 +55,22 @@ fn main() { assert_type_eq(x, &0u8); let &Foo(&x) = &Foo(&0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&x) = &mut Foo(&0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); @@ -79,25 +79,25 @@ fn main() { } if let &&&&&Some(&x) = &&&&&Some(&0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -109,20 +109,20 @@ fn main() { } let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 04d547f30186..acceafdb7ec0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let Foo(mut x) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(mut x) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); @@ -55,22 +55,22 @@ fn main() { assert_type_eq(x, &0u8); let Foo(&x) = &Foo(&0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&x) = &mut Foo(&0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); @@ -79,25 +79,25 @@ fn main() { } if let Some(&x) = &&&&&Some(&0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -109,20 +109,20 @@ fn main() { } let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - //~^ ERROR: the semantics of this pattern will change in edition 2024 + //~^ ERROR: patterns are not allowed to reset the default binding mode //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 4881748f71ad..1c9a469e6ee0 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,4 +1,4 @@ -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:25:9 | LL | let Foo(mut x) = &Foo(0); @@ -14,7 +14,7 @@ note: the lint level is defined here LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:30:9 | LL | let Foo(mut x) = &mut Foo(0); @@ -25,7 +25,7 @@ LL | let Foo(mut x) = &mut Foo(0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:35:9 | LL | let Foo(ref x) = &Foo(0); @@ -36,7 +36,7 @@ LL | let Foo(ref x) = &Foo(0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:40:9 | LL | let Foo(ref x) = &mut Foo(0); @@ -47,7 +47,7 @@ LL | let Foo(ref x) = &mut Foo(0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:57:9 | LL | let Foo(&x) = &Foo(&0); @@ -58,7 +58,7 @@ LL | let Foo(&x) = &Foo(&0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:62:9 | LL | let Foo(&mut x) = &Foo(&mut 0); @@ -69,7 +69,7 @@ LL | let Foo(&mut x) = &Foo(&mut 0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:67:9 | LL | let Foo(&x) = &mut Foo(&0); @@ -80,7 +80,7 @@ LL | let Foo(&x) = &mut Foo(&0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:72:9 | LL | let Foo(&mut x) = &mut Foo(&mut 0); @@ -91,7 +91,7 @@ LL | let Foo(&mut x) = &mut Foo(&mut 0); = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:81:12 | LL | if let Some(&x) = &&&&&Some(&0u8) { @@ -102,7 +102,7 @@ LL | if let Some(&x) = &&&&&Some(&0u8) { = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:87:12 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { @@ -113,7 +113,7 @@ LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:93:12 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { @@ -124,7 +124,7 @@ LL | if let Some(&x) = &&&&&mut Some(&0u8) { = warning: this changes meaning in Rust 2024 = note: for more information, see 123076 -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:99:12 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { @@ -137,7 +137,7 @@ help: desugar the match ergonomics LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ++++ ++++ +++++++ -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:111:9 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; @@ -150,7 +150,7 @@ help: desugar the match ergonomics LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; | + +++ +++ -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:117:9 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; @@ -163,7 +163,7 @@ help: desugar the match ergonomics LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | + +++ -error: the semantics of this pattern will change in edition 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:124:12 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = @@ -176,7 +176,7 @@ help: desugar the match ergonomics LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = | + + + +++ -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/migration_lint.rs:137:9 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index ca34ad8d0ece..33e4f0021b7b 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -99,7 +99,7 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:25:19 | LL | test_pat_on_type![(&x,): &(&T,)]; @@ -107,7 +107,7 @@ LL | test_pat_on_type![(&x,): &(&T,)]; | | | help: desugar the match ergonomics: `&` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:28:19 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; @@ -115,7 +115,7 @@ LL | test_pat_on_type![(&mut x,): &(&mut T,)]; | | | help: desugar the match ergonomics: `&` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:32:19 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; @@ -123,7 +123,7 @@ LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; | | | help: desugar the match ergonomics: `&` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:33:19 | LL | test_pat_on_type![(mut x,): &(T,)]; @@ -131,7 +131,7 @@ LL | test_pat_on_type![(mut x,): &(T,)]; | | | help: desugar the match ergonomics: `&` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:34:19 | LL | test_pat_on_type![(ref x,): &(T,)]; @@ -139,7 +139,7 @@ LL | test_pat_on_type![(ref x,): &(T,)]; | | | help: desugar the match ergonomics: `&` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:35:19 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; @@ -147,7 +147,7 @@ LL | test_pat_on_type![(ref mut x,): &mut (T,)]; | | | help: desugar the match ergonomics: `&mut` -error: patterns are not allowed to reset the default binding mode in rust 2024 +error: patterns are not allowed to reset the default binding mode in edition 2024 --> $DIR/min_match_ergonomics_fail.rs:44:9 | LL | (&x,) => x, From 5db54bee68a0328cb49cef690be53c15d56cb857 Mon Sep 17 00:00:00 2001 From: Noa Date: Thu, 22 Aug 2024 14:42:46 -0500 Subject: [PATCH 018/118] Stabilize Pin::as_deref_mut --- library/core/src/pin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 9c13662e08e8..fac789dbd99f 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1422,7 +1422,7 @@ impl Pin { /// move in the future, and this method does not enable the pointee to move. "Malicious" /// implementations of `Ptr::DerefMut` are likewise ruled out by the contract of /// `Pin::new_unchecked`. - #[unstable(feature = "pin_deref_mut", issue = "86918")] + #[stable(feature = "pin_deref_mut", since = "CURRENT_RUSTC_VERSION")] #[must_use = "`self` will be dropped if the result is not used"] #[inline(always)] pub fn as_deref_mut(self: Pin<&mut Pin>) -> Pin<&mut Ptr::Target> { From 0c41c3414c0e89ccb19310a4ec423ac83a48f039 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Mon, 7 Oct 2024 19:34:13 -0400 Subject: [PATCH 019/118] Allow zero-size reads/writes on null pointers --- library/core/src/intrinsics.rs | 19 ++++++++++++------- library/core/src/ptr/mod.rs | 21 +++++++++++++-------- library/core/src/slice/raw.rs | 4 ++-- library/core/src/ub_checks.rs | 4 ++-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index d7a2f1909cab..d76b7ca66cca 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -64,6 +64,7 @@ #![allow(missing_docs)] use crate::marker::{DiscriminantKind, Tuple}; +use crate::mem::SizedTypeProperties; use crate::{ptr, ub_checks}; pub mod mir; @@ -3311,10 +3312,12 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us size: usize = size_of::(), align: usize = align_of::(), count: usize = count, - ) => - ub_checks::is_aligned_and_not_null(src, align) - && ub_checks::is_aligned_and_not_null(dst, align) - && ub_checks::is_nonoverlapping(src, dst, size, count) + ) => { + let zero_size = count == 0 || size == 0; + ub_checks::is_aligned_and_not_null(src, align, zero_size) + && ub_checks::is_aligned_and_not_null(dst, align, zero_size) + && ub_checks::is_nonoverlapping(src, dst, size, count) + } ); // SAFETY: the safety contract for `copy_nonoverlapping` must be @@ -3412,9 +3415,10 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { src: *const () = src as *const (), dst: *mut () = dst as *mut (), align: usize = align_of::(), + zero_size: bool = T::IS_ZST || count == 0, ) => - ub_checks::is_aligned_and_not_null(src, align) - && ub_checks::is_aligned_and_not_null(dst, align) + ub_checks::is_aligned_and_not_null(src, align, zero_size) + && ub_checks::is_aligned_and_not_null(dst, align, zero_size) ); copy(src, dst, count) } @@ -3491,7 +3495,8 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { ( addr: *const () = dst as *const (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + zero_size: bool = T::IS_ZST || count == 0, + ) => ub_checks::is_aligned_and_not_null(addr, align, zero_size) ); write_bytes(dst, val, count) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 67f1b0cd16de..53ca5a7f198e 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -448,7 +448,7 @@ use crate::cmp::Ordering; use crate::marker::FnPtr; -use crate::mem::{self, MaybeUninit}; +use crate::mem::{self, MaybeUninit, SizedTypeProperties}; use crate::{fmt, hash, intrinsics, ub_checks}; mod alignment; @@ -1165,10 +1165,12 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { size: usize = size_of::(), align: usize = align_of::(), count: usize = count, - ) => - ub_checks::is_aligned_and_not_null(x, align) - && ub_checks::is_aligned_and_not_null(y, align) - && ub_checks::is_nonoverlapping(x, y, size, count) + ) => { + let zero_size = size == 0 || count == 0; + ub_checks::is_aligned_and_not_null(x, align, zero_size) + && ub_checks::is_aligned_and_not_null(y, align, zero_size) + && ub_checks::is_nonoverlapping(x, y, size, count) + } ); // Split up the slice into small power-of-two-sized chunks that LLVM is able @@ -1277,7 +1279,8 @@ pub const unsafe fn replace(dst: *mut T, src: T) -> T { ( addr: *const () = dst as *const (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + is_zst: bool = T::IS_ZST, + ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) ); mem::replace(&mut *dst, src) } @@ -1806,7 +1809,8 @@ pub unsafe fn read_volatile(src: *const T) -> T { ( addr: *const () = src as *const (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + is_zst: bool = T::IS_ZST, + ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) ); intrinsics::volatile_load(src) } @@ -1885,7 +1889,8 @@ pub unsafe fn write_volatile(dst: *mut T, src: T) { ( addr: *mut () = dst as *mut (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + is_zst: bool = T::IS_ZST, + ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) ); intrinsics::volatile_store(dst, src); } diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 84e916b9a84e..27bbadf7c89d 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -132,7 +132,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] align: usize = align_of::(), len: usize = len, ) => - ub_checks::is_aligned_and_not_null(data, align) + ub_checks::is_aligned_and_not_null(data, align, false) && ub_checks::is_valid_allocation_size(size, len) ); &*ptr::slice_from_raw_parts(data, len) @@ -187,7 +187,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m align: usize = align_of::(), len: usize = len, ) => - ub_checks::is_aligned_and_not_null(data, align) + ub_checks::is_aligned_and_not_null(data, align, false) && ub_checks::is_valid_allocation_size(size, len) ); &mut *ptr::slice_from_raw_parts_mut(data, len) diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index c1a8c34539e6..2ea30e77609f 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -116,8 +116,8 @@ pub(crate) const fn check_language_ub() -> bool { /// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the /// check is anyway not executed in `const`. #[inline] -pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize) -> bool { - !ptr.is_null() && ptr.is_aligned_to(align) +pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize, is_zst: bool) -> bool { + if is_zst { ptr.is_aligned_to(align) } else { !ptr.is_null() && ptr.is_aligned_to(align) } } #[inline] From 84dacc18829e24ec5d61087a233de68ef57dfabc Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Mon, 7 Oct 2024 19:34:25 -0400 Subject: [PATCH 020/118] Add more precondition check tests --- library/core/src/ascii/ascii_char.rs | 2 +- library/core/src/ptr/mod.rs | 6 +++-- tests/ui/precondition-checks/alignment.rs | 11 ++++++++ .../ascii-char-digit_unchecked.rs | 11 ++++++++ .../precondition-checks/assert_unchecked.rs | 9 +++++++ .../char-from_u32_unchecked.rs | 9 +++++++ .../copy-nonoverlapping.rs | 25 +++++++++++++++++++ tests/ui/precondition-checks/copy.rs | 23 +++++++++++++++++ tests/ui/precondition-checks/layout.rs | 15 +++++++++++ .../precondition-checks/misaligned-slice.rs | 10 -------- tests/ui/precondition-checks/nonnull.rs | 9 +++++++ .../nonzero-from_mut_unchecked.rs | 12 +++++++++ .../nonzero-new_unchecked.rs | 9 +++++++ tests/ui/precondition-checks/null-slice.rs | 10 -------- .../out-of-bounds-get-unchecked.rs | 11 -------- tests/ui/precondition-checks/read.rs | 18 +++++++++++++ tests/ui/precondition-checks/read_volatile.rs | 17 +++++++++++++ tests/ui/precondition-checks/replace.rs | 17 +++++++++++++ .../slice-from-raw-parts-mut.rs | 16 ++++++++++++ .../slice-from-raw-parts.rs | 15 +++++++++++ .../slice-get_unchecked.rs | 20 +++++++++++++++ .../slice-get_unchecked_mut.rs | 20 +++++++++++++++ .../slice-swap_unchecked.rs | 14 +++++++++++ .../precondition-checks/str-get_unchecked.rs | 18 +++++++++++++ .../str-get_unchecked_mut.rs | 19 ++++++++++++++ .../swap-nonoverlapping.rs | 25 +++++++++++++++++++ tests/ui/precondition-checks/unchecked_add.rs | 9 +++++++ tests/ui/precondition-checks/unchecked_mul.rs | 9 +++++++ tests/ui/precondition-checks/unchecked_shl.rs | 11 ++++++++ tests/ui/precondition-checks/unchecked_shr.rs | 11 ++++++++ tests/ui/precondition-checks/unchecked_sub.rs | 9 +++++++ .../unreachable_unchecked.rs | 9 +++++++ tests/ui/precondition-checks/write.rs | 18 +++++++++++++ tests/ui/precondition-checks/write_bytes.rs | 18 +++++++++++++ .../ui/precondition-checks/write_volatile.rs | 17 +++++++++++++ 35 files changed, 448 insertions(+), 34 deletions(-) create mode 100644 tests/ui/precondition-checks/alignment.rs create mode 100644 tests/ui/precondition-checks/ascii-char-digit_unchecked.rs create mode 100644 tests/ui/precondition-checks/assert_unchecked.rs create mode 100644 tests/ui/precondition-checks/char-from_u32_unchecked.rs create mode 100644 tests/ui/precondition-checks/copy-nonoverlapping.rs create mode 100644 tests/ui/precondition-checks/copy.rs create mode 100644 tests/ui/precondition-checks/layout.rs delete mode 100644 tests/ui/precondition-checks/misaligned-slice.rs create mode 100644 tests/ui/precondition-checks/nonnull.rs create mode 100644 tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs create mode 100644 tests/ui/precondition-checks/nonzero-new_unchecked.rs delete mode 100644 tests/ui/precondition-checks/null-slice.rs delete mode 100644 tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs create mode 100644 tests/ui/precondition-checks/read.rs create mode 100644 tests/ui/precondition-checks/read_volatile.rs create mode 100644 tests/ui/precondition-checks/replace.rs create mode 100644 tests/ui/precondition-checks/slice-from-raw-parts-mut.rs create mode 100644 tests/ui/precondition-checks/slice-from-raw-parts.rs create mode 100644 tests/ui/precondition-checks/slice-get_unchecked.rs create mode 100644 tests/ui/precondition-checks/slice-get_unchecked_mut.rs create mode 100644 tests/ui/precondition-checks/slice-swap_unchecked.rs create mode 100644 tests/ui/precondition-checks/str-get_unchecked.rs create mode 100644 tests/ui/precondition-checks/str-get_unchecked_mut.rs create mode 100644 tests/ui/precondition-checks/swap-nonoverlapping.rs create mode 100644 tests/ui/precondition-checks/unchecked_add.rs create mode 100644 tests/ui/precondition-checks/unchecked_mul.rs create mode 100644 tests/ui/precondition-checks/unchecked_shl.rs create mode 100644 tests/ui/precondition-checks/unchecked_shr.rs create mode 100644 tests/ui/precondition-checks/unchecked_sub.rs create mode 100644 tests/ui/precondition-checks/unreachable_unchecked.rs create mode 100644 tests/ui/precondition-checks/write.rs create mode 100644 tests/ui/precondition-checks/write_bytes.rs create mode 100644 tests/ui/precondition-checks/write_volatile.rs diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index ce09a0b444da..48de4f17b1b3 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -506,7 +506,7 @@ impl AsciiChar { pub const unsafe fn digit_unchecked(d: u8) -> Self { assert_unsafe_precondition!( check_language_ub, - "`AsciiChar::digit_unchecked` input cannot exceed 9.", + "`ascii::Char::digit_unchecked` input cannot exceed 9.", (d: u8 = d) => d < 10 ); diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 53ca5a7f198e..62160937083c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1432,7 +1432,8 @@ pub const unsafe fn read(src: *const T) -> T { ( addr: *const () = src as *const (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + is_zst: bool = T::IS_ZST, + ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) ); crate::intrinsics::read_via_copy(src) } @@ -1637,7 +1638,8 @@ pub const unsafe fn write(dst: *mut T, src: T) { ( addr: *mut () = dst as *mut (), align: usize = align_of::(), - ) => ub_checks::is_aligned_and_not_null(addr, align) + is_zst: bool = T::IS_ZST, + ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) ); intrinsics::write_via_move(dst, src) } diff --git a/tests/ui/precondition-checks/alignment.rs b/tests/ui/precondition-checks/alignment.rs new file mode 100644 index 000000000000..92400528fa07 --- /dev/null +++ b/tests/ui/precondition-checks/alignment.rs @@ -0,0 +1,11 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: Alignment::new_unchecked requires + +#![feature(ptr_alignment_type)] + +fn main() { + unsafe { + std::ptr::Alignment::new_unchecked(0); + } +} diff --git a/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs new file mode 100644 index 000000000000..30c6f79fb08f --- /dev/null +++ b/tests/ui/precondition-checks/ascii-char-digit_unchecked.rs @@ -0,0 +1,11 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: `ascii::Char::digit_unchecked` input cannot exceed 9 + +#![feature(ascii_char)] + +fn main() { + unsafe { + std::ascii::Char::digit_unchecked(b'a'); + } +} diff --git a/tests/ui/precondition-checks/assert_unchecked.rs b/tests/ui/precondition-checks/assert_unchecked.rs new file mode 100644 index 000000000000..22b2b4145502 --- /dev/null +++ b/tests/ui/precondition-checks/assert_unchecked.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: hint::assert_unchecked must never be called when the condition is false + +fn main() { + unsafe { + std::hint::assert_unchecked(false); + } +} diff --git a/tests/ui/precondition-checks/char-from_u32_unchecked.rs b/tests/ui/precondition-checks/char-from_u32_unchecked.rs new file mode 100644 index 000000000000..d950f20c7720 --- /dev/null +++ b/tests/ui/precondition-checks/char-from_u32_unchecked.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: invalid value for `char` + +fn main() { + unsafe { + char::from_u32_unchecked(0xD801); + } +} diff --git a/tests/ui/precondition-checks/copy-nonoverlapping.rs b/tests/ui/precondition-checks/copy-nonoverlapping.rs new file mode 100644 index 000000000000..81018e4bff3e --- /dev/null +++ b/tests/ui/precondition-checks/copy-nonoverlapping.rs @@ -0,0 +1,25 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::copy_nonoverlapping requires +//@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping + +use std::ptr; + +fn main() { + let src = [0u16; 3]; + let mut dst = [0u16; 3]; + let src = src.as_ptr(); + let dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null_src)] + ptr::copy_nonoverlapping(ptr::null(), dst, 1); + #[cfg(null_dst)] + ptr::copy_nonoverlapping(src, ptr::null_mut(), 1); + #[cfg(misaligned_src)] + ptr::copy_nonoverlapping(src.byte_add(1), dst, 1); + #[cfg(misaligned_dst)] + ptr::copy_nonoverlapping(src, dst.byte_add(1), 1); + #[cfg(overlapping)] + ptr::copy_nonoverlapping(dst, dst.add(1), 2); + } +} diff --git a/tests/ui/precondition-checks/copy.rs b/tests/ui/precondition-checks/copy.rs new file mode 100644 index 000000000000..694853f950ab --- /dev/null +++ b/tests/ui/precondition-checks/copy.rs @@ -0,0 +1,23 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::copy requires +//@ revisions: null_src null_dst misaligned_src misaligned_dst + +use std::ptr; + +fn main() { + let src = [0u16; 3]; + let mut dst = [0u16; 3]; + let src = src.as_ptr(); + let dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null_src)] + ptr::copy(ptr::null(), dst, 1); + #[cfg(null_dst)] + ptr::copy(src, ptr::null_mut(), 1); + #[cfg(misaligned_src)] + ptr::copy(src.byte_add(1), dst, 1); + #[cfg(misaligned_dst)] + ptr::copy(src, dst.byte_add(1), 1); + } +} diff --git a/tests/ui/precondition-checks/layout.rs b/tests/ui/precondition-checks/layout.rs new file mode 100644 index 000000000000..4fd1bbc4a994 --- /dev/null +++ b/tests/ui/precondition-checks/layout.rs @@ -0,0 +1,15 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: Layout::from_size_align_unchecked requires +//@ revisions: toolarge badalign +//@[toolarge] compile-flags: --cfg toolarge +//@[badalign] compile-flags: --cfg badalign + +fn main() { + unsafe { + #[cfg(toolarge)] + std::alloc::Layout::from_size_align_unchecked(isize::MAX as usize, 2); + #[cfg(badalign)] + std::alloc::Layout::from_size_align_unchecked(1, 3); + } +} diff --git a/tests/ui/precondition-checks/misaligned-slice.rs b/tests/ui/precondition-checks/misaligned-slice.rs deleted file mode 100644 index 2963a0b5e631..000000000000 --- a/tests/ui/precondition-checks/misaligned-slice.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-fail -//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts -//@ ignore-debug - -fn main() { - unsafe { - let _s: &[u64] = std::slice::from_raw_parts(1usize as *const u64, 0); - } -} diff --git a/tests/ui/precondition-checks/nonnull.rs b/tests/ui/precondition-checks/nonnull.rs new file mode 100644 index 000000000000..6b8edd4e5825 --- /dev/null +++ b/tests/ui/precondition-checks/nonnull.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: NonNull::new_unchecked requires + +fn main() { + unsafe { + std::ptr::NonNull::new_unchecked(std::ptr::null_mut::()); + } +} diff --git a/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs new file mode 100644 index 000000000000..46ce7dc356fe --- /dev/null +++ b/tests/ui/precondition-checks/nonzero-from_mut_unchecked.rs @@ -0,0 +1,12 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: NonZero::from_mut_unchecked requires + +#![feature(nonzero_from_mut)] + +fn main() { + unsafe { + let mut num = 0u8; + std::num::NonZeroU8::from_mut_unchecked(&mut num); + } +} diff --git a/tests/ui/precondition-checks/nonzero-new_unchecked.rs b/tests/ui/precondition-checks/nonzero-new_unchecked.rs new file mode 100644 index 000000000000..7827a42844fd --- /dev/null +++ b/tests/ui/precondition-checks/nonzero-new_unchecked.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: NonZero::new_unchecked requires + +fn main() { + unsafe { + std::num::NonZeroU8::new_unchecked(0); + } +} diff --git a/tests/ui/precondition-checks/null-slice.rs b/tests/ui/precondition-checks/null-slice.rs deleted file mode 100644 index 280960358b7b..000000000000 --- a/tests/ui/precondition-checks/null-slice.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-fail -//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts -//@ ignore-debug - -fn main() { - unsafe { - let _s: &[u8] = std::slice::from_raw_parts(std::ptr::null(), 0); - } -} diff --git a/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs b/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs deleted file mode 100644 index 011e92183fa4..000000000000 --- a/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-fail -//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes -//@ error-pattern: slice::get_unchecked requires -//@ ignore-debug - -fn main() { - unsafe { - let sli: &[u8] = &[0]; - sli.get_unchecked(1); - } -} diff --git a/tests/ui/precondition-checks/read.rs b/tests/ui/precondition-checks/read.rs new file mode 100644 index 000000000000..ab9921a0ceeb --- /dev/null +++ b/tests/ui/precondition-checks/read.rs @@ -0,0 +1,18 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::read requires +//@ revisions: null misaligned +//@ ignore-test + +use std::ptr; + +fn main() { + let src = [0u16; 2]; + let src = src.as_ptr(); + unsafe { + #[cfg(null)] + ptr::read(ptr::null::()); + #[cfg(misaligned)] + ptr::read(src.byte_add(1)); + } +} diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs new file mode 100644 index 000000000000..e14881d02903 --- /dev/null +++ b/tests/ui/precondition-checks/read_volatile.rs @@ -0,0 +1,17 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires +//@ revisions: null misaligned + +use std::ptr; + +fn main() { + let src = [0u16; 2]; + let src = src.as_ptr(); + unsafe { + #[cfg(null)] + ptr::read_volatile(ptr::null::()); + #[cfg(misaligned)] + ptr::read_volatile(src.byte_add(1)); + } +} diff --git a/tests/ui/precondition-checks/replace.rs b/tests/ui/precondition-checks/replace.rs new file mode 100644 index 000000000000..2808cee7b64b --- /dev/null +++ b/tests/ui/precondition-checks/replace.rs @@ -0,0 +1,17 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::replace requires +//@ revisions: null misaligned + +use std::ptr; + +fn main() { + let mut dst = [0u16; 2]; + let dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null)] + ptr::replace(ptr::null_mut::(), 1); + #[cfg(misaligned)] + ptr::replace(dst.byte_add(1), 1u16); + } +} diff --git a/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs new file mode 100644 index 000000000000..3801639e2551 --- /dev/null +++ b/tests/ui/precondition-checks/slice-from-raw-parts-mut.rs @@ -0,0 +1,16 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts_mut requires +//@ revisions: null misaligned toolarge + +fn main() { + unsafe { + #[cfg(null)] + let _s: &mut [u8] = std::slice::from_raw_parts_mut(std::ptr::null_mut(), 0); + #[cfg(misaligned)] + let _s: &mut [u16] = std::slice::from_raw_parts_mut(1usize as *mut u16, 0); + #[cfg(toolarge)] + let _s: &mut [u16] = + std::slice::from_raw_parts_mut(2usize as *mut u16, isize::MAX as usize); + } +} diff --git a/tests/ui/precondition-checks/slice-from-raw-parts.rs b/tests/ui/precondition-checks/slice-from-raw-parts.rs new file mode 100644 index 000000000000..a3690fa045eb --- /dev/null +++ b/tests/ui/precondition-checks/slice-from-raw-parts.rs @@ -0,0 +1,15 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: slice::from_raw_parts requires +//@ revisions: null misaligned toolarge + +fn main() { + unsafe { + #[cfg(null)] + let _s: &[u8] = std::slice::from_raw_parts(std::ptr::null(), 0); + #[cfg(misaligned)] + let _s: &[u16] = std::slice::from_raw_parts(1usize as *const u16, 0); + #[cfg(toolarge)] + let _s: &[u16] = std::slice::from_raw_parts(2usize as *const u16, isize::MAX as usize); + } +} diff --git a/tests/ui/precondition-checks/slice-get_unchecked.rs b/tests/ui/precondition-checks/slice-get_unchecked.rs new file mode 100644 index 000000000000..1d8188fb9531 --- /dev/null +++ b/tests/ui/precondition-checks/slice-get_unchecked.rs @@ -0,0 +1,20 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked requires +//@ revisions: usize range range_to range_from backwards_range + +fn main() { + unsafe { + let s = &[0]; + #[cfg(usize)] + s.get_unchecked(1); + #[cfg(range)] + s.get_unchecked(1..2); + #[cfg(range_to)] + s.get_unchecked(..2); + #[cfg(range_from)] + s.get_unchecked(2..); + #[cfg(backwards_range)] + s.get_unchecked(1..0); + } +} diff --git a/tests/ui/precondition-checks/slice-get_unchecked_mut.rs b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs new file mode 100644 index 000000000000..34c1454af438 --- /dev/null +++ b/tests/ui/precondition-checks/slice-get_unchecked_mut.rs @@ -0,0 +1,20 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: slice::get_unchecked_mut requires +//@ revisions: usize range range_to range_from backwards_range + +fn main() { + unsafe { + let mut s = &mut [0]; + #[cfg(usize)] + s.get_unchecked_mut(1); + #[cfg(range)] + s.get_unchecked_mut(1..2); + #[cfg(range_to)] + s.get_unchecked_mut(..2); + #[cfg(range_from)] + s.get_unchecked_mut(2..); + #[cfg(backwards_range)] + s.get_unchecked_mut(1..0); + } +} diff --git a/tests/ui/precondition-checks/slice-swap_unchecked.rs b/tests/ui/precondition-checks/slice-swap_unchecked.rs new file mode 100644 index 000000000000..227a49091ec2 --- /dev/null +++ b/tests/ui/precondition-checks/slice-swap_unchecked.rs @@ -0,0 +1,14 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: index out of bounds: the len is 2 but the index is 2 +//@ revisions: oob_a oob_b + +fn main() { + let mut pair = [0u8; 2]; + unsafe { + #[cfg(oob_a)] + pair.swap(0, 2); + #[cfg(oob_b)] + pair.swap(2, 0); + } +} diff --git a/tests/ui/precondition-checks/str-get_unchecked.rs b/tests/ui/precondition-checks/str-get_unchecked.rs new file mode 100644 index 000000000000..14d17f997ec9 --- /dev/null +++ b/tests/ui/precondition-checks/str-get_unchecked.rs @@ -0,0 +1,18 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked requires +//@ revisions: range range_to range_from backwards_range + +fn main() { + unsafe { + let s = "💅"; + #[cfg(range)] + s.get_unchecked(4..5); + #[cfg(range_to)] + s.get_unchecked(..5); + #[cfg(range_from)] + s.get_unchecked(5..); + #[cfg(backwards_range)] + s.get_unchecked(1..0); + } +} diff --git a/tests/ui/precondition-checks/str-get_unchecked_mut.rs b/tests/ui/precondition-checks/str-get_unchecked_mut.rs new file mode 100644 index 000000000000..ca1b16900555 --- /dev/null +++ b/tests/ui/precondition-checks/str-get_unchecked_mut.rs @@ -0,0 +1,19 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: str::get_unchecked_mut requires +//@ revisions: range range_to range_from backwards_range + +fn main() { + unsafe { + let mut s: String = "💅".chars().collect(); + let mut s: &mut str = &mut s; + #[cfg(range)] + s.get_unchecked_mut(4..5); + #[cfg(range_to)] + s.get_unchecked_mut(..5); + #[cfg(range_from)] + s.get_unchecked_mut(5..); + #[cfg(backwards_range)] + s.get_unchecked_mut(1..0); + } +} diff --git a/tests/ui/precondition-checks/swap-nonoverlapping.rs b/tests/ui/precondition-checks/swap-nonoverlapping.rs new file mode 100644 index 000000000000..52e4a3c870be --- /dev/null +++ b/tests/ui/precondition-checks/swap-nonoverlapping.rs @@ -0,0 +1,25 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::swap_nonoverlapping requires +//@ revisions: null_src null_dst misaligned_src misaligned_dst overlapping + +use std::ptr; + +fn main() { + let mut src = [0u16; 3]; + let mut dst = [0u16; 3]; + let src = src.as_mut_ptr(); + let dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null_src)] + ptr::swap_nonoverlapping(ptr::null_mut(), dst, 1); + #[cfg(null_dst)] + ptr::swap_nonoverlapping(src, ptr::null_mut(), 1); + #[cfg(misaligned_src)] + ptr::swap_nonoverlapping(src.byte_add(1), dst, 1); + #[cfg(misaligned_dst)] + ptr::swap_nonoverlapping(src, dst.byte_add(1), 1); + #[cfg(overlapping)] + ptr::swap_nonoverlapping(dst, dst.add(1), 2); + } +} diff --git a/tests/ui/precondition-checks/unchecked_add.rs b/tests/ui/precondition-checks/unchecked_add.rs new file mode 100644 index 000000000000..f44a6ea32ad8 --- /dev/null +++ b/tests/ui/precondition-checks/unchecked_add.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow + +fn main() { + unsafe { + 1u8.unchecked_add(u8::MAX); + } +} diff --git a/tests/ui/precondition-checks/unchecked_mul.rs b/tests/ui/precondition-checks/unchecked_mul.rs new file mode 100644 index 000000000000..66655dda136e --- /dev/null +++ b/tests/ui/precondition-checks/unchecked_mul.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_add cannot overflow + +fn main() { + unsafe { + 2u8.unchecked_add(u8::MAX); + } +} diff --git a/tests/ui/precondition-checks/unchecked_shl.rs b/tests/ui/precondition-checks/unchecked_shl.rs new file mode 100644 index 000000000000..1c96db0b1ec7 --- /dev/null +++ b/tests/ui/precondition-checks/unchecked_shl.rs @@ -0,0 +1,11 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shl cannot overflow + +#![feature(unchecked_shifts)] + +fn main() { + unsafe { + 0u8.unchecked_shl(u8::BITS); + } +} diff --git a/tests/ui/precondition-checks/unchecked_shr.rs b/tests/ui/precondition-checks/unchecked_shr.rs new file mode 100644 index 000000000000..4a6d9ffb1d35 --- /dev/null +++ b/tests/ui/precondition-checks/unchecked_shr.rs @@ -0,0 +1,11 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_shr cannot overflow + +#![feature(unchecked_shifts)] + +fn main() { + unsafe { + 0u8.unchecked_shr(u8::BITS); + } +} diff --git a/tests/ui/precondition-checks/unchecked_sub.rs b/tests/ui/precondition-checks/unchecked_sub.rs new file mode 100644 index 000000000000..545dde0e2780 --- /dev/null +++ b/tests/ui/precondition-checks/unchecked_sub.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: u8::unchecked_sub cannot overflow + +fn main() { + unsafe { + 0u8.unchecked_sub(1u8); + } +} diff --git a/tests/ui/precondition-checks/unreachable_unchecked.rs b/tests/ui/precondition-checks/unreachable_unchecked.rs new file mode 100644 index 000000000000..2435450c4b5a --- /dev/null +++ b/tests/ui/precondition-checks/unreachable_unchecked.rs @@ -0,0 +1,9 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached + +fn main() { + unsafe { + std::hint::unreachable_unchecked(); + } +} diff --git a/tests/ui/precondition-checks/write.rs b/tests/ui/precondition-checks/write.rs new file mode 100644 index 000000000000..f76e776fcf35 --- /dev/null +++ b/tests/ui/precondition-checks/write.rs @@ -0,0 +1,18 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::write requires +//@ revisions: null misaligned +//@ ignore-test + +use std::ptr; + +fn main() { + let mut dst = [0u16; 2]; + let mut dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null)] + ptr::write(ptr::null_mut::(), 1u8); + #[cfg(misaligned)] + ptr::write(dst.byte_add(1), 1u16); + } +} diff --git a/tests/ui/precondition-checks/write_bytes.rs b/tests/ui/precondition-checks/write_bytes.rs new file mode 100644 index 000000000000..3f64be9d1ee1 --- /dev/null +++ b/tests/ui/precondition-checks/write_bytes.rs @@ -0,0 +1,18 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::write requires +//@ revisions: null misaligned +//@ ignore-test + +use std::ptr; + +fn main() { + let mut dst = [0u16; 2]; + let mut dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null)] + ptr::write_bytes(ptr::null_mut::(), 1u8, 2); + #[cfg(misaligned)] + ptr::write_bytes(dst.byte_add(1), 1u8, 2); + } +} diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs new file mode 100644 index 000000000000..ac0b89b5ecf2 --- /dev/null +++ b/tests/ui/precondition-checks/write_volatile.rs @@ -0,0 +1,17 @@ +//@ run-fail +//@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes +//@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires +//@ revisions: null misaligned + +use std::ptr; + +fn main() { + let mut dst = [0u16; 2]; + let mut dst = dst.as_mut_ptr(); + unsafe { + #[cfg(null)] + ptr::write_volatile(ptr::null_mut::(), 1u8); + #[cfg(misaligned)] + ptr::write_volatile(dst.byte_add(1), 1u16); + } +} From aec09a43efed613ed12e32cef5d1bd94750e04eb Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 9 Oct 2024 18:34:33 -0400 Subject: [PATCH 021/118] Clean up is_aligned_and_not_null --- library/core/src/ub_checks.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index 2ea30e77609f..daaaf5a71953 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -109,15 +109,15 @@ pub(crate) const fn check_language_ub() -> bool { intrinsics::ub_checks() && const_eval_select((), comptime, runtime) } -/// Checks whether `ptr` is properly aligned with respect to -/// `align_of::()`. +/// Checks whether `ptr` is properly aligned with respect to the given alignment, and +/// if `is_zst == false`, that `ptr` is not null. /// /// In `const` this is approximate and can fail spuriously. It is primarily intended /// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the /// check is anyway not executed in `const`. #[inline] pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize, is_zst: bool) -> bool { - if is_zst { ptr.is_aligned_to(align) } else { !ptr.is_null() && ptr.is_aligned_to(align) } + ptr.is_aligned_to(align) && (is_zst || !ptr.is_null()) } #[inline] From a3606d7ee3dd9d910578a81b2992e61521b1ce21 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 9 Oct 2024 18:46:06 -0400 Subject: [PATCH 022/118] Add a test for zero-sized writes through null --- .../ui/precondition-checks/zero-size-null.rs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/ui/precondition-checks/zero-size-null.rs diff --git a/tests/ui/precondition-checks/zero-size-null.rs b/tests/ui/precondition-checks/zero-size-null.rs new file mode 100644 index 000000000000..43a81175f944 --- /dev/null +++ b/tests/ui/precondition-checks/zero-size-null.rs @@ -0,0 +1,21 @@ +// Test that none of the precondition checks panic on zero-sized reads or writes through null. + +//@ run-pass +//@ compile-flags: -Zmir-opt-level=0 -Copt-level=0 -Cdebug-assertions=yes + +use std::ptr; + +fn main() { + unsafe { + ptr::copy_nonoverlapping::(ptr::null(), ptr::null_mut(), 0); + ptr::copy_nonoverlapping::<()>(ptr::null(), ptr::null_mut(), 123); + ptr::copy::(ptr::null(), ptr::null_mut(), 0); + ptr::copy::<()>(ptr::null(), ptr::null_mut(), 123); + ptr::swap::<()>(ptr::null_mut(), ptr::null_mut()); + ptr::replace::<()>(ptr::null_mut(), ()); + ptr::read::<()>(ptr::null()); + ptr::write::<()>(ptr::null_mut(), ()); + ptr::read_volatile::<()>(ptr::null()); + ptr::write_volatile::<()>(ptr::null_mut(), ()); + } +} From 8a1462265f839607f96acea4bed183736598422d Mon Sep 17 00:00:00 2001 From: Joshua Wong Date: Wed, 9 Oct 2024 14:24:05 -0400 Subject: [PATCH 023/118] add initial tests for placement new changes --- tests/codegen/placement-new.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/codegen/placement-new.rs diff --git a/tests/codegen/placement-new.rs b/tests/codegen/placement-new.rs new file mode 100644 index 000000000000..68260a65a3f3 --- /dev/null +++ b/tests/codegen/placement-new.rs @@ -0,0 +1,27 @@ +//@ compile-flags: -O +#![crate_type = "lib"] + +// Test to check that types with "complex" destructors, but trivial `Default` impls +// are constructed directly into the allocation in `Box::default` and `Arc::default`. + +use std::sync::Arc; + +// CHECK-LABEL: @box_default_inplace +#[no_mangle] +pub fn box_default_inplace() -> Box<(String, String)> { + // CHECK: [[ALLOCA:%.*]] = alloca + // CHECK: [[BOX:%.*]] = {{.*}}call {{.*}}__rust_alloc( + // CHECK: call void @llvm.memcpy{{.*}}(ptr {{.*}}[[BOX]], ptr {{.*}}[[ALLOCA]] + // CHECK: ret ptr [[BOX]] + Box::default() +} + +// CHECK-LABEL: @arc_default_inplace +#[no_mangle] +pub fn arc_default_inplace() -> Arc<(String, String)> { + // CHECK: [[ALLOCA:%.*]] = alloca + // CHECK: [[ARC:%.*]] = {{.*}}call {{.*}}__rust_alloc( + // CHECK: call void @llvm.memcpy + // CHECK: ret ptr [[ARC]] + Arc::default() +} From dd0620b86721ae8cae86736443acd3f72ba6fc32 Mon Sep 17 00:00:00 2001 From: Joshua Wong Date: Wed, 9 Oct 2024 14:24:05 -0400 Subject: [PATCH 024/118] allocate before calling T::default in >::default() The `Box` impl currently calls `T::default()` before allocating the `Box`. Most `Default` impls are trivial, which should in theory allow LLVM to construct `T: Default` directly in the `Box` allocation when calling `>::default()`. However, the allocation may fail, which necessitates calling `T's` destructor if it has one. If the destructor is non-trivial, then LLVM has a hard time proving that it's sound to elide, which makes it construct `T` on the stack first, and then copy it into the allocation. Create an uninit `Box` first, and then write `T::default` into it, so that LLVM now only needs to prove that the `T::default` can't panic, which should be trivial for most `Default` impls. --- library/alloc/src/boxed.rs | 2 +- tests/codegen/placement-new.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 5f2072956835..3e791416820e 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1688,7 +1688,7 @@ impl Default for Box { /// Creates a `Box`, with the `Default` value for T. #[inline] fn default() -> Self { - Box::new(T::default()) + Box::write(Box::new_uninit(), T::default()) } } diff --git a/tests/codegen/placement-new.rs b/tests/codegen/placement-new.rs index 68260a65a3f3..d5c7969dd19b 100644 --- a/tests/codegen/placement-new.rs +++ b/tests/codegen/placement-new.rs @@ -9,9 +9,9 @@ use std::sync::Arc; // CHECK-LABEL: @box_default_inplace #[no_mangle] pub fn box_default_inplace() -> Box<(String, String)> { - // CHECK: [[ALLOCA:%.*]] = alloca + // CHECK-NOT: alloca // CHECK: [[BOX:%.*]] = {{.*}}call {{.*}}__rust_alloc( - // CHECK: call void @llvm.memcpy{{.*}}(ptr {{.*}}[[BOX]], ptr {{.*}}[[ALLOCA]] + // CHECK-NOT: call void @llvm.memcpy // CHECK: ret ptr [[BOX]] Box::default() } From 5e474f7d83fc931f355cfdadf394313e57290050 Mon Sep 17 00:00:00 2001 From: Joshua Wong Date: Wed, 9 Oct 2024 14:24:05 -0400 Subject: [PATCH 025/118] allocate before calling T::default in >::default() Same rationale as in the previous commit. --- library/alloc/src/lib.rs | 1 + library/alloc/src/sync.rs | 8 +++++++- tests/codegen/placement-new.rs | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index c60c0743c7e1..dcfe96be7551 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -104,6 +104,7 @@ #![feature(async_closure)] #![feature(async_fn_traits)] #![feature(async_iterator)] +#![feature(box_uninit_write)] #![feature(clone_to_uninit)] #![feature(coerce_unsized)] #![feature(const_align_of_val)] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 5d099a49854a..0038750d25dd 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3447,7 +3447,13 @@ impl Default for Arc { /// assert_eq!(*x, 0); /// ``` fn default() -> Arc { - Arc::new(Default::default()) + let x = Box::into_raw(Box::write(Box::new_uninit(), ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data: T::default(), + })); + // SAFETY: `Box::into_raw` consumes the `Box` and never returns null + unsafe { Self::from_inner(NonNull::new_unchecked(x)) } } } diff --git a/tests/codegen/placement-new.rs b/tests/codegen/placement-new.rs index d5c7969dd19b..edb25df5eb4d 100644 --- a/tests/codegen/placement-new.rs +++ b/tests/codegen/placement-new.rs @@ -19,9 +19,9 @@ pub fn box_default_inplace() -> Box<(String, String)> { // CHECK-LABEL: @arc_default_inplace #[no_mangle] pub fn arc_default_inplace() -> Arc<(String, String)> { - // CHECK: [[ALLOCA:%.*]] = alloca + // CHECK-NOT: alloca // CHECK: [[ARC:%.*]] = {{.*}}call {{.*}}__rust_alloc( - // CHECK: call void @llvm.memcpy + // CHECK-NOT: call void @llvm.memcpy // CHECK: ret ptr [[ARC]] Arc::default() } From 159e67d44646621f157f07b61f7d78f231c452c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Fri, 11 Oct 2024 00:14:17 +0200 Subject: [PATCH 026/118] rename RcBox to RcInner for consistency --- library/alloc/src/rc.rs | 138 +++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 67 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 0e2c35845e8f..e6f27f536399 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -282,19 +282,19 @@ mod tests; // would interfere with otherwise safe [into|from]_raw() of transmutable // inner types. #[repr(C)] -struct RcBox { +struct RcInner { strong: Cell, weak: Cell, value: T, } -/// Calculate layout for `RcBox` using the inner value's layout +/// Calculate layout for `RcInner` using the inner value's layout fn rcbox_layout_for_value_layout(layout: Layout) -> Layout { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression - // `&*(ptr as *const RcBox)`, but this created a misaligned + // `&*(ptr as *const RcInner)`, but this created a misaligned // reference (see #54908). - Layout::new::>().extend(layout).unwrap().0.pad_to_align() + Layout::new::>().extend(layout).unwrap().0.pad_to_align() } /// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference @@ -314,8 +314,8 @@ pub struct Rc< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { - ptr: NonNull>, - phantom: PhantomData>, + ptr: NonNull>, + phantom: PhantomData>, alloc: A, } @@ -343,37 +343,37 @@ impl, U: ?Sized> DispatchFromDyn> for Rc {} impl Rc { #[inline] - unsafe fn from_inner(ptr: NonNull>) -> Self { + unsafe fn from_inner(ptr: NonNull>) -> Self { unsafe { Self::from_inner_in(ptr, Global) } } #[inline] - unsafe fn from_ptr(ptr: *mut RcBox) -> Self { + unsafe fn from_ptr(ptr: *mut RcInner) -> Self { unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) } } } impl Rc { #[inline(always)] - fn inner(&self) -> &RcBox { + fn inner(&self) -> &RcInner { // This unsafety is ok because while this Rc is alive we're guaranteed // that the inner pointer is valid. unsafe { self.ptr.as_ref() } } #[inline] - fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { let this = mem::ManuallyDrop::new(this); (this.ptr, unsafe { ptr::read(&this.alloc) }) } #[inline] - unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { + unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { Self { ptr, phantom: PhantomData, alloc } } #[inline] - unsafe fn from_ptr_in(ptr: *mut RcBox, alloc: A) -> Self { + unsafe fn from_ptr_in(ptr: *mut RcInner, alloc: A) -> Self { unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } } } @@ -397,7 +397,7 @@ impl Rc { // if the weak pointer is stored inside the strong one. unsafe { Self::from_inner( - Box::leak(Box::new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })) + Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) .into(), ) } @@ -546,8 +546,12 @@ impl Rc { // if the weak pointer is stored inside the strong one. unsafe { Ok(Self::from_inner( - Box::leak(Box::try_new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })?) - .into(), + Box::leak(Box::try_new(RcInner { + strong: Cell::new(1), + weak: Cell::new(1), + value, + })?) + .into(), )) } } @@ -646,7 +650,7 @@ impl Rc { // That would make code size bigger. match Self::try_new_in(value, alloc) { Ok(m) => m, - Err(_) => handle_alloc_error(Layout::new::>()), + Err(_) => handle_alloc_error(Layout::new::>()), } } @@ -765,7 +769,7 @@ impl Rc { // Construct the inner in the "uninitialized" state with a single // weak reference. let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in( - RcBox { + RcInner { strong: Cell::new(0), weak: Cell::new(1), value: mem::MaybeUninit::::uninit(), @@ -773,7 +777,7 @@ impl Rc { alloc, )); let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); - let init_ptr: NonNull> = uninit_ptr.cast(); + let init_ptr: NonNull> = uninit_ptr.cast(); let weak = Weak { ptr: init_ptr, alloc: alloc }; @@ -826,7 +830,7 @@ impl Rc { // the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one. let (ptr, alloc) = Box::into_unique(Box::try_new_in( - RcBox { strong: Cell::new(1), weak: Cell::new(1), value }, + RcInner { strong: Cell::new(1), weak: Cell::new(1), value }, alloc, )?); Ok(unsafe { Self::from_inner_in(ptr.into(), alloc) }) @@ -1059,7 +1063,7 @@ impl Rc<[T]> { |layout| Global.allocate_zeroed(layout), |mem| { ptr::slice_from_raw_parts_mut(mem.cast::(), len) - as *mut RcBox<[mem::MaybeUninit]> + as *mut RcInner<[mem::MaybeUninit]> }, )) } @@ -1132,7 +1136,7 @@ impl Rc<[T], A> { |layout| alloc.allocate_zeroed(layout), |mem| { ptr::slice_from_raw_parts_mut(mem.cast::(), len) - as *mut RcBox<[mem::MaybeUninit]> + as *mut RcInner<[mem::MaybeUninit]> }, ), alloc, @@ -1437,7 +1441,7 @@ impl Rc { #[stable(feature = "weak_into_raw", since = "1.45.0")] #[rustc_never_returns_null_ptr] pub fn as_ptr(this: &Self) -> *const T { - let ptr: *mut RcBox = NonNull::as_ptr(this.ptr); + let ptr: *mut RcInner = NonNull::as_ptr(this.ptr); // SAFETY: This cannot go through Deref::deref or Rc::inner because // this is required to retain raw/mut provenance such that e.g. `get_mut` can @@ -1516,8 +1520,8 @@ impl Rc { pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { let offset = unsafe { data_offset(ptr) }; - // Reverse the offset to find the original RcBox. - let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcBox }; + // Reverse the offset to find the original RcInner. + let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcInner }; unsafe { Self::from_ptr_in(rc_ptr, alloc) } } @@ -2002,17 +2006,17 @@ impl Rc { } impl Rc { - /// Allocates an `RcBox` with sufficient space for + /// Allocates an `RcInner` with sufficient space for /// a possibly-unsized inner value where the value has the layout provided. /// /// The function `mem_to_rcbox` is called with the data pointer - /// and must return back a (potentially fat)-pointer for the `RcBox`. + /// and must return back a (potentially fat)-pointer for the `RcInner`. #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_layout( value_layout: Layout, allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, - ) -> *mut RcBox { + mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcInner, + ) -> *mut RcInner { let layout = rcbox_layout_for_value_layout(value_layout); unsafe { Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rcbox) @@ -2020,24 +2024,24 @@ impl Rc { } } - /// Allocates an `RcBox` with sufficient space for + /// Allocates an `RcInner` with sufficient space for /// a possibly-unsized inner value where the value has the layout provided, /// returning an error if allocation fails. /// /// The function `mem_to_rcbox` is called with the data pointer - /// and must return back a (potentially fat)-pointer for the `RcBox`. + /// and must return back a (potentially fat)-pointer for the `RcInner`. #[inline] unsafe fn try_allocate_for_layout( value_layout: Layout, allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox, - ) -> Result<*mut RcBox, AllocError> { + mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcInner, + ) -> Result<*mut RcInner, AllocError> { let layout = rcbox_layout_for_value_layout(value_layout); // Allocate for the layout. let ptr = allocate(layout)?; - // Initialize the RcBox + // Initialize the RcInner let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr()); unsafe { debug_assert_eq!(Layout::for_value_raw(inner), layout); @@ -2051,15 +2055,15 @@ impl Rc { } impl Rc { - /// Allocates an `RcBox` with sufficient space for an unsized inner value + /// Allocates an `RcInner` with sufficient space for an unsized inner value #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut RcBox { - // Allocate for the `RcBox` using the given value. + unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut RcInner { + // Allocate for the `RcInner` using the given value. unsafe { Rc::::allocate_for_layout( Layout::for_value_raw(ptr), |layout| alloc.allocate(layout), - |mem| mem.with_metadata_of(ptr as *const RcBox), + |mem| mem.with_metadata_of(ptr as *const RcInner), ) } } @@ -2088,14 +2092,14 @@ impl Rc { } impl Rc<[T]> { - /// Allocates an `RcBox<[T]>` with the given length. + /// Allocates an `RcInner<[T]>` with the given length. #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> { + unsafe fn allocate_for_slice(len: usize) -> *mut RcInner<[T]> { unsafe { Self::allocate_for_layout( Layout::array::(len).unwrap(), |layout| Global.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcBox<[T]>, + |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcInner<[T]>, ) } } @@ -2119,7 +2123,7 @@ impl Rc<[T]> { unsafe fn from_iter_exact(iter: impl Iterator, len: usize) -> Rc<[T]> { // Panic guard while cloning T elements. // In the event of a panic, elements that have been written - // into the new RcBox will be dropped, then the memory freed. + // into the new RcInner will be dropped, then the memory freed. struct Guard { mem: NonNull, elems: *mut T, @@ -2154,7 +2158,7 @@ impl Rc<[T]> { guard.n_elems += 1; } - // All clear. Forget the guard so it doesn't free the new RcBox. + // All clear. Forget the guard so it doesn't free the new RcInner. mem::forget(guard); Self::from_ptr(ptr) @@ -2163,15 +2167,15 @@ impl Rc<[T]> { } impl Rc<[T], A> { - /// Allocates an `RcBox<[T]>` with the given length. + /// Allocates an `RcInner<[T]>` with the given length. #[inline] #[cfg(not(no_global_oom_handling))] - unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcBox<[T]> { + unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcInner<[T]> { unsafe { Rc::<[T]>::allocate_for_layout( Layout::array::(len).unwrap(), |layout| alloc.allocate(layout), - |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcBox<[T]>, + |mem| ptr::slice_from_raw_parts_mut(mem.cast::(), len) as *mut RcInner<[T]>, ) } } @@ -2901,9 +2905,9 @@ pub struct Weak< // but it is not necessarily a valid pointer. // `Weak::new` sets this to `usize::MAX` so that it doesn’t need // to allocate space on the heap. That's not a value a real pointer - // will ever have because RcBox has alignment at least 2. + // will ever have because RcInner has alignment at least 2. // This is only possible when `T: Sized`; unsized `T` never dangle. - ptr: NonNull>, + ptr: NonNull>, alloc: A, } @@ -2939,7 +2943,7 @@ impl Weak { pub const fn new() -> Weak { Weak { ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) + NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) }, alloc: Global, } @@ -2966,7 +2970,7 @@ impl Weak { pub fn new_in(alloc: A) -> Weak { Weak { ptr: unsafe { - NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) + NonNull::new_unchecked(ptr::without_provenance_mut::>(usize::MAX)) }, alloc, } @@ -3070,11 +3074,11 @@ impl Weak { #[must_use] #[stable(feature = "rc_as_ptr", since = "1.45.0")] pub fn as_ptr(&self) -> *const T { - let ptr: *mut RcBox = NonNull::as_ptr(self.ptr); + let ptr: *mut RcInner = NonNull::as_ptr(self.ptr); if is_dangling(ptr) { // If the pointer is dangling, we return the sentinel directly. This cannot be - // a valid payload address, as the payload is at least as aligned as RcBox (usize). + // a valid payload address, as the payload is at least as aligned as RcInner (usize). ptr as *const T } else { // SAFETY: if is_dangling returns false, then the pointer is dereferenceable. @@ -3206,14 +3210,14 @@ impl Weak { let ptr = if is_dangling(ptr) { // This is a dangling Weak. - ptr as *mut RcBox + ptr as *mut RcInner } else { // Otherwise, we're guaranteed the pointer came from a nondangling Weak. // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T. let offset = unsafe { data_offset(ptr) }; - // Thus, we reverse the offset to get the whole RcBox. + // Thus, we reverse the offset to get the whole RcInner. // SAFETY: the pointer originated from a Weak, so this offset is safe. - unsafe { ptr.byte_sub(offset) as *mut RcBox } + unsafe { ptr.byte_sub(offset) as *mut RcInner } }; // SAFETY: we now have recovered the original Weak pointer, so can create the Weak. @@ -3288,7 +3292,7 @@ impl Weak { } } - /// Returns `None` when the pointer is dangling and there is no allocated `RcBox`, + /// Returns `None` when the pointer is dangling and there is no allocated `RcInner`, /// (i.e., when this `Weak` was created by `Weak::new`). #[inline] fn inner(&self) -> Option> { @@ -3522,7 +3526,7 @@ trait RcInnerPtr { } } -impl RcInnerPtr for RcBox { +impl RcInnerPtr for RcInner { #[inline(always)] fn weak_ref(&self) -> &Cell { &self.weak @@ -3563,15 +3567,15 @@ impl AsRef for Rc { #[stable(feature = "pin", since = "1.33.0")] impl Unpin for Rc {} -/// Gets the offset within an `RcBox` for the payload behind a pointer. +/// Gets the offset within an `RcInner` for the payload behind a pointer. /// /// # Safety /// /// The pointer must point to (and have valid metadata for) a previously /// valid instance of T, but the T is allowed to be dropped. unsafe fn data_offset(ptr: *const T) -> usize { - // Align the unsized value to the end of the RcBox. - // Because RcBox is repr(C), it will always be the last field in memory. + // Align the unsized value to the end of the RcInner. + // Because RcInner is repr(C), it will always be the last field in memory. // SAFETY: since the only unsized types possible are slices, trait objects, // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation @@ -3581,7 +3585,7 @@ unsafe fn data_offset(ptr: *const T) -> usize { #[inline] fn data_offset_align(align: usize) -> usize { - let layout = Layout::new::>(); + let layout = Layout::new::>(); layout.size() + layout.padding_needed_for(align) } @@ -3627,8 +3631,8 @@ pub struct UniqueRc< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { - ptr: NonNull>, - phantom: PhantomData>, + ptr: NonNull>, + phantom: PhantomData>, alloc: A, } @@ -3664,7 +3668,7 @@ impl UniqueRc { #[unstable(feature = "unique_rc_arc", issue = "112566")] pub fn new_in(value: T, alloc: A) -> Self { let (ptr, alloc) = Box::into_unique(Box::new_in( - RcBox { + RcInner { strong: Cell::new(0), // keep one weak reference so if all the weak pointers that are created are dropped // the UniqueRc still stays valid. @@ -3759,7 +3763,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc { } } -/// A unique owning pointer to a [`RcBox`] **that does not imply the contents are initialized,** +/// A unique owning pointer to a [`RcInner`] **that does not imply the contents are initialized,** /// but will deallocate it (without dropping the value) when dropped. /// /// This is a helper for [`Rc::make_mut()`] to ensure correct cleanup on panic. @@ -3767,21 +3771,21 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc { /// which `MaybeUninit` does not. #[cfg(not(no_global_oom_handling))] struct UniqueRcUninit { - ptr: NonNull>, + ptr: NonNull>, layout_for_value: Layout, alloc: Option, } #[cfg(not(no_global_oom_handling))] impl UniqueRcUninit { - /// Allocates a RcBox with layout suitable to contain `for_value` or a clone of it. + /// Allocates a RcInner with layout suitable to contain `for_value` or a clone of it. fn new(for_value: &T, alloc: A) -> UniqueRcUninit { let layout = Layout::for_value(for_value); let ptr = unsafe { Rc::allocate_for_layout( layout, |layout_for_rcbox| alloc.allocate(layout_for_rcbox), - |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const RcBox), + |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const RcInner), ) }; Self { ptr: NonNull::new(ptr).unwrap(), layout_for_value: layout, alloc: Some(alloc) } From 0a9c87b1f5d871a3f2cc44c274a7bc72a486e69d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Fri, 11 Oct 2024 00:56:56 +0200 Subject: [PATCH 027/118] rename RcBox in other places too --- compiler/rustc_codegen_ssa/src/mir/block.rs | 4 ++-- compiler/rustc_ty_utils/src/abi.rs | 6 +++--- library/alloc/src/sync.rs | 8 ++++---- library/core/src/cell.rs | 14 +++++++------- src/etc/lldb_providers.py | 4 ++-- src/etc/natvis/liballoc.natvis | 2 +- src/tools/miri/tests/fail/memleak_rc.stderr | 4 ++-- tests/debuginfo/strings-and-strs.rs | 3 +-- tests/ui/abi/compatibility.rs | 6 +++--- 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index be9a6d9a90ee..e3553dc03e10 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -992,10 +992,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match op.val { Pair(data_ptr, meta) => { // In the case of Rc, we need to explicitly pass a - // *mut RcBox with a Scalar (not ScalarPair) ABI. This is a hack + // *mut RcInner with a Scalar (not ScalarPair) ABI. This is a hack // that is understood elsewhere in the compiler as a method on // `dyn Trait`. - // To get a `*mut RcBox`, we just keep unwrapping newtypes until + // To get a `*mut RcInner`, we just keep unwrapping newtypes until // we get a value of a built-in pointer type. // // This is also relevant for `Pin<&mut Self>`, where we need to peel the diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index deda16b76b58..7354ea5fb6a2 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -822,10 +822,10 @@ fn make_thin_self_ptr<'tcx>( _ => bug!("receiver type has unsupported layout: {:?}", layout), } - // In the case of Rc, we need to explicitly pass a *mut RcBox + // In the case of Rc, we need to explicitly pass a *mut RcInner // with a Scalar (not ScalarPair) ABI. This is a hack that is understood // elsewhere in the compiler as a method on a `dyn Trait`. - // To get the type `*mut RcBox`, we just keep unwrapping newtypes until we + // To get the type `*mut RcInner`, we just keep unwrapping newtypes until we // get a built-in pointer type let mut wide_pointer_layout = layout; while !wide_pointer_layout.ty.is_unsafe_ptr() && !wide_pointer_layout.ty.is_ref() { @@ -838,7 +838,7 @@ fn make_thin_self_ptr<'tcx>( wide_pointer_layout.ty }; - // we now have a type like `*mut RcBox` + // we now have a type like `*mut RcInner` // change its layout to that of `*mut ()`, a thin pointer, but keep the same type // this is understood as a special case elsewhere in the compiler let unit_ptr_ty = Ty::new_mut_ptr(tcx, tcx.types.unit); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 5d099a49854a..4632f995b82e 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -319,7 +319,7 @@ pub struct Weak< // but it is not necessarily a valid pointer. // `Weak::new` sets this to `usize::MAX` so that it doesn’t need // to allocate space on the heap. That's not a value a real pointer - // will ever have because RcBox has alignment at least 2. + // will ever have because RcInner has alignment at least 2. // This is only possible when `T: Sized`; unsized `T` never dangle. ptr: NonNull>, alloc: A, @@ -1581,7 +1581,7 @@ impl Arc { pub fn as_ptr(this: &Self) -> *const T { let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); - // SAFETY: This cannot go through Deref::deref or RcBoxPtr::inner because + // SAFETY: This cannot go through Deref::deref or RcInnerPtr::inner because // this is required to retain raw/mut provenance such that e.g. `get_mut` can // write through the pointer after the Rc is recovered through `from_raw`. unsafe { &raw mut (*ptr).data } @@ -2936,7 +2936,7 @@ impl Weak { // Otherwise, we're guaranteed the pointer came from a nondangling Weak. // SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T. let offset = unsafe { data_offset(ptr) }; - // Thus, we reverse the offset to get the whole RcBox. + // Thus, we reverse the offset to get the whole RcInner. // SAFETY: the pointer originated from a Weak, so this offset is safe. unsafe { ptr.byte_sub(offset) as *mut ArcInner } }; @@ -3861,7 +3861,7 @@ impl Unpin for Arc {} /// valid instance of T, but the T is allowed to be dropped. unsafe fn data_offset(ptr: *const T) -> usize { // Align the unsized value to the end of the ArcInner. - // Because RcBox is repr(C), it will always be the last field in memory. + // Because RcInner is repr(C), it will always be the last field in memory. // SAFETY: since the only unsized types possible are slices, trait objects, // and extern types, the input safety requirement is currently enough to // satisfy the requirements of align_of_val_raw; this is an implementation diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 8ccd1a44ff16..513b9cbcefca 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -193,11 +193,11 @@ //! use std::marker::PhantomData; //! //! struct Rc { -//! ptr: NonNull>, -//! phantom: PhantomData>, +//! ptr: NonNull>, +//! phantom: PhantomData>, //! } //! -//! struct RcBox { +//! struct RcInner { //! strong: Cell, //! refcount: Cell, //! value: T, @@ -213,9 +213,9 @@ //! } //! } //! -//! trait RcBoxPtr { +//! trait RcInnerPtr { //! -//! fn inner(&self) -> &RcBox; +//! fn inner(&self) -> &RcInner; //! //! fn strong(&self) -> usize { //! self.inner().strong.get() @@ -230,8 +230,8 @@ //! } //! } //! -//! impl RcBoxPtr for Rc { -//! fn inner(&self) -> &RcBox { +//! impl RcInnerPtr for Rc { +//! fn inner(&self) -> &RcInner { //! unsafe { //! self.ptr.as_ref() //! } diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 8750d7682d13..bace228454eb 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -670,11 +670,11 @@ def StdRcSummaryProvider(valobj, dict): class StdRcSyntheticProvider: """Pretty-printer for alloc::rc::Rc and alloc::sync::Arc - struct Rc { ptr: NonNull>, ... } + struct Rc { ptr: NonNull>, ... } rust 1.31.1: struct NonNull { pointer: NonZero<*const T> } rust 1.33.0: struct NonNull { pointer: *const T } struct NonZero(T) - struct RcBox { strong: Cell, weak: Cell, value: T } + struct RcInner { strong: Cell, weak: Cell, value: T } struct Cell { value: UnsafeCell } struct UnsafeCell { value: T } diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis index 49d82dfad820..1528a8b1226c 100644 --- a/src/etc/natvis/liballoc.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -95,7 +95,7 @@ ptr.pointer.data_ptr->weak ptr.pointer.length - + ($T1*)(((size_t*)ptr.pointer.data_ptr) + 2) diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index 820e10743bc5..df12eeed6ac6 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -1,8 +1,8 @@ error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: --> RUSTLIB/alloc/src/rc.rs:LL:CC | -LL | Box::leak(Box::new(RcBox { strong: Cell::new(1), weak: Cell::new(1), value })) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: BACKTRACE: = note: inside `std::rc::Rc::>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC diff --git a/tests/debuginfo/strings-and-strs.rs b/tests/debuginfo/strings-and-strs.rs index b7ee3312d131..3d6589db34b8 100644 --- a/tests/debuginfo/strings-and-strs.rs +++ b/tests/debuginfo/strings-and-strs.rs @@ -19,8 +19,7 @@ // gdb-check:$4 = ("Hello", "World") // gdb-command:print str_in_rc -// gdb-check:$5 = alloc::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull> {pointer: 0x[...]}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} - +// gdb-check:$5 = alloc::rc::Rc<&str, alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull> {pointer: 0x[...]}, phantom: core::marker::PhantomData>, alloc: alloc::alloc::Global} // === LLDB TESTS ================================================================================== // lldb-command:run diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index b439a4bcf867..28c8063a9231 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -160,14 +160,14 @@ mod prelude { pub struct Box(Unique, A); #[repr(C)] - struct RcBox { + struct RcInner { strong: UnsafeCell, weak: UnsafeCell, value: T, } pub struct Rc { - ptr: NonNull>, - phantom: PhantomData>, + ptr: NonNull>, + phantom: PhantomData>, alloc: A, } From c085071631bd26227994fefeb4c34aa33e4d4cef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Oct 2024 11:24:14 -0400 Subject: [PATCH 028/118] Remove unadorned --- compiler/rustc_ast_passes/messages.ftl | 4 ++-- tests/rustdoc-json/fns/extern_safe.rs | 2 +- tests/ui/parser/fn-header-semantic-fail.rs | 4 ++-- tests/ui/parser/fn-header-semantic-fail.stderr | 8 ++++---- tests/ui/parser/no-const-fn-in-extern-block.rs | 2 +- tests/ui/parser/no-const-fn-in-extern-block.stderr | 4 ++-- ...fe-unsafe-on-unadorned-extern-block.edition2021.stderr | 8 ++++---- ...fe-unsafe-on-unadorned-extern-block.edition2024.stderr | 8 ++++---- .../safe-unsafe-on-unadorned-extern-block.rs | 4 ++-- .../unsafe-on-extern-block-issue-126756.fixed | 2 +- .../unsafe-on-extern-block-issue-126756.rs | 2 +- .../unsafe-on-extern-block-issue-126756.stderr | 4 ++-- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index c361c35b723d..f826e71b574c 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -70,8 +70,8 @@ ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have quali .label = in this `extern` block .suggestion = remove this qualifier -ast_passes_extern_invalid_safety = items in unadorned `extern` blocks cannot have safety qualifiers - .suggestion = add unsafe to this `extern` block +ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers + .suggestion = add `unsafe` to this `extern` block ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers .label = in this `extern` block diff --git a/tests/rustdoc-json/fns/extern_safe.rs b/tests/rustdoc-json/fns/extern_safe.rs index a4a2d2c7f8c1..b00f9f50bd2b 100644 --- a/tests/rustdoc-json/fns/extern_safe.rs +++ b/tests/rustdoc-json/fns/extern_safe.rs @@ -2,7 +2,7 @@ extern "C" { //@ is "$.index[*][?(@.name=='f1')].inner.function.header.is_unsafe" true pub fn f1(); - // items in unadorned `extern` blocks cannot have safety qualifiers + // items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } unsafe extern "C" { diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs index 972e52d75daf..f3d834549a86 100644 --- a/tests/ui/parser/fn-header-semantic-fail.rs +++ b/tests/ui/parser/fn-header-semantic-fail.rs @@ -42,7 +42,7 @@ fn main() { extern "C" { async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers - unsafe fn fe2(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + unsafe fn fe2(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers const async unsafe extern "C" fn fe5(); @@ -50,6 +50,6 @@ fn main() { //~| ERROR functions in `extern` blocks //~| ERROR functions in `extern` blocks //~| ERROR functions cannot be both `const` and `async` - //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } } diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr index dda42f24b32d..894e03157c1b 100644 --- a/tests/ui/parser/fn-header-semantic-fail.stderr +++ b/tests/ui/parser/fn-header-semantic-fail.stderr @@ -78,13 +78,13 @@ LL | extern "C" { LL | async fn fe1(); | ^^^^^ help: remove this qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:45:9 | LL | unsafe fn fe2(); | ^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ @@ -134,13 +134,13 @@ LL | extern "C" { LL | const async unsafe extern "C" fn fe5(); | ^^^^^^^^^^ help: remove this qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:48:9 | LL | const async unsafe extern "C" fn fe5(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/parser/no-const-fn-in-extern-block.rs b/tests/ui/parser/no-const-fn-in-extern-block.rs index 3ad9ba006d3d..1d3891084945 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.rs +++ b/tests/ui/parser/no-const-fn-in-extern-block.rs @@ -3,7 +3,7 @@ extern "C" { //~^ ERROR functions in `extern` blocks cannot have qualifiers const unsafe fn bar(); //~^ ERROR functions in `extern` blocks cannot have qualifiers - //~| ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn main() {} diff --git a/tests/ui/parser/no-const-fn-in-extern-block.stderr b/tests/ui/parser/no-const-fn-in-extern-block.stderr index 8c23824a7088..d4428d3cb814 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.stderr +++ b/tests/ui/parser/no-const-fn-in-extern-block.stderr @@ -15,13 +15,13 @@ LL | extern "C" { LL | const unsafe fn bar(); | ^^^^^ help: remove this qualifier -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/no-const-fn-in-extern-block.rs:4:5 | LL | const unsafe fn bar(); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr index 937979872866..ddc5477116f7 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr @@ -1,21 +1,21 @@ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr index e9db6006c0b5..ae7b4cd47c07 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr @@ -10,24 +10,24 @@ LL | | LL | | } | |_^ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:8:5 | LL | safe static TEST1: i32; | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 | LL | safe fn test1(i: i32); | ^^^^^^^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs index 4badb50b2673..89415a69f08f 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.rs @@ -6,9 +6,9 @@ extern "C" { //[edition2024]~^ ERROR extern blocks must be unsafe safe static TEST1: i32; - //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~^ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers safe fn test1(i: i32); - //~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + //~^ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn test2() { diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed index 857d34eef852..79983a64c2bd 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed @@ -3,7 +3,7 @@ #![allow(dead_code)] unsafe extern "C" { - unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + unsafe fn foo(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn main() {} diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs index edab9850d796..cb84d3d14114 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] extern "C" { - unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers + unsafe fn foo(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } fn main() {} diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr index 073245e650b1..cf1c0012f4d3 100644 --- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr +++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr @@ -1,10 +1,10 @@ -error: items in unadorned `extern` blocks cannot have safety qualifiers +error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/unsafe-on-extern-block-issue-126756.rs:6:5 | LL | unsafe fn foo(); | ^^^^^^^^^^^^^^^^ | -help: add unsafe to this `extern` block +help: add `unsafe` to this `extern` block | LL | unsafe extern "C" { | ++++++ From d6391d5d4d1fa20da66e6a58a593b9cb29fa4b1c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 11 Oct 2024 11:30:03 -0400 Subject: [PATCH 029/118] Note what qualifier --- compiler/rustc_ast_passes/messages.ftl | 4 ++-- .../rustc_ast_passes/src/ast_validation.rs | 15 +++++++----- compiler/rustc_ast_passes/src/errors.rs | 1 + tests/ui/extern/issue-95829.rs | 2 +- tests/ui/extern/issue-95829.stderr | 4 ++-- tests/ui/parser/fn-header-semantic-fail.rs | 10 ++++---- .../ui/parser/fn-header-semantic-fail.stderr | 24 +++++++++---------- .../ui/parser/no-const-fn-in-extern-block.rs | 6 ++--- .../parser/no-const-fn-in-extern-block.stderr | 8 +++---- 9 files changed, 39 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index f826e71b574c..3ea17cbc2799 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -66,9 +66,9 @@ ast_passes_equality_in_where = equality constraints are not yet supported in `wh ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block -ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers +ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier .label = in this `extern` block - .suggestion = remove this qualifier + .suggestion = remove the `{$kw}` qualifier ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers .suggestion = add `unsafe` to this `extern` block diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 5bdd9b6eda80..cd296d39770c 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -561,21 +561,24 @@ impl<'a> AstValidator<'a> { // Deconstruct to ensure exhaustiveness FnHeader { safety: _, coroutine_kind, constness, ext }: FnHeader, ) { - let report_err = |span| { - self.dcx() - .emit_err(errors::FnQualifierInExtern { span, block: self.current_extern_span() }); + let report_err = |span, kw| { + self.dcx().emit_err(errors::FnQualifierInExtern { + span, + kw, + block: self.current_extern_span(), + }); }; match coroutine_kind { - Some(knd) => report_err(knd.span()), + Some(kind) => report_err(kind.span(), kind.as_str()), None => (), } match constness { - Const::Yes(span) => report_err(span), + Const::Yes(span) => report_err(span, "const"), Const::No => (), } match ext { Extern::None => (), - Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span), + Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span, "extern"), } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 5cce47ce7bd2..712bb4b9ba5b 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -295,6 +295,7 @@ pub(crate) struct FnQualifierInExtern { pub span: Span, #[label] pub block: Span, + pub kw: &'static str, } #[derive(Diagnostic)] diff --git a/tests/ui/extern/issue-95829.rs b/tests/ui/extern/issue-95829.rs index ad4e04f7c3a9..c5ae4c682659 100644 --- a/tests/ui/extern/issue-95829.rs +++ b/tests/ui/extern/issue-95829.rs @@ -2,7 +2,7 @@ extern { async fn L() { //~ ERROR: incorrect function inside `extern` block - //~^ ERROR: functions in `extern` blocks cannot have qualifiers + //~^ ERROR: functions in `extern` blocks cannot have `async` qualifier async fn M() {} } } diff --git a/tests/ui/extern/issue-95829.stderr b/tests/ui/extern/issue-95829.stderr index 16504d1f0c9d..2f396b8cc041 100644 --- a/tests/ui/extern/issue-95829.stderr +++ b/tests/ui/extern/issue-95829.stderr @@ -15,13 +15,13 @@ LL | | } = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/issue-95829.rs:4:5 | LL | extern { | ------ in this `extern` block LL | async fn L() { - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier error: aborting due to 2 previous errors diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs index f3d834549a86..202f362c81c6 100644 --- a/tests/ui/parser/fn-header-semantic-fail.rs +++ b/tests/ui/parser/fn-header-semantic-fail.rs @@ -41,15 +41,15 @@ fn main() { } extern "C" { - async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers - unsafe fn fe2(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers - const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers - extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers + async fn fe1(); //~ ERROR functions in `extern` blocks cannot + unsafe fn fe2(); //~ ERROR items in `extern` blocks without an `unsafe` qualifier cannot + const fn fe3(); //~ ERROR functions in `extern` blocks cannot + extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot const async unsafe extern "C" fn fe5(); //~^ ERROR functions in `extern` blocks //~| ERROR functions in `extern` blocks //~| ERROR functions in `extern` blocks //~| ERROR functions cannot be both `const` and `async` - //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have } } diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr index 894e03157c1b..17e880c3a79d 100644 --- a/tests/ui/parser/fn-header-semantic-fail.stderr +++ b/tests/ui/parser/fn-header-semantic-fail.stderr @@ -70,13 +70,13 @@ LL | const async unsafe extern "C" fn fi5() {} | | `async` because of this | `const` because of this -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/fn-header-semantic-fail.rs:44:9 | LL | extern "C" { | ---------- in this `extern` block LL | async fn fe1(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:45:9 @@ -89,50 +89,50 @@ help: add `unsafe` to this `extern` block LL | unsafe extern "C" { | ++++++ -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/fn-header-semantic-fail.rs:46:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | const fn fe3(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `extern` qualifier --> $DIR/fn-header-semantic-fail.rs:47:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | extern "C" fn fe4(); - | ^^^^^^^^^^ help: remove this qualifier + | ^^^^^^^^^^ help: remove the `extern` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `async` qualifier --> $DIR/fn-header-semantic-fail.rs:48:15 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `async` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/fn-header-semantic-fail.rs:48:9 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `extern` qualifier --> $DIR/fn-header-semantic-fail.rs:48:28 | LL | extern "C" { | ---------- in this `extern` block ... LL | const async unsafe extern "C" fn fe5(); - | ^^^^^^^^^^ help: remove this qualifier + | ^^^^^^^^^^ help: remove the `extern` qualifier error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/fn-header-semantic-fail.rs:48:9 diff --git a/tests/ui/parser/no-const-fn-in-extern-block.rs b/tests/ui/parser/no-const-fn-in-extern-block.rs index 1d3891084945..0f1e44ced10e 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.rs +++ b/tests/ui/parser/no-const-fn-in-extern-block.rs @@ -1,9 +1,9 @@ extern "C" { const fn foo(); - //~^ ERROR functions in `extern` blocks cannot have qualifiers + //~^ ERROR functions in `extern` blocks cannot const unsafe fn bar(); - //~^ ERROR functions in `extern` blocks cannot have qualifiers - //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers + //~^ ERROR functions in `extern` blocks cannot + //~| ERROR items in `extern` blocks without an `unsafe` qualifier cannot } fn main() {} diff --git a/tests/ui/parser/no-const-fn-in-extern-block.stderr b/tests/ui/parser/no-const-fn-in-extern-block.stderr index d4428d3cb814..46f845e85c28 100644 --- a/tests/ui/parser/no-const-fn-in-extern-block.stderr +++ b/tests/ui/parser/no-const-fn-in-extern-block.stderr @@ -1,19 +1,19 @@ -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/no-const-fn-in-extern-block.rs:2:5 | LL | extern "C" { | ---------- in this `extern` block LL | const fn foo(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier -error: functions in `extern` blocks cannot have qualifiers +error: functions in `extern` blocks cannot have `const` qualifier --> $DIR/no-const-fn-in-extern-block.rs:4:5 | LL | extern "C" { | ---------- in this `extern` block ... LL | const unsafe fn bar(); - | ^^^^^ help: remove this qualifier + | ^^^^^ help: remove the `const` qualifier error: items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers --> $DIR/no-const-fn-in-extern-block.rs:4:5 From 624c071b997f3bab0ef086af24f59ebc95f37c59 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 11 Oct 2024 19:13:31 +0200 Subject: [PATCH 030/118] Single commit implementing the enzyme/autodiff frontend Co-authored-by: Lorenz Schmidt --- .../rustc_ast/src/expand/autodiff_attrs.rs | 283 ++++++ compiler/rustc_ast/src/expand/mod.rs | 2 + compiler/rustc_ast/src/expand/typetree.rs | 90 ++ compiler/rustc_builtin_macros/Cargo.toml | 4 + compiler/rustc_builtin_macros/messages.ftl | 9 + compiler/rustc_builtin_macros/src/autodiff.rs | 820 ++++++++++++++++++ compiler/rustc_builtin_macros/src/errors.rs | 72 ++ compiler/rustc_builtin_macros/src/lib.rs | 3 + compiler/rustc_expand/src/build.rs | 29 + compiler/rustc_feature/src/builtin_attrs.rs | 5 + compiler/rustc_passes/messages.ftl | 4 + compiler/rustc_passes/src/check_attr.rs | 15 + compiler/rustc_passes/src/errors.rs | 8 + compiler/rustc_span/src/symbol.rs | 5 + library/core/src/lib.rs | 9 + library/core/src/macros/mod.rs | 18 + library/std/src/lib.rs | 9 +- 17 files changed, 1384 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_ast/src/expand/autodiff_attrs.rs create mode 100644 compiler/rustc_ast/src/expand/typetree.rs create mode 100644 compiler/rustc_builtin_macros/src/autodiff.rs diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs new file mode 100644 index 000000000000..05714731b9d4 --- /dev/null +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -0,0 +1,283 @@ +//! This crate handles the user facing autodiff macro. For each `#[autodiff(...)]` attribute, +//! we create an [`AutoDiffItem`] which contains the source and target function names. The source +//! is the function to which the autodiff attribute is applied, and the target is the function +//! getting generated by us (with a name given by the user as the first autodiff arg). + +use std::fmt::{self, Display, Formatter}; +use std::str::FromStr; + +use crate::expand::typetree::TypeTree; +use crate::expand::{Decodable, Encodable, HashStable_Generic}; +use crate::ptr::P; +use crate::{Ty, TyKind}; + +/// Forward and Reverse Mode are well known names for automatic differentiation implementations. +/// Enzyme does support both, but with different semantics, see DiffActivity. The First variants +/// are a hack to support higher order derivatives. We need to compute first order derivatives +/// before we compute second order derivatives, otherwise we would differentiate our placeholder +/// functions. The proper solution is to recognize and resolve this DAG of autodiff invocations, +/// as it's already done in the C++ and Julia frontend of Enzyme. +/// +/// (FIXME) remove *First variants. +/// Documentation for using [reverse](https://enzyme.mit.edu/rust/rev.html) and +/// [forward](https://enzyme.mit.edu/rust/fwd.html) mode is available online. +#[derive(Clone, Copy, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum DiffMode { + /// No autodiff is applied (used during error handling). + Error, + /// The primal function which we will differentiate. + Source, + /// The target function, to be created using forward mode AD. + Forward, + /// The target function, to be created using reverse mode AD. + Reverse, + /// The target function, to be created using forward mode AD. + /// This target function will also be used as a source for higher order derivatives, + /// so compute it before all Forward/Reverse targets and optimize it through llvm. + ForwardFirst, + /// The target function, to be created using reverse mode AD. + /// This target function will also be used as a source for higher order derivatives, + /// so compute it before all Forward/Reverse targets and optimize it through llvm. + ReverseFirst, +} + +/// Dual and Duplicated (and their Only variants) are getting lowered to the same Enzyme Activity. +/// However, under forward mode we overwrite the previous shadow value, while for reverse mode +/// we add to the previous shadow value. To not surprise users, we picked different names. +/// Dual numbers is also a quite well known name for forward mode AD types. +#[derive(Clone, Copy, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum DiffActivity { + /// Implicit or Explicit () return type, so a special case of Const. + None, + /// Don't compute derivatives with respect to this input/output. + Const, + /// Reverse Mode, Compute derivatives for this scalar input/output. + Active, + /// Reverse Mode, Compute derivatives for this scalar output, but don't compute + /// the original return value. + ActiveOnly, + /// Forward Mode, Compute derivatives for this input/output and *overwrite* the shadow argument + /// with it. + Dual, + /// Forward Mode, Compute derivatives for this input/output and *overwrite* the shadow argument + /// with it. Drop the code which updates the original input/output for maximum performance. + DualOnly, + /// Reverse Mode, Compute derivatives for this &T or *T input and *add* it to the shadow argument. + Duplicated, + /// Reverse Mode, Compute derivatives for this &T or *T input and *add* it to the shadow argument. + /// Drop the code which updates the original input for maximum performance. + DuplicatedOnly, + /// All Integers must be Const, but these are used to mark the integer which represents the + /// length of a slice/vec. This is used for safety checks on slices. + FakeActivitySize, +} +/// We generate one of these structs for each `#[autodiff(...)]` attribute. +#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct AutoDiffItem { + /// The name of the function getting differentiated + pub source: String, + /// The name of the function being generated + pub target: String, + pub attrs: AutoDiffAttrs, + /// Describe the memory layout of input types + pub inputs: Vec, + /// Describe the memory layout of the output type + pub output: TypeTree, +} +#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct AutoDiffAttrs { + /// Conceptually either forward or reverse mode AD, as described in various autodiff papers and + /// e.g. in the [JAX + /// Documentation](https://jax.readthedocs.io/en/latest/_tutorials/advanced-autodiff.html#how-it-s-made-two-foundational-autodiff-functions). + pub mode: DiffMode, + pub ret_activity: DiffActivity, + pub input_activity: Vec, +} + +impl DiffMode { + pub fn is_rev(&self) -> bool { + matches!(self, DiffMode::Reverse | DiffMode::ReverseFirst) + } + pub fn is_fwd(&self) -> bool { + matches!(self, DiffMode::Forward | DiffMode::ForwardFirst) + } +} + +impl Display for DiffMode { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + DiffMode::Error => write!(f, "Error"), + DiffMode::Source => write!(f, "Source"), + DiffMode::Forward => write!(f, "Forward"), + DiffMode::Reverse => write!(f, "Reverse"), + DiffMode::ForwardFirst => write!(f, "ForwardFirst"), + DiffMode::ReverseFirst => write!(f, "ReverseFirst"), + } + } +} + +/// Active(Only) is valid in reverse-mode AD for scalar float returns (f16/f32/...). +/// Dual(Only) is valid in forward-mode AD for scalar float returns (f16/f32/...). +/// Const is valid for all cases and means that we don't compute derivatives wrt. this output. +/// That usually means we have a &mut or *mut T output and compute derivatives wrt. that arg, +/// but this is too complex to verify here. Also it's just a logic error if users get this wrong. +pub fn valid_ret_activity(mode: DiffMode, activity: DiffActivity) -> bool { + if activity == DiffActivity::None { + // Only valid if primal returns (), but we can't check that here. + return true; + } + match mode { + DiffMode::Error => false, + DiffMode::Source => false, + DiffMode::Forward | DiffMode::ForwardFirst => { + activity == DiffActivity::Dual + || activity == DiffActivity::DualOnly + || activity == DiffActivity::Const + } + DiffMode::Reverse | DiffMode::ReverseFirst => { + activity == DiffActivity::Const + || activity == DiffActivity::Active + || activity == DiffActivity::ActiveOnly + } + } +} + +/// For indirections (ptr/ref) we can't use Active, since Active allocates a shadow value +/// for the given argument, but we generally can't know the size of such a type. +/// For scalar types (f16/f32/f64/f128) we can use Active and we can't use Duplicated, +/// since Duplicated expects a mutable ref/ptr and we would thus end up with a shadow value +/// who is an indirect type, which doesn't match the primal scalar type. We can't prevent +/// users here from marking scalars as Duplicated, due to type aliases. +pub fn valid_ty_for_activity(ty: &P, activity: DiffActivity) -> bool { + use DiffActivity::*; + // It's always allowed to mark something as Const, since we won't compute derivatives wrt. it. + if matches!(activity, Const) { + return true; + } + if matches!(activity, Dual | DualOnly) { + return true; + } + // FIXME(ZuseZ4) We should make this more robust to also + // handle type aliases. Once that is done, we can be more restrictive here. + if matches!(activity, Active | ActiveOnly) { + return true; + } + matches!(ty.kind, TyKind::Ptr(_) | TyKind::Ref(..)) + && matches!(activity, Duplicated | DuplicatedOnly) +} +pub fn valid_input_activity(mode: DiffMode, activity: DiffActivity) -> bool { + use DiffActivity::*; + return match mode { + DiffMode::Error => false, + DiffMode::Source => false, + DiffMode::Forward | DiffMode::ForwardFirst => { + matches!(activity, Dual | DualOnly | Const) + } + DiffMode::Reverse | DiffMode::ReverseFirst => { + matches!(activity, Active | ActiveOnly | Duplicated | DuplicatedOnly | Const) + } + }; +} + +impl Display for DiffActivity { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + DiffActivity::None => write!(f, "None"), + DiffActivity::Const => write!(f, "Const"), + DiffActivity::Active => write!(f, "Active"), + DiffActivity::ActiveOnly => write!(f, "ActiveOnly"), + DiffActivity::Dual => write!(f, "Dual"), + DiffActivity::DualOnly => write!(f, "DualOnly"), + DiffActivity::Duplicated => write!(f, "Duplicated"), + DiffActivity::DuplicatedOnly => write!(f, "DuplicatedOnly"), + DiffActivity::FakeActivitySize => write!(f, "FakeActivitySize"), + } + } +} + +impl FromStr for DiffMode { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "Error" => Ok(DiffMode::Error), + "Source" => Ok(DiffMode::Source), + "Forward" => Ok(DiffMode::Forward), + "Reverse" => Ok(DiffMode::Reverse), + "ForwardFirst" => Ok(DiffMode::ForwardFirst), + "ReverseFirst" => Ok(DiffMode::ReverseFirst), + _ => Err(()), + } + } +} +impl FromStr for DiffActivity { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "None" => Ok(DiffActivity::None), + "Active" => Ok(DiffActivity::Active), + "ActiveOnly" => Ok(DiffActivity::ActiveOnly), + "Const" => Ok(DiffActivity::Const), + "Dual" => Ok(DiffActivity::Dual), + "DualOnly" => Ok(DiffActivity::DualOnly), + "Duplicated" => Ok(DiffActivity::Duplicated), + "DuplicatedOnly" => Ok(DiffActivity::DuplicatedOnly), + _ => Err(()), + } + } +} + +impl AutoDiffAttrs { + pub fn has_ret_activity(&self) -> bool { + self.ret_activity != DiffActivity::None + } + pub fn has_active_only_ret(&self) -> bool { + self.ret_activity == DiffActivity::ActiveOnly + } + + pub fn error() -> Self { + AutoDiffAttrs { + mode: DiffMode::Error, + ret_activity: DiffActivity::None, + input_activity: Vec::new(), + } + } + pub fn source() -> Self { + AutoDiffAttrs { + mode: DiffMode::Source, + ret_activity: DiffActivity::None, + input_activity: Vec::new(), + } + } + + pub fn is_active(&self) -> bool { + self.mode != DiffMode::Error + } + + pub fn is_source(&self) -> bool { + self.mode == DiffMode::Source + } + pub fn apply_autodiff(&self) -> bool { + !matches!(self.mode, DiffMode::Error | DiffMode::Source) + } + + pub fn into_item( + self, + source: String, + target: String, + inputs: Vec, + output: TypeTree, + ) -> AutoDiffItem { + AutoDiffItem { source, target, inputs, output, attrs: self } + } +} + +impl fmt::Display for AutoDiffItem { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Differentiating {} -> {}", self.source, self.target)?; + write!(f, " with attributes: {:?}", self.attrs)?; + write!(f, " with inputs: {:?}", self.inputs)?; + write!(f, " with output: {:?}", self.output) + } +} diff --git a/compiler/rustc_ast/src/expand/mod.rs b/compiler/rustc_ast/src/expand/mod.rs index 13413281bc7c..d259677e98e3 100644 --- a/compiler/rustc_ast/src/expand/mod.rs +++ b/compiler/rustc_ast/src/expand/mod.rs @@ -7,6 +7,8 @@ use rustc_span::symbol::Ident; use crate::MetaItem; pub mod allocator; +pub mod autodiff_attrs; +pub mod typetree; #[derive(Debug, Clone, Encodable, Decodable, HashStable_Generic)] pub struct StrippedCfgItem { diff --git a/compiler/rustc_ast/src/expand/typetree.rs b/compiler/rustc_ast/src/expand/typetree.rs new file mode 100644 index 000000000000..9a2dd2e85e0d --- /dev/null +++ b/compiler/rustc_ast/src/expand/typetree.rs @@ -0,0 +1,90 @@ +//! This module contains the definition of the `TypeTree` and `Type` structs. +//! They are thin Rust wrappers around the TypeTrees used by Enzyme as the LLVM based autodiff +//! backend. The Enzyme TypeTrees currently have various limitations and should be rewritten, so the +//! Rust frontend obviously has the same limitations. The main motivation of TypeTrees is to +//! represent how a type looks like "in memory". Enzyme can deduce this based on usage patterns in +//! the user code, but this is extremely slow and not even always sufficient. As such we lower some +//! information from rustc to help Enzyme. For a full explanation of their design it is necessary to +//! analyze the implementation in Enzyme core itself. As a rough summary, `-1` in Enzyme speech means +//! everywhere. That is `{0:-1: Float}` means at index 0 you have a ptr, if you dereference it it +//! will be floats everywhere. Thus `* f32`. If you have `{-1:int}` it means int's everywhere, +//! e.g. [i32; N]. `{0:-1:-1 float}` then means one pointer at offset 0, if you dereference it there +//! will be only pointers, if you dereference these new pointers they will point to array of floats. +//! Generally, it allows byte-specific descriptions. +//! FIXME: This description might be partly inaccurate and should be extended, along with +//! adding documentation to the corresponding Enzyme core code. +//! FIXME: Rewrite the TypeTree logic in Enzyme core to reduce the need for the rustc frontend to +//! provide typetree information. +//! FIXME: We should also re-evaluate where we create TypeTrees from Rust types, since MIR +//! representations of some types might not be accurate. For example a vector of floats might be +//! represented as a vector of u8s in MIR in some cases. + +use std::fmt; + +use crate::expand::{Decodable, Encodable, HashStable_Generic}; + +#[derive(Clone, Copy, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub enum Kind { + Anything, + Integer, + Pointer, + Half, + Float, + Double, + Unknown, +} + +#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct TypeTree(pub Vec); + +impl TypeTree { + pub fn new() -> Self { + Self(Vec::new()) + } + pub fn all_ints() -> Self { + Self(vec![Type { offset: -1, size: 1, kind: Kind::Integer, child: TypeTree::new() }]) + } + pub fn int(size: usize) -> Self { + let mut ints = Vec::with_capacity(size); + for i in 0..size { + ints.push(Type { + offset: i as isize, + size: 1, + kind: Kind::Integer, + child: TypeTree::new(), + }); + } + Self(ints) + } +} + +#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct FncTree { + pub args: Vec, + pub ret: TypeTree, +} + +#[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] +pub struct Type { + pub offset: isize, + pub size: usize, + pub kind: Kind, + pub child: TypeTree, +} + +impl Type { + pub fn add_offset(self, add: isize) -> Self { + let offset = match self.offset { + -1 => add, + x => add + x, + }; + + Self { size: self.size, kind: self.kind, child: self.child, offset } + } +} + +impl fmt::Display for Type { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(self, f) + } +} diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 21b87be4b81d..ef48486f6f15 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -3,6 +3,10 @@ name = "rustc_builtin_macros" version = "0.0.0" edition = "2021" + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(llvm_enzyme)'] } + [lib] doctest = false diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 77cb8dc63c48..6ebc2fd870cc 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -69,6 +69,15 @@ builtin_macros_assert_requires_boolean = macro requires a boolean expression as builtin_macros_assert_requires_expression = macro requires an expression as an argument .suggestion = try removing semicolon +builtin_macros_autodiff = autodiff must be applied to function +builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode +builtin_macros_autodiff_mode = unknown Mode: `{$mode}`. Use `Forward` or `Reverse` +builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode +builtin_macros_autodiff_not_build = this rustc version does not support autodiff +builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} +builtin_macros_autodiff_ty_activity = {$act} can not be used for this type + +builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s .label = not applicable here .label2 = not a `struct`, `enum` or `union` diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs new file mode 100644 index 000000000000..66bb11ca5228 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -0,0 +1,820 @@ +//! This module contains the implementation of the `#[autodiff]` attribute. +//! Currently our linter isn't smart enough to see that each import is used in one of the two +//! configs (autodiff enabled or disabled), so we have to add cfg's to each import. +//! FIXME(ZuseZ4): Remove this once we have a smarter linter. + +#[cfg(llvm_enzyme)] +mod llvm_enzyme { + use std::str::FromStr; + use std::string::String; + + use rustc_ast::expand::autodiff_attrs::{ + AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ty_for_activity, + }; + use rustc_ast::ptr::P; + use rustc_ast::token::{Token, TokenKind}; + use rustc_ast::tokenstream::*; + use rustc_ast::visit::AssocCtxt::*; + use rustc_ast::{ + self as ast, AssocItemKind, BindingMode, FnRetTy, FnSig, Generics, ItemKind, MetaItemInner, + PatKind, TyKind, + }; + use rustc_expand::base::{Annotatable, ExtCtxt}; + use rustc_span::symbol::{Ident, kw, sym}; + use rustc_span::{Span, Symbol}; + use thin_vec::{ThinVec, thin_vec}; + use tracing::{debug, trace}; + + use crate::errors; + + // If we have a default `()` return type or explicitley `()` return type, + // then we often can skip doing some work. + fn has_ret(ty: &FnRetTy) -> bool { + match ty { + FnRetTy::Ty(ty) => !ty.kind.is_unit(), + FnRetTy::Default(_) => false, + } + } + fn first_ident(x: &MetaItemInner) -> rustc_span::symbol::Ident { + let segments = &x.meta_item().unwrap().path.segments; + assert!(segments.len() == 1); + segments[0].ident + } + + fn name(x: &MetaItemInner) -> String { + first_ident(x).name.to_string() + } + + pub(crate) fn from_ast( + ecx: &mut ExtCtxt<'_>, + meta_item: &ThinVec, + has_ret: bool, + ) -> AutoDiffAttrs { + let dcx = ecx.sess.dcx(); + let mode = name(&meta_item[1]); + let Ok(mode) = DiffMode::from_str(&mode) else { + dcx.emit_err(errors::AutoDiffInvalidMode { span: meta_item[1].span(), mode }); + return AutoDiffAttrs::error(); + }; + let mut activities: Vec = vec![]; + let mut errors = false; + for x in &meta_item[2..] { + let activity_str = name(&x); + let res = DiffActivity::from_str(&activity_str); + match res { + Ok(x) => activities.push(x), + Err(_) => { + dcx.emit_err(errors::AutoDiffUnknownActivity { + span: x.span(), + act: activity_str, + }); + errors = true; + } + }; + } + if errors { + return AutoDiffAttrs::error(); + } + + // If a return type exist, we need to split the last activity, + // otherwise we return None as placeholder. + let (ret_activity, input_activity) = if has_ret { + let Some((last, rest)) = activities.split_last() else { + unreachable!( + "should not be reachable because we counted the number of activities previously" + ); + }; + (last, rest) + } else { + (&DiffActivity::None, activities.as_slice()) + }; + + AutoDiffAttrs { mode, ret_activity: *ret_activity, input_activity: input_activity.to_vec() } + } + + /// We expand the autodiff macro to generate a new placeholder function which passes + /// type-checking and can be called by users. The function body of the placeholder function will + /// later be replaced on LLVM-IR level, so the design of the body is less important and for now + /// should just prevent early inlining and optimizations which alter the function signature. + /// The exact signature of the generated function depends on the configuration provided by the + /// user, but here is an example: + /// + /// ``` + /// #[autodiff(cos_box, Reverse, Duplicated, Active)] + /// fn sin(x: &Box) -> f32 { + /// f32::sin(**x) + /// } + /// ``` + /// which becomes expanded to: + /// ``` + /// #[rustc_autodiff] + /// #[inline(never)] + /// fn sin(x: &Box) -> f32 { + /// f32::sin(**x) + /// } + /// #[rustc_autodiff(Reverse, Duplicated, Active)] + /// #[inline(never)] + /// fn cos_box(x: &Box, dx: &mut Box, dret: f32) -> f32 { + /// unsafe { + /// asm!("NOP"); + /// }; + /// ::core::hint::black_box(sin(x)); + /// ::core::hint::black_box((dx, dret)); + /// ::core::hint::black_box(sin(x)) + /// } + /// ``` + /// FIXME(ZuseZ4): Once autodiff is enabled by default, make this a doc comment which is checked + /// in CI. + pub(crate) fn expand( + ecx: &mut ExtCtxt<'_>, + expand_span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, + ) -> Vec { + let dcx = ecx.sess.dcx(); + // first get the annotable item: + let (sig, is_impl): (FnSig, bool) = match &item { + Annotatable::Item(ref iitem) => { + let sig = match &iitem.kind { + ItemKind::Fn(box ast::Fn { sig, .. }) => sig, + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + (sig.clone(), false) + } + Annotatable::AssocItem(ref assoc_item, _) => { + let sig = match &assoc_item.kind { + ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig, + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + (sig.clone(), true) + } + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + + let meta_item_vec: ThinVec = match meta_item.kind { + ast::MetaItemKind::List(ref vec) => vec.clone(), + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + + let has_ret = has_ret(&sig.decl.output); + let sig_span = ecx.with_call_site_ctxt(sig.span); + + let (vis, primal) = match &item { + Annotatable::Item(ref iitem) => (iitem.vis.clone(), iitem.ident.clone()), + Annotatable::AssocItem(ref assoc_item, _) => { + (assoc_item.vis.clone(), assoc_item.ident.clone()) + } + _ => { + dcx.emit_err(errors::AutoDiffInvalidApplication { span: item.span() }); + return vec![item]; + } + }; + + // create TokenStream from vec elemtents: + // meta_item doesn't have a .tokens field + let comma: Token = Token::new(TokenKind::Comma, Span::default()); + let mut ts: Vec = vec![]; + if meta_item_vec.len() < 2 { + // At the bare minimum, we need a fnc name and a mode, even for a dummy function with no + // input and output args. + dcx.emit_err(errors::AutoDiffMissingConfig { span: item.span() }); + return vec![item]; + } else { + for t in meta_item_vec.clone()[1..].iter() { + let val = first_ident(t); + let t = Token::from_ast_ident(val); + ts.push(TokenTree::Token(t, Spacing::Joint)); + ts.push(TokenTree::Token(comma.clone(), Spacing::Alone)); + } + } + if !has_ret { + // We don't want users to provide a return activity if the function doesn't return anything. + // For simplicity, we just add a dummy token to the end of the list. + let t = Token::new(TokenKind::Ident(sym::None, false.into()), Span::default()); + ts.push(TokenTree::Token(t, Spacing::Joint)); + } + let ts: TokenStream = TokenStream::from_iter(ts); + + let x: AutoDiffAttrs = from_ast(ecx, &meta_item_vec, has_ret); + if !x.is_active() { + // We encountered an error, so we return the original item. + // This allows us to potentially parse other attributes. + return vec![item]; + } + let span = ecx.with_def_site_ctxt(expand_span); + + let n_active: u32 = x + .input_activity + .iter() + .filter(|a| **a == DiffActivity::Active || **a == DiffActivity::ActiveOnly) + .count() as u32; + let (d_sig, new_args, idents, errored) = gen_enzyme_decl(ecx, &sig, &x, span); + let new_decl_span = d_sig.span; + let d_body = gen_enzyme_body( + ecx, + &x, + n_active, + &sig, + &d_sig, + primal, + &new_args, + span, + sig_span, + new_decl_span, + idents, + errored, + ); + let d_ident = first_ident(&meta_item_vec[0]); + + // The first element of it is the name of the function to be generated + let asdf = Box::new(ast::Fn { + defaultness: ast::Defaultness::Final, + sig: d_sig, + generics: Generics::default(), + body: Some(d_body), + }); + let mut rustc_ad_attr = + P(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); + + let ts2: Vec = vec![TokenTree::Token( + Token::new(TokenKind::Ident(sym::never, false.into()), span), + Spacing::Joint, + )]; + let never_arg = ast::DelimArgs { + dspan: ast::tokenstream::DelimSpan::from_single(span), + delim: ast::token::Delimiter::Parenthesis, + tokens: ast::tokenstream::TokenStream::from_iter(ts2), + }; + let inline_item = ast::AttrItem { + unsafety: ast::Safety::Default, + path: ast::Path::from_ident(Ident::with_dummy_span(sym::inline)), + args: ast::AttrArgs::Delimited(never_arg), + tokens: None, + }; + let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None }); + let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); + let attr: ast::Attribute = ast::Attribute { + kind: ast::AttrKind::Normal(rustc_ad_attr.clone()), + id: new_id, + style: ast::AttrStyle::Outer, + span, + }; + let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); + let inline_never: ast::Attribute = ast::Attribute { + kind: ast::AttrKind::Normal(inline_never_attr), + id: new_id, + style: ast::AttrStyle::Outer, + span, + }; + + // Don't add it multiple times: + let orig_annotatable: Annotatable = match item { + Annotatable::Item(ref mut iitem) => { + if !iitem.attrs.iter().any(|a| a.id == attr.id) { + iitem.attrs.push(attr.clone()); + } + if !iitem.attrs.iter().any(|a| a.id == inline_never.id) { + iitem.attrs.push(inline_never.clone()); + } + Annotatable::Item(iitem.clone()) + } + Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => { + if !assoc_item.attrs.iter().any(|a| a.id == attr.id) { + assoc_item.attrs.push(attr.clone()); + } + if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) { + assoc_item.attrs.push(inline_never.clone()); + } + Annotatable::AssocItem(assoc_item.clone(), i) + } + _ => { + unreachable!("annotatable kind checked previously") + } + }; + // Now update for d_fn + rustc_ad_attr.item.args = rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs { + dspan: DelimSpan::dummy(), + delim: rustc_ast::token::Delimiter::Parenthesis, + tokens: ts, + }); + let d_attr: ast::Attribute = ast::Attribute { + kind: ast::AttrKind::Normal(rustc_ad_attr.clone()), + id: new_id, + style: ast::AttrStyle::Outer, + span, + }; + + let d_annotatable = if is_impl { + let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf); + let d_fn = P(ast::AssocItem { + attrs: thin_vec![d_attr.clone(), inline_never], + id: ast::DUMMY_NODE_ID, + span, + vis, + ident: d_ident, + kind: assoc_item, + tokens: None, + }); + Annotatable::AssocItem(d_fn, Impl) + } else { + let mut d_fn = ecx.item( + span, + d_ident, + thin_vec![d_attr.clone(), inline_never], + ItemKind::Fn(asdf), + ); + d_fn.vis = vis; + Annotatable::Item(d_fn) + }; + + return vec![orig_annotatable, d_annotatable]; + } + + // shadow arguments (the extra ones which were not in the original (primal) function), in reverse mode must be + // mutable references or ptrs, because Enzyme will write into them. + fn assure_mut_ref(ty: &ast::Ty) -> ast::Ty { + let mut ty = ty.clone(); + match ty.kind { + TyKind::Ptr(ref mut mut_ty) => { + mut_ty.mutbl = ast::Mutability::Mut; + } + TyKind::Ref(_, ref mut mut_ty) => { + mut_ty.mutbl = ast::Mutability::Mut; + } + _ => { + panic!("unsupported type: {:?}", ty); + } + } + ty + } + + /// We only want this function to type-check, since we will replace the body + /// later on llvm level. Using `loop {}` does not cover all return types anymore, + /// so instead we build something that should pass. We also add a inline_asm + /// line, as one more barrier for rustc to prevent inlining of this function. + /// FIXME(ZuseZ4): We still have cases of incorrect inlining across modules, see + /// , so this isn't sufficient. + /// It also triggers an Enzyme crash if we due to a bug ever try to differentiate + /// this function (which should never happen, since it is only a placeholder). + /// Finally, we also add back_box usages of all input arguments, to prevent rustc + /// from optimizing any arguments away. + fn gen_enzyme_body( + ecx: &ExtCtxt<'_>, + x: &AutoDiffAttrs, + n_active: u32, + sig: &ast::FnSig, + d_sig: &ast::FnSig, + primal: Ident, + new_names: &[String], + span: Span, + sig_span: Span, + new_decl_span: Span, + idents: Vec, + errored: bool, + ) -> P { + let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]); + let noop = ast::InlineAsm { + asm_macro: ast::AsmMacro::Asm, + template: vec![ast::InlineAsmTemplatePiece::String("NOP".into())], + template_strs: Box::new([]), + operands: vec![], + clobber_abis: vec![], + options: ast::InlineAsmOptions::PURE | ast::InlineAsmOptions::NOMEM, + line_spans: vec![], + }; + let noop_expr = ecx.expr_asm(span, P(noop)); + let unsf = ast::BlockCheckMode::Unsafe(ast::UnsafeSource::CompilerGenerated); + let unsf_block = ast::Block { + stmts: thin_vec![ecx.stmt_semi(noop_expr)], + id: ast::DUMMY_NODE_ID, + tokens: None, + rules: unsf, + span, + could_be_bare_literal: false, + }; + let unsf_expr = ecx.expr_block(P(unsf_block)); + let blackbox_call_expr = ecx.expr_path(ecx.path(span, blackbox_path)); + let primal_call = gen_primal_call(ecx, span, primal, idents); + let black_box_primal_call = + ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![ + primal_call.clone() + ]); + let tup_args = new_names + .iter() + .map(|arg| ecx.expr_path(ecx.path_ident(span, Ident::from_str(arg)))) + .collect(); + + let black_box_remaining_args = + ecx.expr_call(sig_span, blackbox_call_expr.clone(), thin_vec![ + ecx.expr_tuple(sig_span, tup_args) + ]); + + let mut body = ecx.block(span, ThinVec::new()); + body.stmts.push(ecx.stmt_semi(unsf_expr)); + + // This uses primal args which won't be available if we errored before + if !errored { + body.stmts.push(ecx.stmt_semi(black_box_primal_call.clone())); + } + body.stmts.push(ecx.stmt_semi(black_box_remaining_args)); + + if !has_ret(&d_sig.decl.output) { + // there is no return type that we have to match, () works fine. + return body; + } + + // having an active-only return means we'll drop the original return type. + // So that can be treated identical to not having one in the first place. + let primal_ret = has_ret(&sig.decl.output) && !x.has_active_only_ret(); + + if primal_ret && n_active == 0 && x.mode.is_rev() { + // We only have the primal ret. + body.stmts.push(ecx.stmt_expr(black_box_primal_call.clone())); + return body; + } + + if !primal_ret && n_active == 1 { + // Again no tuple return, so return default float val. + let ty = match d_sig.decl.output { + FnRetTy::Ty(ref ty) => ty.clone(), + FnRetTy::Default(span) => { + panic!("Did not expect Default ret ty: {:?}", span); + } + }; + let arg = ty.kind.is_simple_path().unwrap(); + let sl: Vec = vec![arg, kw::Default]; + let tmp = ecx.def_site_path(&sl); + let default_call_expr = ecx.expr_path(ecx.path(span, tmp)); + let default_call_expr = ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]); + body.stmts.push(ecx.stmt_expr(default_call_expr)); + return body; + } + + let mut exprs = ThinVec::>::new(); + if primal_ret { + // We have both primal ret and active floats. + // primal ret is first, by construction. + exprs.push(primal_call.clone()); + } + + // Now construct default placeholder for each active float. + // Is there something nicer than f32::default() and f64::default()? + let d_ret_ty = match d_sig.decl.output { + FnRetTy::Ty(ref ty) => ty.clone(), + FnRetTy::Default(span) => { + panic!("Did not expect Default ret ty: {:?}", span); + } + }; + let mut d_ret_ty = match d_ret_ty.kind.clone() { + TyKind::Tup(ref tys) => tys.clone(), + TyKind::Path(_, rustc_ast::Path { segments, .. }) => { + if let [segment] = &segments[..] + && segment.args.is_none() + { + let id = vec![segments[0].ident]; + let kind = TyKind::Path(None, ecx.path(span, id)); + let ty = P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None }); + thin_vec![ty] + } else { + panic!("Expected tuple or simple path return type"); + } + } + _ => { + // We messed up construction of d_sig + panic!("Did not expect non-tuple ret ty: {:?}", d_ret_ty); + } + }; + + if x.mode.is_fwd() && x.ret_activity == DiffActivity::Dual { + assert!(d_ret_ty.len() == 2); + // both should be identical, by construction + let arg = d_ret_ty[0].kind.is_simple_path().unwrap(); + let arg2 = d_ret_ty[1].kind.is_simple_path().unwrap(); + assert!(arg == arg2); + let sl: Vec = vec![arg, kw::Default]; + let tmp = ecx.def_site_path(&sl); + let default_call_expr = ecx.expr_path(ecx.path(span, tmp)); + let default_call_expr = ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]); + exprs.push(default_call_expr); + } else if x.mode.is_rev() { + if primal_ret { + // We have extra handling above for the primal ret + d_ret_ty = d_ret_ty[1..].to_vec().into(); + } + + for arg in d_ret_ty.iter() { + let arg = arg.kind.is_simple_path().unwrap(); + let sl: Vec = vec![arg, kw::Default]; + let tmp = ecx.def_site_path(&sl); + let default_call_expr = ecx.expr_path(ecx.path(span, tmp)); + let default_call_expr = + ecx.expr_call(new_decl_span, default_call_expr, thin_vec![]); + exprs.push(default_call_expr); + } + } + + let ret: P; + match &exprs[..] { + [] => { + assert!(!has_ret(&d_sig.decl.output)); + // We don't have to match the return type. + return body; + } + [arg] => { + ret = ecx + .expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![arg.clone()]); + } + args => { + let ret_tuple: P = ecx.expr_tuple(span, args.into()); + ret = + ecx.expr_call(new_decl_span, blackbox_call_expr.clone(), thin_vec![ret_tuple]); + } + } + assert!(has_ret(&d_sig.decl.output)); + body.stmts.push(ecx.stmt_expr(ret)); + + body + } + + fn gen_primal_call( + ecx: &ExtCtxt<'_>, + span: Span, + primal: Ident, + idents: Vec, + ) -> P { + let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower; + if has_self { + let args: ThinVec<_> = + idents[1..].iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); + let self_expr = ecx.expr_self(span); + ecx.expr_method_call(span, self_expr, primal, args.clone()) + } else { + let args: ThinVec<_> = + idents.iter().map(|arg| ecx.expr_path(ecx.path_ident(span, *arg))).collect(); + let primal_call_expr = ecx.expr_path(ecx.path_ident(span, primal)); + ecx.expr_call(span, primal_call_expr, args) + } + } + + // Generate the new function declaration. Const arguments are kept as is. Duplicated arguments must + // be pointers or references. Those receive a shadow argument, which is a mutable reference/pointer. + // Active arguments must be scalars. Their shadow argument is added to the return type (and will be + // zero-initialized by Enzyme). + // Each argument of the primal function (and the return type if existing) must be annotated with an + // activity. + // + // Error handling: If the user provides an invalid configuration (incorrect numbers, types, or + // both), we emit an error and return the original signature. This allows us to continue parsing. + fn gen_enzyme_decl( + ecx: &ExtCtxt<'_>, + sig: &ast::FnSig, + x: &AutoDiffAttrs, + span: Span, + ) -> (ast::FnSig, Vec, Vec, bool) { + let dcx = ecx.sess.dcx(); + let has_ret = has_ret(&sig.decl.output); + let sig_args = sig.decl.inputs.len() + if has_ret { 1 } else { 0 }; + let num_activities = x.input_activity.len() + if x.has_ret_activity() { 1 } else { 0 }; + if sig_args != num_activities { + dcx.emit_err(errors::AutoDiffInvalidNumberActivities { + span, + expected: sig_args, + found: num_activities, + }); + // This is not the right signature, but we can continue parsing. + return (sig.clone(), vec![], vec![], true); + } + assert!(sig.decl.inputs.len() == x.input_activity.len()); + assert!(has_ret == x.has_ret_activity()); + let mut d_decl = sig.decl.clone(); + let mut d_inputs = Vec::new(); + let mut new_inputs = Vec::new(); + let mut idents = Vec::new(); + let mut act_ret = ThinVec::new(); + + // We have two loops, a first one just to check the activities and types and possibly report + // multiple errors in one compilation session. + let mut errors = false; + for (arg, activity) in sig.decl.inputs.iter().zip(x.input_activity.iter()) { + if !valid_input_activity(x.mode, *activity) { + dcx.emit_err(errors::AutoDiffInvalidApplicationModeAct { + span, + mode: x.mode.to_string(), + act: activity.to_string(), + }); + errors = true; + } + if !valid_ty_for_activity(&arg.ty, *activity) { + dcx.emit_err(errors::AutoDiffInvalidTypeForActivity { + span: arg.ty.span, + act: activity.to_string(), + }); + errors = true; + } + } + if errors { + // This is not the right signature, but we can continue parsing. + return (sig.clone(), new_inputs, idents, true); + } + let unsafe_activities = x + .input_activity + .iter() + .any(|&act| matches!(act, DiffActivity::DuplicatedOnly | DiffActivity::DualOnly)); + for (arg, activity) in sig.decl.inputs.iter().zip(x.input_activity.iter()) { + d_inputs.push(arg.clone()); + match activity { + DiffActivity::Active => { + act_ret.push(arg.ty.clone()); + } + DiffActivity::ActiveOnly => { + // We will add the active scalar to the return type. + // This is handled later. + } + DiffActivity::Duplicated | DiffActivity::DuplicatedOnly => { + let mut shadow_arg = arg.clone(); + // We += into the shadow in reverse mode. + shadow_arg.ty = P(assure_mut_ref(&arg.ty)); + let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind { + ident.name + } else { + debug!("{:#?}", &shadow_arg.pat); + panic!("not an ident?"); + }; + let name: String = format!("d{}", old_name); + new_inputs.push(name.clone()); + let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span); + shadow_arg.pat = P(ast::Pat { + id: ast::DUMMY_NODE_ID, + kind: PatKind::Ident(BindingMode::NONE, ident, None), + span: shadow_arg.pat.span, + tokens: shadow_arg.pat.tokens.clone(), + }); + d_inputs.push(shadow_arg); + } + DiffActivity::Dual | DiffActivity::DualOnly => { + let mut shadow_arg = arg.clone(); + let old_name = if let PatKind::Ident(_, ident, _) = arg.pat.kind { + ident.name + } else { + debug!("{:#?}", &shadow_arg.pat); + panic!("not an ident?"); + }; + let name: String = format!("b{}", old_name); + new_inputs.push(name.clone()); + let ident = Ident::from_str_and_span(&name, shadow_arg.pat.span); + shadow_arg.pat = P(ast::Pat { + id: ast::DUMMY_NODE_ID, + kind: PatKind::Ident(BindingMode::NONE, ident, None), + span: shadow_arg.pat.span, + tokens: shadow_arg.pat.tokens.clone(), + }); + d_inputs.push(shadow_arg); + } + DiffActivity::Const => { + // Nothing to do here. + } + DiffActivity::None | DiffActivity::FakeActivitySize => { + panic!("Should not happen"); + } + } + if let PatKind::Ident(_, ident, _) = arg.pat.kind { + idents.push(ident.clone()); + } else { + panic!("not an ident?"); + } + } + + let active_only_ret = x.ret_activity == DiffActivity::ActiveOnly; + if active_only_ret { + assert!(x.mode.is_rev()); + } + + // If we return a scalar in the primal and the scalar is active, + // then add it as last arg to the inputs. + if x.mode.is_rev() { + match x.ret_activity { + DiffActivity::Active | DiffActivity::ActiveOnly => { + let ty = match d_decl.output { + FnRetTy::Ty(ref ty) => ty.clone(), + FnRetTy::Default(span) => { + panic!("Did not expect Default ret ty: {:?}", span); + } + }; + let name = "dret".to_string(); + let ident = Ident::from_str_and_span(&name, ty.span); + let shadow_arg = ast::Param { + attrs: ThinVec::new(), + ty: ty.clone(), + pat: P(ast::Pat { + id: ast::DUMMY_NODE_ID, + kind: PatKind::Ident(BindingMode::NONE, ident, None), + span: ty.span, + tokens: None, + }), + id: ast::DUMMY_NODE_ID, + span: ty.span, + is_placeholder: false, + }; + d_inputs.push(shadow_arg); + new_inputs.push(name); + } + _ => {} + } + } + d_decl.inputs = d_inputs.into(); + + if x.mode.is_fwd() { + if let DiffActivity::Dual = x.ret_activity { + let ty = match d_decl.output { + FnRetTy::Ty(ref ty) => ty.clone(), + FnRetTy::Default(span) => { + panic!("Did not expect Default ret ty: {:?}", span); + } + }; + // Dual can only be used for f32/f64 ret. + // In that case we return now a tuple with two floats. + let kind = TyKind::Tup(thin_vec![ty.clone(), ty.clone()]); + let ty = P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None }); + d_decl.output = FnRetTy::Ty(ty); + } + if let DiffActivity::DualOnly = x.ret_activity { + // No need to change the return type, + // we will just return the shadow in place + // of the primal return. + } + } + + // If we use ActiveOnly, drop the original return value. + d_decl.output = + if active_only_ret { FnRetTy::Default(span) } else { d_decl.output.clone() }; + + trace!("act_ret: {:?}", act_ret); + + // If we have an active input scalar, add it's gradient to the + // return type. This might require changing the return type to a + // tuple. + if act_ret.len() > 0 { + let ret_ty = match d_decl.output { + FnRetTy::Ty(ref ty) => { + if !active_only_ret { + act_ret.insert(0, ty.clone()); + } + let kind = TyKind::Tup(act_ret); + P(rustc_ast::Ty { kind, id: ty.id, span: ty.span, tokens: None }) + } + FnRetTy::Default(span) => { + if act_ret.len() == 1 { + act_ret[0].clone() + } else { + let kind = TyKind::Tup(act_ret.iter().map(|arg| arg.clone()).collect()); + P(rustc_ast::Ty { kind, id: ast::DUMMY_NODE_ID, span, tokens: None }) + } + } + }; + d_decl.output = FnRetTy::Ty(ret_ty); + } + + let mut d_header = sig.header.clone(); + if unsafe_activities { + d_header.safety = rustc_ast::Safety::Unsafe(span); + } + let d_sig = FnSig { header: d_header, decl: d_decl, span }; + trace!("Generated signature: {:?}", d_sig); + (d_sig, new_inputs, idents, false) + } +} + +#[cfg(not(llvm_enzyme))] +mod ad_fallback { + use rustc_ast::ast; + use rustc_expand::base::{Annotatable, ExtCtxt}; + use rustc_span::Span; + + use crate::errors; + pub(crate) fn expand( + ecx: &mut ExtCtxt<'_>, + _expand_span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, + ) -> Vec { + ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); + return vec![item]; + } +} + +#[cfg(not(llvm_enzyme))] +pub(crate) use ad_fallback::expand; +#[cfg(llvm_enzyme)] +pub(crate) use llvm_enzyme::expand; diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 639c2aa231cb..f8e65661e52e 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -145,6 +145,78 @@ pub(crate) struct AllocMustStatics { pub(crate) span: Span, } +#[cfg(llvm_enzyme)] +pub(crate) use autodiff::*; + +#[cfg(llvm_enzyme)] +mod autodiff { + use super::*; + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_missing_config)] + pub(crate) struct AutoDiffMissingConfig { + #[primary_span] + pub(crate) span: Span, + } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_unknown_activity)] + pub(crate) struct AutoDiffUnknownActivity { + #[primary_span] + pub(crate) span: Span, + pub(crate) act: String, + } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_ty_activity)] + pub(crate) struct AutoDiffInvalidTypeForActivity { + #[primary_span] + pub(crate) span: Span, + pub(crate) act: String, + } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_number_activities)] + pub(crate) struct AutoDiffInvalidNumberActivities { + #[primary_span] + pub(crate) span: Span, + pub(crate) expected: usize, + pub(crate) found: usize, + } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_mode_activity)] + pub(crate) struct AutoDiffInvalidApplicationModeAct { + #[primary_span] + pub(crate) span: Span, + pub(crate) mode: String, + pub(crate) act: String, + } + + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_mode)] + pub(crate) struct AutoDiffInvalidMode { + #[primary_span] + pub(crate) span: Span, + pub(crate) mode: String, + } + + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff)] + pub(crate) struct AutoDiffInvalidApplication { + #[primary_span] + pub(crate) span: Span, + } +} + +#[cfg(not(llvm_enzyme))] +pub(crate) use ad_fallback::*; +#[cfg(not(llvm_enzyme))] +mod ad_fallback { + use super::*; + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_not_build)] + pub(crate) struct AutoDiffSupportNotBuild { + #[primary_span] + pub(crate) span: Span, + } +} + #[derive(Diagnostic)] #[diag(builtin_macros_concat_bytes_invalid)] pub(crate) struct ConcatBytesInvalid { diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index ebe5e2b54429..377d7f542cf4 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -5,6 +5,7 @@ #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +#![cfg_attr(not(bootstrap), feature(autodiff))] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] @@ -29,6 +30,7 @@ use crate::deriving::*; mod alloc_error_handler; mod assert; +mod autodiff; mod cfg; mod cfg_accessible; mod cfg_eval; @@ -106,6 +108,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { register_attr! { alloc_error_handler: alloc_error_handler::expand, + autodiff: autodiff::expand, bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b5945759d43a..743a9854f796 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -220,6 +220,10 @@ impl<'a> ExtCtxt<'a> { self.stmt_local(local, span) } + pub fn stmt_semi(&self, expr: P) -> ast::Stmt { + ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Semi(expr) } + } + pub fn stmt_local(&self, local: P, span: Span) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Let(local), span } } @@ -287,6 +291,25 @@ impl<'a> ExtCtxt<'a> { self.expr(sp, ast::ExprKind::Paren(e)) } + pub fn expr_method_call( + &self, + span: Span, + expr: P, + ident: Ident, + args: ThinVec>, + ) -> P { + let seg = ast::PathSegment::from_ident(ident); + self.expr( + span, + ast::ExprKind::MethodCall(Box::new(ast::MethodCall { + seg, + receiver: expr, + args, + span, + })), + ) + } + pub fn expr_call( &self, span: Span, @@ -295,6 +318,12 @@ impl<'a> ExtCtxt<'a> { ) -> P { self.expr(span, ast::ExprKind::Call(expr, args)) } + pub fn expr_loop(&self, sp: Span, block: P) -> P { + self.expr(sp, ast::ExprKind::Loop(block, None, sp)) + } + pub fn expr_asm(&self, sp: Span, expr: P) -> P { + self.expr(sp, ast::ExprKind::InlineAsm(expr)) + } pub fn expr_call_ident( &self, span: Span, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 17827b4e43b3..477760a45975 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -752,6 +752,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ template!(NameValueStr: "transparent|semitransparent|opaque"), ErrorFollowing, EncodeCrossCrate::Yes, "used internally for testing macro hygiene", ), + rustc_attr!( + rustc_autodiff, Normal, + template!(Word, List: r#""...""#), DuplicatesOk, + EncodeCrossCrate::No, INTERNAL_UNSTABLE + ), // ========================================================================== // Internal attributes, Diagnostics related: diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index be76d6cef2b8..d60d7e00d4bb 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -49,6 +49,10 @@ passes_attr_crate_level = passes_attr_only_in_functions = `{$attr}` attribute can only be used on functions +passes_autodiff_attr = + `#[autodiff]` should be applied to a function + .label = not a function + passes_both_ffi_const_and_pure = `#[ffi_const]` function cannot be `#[ffi_pure]` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 44a62383e6ee..7ce29260e367 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -243,6 +243,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_generic_attr(hir_id, attr, target, Target::Fn); self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } + [sym::autodiff, ..] => { + self.check_autodiff(hir_id, attr, span, target) + } [sym::coroutine, ..] => { self.check_coroutine(attr, target); } @@ -2345,6 +2348,18 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(errors::RustcPubTransparent { span, attr_span }); } } + + /// Checks if `#[autodiff]` is applied to an item other than a function item. + fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) { + debug!("check_autodiff"); + match target { + Target::Fn => {} + _ => { + self.dcx().emit_err(errors::AutoDiffAttr { attr_span: span }); + self.abort.set(true); + } + } + } } impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4f00c90fa3b0..70f525ec0e81 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -20,6 +20,14 @@ use crate::lang_items::Duplicate; #[diag(passes_incorrect_do_not_recommend_location)] pub(crate) struct IncorrectDoNotRecommendLocation; +#[derive(Diagnostic)] +#[diag(passes_autodiff_attr)] +pub(crate) struct AutoDiffAttr { + #[primary_span] + #[label] + pub attr_span: Span, +} + #[derive(LintDiagnostic)] #[diag(passes_outer_crate_level_attr)] pub(crate) struct OuterCrateLevelAttr; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8e0009695db6..92946ef52623 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -481,6 +481,8 @@ symbols! { audit_that, augmented_assignments, auto_traits, + autodiff, + autodiff_fallback, automatically_derived, avx, avx512_target_feature, @@ -544,6 +546,7 @@ symbols! { cfg_accessible, cfg_attr, cfg_attr_multi, + cfg_autodiff_fallback, cfg_boolean_literals, cfg_doctest, cfg_eval, @@ -998,6 +1001,7 @@ symbols! { hashset_iter_ty, hexagon_target_feature, hidden, + hint, homogeneous_aggregate, host, html_favicon_url, @@ -1650,6 +1654,7 @@ symbols! { rustc_allow_incoherent_impl, rustc_allowed_through_unstable_modules, rustc_attrs, + rustc_autodiff, rustc_box, rustc_builtin_macro, rustc_capture_analysis, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 96ab5755328e..f69a33bca844 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -278,6 +278,15 @@ pub mod assert_matches { pub use crate::macros::{assert_matches, debug_assert_matches}; } +// We don't export this through #[macro_export] for now, to avoid breakage. +#[cfg(not(bootstrap))] +#[unstable(feature = "autodiff", issue = "124509")] +/// Unstable module containing the unstable `autodiff` macro. +pub mod autodiff { + #[unstable(feature = "autodiff", issue = "124509")] + pub use crate::macros::builtin::autodiff; +} + #[unstable(feature = "cfg_match", issue = "115585")] pub use crate::macros::cfg_match; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index aa0646846e43..b5e5b58f7051 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1539,6 +1539,24 @@ pub(crate) mod builtin { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } + /// Automatic Differentiation macro which allows generating a new function to compute + /// the derivative of a given function. It may only be applied to a function. + /// The expected usage syntax is + /// `#[autodiff(NAME, MODE, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]` + /// where: + /// NAME is a string that represents a valid function name. + /// MODE is any of Forward, Reverse, ForwardFirst, ReverseFirst. + /// INPUT_ACTIVITIES consists of one valid activity for each input parameter. + /// OUTPUT_ACTIVITY must not be set if we implicitely return nothing (or explicitely return + /// `-> ()`. Otherwise it must be set to one of the allowed activities. + #[unstable(feature = "autodiff", issue = "124509")] + #[allow_internal_unstable(rustc_attrs)] + #[rustc_builtin_macro] + #[cfg(not(bootstrap))] + pub macro autodiff($item:item) { + /* compiler built-in */ + } + /// Asserts that a boolean expression is `true` at runtime. /// /// This will invoke the [`panic!`] macro if the provided expression cannot be diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 65a9aa66c7cc..35ed761759bd 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -267,6 +267,7 @@ #![allow(unused_features)] // // Features: +#![cfg_attr(not(bootstrap), feature(autodiff))] #![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))] #![cfg_attr( all(target_vendor = "fortanix", target_env = "sgx"), @@ -627,7 +628,13 @@ pub mod simd { #[doc(inline)] pub use crate::std_float::StdFloat; } - +#[cfg(not(bootstrap))] +#[unstable(feature = "autodiff", issue = "124509")] +/// This module provides support for automatic differentiation. +pub mod autodiff { + /// This macro handles automatic differentiation. + pub use core::autodiff::autodiff; +} #[stable(feature = "futures_api", since = "1.36.0")] pub mod task { //! Types and Traits for working with asynchronous tasks. From 7c37d2db98ec28b633ddc69ca0cf0ca651ae00b3 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Fri, 11 Oct 2024 20:38:43 +0200 Subject: [PATCH 031/118] Add pretty, ui, and feature-gate tests for the enzyme/autodiff frontend --- tests/pretty/autodiff_forward.pp | 107 ++++++++++++ tests/pretty/autodiff_forward.rs | 39 +++++ tests/pretty/autodiff_reverse.pp | 86 ++++++++++ tests/pretty/autodiff_reverse.rs | 40 +++++ tests/ui/autodiff/autodiff_illegal.rs | 160 ++++++++++++++++++ tests/ui/autodiff/autodiff_illegal.stderr | 152 +++++++++++++++++ tests/ui/autodiff/auxiliary/my_macro.rs | 12 ++ tests/ui/autodiff/visibility.rs | 17 ++ .../autodiff/visibility.std_autodiff.stderr | 24 +++ ...ature-gate-autodiff-use.has_support.stderr | 23 +++ ...eature-gate-autodiff-use.no_support.stderr | 29 ++++ .../feature-gate-autodiff-use.rs | 17 ++ .../feature-gate-autodiff.has_support.stderr | 13 ++ .../feature-gate-autodiff.no_support.stderr | 13 ++ .../ui/feature-gates/feature-gate-autodiff.rs | 12 ++ 15 files changed, 744 insertions(+) create mode 100644 tests/pretty/autodiff_forward.pp create mode 100644 tests/pretty/autodiff_forward.rs create mode 100644 tests/pretty/autodiff_reverse.pp create mode 100644 tests/pretty/autodiff_reverse.rs create mode 100644 tests/ui/autodiff/autodiff_illegal.rs create mode 100644 tests/ui/autodiff/autodiff_illegal.stderr create mode 100644 tests/ui/autodiff/auxiliary/my_macro.rs create mode 100644 tests/ui/autodiff/visibility.rs create mode 100644 tests/ui/autodiff/visibility.std_autodiff.stderr create mode 100644 tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr create mode 100644 tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr create mode 100644 tests/ui/feature-gates/feature-gate-autodiff-use.rs create mode 100644 tests/ui/feature-gates/feature-gate-autodiff.has_support.stderr create mode 100644 tests/ui/feature-gates/feature-gate-autodiff.no_support.stderr create mode 100644 tests/ui/feature-gates/feature-gate-autodiff.rs diff --git a/tests/pretty/autodiff_forward.pp b/tests/pretty/autodiff_forward.pp new file mode 100644 index 000000000000..23c3b5b34a82 --- /dev/null +++ b/tests/pretty/autodiff_forward.pp @@ -0,0 +1,107 @@ +#![feature(prelude_import)] +#![no_std] +//@ needs-enzyme + +#![feature(autodiff)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ pretty-mode:expanded +//@ pretty-compare-only +//@ pp-exact:autodiff_forward.pp + +// Test that forward mode ad macros are expanded correctly. + +use std::autodiff::autodiff; + +#[rustc_autodiff] +#[inline(never)] +pub fn f1(x: &[f64], y: f64) -> f64 { + + + + // Not the most interesting derivative, but who are we to judge + + // We want to be sure that the same function can be differentiated in different ways + + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(Forward, Dual, Const, Dual,)] +#[inline(never)] +pub fn df1(x: &[f64], bx: &[f64], y: f64) -> (f64, f64) { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f1(x, y)); + ::core::hint::black_box((bx,)); + ::core::hint::black_box((f1(x, y), f64::default())) +} +#[rustc_autodiff] +#[inline(never)] +pub fn f2(x: &[f64], y: f64) -> f64 { + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(Forward, Dual, Const, Const,)] +#[inline(never)] +pub fn df2(x: &[f64], bx: &[f64], y: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f2(x, y)); + ::core::hint::black_box((bx,)); + ::core::hint::black_box(f2(x, y)) +} +#[rustc_autodiff] +#[inline(never)] +pub fn f3(x: &[f64], y: f64) -> f64 { + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(ForwardFirst, Dual, Const, Const,)] +#[inline(never)] +pub fn df3(x: &[f64], bx: &[f64], y: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f3(x, y)); + ::core::hint::black_box((bx,)); + ::core::hint::black_box(f3(x, y)) +} +#[rustc_autodiff] +#[inline(never)] +pub fn f4() {} +#[rustc_autodiff(Forward, None)] +#[inline(never)] +pub fn df4() { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f4()); + ::core::hint::black_box(()); +} +#[rustc_autodiff] +#[inline(never)] +#[rustc_autodiff] +#[inline(never)] +#[rustc_autodiff] +#[inline(never)] +pub fn f5(x: &[f64], y: f64) -> f64 { + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(Forward, Const, Dual, Const,)] +#[inline(never)] +pub fn df5_y(x: &[f64], y: f64, by: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f5(x, y)); + ::core::hint::black_box((by,)); + ::core::hint::black_box(f5(x, y)) +} +#[rustc_autodiff(Forward, Dual, Const, Const,)] +#[inline(never)] +pub fn df5_x(x: &[f64], bx: &[f64], y: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f5(x, y)); + ::core::hint::black_box((bx,)); + ::core::hint::black_box(f5(x, y)) +} +#[rustc_autodiff(Reverse, Duplicated, Const, Active,)] +#[inline(never)] +pub fn df5_rev(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f5(x, y)); + ::core::hint::black_box((dx, dret)); + ::core::hint::black_box(f5(x, y)) +} +fn main() {} diff --git a/tests/pretty/autodiff_forward.rs b/tests/pretty/autodiff_forward.rs new file mode 100644 index 000000000000..35108d0d6f11 --- /dev/null +++ b/tests/pretty/autodiff_forward.rs @@ -0,0 +1,39 @@ +//@ needs-enzyme + +#![feature(autodiff)] +//@ pretty-mode:expanded +//@ pretty-compare-only +//@ pp-exact:autodiff_forward.pp + +// Test that forward mode ad macros are expanded correctly. + +use std::autodiff::autodiff; + +#[autodiff(df1, Forward, Dual, Const, Dual)] +pub fn f1(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +#[autodiff(df2, Forward, Dual, Const, Const)] +pub fn f2(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +#[autodiff(df3, ForwardFirst, Dual, Const, Const)] +pub fn f3(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +// Not the most interesting derivative, but who are we to judge +#[autodiff(df4, Forward)] +pub fn f4() {} + +// We want to be sure that the same function can be differentiated in different ways +#[autodiff(df5_rev, Reverse, Duplicated, Const, Active)] +#[autodiff(df5_x, Forward, Dual, Const, Const)] +#[autodiff(df5_y, Forward, Const, Dual, Const)] +pub fn f5(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +fn main() {} diff --git a/tests/pretty/autodiff_reverse.pp b/tests/pretty/autodiff_reverse.pp new file mode 100644 index 000000000000..a98d3782c703 --- /dev/null +++ b/tests/pretty/autodiff_reverse.pp @@ -0,0 +1,86 @@ +#![feature(prelude_import)] +#![no_std] +//@ needs-enzyme + +#![feature(autodiff)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ pretty-mode:expanded +//@ pretty-compare-only +//@ pp-exact:autodiff_reverse.pp + +// Test that reverse mode ad macros are expanded correctly. + +use std::autodiff::autodiff; + +#[rustc_autodiff] +#[inline(never)] +pub fn f1(x: &[f64], y: f64) -> f64 { + + // Not the most interesting derivative, but who are we to judge + + + // What happens if we already have Reverse in type (enum variant decl) and value (enum variant + // constructor) namespace? > It's expected to work normally. + + + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(Reverse, Duplicated, Const, Active,)] +#[inline(never)] +pub fn df1(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f1(x, y)); + ::core::hint::black_box((dx, dret)); + ::core::hint::black_box(f1(x, y)) +} +#[rustc_autodiff] +#[inline(never)] +pub fn f2() {} +#[rustc_autodiff(Reverse, None)] +#[inline(never)] +pub fn df2() { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f2()); + ::core::hint::black_box(()); +} +#[rustc_autodiff] +#[inline(never)] +pub fn f3(x: &[f64], y: f64) -> f64 { + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(ReverseFirst, Duplicated, Const, Active,)] +#[inline(never)] +pub fn df3(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f3(x, y)); + ::core::hint::black_box((dx, dret)); + ::core::hint::black_box(f3(x, y)) +} +enum Foo { Reverse, } +use Foo::Reverse; +#[rustc_autodiff] +#[inline(never)] +pub fn f4(x: f32) { ::core::panicking::panic("not implemented") } +#[rustc_autodiff(Reverse, Const, None)] +#[inline(never)] +pub fn df4(x: f32) { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f4(x)); + ::core::hint::black_box(()); +} +#[rustc_autodiff] +#[inline(never)] +pub fn f5(x: *const f32, y: &f32) { + ::core::panicking::panic("not implemented") +} +#[rustc_autodiff(Reverse, DuplicatedOnly, Duplicated, None)] +#[inline(never)] +pub unsafe fn df5(x: *const f32, dx: *mut f32, y: &f32, dy: &mut f32) { + unsafe { asm!("NOP", options(pure, nomem)); }; + ::core::hint::black_box(f5(x, y)); + ::core::hint::black_box((dx, dy)); +} +fn main() {} diff --git a/tests/pretty/autodiff_reverse.rs b/tests/pretty/autodiff_reverse.rs new file mode 100644 index 000000000000..657201caa940 --- /dev/null +++ b/tests/pretty/autodiff_reverse.rs @@ -0,0 +1,40 @@ +//@ needs-enzyme + +#![feature(autodiff)] +//@ pretty-mode:expanded +//@ pretty-compare-only +//@ pp-exact:autodiff_reverse.pp + +// Test that reverse mode ad macros are expanded correctly. + +use std::autodiff::autodiff; + +#[autodiff(df1, Reverse, Duplicated, Const, Active)] +pub fn f1(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +// Not the most interesting derivative, but who are we to judge +#[autodiff(df2, Reverse)] +pub fn f2() {} + +#[autodiff(df3, ReverseFirst, Duplicated, Const, Active)] +pub fn f3(x: &[f64], y: f64) -> f64 { + unimplemented!() +} + +enum Foo { Reverse } +use Foo::Reverse; +// What happens if we already have Reverse in type (enum variant decl) and value (enum variant +// constructor) namespace? > It's expected to work normally. +#[autodiff(df4, Reverse, Const)] +pub fn f4(x: f32) { + unimplemented!() +} + +#[autodiff(df5, Reverse, DuplicatedOnly, Duplicated)] +pub fn f5(x: *const f32, y: &f32) { + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs new file mode 100644 index 000000000000..c0548d2bbb8f --- /dev/null +++ b/tests/ui/autodiff/autodiff_illegal.rs @@ -0,0 +1,160 @@ +//@ needs-enzyme + +#![feature(autodiff)] +//@ pretty-mode:expanded +//@ pretty-compare-only +//@ pp-exact:autodiff_illegal.pp + +// Test that invalid ad macros give nice errors and don't ICE. + +use std::autodiff::autodiff; + +// We can't use Duplicated on scalars +#[autodiff(df1, Reverse, Duplicated)] +pub fn f1(x: f64) { +//~^ ERROR Duplicated can not be used for this type + unimplemented!() +} + +// Too many activities +#[autodiff(df3, Reverse, Duplicated, Const)] +pub fn f3(x: f64) { +//~^^ ERROR expected 1 activities, but found 2 + unimplemented!() +} + +// To few activities +#[autodiff(df4, Reverse)] +pub fn f4(x: f64) { +//~^^ ERROR expected 1 activities, but found 0 + unimplemented!() +} + +// We can't use Dual in Reverse mode +#[autodiff(df5, Reverse, Dual)] +pub fn f5(x: f64) { +//~^^ ERROR Dual can not be used in Reverse Mode + unimplemented!() +} + +// We can't use Duplicated in Forward mode +#[autodiff(df6, Forward, Duplicated)] +pub fn f6(x: f64) { +//~^^ ERROR Duplicated can not be used in Forward Mode +//~^^ ERROR Duplicated can not be used for this type + unimplemented!() +} + +fn dummy() { + + #[autodiff(df7, Forward, Dual)] + let mut x = 5; + //~^ ERROR autodiff must be applied to function + + #[autodiff(df7, Forward, Dual)] + x = x + 3; + //~^^ ERROR attributes on expressions are experimental [E0658] + //~^^ ERROR autodiff must be applied to function + + #[autodiff(df7, Forward, Dual)] + let add_one_v2 = |x: u32| -> u32 { x + 1 }; + //~^ ERROR autodiff must be applied to function +} + +// Malformed, where args? +#[autodiff] +pub fn f7(x: f64) { +//~^ ERROR autodiff must be applied to function + unimplemented!() +} + +// Malformed, where args? +#[autodiff()] +pub fn f8(x: f64) { +//~^ ERROR autodiff requires at least a name and mode + unimplemented!() +} + +// Invalid attribute syntax +#[autodiff = ""] +pub fn f9(x: f64) { +//~^ ERROR autodiff must be applied to function + unimplemented!() +} + +fn fn_exists() {} + +// We colide with an already existing function +#[autodiff(fn_exists, Reverse, Active)] +pub fn f10(x: f64) { +//~^^ ERROR the name `fn_exists` is defined multiple times [E0428] + unimplemented!() +} + +// Malformed, missing a mode +#[autodiff(df11)] +pub fn f11() { +//~^ ERROR autodiff requires at least a name and mode + unimplemented!() +} + +// Invalid Mode +#[autodiff(df12, Debug)] +pub fn f12() { +//~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse` + unimplemented!() +} + +// Invalid, please pick one Mode +// or use two autodiff macros. +#[autodiff(df13, Forward, Reverse)] +pub fn f13() { +//~^^ ERROR did not recognize Activity: `Reverse` + unimplemented!() +} + +struct Foo {} + +// We can't handle Active structs, because that would mean (in the general case), that we would +// need to allocate and initialize arbitrary user types. We have Duplicated/Dual input args for +// that. FIXME: Give a nicer error and suggest to the user to have a `&mut Foo` input instead. +#[autodiff(df14, Reverse, Active, Active)] +fn f14(x: f32) -> Foo { + unimplemented!() +} + +type MyFloat = f32; + +// We would like to support type alias to f32/f64 in argument type in the future, +// but that requires us to implement our checks at a later stage +// like THIR which has type information available. +#[autodiff(df15, Reverse, Active, Active)] +fn f15(x: MyFloat) -> f32 { +//~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] + unimplemented!() +} + +// We would like to support type alias to f32/f64 in return type in the future +#[autodiff(df16, Reverse, Active, Active)] +fn f16(x: f32) -> MyFloat { + unimplemented!() +} + +#[repr(transparent)] +struct F64Trans { inner: f64 } + +// We would like to support `#[repr(transparent)]` f32/f64 wrapper in return type in the future +#[autodiff(df17, Reverse, Active, Active)] +fn f17(x: f64) -> F64Trans { + unimplemented!() +} + +// We would like to support `#[repr(transparent)]` f32/f64 wrapper in argument type in the future +#[autodiff(df18, Reverse, Active, Active)] +fn f18(x: F64Trans) -> f64 { + //~^^ ERROR failed to resolve: use of undeclared type `F64Trans` [E0433] + unimplemented!() +} + + +fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr new file mode 100644 index 000000000000..3a7242b2f5d9 --- /dev/null +++ b/tests/ui/autodiff/autodiff_illegal.stderr @@ -0,0 +1,152 @@ +error[E0658]: attributes on expressions are experimental + --> $DIR/autodiff_illegal.rs:54:5 + | +LL | #[autodiff(df7, Forward, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #15701 for more information + = help: add `#![feature(stmt_expr_attributes)]` 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: Duplicated can not be used for this type + --> $DIR/autodiff_illegal.rs:14:14 + | +LL | pub fn f1(x: f64) { + | ^^^ + +error: expected 1 activities, but found 2 + --> $DIR/autodiff_illegal.rs:20:1 + | +LL | #[autodiff(df3, Reverse, Duplicated, Const)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected 1 activities, but found 0 + --> $DIR/autodiff_illegal.rs:27:1 + | +LL | #[autodiff(df4, Reverse)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: Dual can not be used in Reverse Mode + --> $DIR/autodiff_illegal.rs:34:1 + | +LL | #[autodiff(df5, Reverse, Dual)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: Duplicated can not be used in Forward Mode + --> $DIR/autodiff_illegal.rs:41:1 + | +LL | #[autodiff(df6, Forward, Duplicated)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: Duplicated can not be used for this type + --> $DIR/autodiff_illegal.rs:42:14 + | +LL | pub fn f6(x: f64) { + | ^^^ + +error: autodiff must be applied to function + --> $DIR/autodiff_illegal.rs:51:5 + | +LL | let mut x = 5; + | ^^^^^^^^^^^^^^ + +error: autodiff must be applied to function + --> $DIR/autodiff_illegal.rs:55:5 + | +LL | x = x + 3; + | ^ + +error: autodiff must be applied to function + --> $DIR/autodiff_illegal.rs:60:5 + | +LL | let add_one_v2 = |x: u32| -> u32 { x + 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: autodiff must be applied to function + --> $DIR/autodiff_illegal.rs:66:1 + | +LL | / pub fn f7(x: f64) { +LL | | +LL | | unimplemented!() +LL | | } + | |_^ + +error: autodiff requires at least a name and mode + --> $DIR/autodiff_illegal.rs:73:1 + | +LL | / pub fn f8(x: f64) { +LL | | +LL | | unimplemented!() +LL | | } + | |_^ + +error: autodiff must be applied to function + --> $DIR/autodiff_illegal.rs:80:1 + | +LL | / pub fn f9(x: f64) { +LL | | +LL | | unimplemented!() +LL | | } + | |_^ + +error[E0428]: the name `fn_exists` is defined multiple times + --> $DIR/autodiff_illegal.rs:88:1 + | +LL | fn fn_exists() {} + | -------------- previous definition of the value `fn_exists` here +... +LL | #[autodiff(fn_exists, Reverse, Active)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn_exists` redefined here + | + = note: `fn_exists` must be defined only once in the value namespace of this module + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: autodiff requires at least a name and mode + --> $DIR/autodiff_illegal.rs:96:1 + | +LL | / pub fn f11() { +LL | | +LL | | unimplemented!() +LL | | } + | |_^ + +error: unknown Mode: `Debug`. Use `Forward` or `Reverse` + --> $DIR/autodiff_illegal.rs:102:18 + | +LL | #[autodiff(df12, Debug)] + | ^^^^^ + +error: did not recognize Activity: `Reverse` + --> $DIR/autodiff_illegal.rs:110:27 + | +LL | #[autodiff(df13, Forward, Reverse)] + | ^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type `MyFloat` + --> $DIR/autodiff_illegal.rs:131:1 + | +LL | #[autodiff(df15, Reverse, Active, Active)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat` + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0433]: failed to resolve: use of undeclared type `F64Trans` + --> $DIR/autodiff_illegal.rs:153:1 + | +LL | #[autodiff(df18, Reverse, Active, Active)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans` + | + = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 19 previous errors + +Some errors have detailed explanations: E0428, E0433, E0658. +For more information about an error, try `rustc --explain E0428`. diff --git a/tests/ui/autodiff/auxiliary/my_macro.rs b/tests/ui/autodiff/auxiliary/my_macro.rs new file mode 100644 index 000000000000..417199611cca --- /dev/null +++ b/tests/ui/autodiff/auxiliary/my_macro.rs @@ -0,0 +1,12 @@ +//@ force-host +//@ no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +#[macro_use] +pub fn autodiff(_attr: TokenStream, item: TokenStream) -> TokenStream { + item // identity proc-macro +} diff --git a/tests/ui/autodiff/visibility.rs b/tests/ui/autodiff/visibility.rs new file mode 100644 index 000000000000..6a4851de2dc0 --- /dev/null +++ b/tests/ui/autodiff/visibility.rs @@ -0,0 +1,17 @@ +//@ ignore-enzyme +//@ revisions: std_autodiff no_std_autodiff +//@[no_std_autodiff] check-pass +//@ aux-build: my_macro.rs +#![crate_type = "lib"] +#![feature(autodiff)] + +#[cfg(std_autodiff)] +use std::autodiff::autodiff; + +extern crate my_macro; +use my_macro::autodiff; // bring `autodiff` in scope + +#[autodiff] +//[std_autodiff]~^^^ ERROR the name `autodiff` is defined multiple times +//[std_autodiff]~^^ ERROR this rustc version does not support autodiff +fn foo() {} diff --git a/tests/ui/autodiff/visibility.std_autodiff.stderr b/tests/ui/autodiff/visibility.std_autodiff.stderr new file mode 100644 index 000000000000..720c9a00170e --- /dev/null +++ b/tests/ui/autodiff/visibility.std_autodiff.stderr @@ -0,0 +1,24 @@ +error[E0252]: the name `autodiff` is defined multiple times + --> $DIR/visibility.rs:12:5 + | +LL | use std::autodiff::autodiff; + | ----------------------- previous import of the macro `autodiff` here +... +LL | use my_macro::autodiff; // bring `autodiff` in scope + | ^^^^^^^^^^^^^^^^^^ `autodiff` reimported here + | + = note: `autodiff` must be defined only once in the macro namespace of this module +help: you can use `as` to change the binding name of the import + | +LL | use my_macro::autodiff as other_autodiff; // bring `autodiff` in scope + | +++++++++++++++++ + +error: this rustc version does not support autodiff + --> $DIR/visibility.rs:14:1 + | +LL | #[autodiff] + | ^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0252`. diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr new file mode 100644 index 000000000000..36a017dd53c2 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr @@ -0,0 +1,23 @@ +error[E0658]: use of unstable library feature 'autodiff' + --> $DIR/feature-gate-autodiff-use.rs:13:3 + | +LL | #[autodiff(dfoo, Reverse)] + | ^^^^^^^^ + | + = note: see issue #124509 for more information + = help: add `#![feature(autodiff)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: use of unstable library feature 'autodiff' + --> $DIR/feature-gate-autodiff-use.rs:9:5 + | +LL | use std::autodiff::autodiff; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #124509 for more information + = help: add `#![feature(autodiff)]` 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: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr new file mode 100644 index 000000000000..4b767f824c80 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr @@ -0,0 +1,29 @@ +error[E0658]: use of unstable library feature 'autodiff' + --> $DIR/feature-gate-autodiff-use.rs:13:3 + | +LL | #[autodiff(dfoo, Reverse)] + | ^^^^^^^^ + | + = note: see issue #124509 for more information + = help: add `#![feature(autodiff)]` 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: this rustc version does not support autodiff + --> $DIR/feature-gate-autodiff-use.rs:13:1 + | +LL | #[autodiff(dfoo, Reverse)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0658]: use of unstable library feature 'autodiff' + --> $DIR/feature-gate-autodiff-use.rs:9:5 + | +LL | use std::autodiff::autodiff; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #124509 for more information + = help: add `#![feature(autodiff)]` 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: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-autodiff-use.rs b/tests/ui/feature-gates/feature-gate-autodiff-use.rs new file mode 100644 index 000000000000..2276a79d6e2d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff-use.rs @@ -0,0 +1,17 @@ +//@ revisions: has_support no_support +//@[no_support] ignore-enzyme +//@[has_support] needs-enzyme + +// This checks that without enabling the autodiff feature, we can't import std::autodiff::autodiff; + +#![crate_type = "lib"] + +use std::autodiff::autodiff; +//[has_support]~^ ERROR use of unstable library feature 'autodiff' +//[no_support]~^^ ERROR use of unstable library feature 'autodiff' + +#[autodiff(dfoo, Reverse)] +//[has_support]~^ ERROR use of unstable library feature 'autodiff' [E0658] +//[no_support]~^^ ERROR use of unstable library feature 'autodiff' [E0658] +//[no_support]~| ERROR this rustc version does not support autodiff +fn foo() {} diff --git a/tests/ui/feature-gates/feature-gate-autodiff.has_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff.has_support.stderr new file mode 100644 index 000000000000..c25cf7d33737 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff.has_support.stderr @@ -0,0 +1,13 @@ +error: cannot find attribute `autodiff` in this scope + --> $DIR/feature-gate-autodiff.rs:9:3 + | +LL | #[autodiff(dfoo, Reverse)] + | ^^^^^^^^ + | +help: consider importing this attribute macro + | +LL + use std::autodiff::autodiff; + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/feature-gates/feature-gate-autodiff.no_support.stderr b/tests/ui/feature-gates/feature-gate-autodiff.no_support.stderr new file mode 100644 index 000000000000..c25cf7d33737 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff.no_support.stderr @@ -0,0 +1,13 @@ +error: cannot find attribute `autodiff` in this scope + --> $DIR/feature-gate-autodiff.rs:9:3 + | +LL | #[autodiff(dfoo, Reverse)] + | ^^^^^^^^ + | +help: consider importing this attribute macro + | +LL + use std::autodiff::autodiff; + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/feature-gates/feature-gate-autodiff.rs b/tests/ui/feature-gates/feature-gate-autodiff.rs new file mode 100644 index 000000000000..4249b229a698 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-autodiff.rs @@ -0,0 +1,12 @@ +//@ revisions: has_support no_support +//@[no_support] ignore-enzyme +//@[has_support] needs-enzyme + +#![crate_type = "lib"] + +// This checks that without the autodiff feature enabled, we can't use it. + +#[autodiff(dfoo, Reverse)] +//[has_support]~^ ERROR cannot find attribute `autodiff` in this scope +//[no_support]~^^ ERROR cannot find attribute `autodiff` in this scope +fn foo() {} From 1ac72b94bc5e8536e61232125b99dd052ac74b38 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Sat, 12 Oct 2024 13:43:17 +0100 Subject: [PATCH 032/118] Add ExtractIf for ThinVec --- compiler/rustc_data_structures/src/lib.rs | 1 + compiler/rustc_data_structures/src/thinvec.rs | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 compiler/rustc_data_structures/src/thinvec.rs diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index f225684d99ff..fba2707922bc 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -76,6 +76,7 @@ pub mod svh; pub mod sync; pub mod tagged_ptr; pub mod temp_dir; +pub mod thinvec; pub mod transitive_relation; pub mod unhash; pub mod unord; diff --git a/compiler/rustc_data_structures/src/thinvec.rs b/compiler/rustc_data_structures/src/thinvec.rs new file mode 100644 index 000000000000..e60ac2cbc8b4 --- /dev/null +++ b/compiler/rustc_data_structures/src/thinvec.rs @@ -0,0 +1,92 @@ +//! This is a copy-paste of `Vec::extract_if` for `ThinVec`. +//! +//! FIXME: is merged, this can be removed. + +use std::{ptr, slice}; + +use thin_vec::ThinVec; + +/// An iterator for [`ThinVec`] which uses a closure to determine if an element should be removed. +#[must_use = "iterators are lazy and do nothing unless consumed"] +pub struct ExtractIf<'a, T, F> { + vec: &'a mut ThinVec, + /// The index of the item that will be inspected by the next call to `next`. + idx: usize, + /// The number of items that have been drained (removed) thus far. + del: usize, + /// The original length of `vec` prior to draining. + old_len: usize, + /// The filter test predicate. + pred: F, +} + +impl<'a, T, F> ExtractIf<'a, T, F> +where + F: FnMut(&mut T) -> bool, +{ + pub fn new(vec: &'a mut ThinVec, filter: F) -> Self { + let old_len = vec.len(); + + // Guard against us getting leaked (leak amplification) + unsafe { + vec.set_len(0); + } + + ExtractIf { vec, idx: 0, del: 0, old_len, pred: filter } + } +} + +impl Iterator for ExtractIf<'_, T, F> +where + F: FnMut(&mut T) -> bool, +{ + type Item = T; + fn next(&mut self) -> Option { + unsafe { + while self.idx < self.old_len { + let i = self.idx; + let v = slice::from_raw_parts_mut(self.vec.as_mut_ptr(), self.old_len); + let drained = (self.pred)(&mut v[i]); + // Update the index *after* the predicate is called. If the index + // is updated prior and the predicate panics, the element at this + // index would be leaked. + self.idx += 1; + if drained { + self.del += 1; + return Some(ptr::read(&v[i])); + } else if self.del > 0 { + let del = self.del; + let src: *const T = &v[i]; + let dst: *mut T = &mut v[i - del]; + ptr::copy_nonoverlapping(src, dst, 1); + } + } + None + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.old_len - self.idx)) + } +} + +impl Drop for ExtractIf<'_, A, F> { + fn drop(&mut self) { + unsafe { + if self.idx < self.old_len && self.del > 0 { + // This is a pretty messed up state, and there isn't really an + // obviously right thing to do. We don't want to keep trying + // to execute `pred`, so we just backshift all the unprocessed + // elements and tell the vec that they still exist. The backshift + // is required to prevent a double-drop of the last successfully + // drained item prior to a panic in the predicate. + let ptr = self.vec.as_mut_ptr(); + let src = ptr.add(self.idx); + let dst = src.sub(self.del); + let tail_len = self.old_len - self.idx; + src.copy_to(dst, tail_len); + } + self.vec.set_len(self.old_len - self.del); + } + } +} From 7ec06b0d1d08cbcc6ed2f7e6ae87fe18056f69ef Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Wed, 9 Oct 2024 01:02:55 +0100 Subject: [PATCH 033/118] Swap Vec to type alias --- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../src/obligation_forest/mod.rs | 3 +- compiler/rustc_hir_analysis/src/autoderef.rs | 11 ++-- compiler/rustc_hir_typeck/src/autoderef.rs | 5 +- compiler/rustc_hir_typeck/src/closure.rs | 4 +- compiler/rustc_hir_typeck/src/coercion.rs | 33 +++++----- .../src/fn_ctxt/inspect_obligations.rs | 13 ++-- compiler/rustc_hir_typeck/src/method/mod.rs | 3 +- .../src/infer/canonical/query_response.rs | 7 +- compiler/rustc_infer/src/infer/mod.rs | 10 +-- .../rustc_infer/src/infer/opaque_types/mod.rs | 8 +-- compiler/rustc_infer/src/infer/projection.rs | 4 +- .../rustc_infer/src/infer/relate/lattice.rs | 8 +-- .../src/infer/relate/type_relating.rs | 8 +-- compiler/rustc_infer/src/traits/engine.rs | 10 +-- compiler/rustc_infer/src/traits/mod.rs | 2 + compiler/rustc_infer/src/traits/project.rs | 6 +- .../src/error_reporting/mod.rs | 7 +- .../src/solve/fulfill.rs | 17 ++--- .../src/traits/coherence.rs | 9 +-- .../src/traits/engine.rs | 3 +- .../src/traits/fulfill.rs | 54 +++++++++------ .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/normalize.rs | 14 ++-- .../src/traits/outlives_bounds.rs | 2 +- .../src/traits/project.rs | 63 +++++++++--------- .../src/traits/query/normalize.rs | 14 ++-- .../src/traits/query/type_op/mod.rs | 6 +- .../src/traits/select/candidate_assembly.rs | 6 +- .../src/traits/select/confirmation.rs | 65 ++++++++++--------- .../src/traits/select/mod.rs | 20 +++--- .../rustc_trait_selection/src/traits/wf.rs | 39 ++++++----- .../src/normalize_projection_ty.rs | 5 +- 33 files changed, 250 insertions(+), 215 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 82aeca666935..238d7d0749a5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -18,6 +18,7 @@ use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; +use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -40,7 +41,6 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::{DUMMY_SP, Span}; use rustc_target::abi::{FIRST_VARIANT, FieldIdx}; -use rustc_trait_selection::traits::PredicateObligation; use rustc_trait_selection::traits::query::type_op::custom::{ CustomTypeOp, scrape_region_constraints, }; @@ -2940,7 +2940,7 @@ impl NormalizeLocation for Location { pub(super) struct InstantiateOpaqueType<'tcx> { pub base_universe: Option, pub region_constraints: Option>, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index cfe7dd13e80b..aca99b9fab1c 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -402,9 +402,10 @@ impl ObligationForest { } /// Returns the set of obligations that are in a pending state. - pub fn map_pending_obligations(&self, f: F) -> Vec

+ pub fn map_pending_obligations(&self, f: F) -> R where F: Fn(&O) -> P, + R: FromIterator

, { self.nodes .iter() diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index 8d11328743c7..5a66c31a0cc3 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -1,4 +1,5 @@ use rustc_infer::infer::InferCtxt; +use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Limit; use rustc_span::Span; @@ -23,7 +24,7 @@ struct AutoderefSnapshot<'tcx> { reached_recursion_limit: bool, steps: Vec<(Ty<'tcx>, AutoderefKind)>, cur_ty: Ty<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } pub struct Autoderef<'a, 'tcx> { @@ -119,7 +120,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { state: AutoderefSnapshot { steps: vec![], cur_ty: infcx.resolve_vars_if_possible(base_ty), - obligations: vec![], + obligations: PredicateObligations::new(), at_start: true, reached_recursion_limit: false, }, @@ -165,7 +166,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { pub fn structurally_normalize( &self, ty: Ty<'tcx>, - ) -> Option<(Ty<'tcx>, Vec>)> { + ) -> Option<(Ty<'tcx>, PredicateObligations<'tcx>)> { let ocx = ObligationCtxt::new(self.infcx); let Ok(normalized_ty) = ocx.structurally_normalize( &traits::ObligationCause::misc(self.span, self.body_id), @@ -204,11 +205,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { self.state.steps.len() } - pub fn into_obligations(self) -> Vec> { + pub fn into_obligations(self) -> PredicateObligations<'tcx> { self.state.obligations } - pub fn current_obligations(&self) -> Vec> { + pub fn current_obligations(&self) -> PredicateObligations<'tcx> { self.state.obligations.clone() } diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index d2d6da8f32b3..e4ca1cee7572 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -5,6 +5,7 @@ use std::iter; use itertools::Itertools; use rustc_hir_analysis::autoderef::{Autoderef, AutoderefKind}; use rustc_infer::infer::InferOk; +use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -36,10 +37,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> InferOk<'tcx, Vec>> { let steps = autoderef.steps(); if steps.is_empty() { - return InferOk { obligations: vec![], value: vec![] }; + return InferOk { obligations: PredicateObligations::new(), value: vec![] }; } - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let targets = steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty(false))); let steps: Vec<_> = steps diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index fcaa5751152b..fd6ac7de14a7 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, InferResult}; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::span_bug; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; @@ -805,7 +805,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706 // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796 self.commit_if_ok(|_| { - let mut all_obligations = vec![]; + let mut all_obligations = PredicateObligations::new(); let supplied_sig = self.instantiate_binder_with_fresh_vars( self.tcx.def_span(expr_def_id), BoundRegionConversionTime::FnCall, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bd0b98702983..f81bc727aa1c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -46,6 +46,7 @@ use rustc_infer::infer::relate::RelateResult; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::{ IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation, + PredicateObligations, }; use rustc_middle::lint::in_external_macro; use rustc_middle::span_bug; @@ -120,7 +121,7 @@ fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec( adj: Vec>, target: Ty<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, ) -> CoerceResult<'tcx> { Ok(InferOk { value: (adj, target), obligations }) } @@ -184,7 +185,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Coercing from `!` to any type is allowed: if a.is_never() { if self.coerce_never { - return success(simple(Adjust::NeverToAny)(b), b, vec![]); + return success(simple(Adjust::NeverToAny)(b), b, PredicateObligations::new()); } else { // Otherwise the only coercion we can do is unification. return self.unify_and(a, b, identity); @@ -278,7 +279,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Two unresolved type variables: create a `Coerce` predicate. let target_ty = if self.use_lub { self.next_ty_var(self.cause.span) } else { b }; - let mut obligations = Vec::with_capacity(2); + let mut obligations = PredicateObligations::with_capacity(2); for &source_ty in &[a, b] { if source_ty != target_ty { obligations.push(Obligation::new( @@ -744,7 +745,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Check the obligations of the cast -- for example, when casting // `usize` to `dyn* Clone + 'static`: - let mut obligations: Vec<_> = predicates + let obligations = predicates .iter() .map(|predicate| { // For each existential predicate (e.g., `?Self: Clone`) instantiate @@ -764,21 +765,21 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { ty::OutlivesPredicate(a, b_region), ))), ), + // Enforce that the type is `usize`/pointer-sized. + Obligation::new( + self.tcx, + self.cause.clone(), + self.param_env, + ty::TraitRef::new( + self.tcx, + self.tcx + .require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), + [a], + ), + ), ]) .collect(); - // Enforce that the type is `usize`/pointer-sized. - obligations.push(Obligation::new( - self.tcx, - self.cause.clone(), - self.param_env, - ty::TraitRef::new( - self.tcx, - self.tcx.require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)), - [a], - ), - )); - Ok(InferOk { value: ( vec![Adjustment { kind: Adjust::Pointer(PointerCoercion::DynStar), target: b }], diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 2aad9a043f97..693cb4465cc1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -1,6 +1,6 @@ //! A utility module to inspect currently ambiguous obligations in the current context. -use rustc_infer::traits::{self, ObligationCause}; +use rustc_infer::traits::{self, ObligationCause, PredicateObligations}; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_span::Span; @@ -15,10 +15,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Returns a list of all obligations whose self type has been unified /// with the unconstrained type `self_ty`. #[instrument(skip(self), level = "debug")] - pub(crate) fn obligations_for_self_ty( - &self, - self_ty: ty::TyVid, - ) -> Vec> { + pub(crate) fn obligations_for_self_ty(&self, self_ty: ty::TyVid) -> PredicateObligations<'tcx> { if self.next_trait_solver() { self.obligations_for_self_ty_next(self_ty) } else { @@ -75,10 +72,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(crate) fn obligations_for_self_ty_next( &self, self_ty: ty::TyVid, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let obligations = self.fulfillment_cx.borrow().pending_obligations(); debug!(?obligations); - let mut obligations_for_self_ty = vec![]; + let mut obligations_for_self_ty = PredicateObligations::new(); for obligation in obligations { let mut visitor = NestedObligationsForSelfTy { fcx: self, @@ -103,7 +100,7 @@ struct NestedObligationsForSelfTy<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, self_ty: ty::TyVid, root_cause: &'a ObligationCause<'tcx>, - obligations_for_self_ty: &'a mut Vec>, + obligations_for_self_ty: &'a mut PredicateObligations<'tcx>, } impl<'a, 'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'a, 'tcx> { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index cb8b1df2c6e4..2de5947b16ff 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -12,6 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_infer::infer::{self, InferOk}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ @@ -412,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); // FIXME(effects): revisit when binops get `#[const_trait]` diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 7791bd736281..1d3d32ef7497 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -28,7 +28,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult}; use crate::traits::query::NoSolution; use crate::traits::{ - Obligation, ObligationCause, PredicateObligation, ScrubbedTraitError, TraitEngine, + Obligation, ObligationCause, PredicateObligation, PredicateObligations, ScrubbedTraitError, + TraitEngine, }; impl<'tcx> InferCtxt<'tcx> { @@ -493,7 +494,7 @@ impl<'tcx> InferCtxt<'tcx> { ), }; - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); // Carry all newly resolved opaque types to the caller's scope for &(a, b) in &query_response.value.opaque_types { @@ -598,7 +599,7 @@ impl<'tcx> InferCtxt<'tcx> { variables1: &OriginalQueryValues<'tcx>, variables2: impl Fn(BoundVar) -> GenericArg<'tcx>, ) -> InferResult<'tcx, ()> { - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); for (index, value1) in variables1.var_values.iter().enumerate() { let value2 = variables2(BoundVar::new(index)); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index bc813305ba48..7ef714475fc2 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -50,7 +50,9 @@ use tracing::{debug, instrument}; use type_variable::TypeVariableOrigin; use crate::infer::region_constraints::UndoLog; -use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine}; +use crate::traits::{ + self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, +}; pub mod at; pub mod canonical; @@ -68,7 +70,7 @@ pub(crate) mod snapshot; mod type_variable; /// `InferOk<'tcx, ()>` is used a lot. It may seem like a useless wrapper -/// around `Vec>`, but it has one important property: +/// around `PredicateObligations<'tcx>`, but it has one important property: /// because `InferOk` is marked with `#[must_use]`, if you have a method /// `InferCtxt::f` that returns `InferResult<'tcx, ()>` and you call it with /// `infcx.f()?;` you'll get a warning about the obligations being discarded @@ -78,7 +80,7 @@ mod type_variable; #[derive(Debug)] pub struct InferOk<'tcx, T> { pub value: T, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } pub type InferResult<'tcx, T> = Result, TypeError<'tcx>>; @@ -658,7 +660,7 @@ impl<'tcx, T> InferOk<'tcx, T> { } impl<'tcx> InferOk<'tcx, ()> { - pub fn into_obligations(self) -> Vec> { + pub fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 365ddaba138f..853ae6d26412 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -16,7 +16,7 @@ use tracing::{debug, instrument}; use super::DefineOpaqueTypes; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::{self, Obligation}; +use crate::traits::{self, Obligation, PredicateObligations}; mod table; @@ -46,14 +46,14 @@ impl<'tcx> InferCtxt<'tcx> { ) -> InferOk<'tcx, T> { // We handle opaque types differently in the new solver. if self.next_trait_solver() { - return InferOk { value, obligations: vec![] }; + return InferOk { value, obligations: PredicateObligations::new() }; } if !value.has_opaque_types() { - return InferOk { value, obligations: vec![] }; + return InferOk { value, obligations: PredicateObligations::new() }; } - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, lt_op: |lt| lt, diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index b78f9d492685..1bee9632110b 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -2,7 +2,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, Ty}; use super::InferCtxt; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; impl<'tcx> InferCtxt<'tcx> { /// Instead of normalizing an associated type projection, @@ -17,7 +17,7 @@ impl<'tcx> InferCtxt<'tcx> { projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Ty<'tcx> { debug_assert!(!self.next_trait_solver()); let ty_var = self.next_ty_var(self.tcx.def_span(projection_ty.def_id)); diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 7eb61abfbc12..4eb77a99be78 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -27,7 +27,7 @@ use tracing::{debug, instrument}; use super::StructurallyRelateAliases; use super::combine::PredicateEmittingRelation; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace}; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; #[derive(Clone, Copy)] pub(crate) enum LatticeOpKind { @@ -52,7 +52,7 @@ pub(crate) struct LatticeOp<'infcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, // Mutable fields kind: LatticeOpKind, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> { @@ -62,10 +62,10 @@ impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, kind: LatticeOpKind, ) -> LatticeOp<'infcx, 'tcx> { - LatticeOp { infcx, trace, param_env, kind, obligations: vec![] } + LatticeOp { infcx, trace, param_env, kind, obligations: PredicateObligations::new() } } - pub(crate) fn into_obligations(self) -> Vec> { + pub(crate) fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 35103c070c27..009271a8378f 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -11,7 +11,7 @@ use tracing::{debug, instrument}; use crate::infer::BoundRegionConversionTime::HigherRankedType; use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}; use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace}; -use crate::traits::{Obligation, PredicateObligation}; +use crate::traits::{Obligation, PredicateObligations}; /// Enforce that `a` is equal to or a subtype of `b`. pub(crate) struct TypeRelating<'infcx, 'tcx> { @@ -24,7 +24,7 @@ pub(crate) struct TypeRelating<'infcx, 'tcx> { // Mutable fields. ambient_variance: ty::Variance, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, /// The cache only tracks the `ambient_variance` as it's the /// only field which is mutable and which meaningfully changes /// the result when relating types. @@ -65,12 +65,12 @@ impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> { param_env, define_opaque_types, ambient_variance, - obligations: vec![], + obligations: PredicateObligations::new(), cache: Default::default(), } } - pub(crate) fn into_obligations(self) -> Vec> { + pub(crate) fn into_obligations(self) -> PredicateObligations<'tcx> { self.obligations } } diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index a076cdad672a..ba1516655b0b 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, Ty, Upcast}; -use super::{ObligationCause, PredicateObligation}; +use super::{ObligationCause, PredicateObligation, PredicateObligations}; use crate::infer::InferCtxt; use crate::traits::Obligation; @@ -20,7 +20,7 @@ pub enum ScrubbedTraitError<'tcx> { /// An ambiguity. This goal may hold if further inference is done. Ambiguity, /// An old-solver-style cycle error, which will fatal. - Cycle(Vec>), + Cycle(PredicateObligations<'tcx>), } impl<'tcx> ScrubbedTraitError<'tcx> { @@ -62,7 +62,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, ) { for obligation in obligations { self.register_predicate_obligation(infcx, obligation); @@ -84,7 +84,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { self.collect_remaining_errors(infcx) } - fn pending_obligations(&self) -> Vec>; + fn pending_obligations(&self) -> PredicateObligations<'tcx>; /// Among all pending obligations, collect those are stalled on a inference variable which has /// changed since the last call to `select_where_possible`. Those obligations are marked as @@ -92,7 +92,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { fn drain_unstalled_obligations( &mut self, infcx: &InferCtxt<'tcx>, - ) -> Vec>; + ) -> PredicateObligations<'tcx>; } pub trait FromSolverError<'tcx, E>: Debug + 'tcx { diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 34b0fe3e9678..2d02391c57a7 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -84,6 +84,8 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>; pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; +pub type PredicateObligations<'tcx> = Vec>; + impl<'tcx> PredicateObligation<'tcx> { /// Flips the polarity of the inner predicate. /// diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 64b72de39862..cab2ce9f5a0f 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -6,7 +6,7 @@ use rustc_middle::traits::EvaluationResult; use rustc_middle::ty; use tracing::{debug, info}; -use super::PredicateObligation; +use super::PredicateObligations; use crate::infer::snapshot::undo_log::InferCtxtUndoLogs; pub(crate) type UndoLog<'tcx> = @@ -20,7 +20,7 @@ pub struct MismatchedProjectionTypes<'tcx> { #[derive(Clone)] pub struct Normalized<'tcx, T> { pub value: T, - pub obligations: Vec>, + pub obligations: PredicateObligations<'tcx>, } pub type NormalizedTerm<'tcx> = Normalized<'tcx, ty::Term<'tcx>>; @@ -191,7 +191,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); let mut ty = ty.clone(); if result.must_apply_considering_regions() { - ty.obligations = vec![]; + ty.obligations = PredicateObligations::new(); } map.insert(key, ProjectionCacheEntry::NormalizedTerm { ty, diff --git a/compiler/rustc_trait_selection/src/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/mod.rs index cb7efeaae0bf..82695688ae89 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/mod.rs @@ -2,7 +2,7 @@ use std::ops::Deref; use rustc_errors::DiagCtxtHandle; use rustc_infer::infer::InferCtxt; -use rustc_infer::traits::PredicateObligation; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::ty::{self, Ty}; @@ -28,8 +28,7 @@ pub struct TypeErrCtxt<'a, 'tcx> { pub normalize_fn_sig: Box) -> ty::PolyFnSig<'tcx> + 'a>, - pub autoderef_steps: - Box) -> Vec<(Ty<'tcx>, Vec>)> + 'a>, + pub autoderef_steps: Box) -> Vec<(Ty<'tcx>, PredicateObligations<'tcx>)> + 'a>, } #[extension(pub trait InferCtxtErrorExt<'tcx>)] @@ -45,7 +44,7 @@ impl<'tcx> InferCtxt<'tcx> { normalize_fn_sig: Box::new(|fn_sig| fn_sig), autoderef_steps: Box::new(|ty| { debug_assert!(false, "shouldn't be using autoderef_steps outside of typeck"); - vec![(ty, vec![])] + vec![(ty, PredicateObligations::new())] }), } } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 081d7a6a769a..8ec4427091d0 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -7,7 +7,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; use rustc_infer::traits::{ self, FromSolverError, MismatchedProjectionTypes, Obligation, ObligationCause, - ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, + ObligationCauseCode, PredicateObligation, PredicateObligations, SelectionError, TraitEngine, }; use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -49,8 +49,8 @@ struct ObligationStorage<'tcx> { /// We cannot eagerly return these as error so we instead store them here /// to avoid recomputing them each time `select_where_possible` is called. /// This also allows us to return the correct `FulfillmentError` for them. - overflowed: Vec>, - pending: Vec>, + overflowed: PredicateObligations<'tcx>, + pending: PredicateObligations<'tcx>, } impl<'tcx> ObligationStorage<'tcx> { @@ -58,13 +58,13 @@ impl<'tcx> ObligationStorage<'tcx> { self.pending.push(obligation); } - fn clone_pending(&self) -> Vec> { + fn clone_pending(&self) -> PredicateObligations<'tcx> { let mut obligations = self.pending.clone(); obligations.extend(self.overflowed.iter().cloned()); obligations } - fn take_pending(&mut self) -> Vec> { + fn take_pending(&mut self) -> PredicateObligations<'tcx> { let mut obligations = mem::take(&mut self.pending); obligations.append(&mut self.overflowed); obligations @@ -197,14 +197,11 @@ where errors } - fn pending_obligations(&self) -> Vec> { + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.obligations.clone_pending() } - fn drain_unstalled_obligations( - &mut self, - _: &InferCtxt<'tcx>, - ) -> Vec> { + fn drain_unstalled_obligations(&mut self, _: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> { self.obligations.take_pending() } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index b29e41beab55..f4a2483cebf8 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,6 +11,7 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; @@ -279,7 +280,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 @@ -491,7 +492,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } else { ty.super_visit_with(self); } @@ -514,7 +515,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } else { ct.super_visit_with(self); } @@ -545,7 +546,7 @@ fn plug_infer_with_placeholders<'tcx>( else { bug!("we always expect to be able to plug an infer var with placeholder") }; - assert_eq!(obligations, &[]); + assert_eq!(obligations.len(), 0); } } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index d562692c1a86..eda3f6e80230 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -10,6 +10,7 @@ use rustc_infer::infer::canonical::{ }; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace}; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::traits::query::NoSolution; @@ -208,7 +209,7 @@ where /// getting ignored. You can make a new `ObligationCtxt` if this /// needs to be done in a loop, for example. #[must_use] - pub fn into_pending_obligations(self) -> Vec> { + pub fn into_pending_obligations(self) -> PredicateObligations<'tcx> { self.engine.borrow().pending_obligations() } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 33b8cf037017..3e3834a11c62 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -6,7 +6,8 @@ use rustc_data_structures::obligation_forest::{ }; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::{ - FromSolverError, PolyTraitObligation, ProjectionCacheKey, SelectionError, TraitEngine, + FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError, + TraitEngine, }; use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; @@ -27,6 +28,8 @@ use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; +pub(crate) type PendingPredicateObligations<'tcx> = Vec>; + impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { /// Note that we include both the `ParamEnv` and the `Predicate`, /// as the `ParamEnv` can influence whether fulfillment succeeds @@ -161,15 +164,16 @@ where fn drain_unstalled_obligations( &mut self, infcx: &InferCtxt<'tcx>, - ) -> Vec> { - let mut processor = DrainProcessor { removed_predicates: Vec::new(), infcx }; + ) -> PredicateObligations<'tcx> { + let mut processor = + DrainProcessor { removed_predicates: PredicateObligations::new(), infcx }; let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor); assert!(outcome.errors.is_empty()); return processor.removed_predicates; struct DrainProcessor<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, - removed_predicates: Vec>, + removed_predicates: PredicateObligations<'tcx>, } impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> { @@ -190,7 +194,7 @@ where ) -> ProcessResult, !> { assert!(self.needs_process_obligation(pending_obligation)); self.removed_predicates.push(pending_obligation.obligation.clone()); - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } fn process_backedge<'c, I>( @@ -207,7 +211,7 @@ where } } - fn pending_obligations(&self) -> Vec> { + fn pending_obligations(&self) -> PredicateObligations<'tcx> { self.predicates.map_pending_obligations(|o| o.obligation.clone()) } } @@ -216,7 +220,7 @@ struct FulfillProcessor<'a, 'tcx> { selcx: SelectionContext<'a, 'tcx>, } -fn mk_pending(os: Vec>) -> Vec> { +fn mk_pending<'tcx>(os: PredicateObligations<'tcx>) -> PendingPredicateObligations<'tcx> { os.into_iter() .map(|o| PendingPredicateObligation { obligation: o, stalled_on: vec![] }) .collect() @@ -321,7 +325,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { let infcx = self.selcx.infcx; if obligation.predicate.has_aliases() { - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( &mut self.selcx, obligation.param_env, @@ -369,7 +373,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) => { let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder)); - ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) + let mut obligations = PredicateObligations::with_capacity(1); + obligations.push(obligation.with(infcx.tcx, pred)); + + ProcessResult::Changed(mk_pending(obligations)) } ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::NormalizesTo(..) => { @@ -395,7 +402,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)); } - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate( @@ -405,7 +412,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { if infcx.considering_regions { infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause); } - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data)) => { @@ -422,7 +429,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { if !self.selcx.tcx().is_dyn_compatible(trait_def_id) { ProcessResult::Error(FulfillmentErrorCode::Select(Unimplemented)) } else { - ProcessResult::Changed(vec![]) + ProcessResult::Changed(Default::default()) } } @@ -451,7 +458,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { pending_obligation.stalled_on.extend([var]); return ProcessResult::Unchanged; } - ty::ConstKind::Error(_) => return ProcessResult::Changed(vec![]), + ty::ConstKind::Error(_) => { + return ProcessResult::Changed(PendingPredicateObligations::new()); + } ty::ConstKind::Value(ty, _) => ty, ty::ConstKind::Unevaluated(uv) => { infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args) @@ -460,7 +469,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { // `>::Output` when this is an `Expr` representing // `lhs + rhs`. ty::ConstKind::Expr(_) => { - return ProcessResult::Changed(mk_pending(vec![])); + return ProcessResult::Changed(mk_pending(PredicateObligations::new())); } ty::ConstKind::Placeholder(_) => { bug!("placeholder const {:?} in old solver", ct) @@ -568,7 +577,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { obligation.param_env, obligation.cause.span, ) { - Ok(()) => ProcessResult::Changed(vec![]), + Ok(()) => ProcessResult::Changed(Default::default()), Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.extend( @@ -722,7 +731,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { debug!("process_child_obligations: coinductive match"); Ok(()) } else { - let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect(); + let cycle = cycle.map(|c| c.obligation.clone()).collect(); Err(FulfillmentErrorCode::Cycle(cycle)) } } @@ -745,7 +754,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { "selecting trait at depth {} evaluated to holds", obligation.recursion_depth ); - return ProcessResult::Changed(vec![]); + return ProcessResult::Changed(Default::default()); } } @@ -809,7 +818,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { .projection_cache() .complete(key, EvaluationResult::EvaluatedToOk); } - return ProcessResult::Changed(vec![]); + return ProcessResult::Changed(Default::default()); } else { debug!("Does NOT hold: {:?}", obligation); } @@ -826,9 +835,12 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { ProcessResult::Unchanged } // Let the caller handle the recursion - ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![ - project_obligation.with(tcx, project_obligation.predicate), - ])), + ProjectAndUnifyResult::Recursive => { + let mut obligations = PredicateObligations::with_capacity(1); + obligations.push(project_obligation.with(tcx, project_obligation.predicate)); + + ProcessResult::Changed(mk_pending(obligations)) + } ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { ProcessResult::Error(FulfillmentErrorCode::Project(e)) } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 655bef0bab74..0fb795fc1840 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -114,7 +114,7 @@ impl<'tcx> Debug for FulfillmentError<'tcx> { pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only /// if it is already implemented. - Cycle(Vec>), + Cycle(PredicateObligations<'tcx>), Select(SelectionError<'tcx>), Project(MismatchedProjectionTypes<'tcx>), Subtype(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index a7130cbd28f2..7eac35593488 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -4,7 +4,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::InferOk; use rustc_infer::infer::at::At; use rustc_infer::traits::{ - FromSolverError, Normalized, Obligation, PredicateObligation, TraitEngine, + FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, }; use rustc_macros::extension; use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; @@ -29,7 +29,7 @@ impl<'tcx> At<'_, 'tcx> { /// projection may be fallible. fn normalize>>(&self, value: T) -> InferOk<'tcx, T> { if self.infcx.next_trait_solver() { - InferOk { value, obligations: Vec::new() } + InferOk { value, obligations: PredicateObligations::new() } } else { let mut selcx = SelectionContext::new(self.infcx); let Normalized { value, obligations } = @@ -83,7 +83,7 @@ pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( where T: TypeFoldable>, { - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations); Normalized { value, obligations } } @@ -95,14 +95,14 @@ pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( cause: ObligationCause<'tcx>, depth: usize, value: T, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> T where T: TypeFoldable>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations); - let result = ensure_sufficient_stack(|| normalizer.fold(value)); + let result = ensure_sufficient_stack(|| AssocTypeNormalizer::fold(&mut normalizer, value)); debug!(?result, obligations.len = normalizer.obligations.len()); debug!(?normalizer.obligations,); result @@ -128,7 +128,7 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> { selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, - obligations: &'a mut Vec>, + obligations: &'a mut PredicateObligations<'tcx>, depth: usize, universes: Vec>, } @@ -139,7 +139,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &'a mut Vec>, + obligations: &'a mut PredicateObligations<'tcx>, ) -> AssocTypeNormalizer<'a, 'b, 'tcx> { debug_assert!(!selcx.infcx.next_trait_solver()); AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index f1faff2c036f..339e4bf1f22c 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -77,7 +77,7 @@ fn implied_outlives_bounds<'a, 'tcx>( else { return vec![]; }; - assert_eq!(&obligations, &[]); + assert_eq!(obligations.len(), 0); // Because of #109628, we may have unexpected placeholders. Ignore them! // FIXME(#109628): panic in this case once the issue is fixed. diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9cd99d99fc3c..7f7c9bced185 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -9,7 +9,7 @@ use rustc_hir::def::DefKind; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::resolve::OpportunisticRegionResolver; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; pub use rustc_middle::traits::Reveal; use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData}; @@ -146,7 +146,7 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { /// of the old return type, which was: /// ```ignore (not-rust) /// Result< -/// Result>>, InProgress>, +/// Result>, InProgress>, /// MismatchedProjectionTypes<'tcx>, /// > /// ``` @@ -155,7 +155,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// projection cannot be normalized because the required trait bound does /// not hold, this is returned, with `obligations` being a predicate that /// cannot be proven. - Holds(Vec>), + Holds(PredicateObligations<'tcx>), /// The projection cannot be normalized due to ambiguity. Resolving some /// inference variables in the projection may fix this. FailedNormalization, @@ -231,7 +231,7 @@ fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let infcx = selcx.infcx; let normalized = match opt_normalize_projection_term( @@ -289,7 +289,7 @@ pub fn normalize_projection_ty<'a, 'b, 'tcx>( projection_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Term<'tcx> { opt_normalize_projection_term( selcx, @@ -330,7 +330,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Result>, InProgress> { let infcx = selcx.infcx; debug_assert!(!selcx.infcx.next_trait_solver()); @@ -452,7 +452,8 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( Ok(Some(result.value)) } Ok(Projected::NoProgress(projected_ty)) => { - let result = Normalized { value: projected_ty, obligations: vec![] }; + let result = + Normalized { value: projected_ty, obligations: PredicateObligations::new() }; if use_cache { infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone()); } @@ -519,13 +520,14 @@ fn normalize_to_error<'a, 'tcx>( selcx.infcx.next_const_var(cause.span).into() } }; - let trait_obligation = Obligation { + let mut obligations = PredicateObligations::new(); + obligations.push(Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.upcast(selcx.tcx()), - }; - Normalized { value: new_value, obligations: vec![trait_obligation] } + }); + Normalized { value: new_value, obligations } } /// Confirm and normalize the given inherent projection. @@ -536,7 +538,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> Ty<'tcx> { let tcx = selcx.tcx(); @@ -604,7 +606,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>( alias_ty: ty::AliasTy<'tcx>, cause: ObligationCause<'tcx>, depth: usize, - obligations: &mut Vec>, + obligations: &mut PredicateObligations<'tcx>, ) -> ty::GenericArgsRef<'tcx> { let tcx = selcx.tcx(); @@ -657,15 +659,15 @@ enum Projected<'tcx> { struct Progress<'tcx> { term: ty::Term<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, } impl<'tcx> Progress<'tcx> { fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { - Progress { term: Ty::new_error(tcx, guar).into(), obligations: vec![] } + Progress { term: Ty::new_error(tcx, guar).into(), obligations: PredicateObligations::new() } } - fn with_addl_obligations(mut self, mut obligations: Vec>) -> Self { + fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self { self.obligations.append(&mut obligations); self } @@ -1351,7 +1353,7 @@ fn confirm_select_candidate<'cx, 'tcx>( fn confirm_coroutine_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1410,7 +1412,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( fn confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1458,7 +1460,7 @@ fn confirm_future_candidate<'cx, 'tcx>( fn confirm_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); let ty::Coroutine(_, args) = self_ty.kind() else { @@ -1504,7 +1506,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( fn confirm_async_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() else { @@ -1558,7 +1560,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( fn confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - data: Vec>, + data: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); @@ -1569,17 +1571,17 @@ fn confirm_builtin_candidate<'cx, 'tcx>( let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); assert_eq!(discriminant_def_id, item_def_id); - (self_ty.discriminant_ty(tcx).into(), Vec::new()) + (self_ty.discriminant_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) { let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0]; assert_eq!(destructor_def_id, item_def_id); - (self_ty.async_destructor_ty(tcx).into(), Vec::new()) + (self_ty.async_destructor_ty(tcx).into(), PredicateObligations::new()) } else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) { let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, item_def_id); - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let normalize = |ty| { normalize_with_depth_to( selcx, @@ -1627,7 +1629,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( fn confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1663,7 +1665,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( fn confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1782,7 +1784,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn confirm_async_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1934,7 +1936,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: Vec>, + nested: PredicateObligations<'tcx>, ) -> Progress<'tcx> { let [ // We already checked that the goal_kind >= closure_kind @@ -1987,7 +1989,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( ); let cache_projection = cache_entry.projection_term; - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let obligation_projection = obligation.predicate; let obligation_projection = ensure_sufficient_stack(|| { normalize_with_depth_to( @@ -2034,7 +2036,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( ); debug!("confirm_param_env_candidate: {}", msg); let err = Ty::new_error_with_message(infcx.tcx, obligation.cause.span, msg); - Progress { term: err.into(), obligations: vec![] } + Progress { term: err.into(), obligations: PredicateObligations::new() } } } } @@ -2047,6 +2049,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let tcx = selcx.tcx(); let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source; + let assoc_item_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); @@ -2102,7 +2105,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( fn assoc_ty_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTermObligation<'tcx>, - nested: &mut Vec>, + nested: &mut PredicateObligations<'tcx>, ) { let tcx = selcx.tcx(); let predicates = tcx diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 36b24eac5c43..18412b844ff7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -4,6 +4,7 @@ use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_infer::traits::PredicateObligations; use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; @@ -20,8 +21,7 @@ use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; use crate::traits::normalize::needs_normalization; use crate::traits::{ - BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, PredicateObligation, - Reveal, ScrubbedTraitError, + BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError, }; #[extension(pub trait QueryNormalizeExt<'tcx>)] @@ -80,7 +80,9 @@ impl<'a, 'tcx> At<'a, 'tcx> { match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>( self, value, universes, ) { - Ok(value) => return Ok(Normalized { value, obligations: vec![] }), + Ok(value) => { + return Ok(Normalized { value, obligations: PredicateObligations::new() }); + } Err(_errors) => { return Err(NoSolution); } @@ -88,14 +90,14 @@ impl<'a, 'tcx> At<'a, 'tcx> { } if !needs_normalization(&value, self.param_env.reveal()) { - return Ok(Normalized { value, obligations: vec![] }); + return Ok(Normalized { value, obligations: PredicateObligations::new() }); } let mut normalizer = QueryNormalizer { infcx: self.infcx, cause: self.cause, param_env: self.param_env, - obligations: vec![], + obligations: PredicateObligations::new(), cache: SsoHashMap::new(), anon_depth: 0, universes, @@ -164,7 +166,7 @@ struct QueryNormalizer<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - obligations: Vec>, + obligations: PredicateObligations<'tcx>, cache: SsoHashMap, Ty<'tcx>>, anon_depth: usize, universes: Vec>, 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 a765de92afd5..5ae8c87ec027 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 @@ -2,7 +2,7 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; -use rustc_infer::traits::PredicateObligation; +use rustc_infer::traits::PredicateObligations; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; @@ -103,13 +103,13 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't ( Self::QueryResponse, Option>>, - Vec>, + PredicateObligations<'tcx>, Certainty, ), NoSolution, > { if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) { - return Ok((result, None, vec![], Certainty::Proven)); + return Ok((result, None, PredicateObligations::new(), Certainty::Proven)); } let mut canonical_var_values = OriginalQueryValues::default(); diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 20adda6f0de2..52048ca79f92 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -12,7 +12,9 @@ use hir::LangItem; use hir::def_id::DefId; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; -use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation, SelectionError}; +use rustc_infer::traits::{ + Obligation, ObligationCause, PolyTraitObligation, PredicateObligations, SelectionError, +}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; @@ -963,7 +965,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 0, // We're *intentionally* throwing these away, // since we don't actually use them. - &mut vec![], + &mut PredicateObligations::new(), ) .as_type() .unwrap(); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 5141e969608e..cc5c7532b505 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -24,7 +24,7 @@ use rustc_span::def_id::DefId; use tracing::{debug, instrument}; use super::SelectionCandidate::{self, *}; -use super::{BuiltinImplConditions, SelectionContext}; +use super::{BuiltinImplConditions, PredicateObligations, SelectionContext}; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; use crate::traits::util::{self, closure_trait_ref_and_return_type}; use crate::traits::{ @@ -85,7 +85,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // No nested obligations or confirmation process. The checks that we do in // candidate assembly are sufficient. - AsyncFnKindHelperCandidate => ImplSource::Builtin(BuiltinImplSource::Misc, vec![]), + AsyncFnKindHelperCandidate => { + ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new()) + } CoroutineCandidate => { let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?; @@ -121,7 +123,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // This indicates something like `Trait + Send: Send`. In this case, we know that // this holds because that's what the object type is telling us, and there's really // no additional obligations to prove and no types in particular to unify, etc. - ImplSource::Builtin(BuiltinImplSource::Misc, Vec::new()) + ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new()) } BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?, @@ -149,7 +151,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let tcx = self.tcx(); let placeholder_trait_predicate = @@ -179,7 +181,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { HigherRankedType, candidate, ); - let mut obligations = Vec::new(); + let mut obligations = PredicateObligations::new(); let candidate = normalize_with_depth_to( self, obligation.param_env, @@ -226,7 +228,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, param: ty::PolyTraitRef<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, ?param, "confirm_param_candidate"); // During evaluation, we already checked that this @@ -249,7 +251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, has_nested: bool, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); let tcx = self.tcx(); @@ -279,7 +281,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested, ) } else { - vec![] + PredicateObligations::new() }; debug!(?obligations); @@ -291,7 +293,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_transmutability_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { use rustc_transmute::{Answer, Assume, Condition}; /// Generate sub-obligations for reference-to-reference transmutations. @@ -301,7 +303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (src_lifetime, src_ty, src_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability), (dst_lifetime, dst_ty, dst_mut): (ty::Region<'tcx>, Ty<'tcx>, Mutability), assume: Assume, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let make_transmute_obl = |src, dst| { let transmute_trait = obligation.predicate.def_id(); let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2); @@ -347,7 +349,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Given a transmutation from `&'a (mut) Src` and `&'dst (mut) Dst`, // it is always the case that `Src` must be transmutable into `Dst`, // and that that `'src` must outlive `'dst`. - let mut obls = vec![make_transmute_obl(src_ty, dst_ty)]; + let mut obls = PredicateObligations::with_capacity(1); + obls.push(make_transmute_obl(src_ty, dst_ty)); if !assume.lifetimes { obls.push(make_outlives_obl(src_lifetime, dst_lifetime)); } @@ -382,7 +385,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, cond: Condition>, assume: Assume, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { match cond { // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` // Not possible until the trait solver supports disjunctions of obligations @@ -424,7 +427,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let fully_flattened = match maybe_transmutable { Answer::No(_) => Err(Unimplemented)?, Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, cond, assume), - Answer::Yes => vec![], + Answer::Yes => PredicateObligations::new(), }; debug!(?fully_flattened); @@ -439,7 +442,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_auto_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { debug!(?obligation, "confirm_auto_impl_candidate"); let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); @@ -453,14 +456,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, trait_def_id: DefId, nested: ty::Binder<'tcx, Vec>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?nested, "vtable_auto_impl"); ensure_sufficient_stack(|| { let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); let trait_ref = self.infcx.enter_forall_and_leak_universe(poly_trait_ref); - let trait_obligations: Vec> = self.impl_or_trait_obligations( + let trait_obligations = self.impl_or_trait_obligations( &cause, obligation.recursion_depth + 1, obligation.param_env, @@ -566,7 +569,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref)); let unnormalized_upcast_trait_ref = @@ -706,7 +709,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, fn_host_effect: ty::Const<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { debug!(?obligation, "confirm_fn_pointer_candidate"); let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); @@ -750,7 +753,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_trait_alias_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { debug!(?obligation, "confirm_trait_alias_candidate"); let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); @@ -775,7 +778,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_coroutine_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -805,7 +808,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_future_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -835,7 +838,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -865,7 +868,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_async_iterator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else { @@ -896,7 +899,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); @@ -926,13 +929,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn confirm_async_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty()); let tcx = self.tcx(); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let (trait_ref, kind_ty) = match *self_ty.kind() { ty::CoroutineClosure(_, args) => { let args = args.as_coroutine_closure(); @@ -1055,7 +1058,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: TraitObligation<'tcx>, found_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, HigherRankedType, @@ -1210,7 +1213,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // words, if the object type is `Foo + Send`, this would create an obligation for // the `Send` check.) // - Projection predicates - let mut nested: Vec<_> = data + let mut nested: PredicateObligations<'_> = data .iter() .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source))) .collect(); @@ -1254,7 +1257,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tail_field = def.non_enum_variant().tail(); let tail_field_ty = tcx.type_of(tail_field.did); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); // Extract `TailField` and `TailField` from `Struct` and `Struct`, // normalizing in the process, since `type_of` returns something directly from @@ -1339,7 +1342,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: Option, - ) -> Result>, SelectionError<'tcx>> { + ) -> Result, SelectionError<'tcx>> { let Some(host_effect_index) = self.tcx().generics_of(obligation.predicate.def_id()).host_effect_index else { @@ -1353,7 +1356,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); // If we have a custom `impl const Drop`, then diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fba1d1025ca6..621babe91042 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::relate::TypeRelation; -use rustc_infer::traits::TraitObligation; +use rustc_infer::traits::{PredicateObligations, TraitObligation}; use rustc_middle::bug; use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds}; use rustc_middle::mir::interpret::ErrorHandled; @@ -1067,7 +1067,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && fresh_trait_pred.has_aliases() && fresh_trait_pred.is_global() { - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let predicate = normalize_with_depth_to( this, param_env, @@ -1715,7 +1715,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> ProjectionMatchesProjection { debug_assert_eq!(obligation.predicate.def_id, env_predicate.projection_def_id()); - let mut nested_obligations = Vec::new(); + let mut nested_obligations = PredicateObligations::new(); let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, BoundRegionConversionTime::HigherRankedType, @@ -2410,7 +2410,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { recursion_depth: usize, trait_def_id: DefId, types: ty::Binder<'tcx, Vec>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { // Because the types were potentially derived from // higher-ranked obligations they may reference late-bound // regions. For example, `for<'a> Foo<&'a i32> : Copy` would @@ -2552,9 +2552,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> { b_data: &'tcx ty::List>, a_region: ty::Region<'tcx>, b_region: ty::Region<'tcx>, - ) -> SelectionResult<'tcx, Vec>> { + ) -> SelectionResult<'tcx, PredicateObligations<'tcx>> { let tcx = self.tcx(); - let mut nested = vec![]; + let mut nested = PredicateObligations::new(); // We may upcast to auto traits that are either explicitly listed in // the object type's bounds, or implied by the principal trait ref's @@ -2705,7 +2705,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, where_clause_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, ()> { + ) -> Result, ()> { self.match_poly_trait_ref(obligation, where_clause_trait_ref) } @@ -2716,7 +2716,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { &mut self, obligation: &PolyTraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Result>, ()> { + ) -> Result, ()> { let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let trait_ref = self.infcx.instantiate_binder_with_fresh_vars( obligation.cause.span, @@ -2797,7 +2797,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { def_id: DefId, // of impl or trait args: GenericArgsRef<'tcx>, // for impl or trait parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let tcx = self.tcx(); // To allow for one-pass evaluation of the nested obligation, @@ -2817,7 +2817,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let predicates = tcx.predicates_of(def_id); assert_eq!(predicates.parent, None); let predicates = predicates.instantiate_own(tcx, args); - let mut obligations = Vec::with_capacity(predicates.len()); + let mut obligations = PredicateObligations::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { let cause = if tcx.is_lang_item(parent_trait_pred.def_id(), LangItem::CoerceUnsized) { cause.clone() diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index a849cdfe1257..07e68e5a3e81 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -2,7 +2,7 @@ use std::iter; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_infer::traits::ObligationCauseCode; +use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; use rustc_middle::bug; use rustc_middle::ty::{ self, GenericArg, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, @@ -27,7 +27,7 @@ pub fn obligations<'tcx>( recursion_depth: usize, arg: GenericArg<'tcx>, span: Span, -) -> Option>> { +) -> Option> { // Handle the "livelock" case (see comment above) by bailing out if necessary. let arg = match arg.unpack() { GenericArgKind::Type(ty) => { @@ -61,11 +61,18 @@ pub fn obligations<'tcx>( .into() } // There is nothing we have to do for lifetimes. - GenericArgKind::Lifetime(..) => return Some(Vec::new()), + GenericArgKind::Lifetime(..) => return Some(PredicateObligations::new()), }; - let mut wf = - WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth, item: None }; + let mut wf = WfPredicates { + infcx, + param_env, + body_id, + span, + out: PredicateObligations::new(), + recursion_depth, + item: None, + }; wf.compute(arg); debug!("wf::obligations({:?}, body_id={:?}) = {:?}", arg, body_id, wf.out); @@ -82,7 +89,7 @@ pub fn unnormalized_obligations<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, arg: GenericArg<'tcx>, -) -> Option>> { +) -> Option> { debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); // However, if `arg` IS an unresolved inference variable, returns `None`, @@ -93,7 +100,7 @@ pub fn unnormalized_obligations<'tcx>( } if let ty::GenericArgKind::Lifetime(..) = arg.unpack() { - return Some(vec![]); + return Some(PredicateObligations::new()); } let mut wf = WfPredicates { @@ -101,7 +108,7 @@ pub fn unnormalized_obligations<'tcx>( param_env, body_id: CRATE_DEF_ID, span: DUMMY_SP, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: None, }; @@ -120,13 +127,13 @@ pub fn trait_obligations<'tcx>( trait_pred: ty::TraitPredicate<'tcx>, span: Span, item: &'tcx hir::Item<'tcx>, -) -> Vec> { +) -> PredicateObligations<'tcx> { let mut wf = WfPredicates { infcx, param_env, body_id, span, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: Some(item), }; @@ -147,13 +154,13 @@ pub fn clause_obligations<'tcx>( body_id: LocalDefId, clause: ty::Clause<'tcx>, span: Span, -) -> Vec> { +) -> PredicateObligations<'tcx> { let mut wf = WfPredicates { infcx, param_env, body_id, span, - out: vec![], + out: PredicateObligations::new(), recursion_depth: 0, item: None, }; @@ -192,7 +199,7 @@ struct WfPredicates<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, body_id: LocalDefId, span: Span, - out: Vec>, + out: PredicateObligations<'tcx>, recursion_depth: usize, item: Option<&'tcx hir::Item<'tcx>>, } @@ -323,7 +330,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { traits::ObligationCause::new(self.span, self.body_id, code) } - fn normalize(self, infcx: &InferCtxt<'tcx>) -> Vec> { + fn normalize(self, infcx: &InferCtxt<'tcx>) -> PredicateObligations<'tcx> { // Do not normalize `wf` obligations with the new solver. // // The current deep normalization routine with the new solver does not @@ -336,7 +343,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let cause = self.cause(ObligationCauseCode::WellFormed(None)); let param_env = self.param_env; - let mut obligations = Vec::with_capacity(self.out.len()); + let mut obligations = PredicateObligations::with_capacity(self.out.len()); for mut obligation in self.out { assert!(!obligation.has_escaping_bound_vars()); let mut selcx = traits::SelectionContext::new(infcx); @@ -553,7 +560,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { &mut self, def_id: DefId, args: GenericArgsRef<'tcx>, - ) -> Vec> { + ) -> PredicateObligations<'tcx> { let predicates = self.tcx().predicates_of(def_id); let mut origins = vec![def_id; predicates.predicates.len()]; let mut head = predicates; diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 3102da218db4..4c2b7e4769ab 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -1,5 +1,6 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; +use rustc_infer::traits::PredicateObligations; use rustc_middle::query::Providers; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; @@ -30,7 +31,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( debug_assert!(!ocx.infcx.next_trait_solver()); let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let answer = traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations); ocx.register_obligations(obligations); @@ -99,7 +100,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( |ocx, ParamEnvAnd { param_env, value: goal }| { let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); - let mut obligations = vec![]; + let mut obligations = PredicateObligations::new(); let answer = traits::normalize_inherent_projection( selcx, param_env, From 8de8f46f789e5e61a0129fd9a7cf0c942a6301d8 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Thu, 10 Oct 2024 19:56:21 +0100 Subject: [PATCH 034/118] Swap PredicateObligation to ThinVec --- Cargo.lock | 5 +- .../src/obligation_forest/mod.rs | 3 +- .../src/obligation_forest/tests.rs | 68 ++++++++++--------- compiler/rustc_infer/Cargo.toml | 1 + compiler/rustc_infer/src/traits/mod.rs | 3 +- compiler/rustc_middle/src/traits/mod.rs | 9 +-- compiler/rustc_trait_selection/Cargo.toml | 1 + .../src/solve/fulfill.rs | 4 +- .../src/traits/fulfill.rs | 3 +- compiler/rustc_type_ir/Cargo.toml | 3 +- compiler/rustc_type_ir/src/fold.rs | 7 ++ compiler/rustc_type_ir/src/visit.rs | 8 +++ 12 files changed, 73 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c62c379f70d7..501d143890b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -3857,6 +3857,7 @@ dependencies = [ "rustc_target", "rustc_type_ir", "smallvec", + "thin-vec", "tracing", ] @@ -4490,6 +4491,7 @@ dependencies = [ "rustc_transmute", "rustc_type_ir", "smallvec", + "thin-vec", "tracing", ] @@ -4561,6 +4563,7 @@ dependencies = [ "rustc_span", "rustc_type_ir_macros", "smallvec", + "thin-vec", "tracing", ] diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index aca99b9fab1c..34a2464972a6 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -75,6 +75,7 @@ use std::fmt::Debug; use std::hash; use std::marker::PhantomData; +use thin_vec::ThinVec; use tracing::debug; use crate::fx::{FxHashMap, FxHashSet}; @@ -141,7 +142,7 @@ pub trait ObligationProcessor { #[derive(Debug)] pub enum ProcessResult { Unchanged, - Changed(Vec), + Changed(ThinVec), Error(E), } diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs index 8391e98ba8b0..739ef74e3f7a 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs @@ -1,5 +1,7 @@ use std::fmt; +use thin_vec::thin_vec; + use super::*; impl<'a> super::ForestObligation for &'a str { @@ -101,9 +103,9 @@ fn push_pop() { // |-> A.3 let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), "B" => ProcessResult::Error("B is for broken"), - "C" => ProcessResult::Changed(vec![]), + "C" => ProcessResult::Changed(thin_vec![]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -123,8 +125,8 @@ fn push_pop() { |obligation| match *obligation { "A.1" => ProcessResult::Unchanged, "A.2" => ProcessResult::Unchanged, - "A.3" => ProcessResult::Changed(vec!["A.3.i"]), - "D" => ProcessResult::Changed(vec!["D.1", "D.2"]), + "A.3" => ProcessResult::Changed(thin_vec!["A.3.i"]), + "D" => ProcessResult::Changed(thin_vec!["D.1", "D.2"]), "A.3.i" | "D.1" | "D.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -139,11 +141,11 @@ fn push_pop() { // |-> D.2 |-> D.2.i let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.1" => ProcessResult::Changed(vec![]), + "A.1" => ProcessResult::Changed(thin_vec![]), "A.2" => ProcessResult::Error("A is for apple"), - "A.3.i" => ProcessResult::Changed(vec![]), - "D.1" => ProcessResult::Changed(vec!["D.1.i"]), - "D.2" => ProcessResult::Changed(vec!["D.2.i"]), + "A.3.i" => ProcessResult::Changed(thin_vec![]), + "D.1" => ProcessResult::Changed(thin_vec!["D.1.i"]), + "D.2" => ProcessResult::Changed(thin_vec!["D.2.i"]), "D.1.i" | "D.2.i" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -158,7 +160,7 @@ fn push_pop() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "D.1.i" => ProcessResult::Error("D is for dumb"), - "D.2.i" => ProcessResult::Changed(vec![]), + "D.2.i" => ProcessResult::Changed(thin_vec![]), _ => panic!("unexpected obligation {:?}", obligation), }, |_| {}, @@ -184,10 +186,10 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), - "A.1" => ProcessResult::Changed(vec![]), - "A.2" => ProcessResult::Changed(vec!["A.2.i", "A.2.ii"]), - "A.3" => ProcessResult::Changed(vec![]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), + "A.1" => ProcessResult::Changed(thin_vec![]), + "A.2" => ProcessResult::Changed(thin_vec!["A.2.i", "A.2.ii"]), + "A.3" => ProcessResult::Changed(thin_vec![]), "A.2.i" | "A.2.ii" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -201,7 +203,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A.2.i" => ProcessResult::Unchanged, - "A.2.ii" => ProcessResult::Changed(vec![]), + "A.2.ii" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -211,7 +213,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.2.i" => ProcessResult::Changed(vec!["A.2.i.a"]), + "A.2.i" => ProcessResult::Changed(thin_vec!["A.2.i.a"]), "A.2.i.a" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -222,7 +224,7 @@ fn success_in_grandchildren() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.2.i.a" => ProcessResult::Changed(vec![]), + "A.2.i.a" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -247,7 +249,7 @@ fn to_errors_no_throw() { forest.register_obligation("A"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]), "A.1" | "A.2" | "A.3" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -269,7 +271,7 @@ fn diamond() { forest.register_obligation("A"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["A.1", "A.2"]), + "A" => ProcessResult::Changed(thin_vec!["A.1", "A.2"]), "A.1" | "A.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -280,8 +282,8 @@ fn diamond() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A.1" => ProcessResult::Changed(vec!["D"]), - "A.2" => ProcessResult::Changed(vec!["D"]), + "A.1" => ProcessResult::Changed(thin_vec!["D"]), + "A.2" => ProcessResult::Changed(thin_vec!["D"]), "D" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -295,7 +297,7 @@ fn diamond() { |obligation| match *obligation { "D" => { d_count += 1; - ProcessResult::Changed(vec![]) + ProcessResult::Changed(thin_vec![]) } _ => unreachable!(), }, @@ -313,7 +315,7 @@ fn diamond() { forest.register_obligation("A'"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]), + "A'" => ProcessResult::Changed(thin_vec!["A'.1", "A'.2"]), "A'.1" | "A'.2" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -324,8 +326,8 @@ fn diamond() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A'.1" => ProcessResult::Changed(vec!["D'", "A'"]), - "A'.2" => ProcessResult::Changed(vec!["D'"]), + "A'.1" => ProcessResult::Changed(thin_vec!["D'", "A'"]), + "A'.2" => ProcessResult::Changed(thin_vec!["D'"]), "D'" | "A'" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -366,7 +368,7 @@ fn done_dependency() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]), + "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(thin_vec![]), _ => unreachable!(), }, |_| {}, @@ -379,7 +381,9 @@ fn done_dependency() { forest.register_obligation("(A,B,C): Sized"); let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "(A,B,C): Sized" => ProcessResult::Changed(vec!["A: Sized", "B: Sized", "C: Sized"]), + "(A,B,C): Sized" => { + ProcessResult::Changed(thin_vec!["A: Sized", "B: Sized", "C: Sized"]) + } _ => unreachable!(), }, |_| {}, @@ -399,10 +403,10 @@ fn orphan() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { - "A" => ProcessResult::Changed(vec!["D", "E"]), + "A" => ProcessResult::Changed(thin_vec!["D", "E"]), "B" => ProcessResult::Unchanged, - "C1" => ProcessResult::Changed(vec![]), - "C2" => ProcessResult::Changed(vec![]), + "C1" => ProcessResult::Changed(thin_vec![]), + "C2" => ProcessResult::Changed(thin_vec![]), "D" | "E" => ProcessResult::Unchanged, _ => unreachable!(), }, @@ -416,7 +420,7 @@ fn orphan() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "D" | "E" => ProcessResult::Unchanged, - "B" => ProcessResult::Changed(vec!["D"]), + "B" => ProcessResult::Changed(thin_vec!["D"]), _ => unreachable!(), }, |_| {}, @@ -459,7 +463,7 @@ fn simultaneous_register_and_error() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A" => ProcessResult::Error("An error"), - "B" => ProcessResult::Changed(vec!["A"]), + "B" => ProcessResult::Changed(thin_vec!["A"]), _ => unreachable!(), }, |_| {}, @@ -474,7 +478,7 @@ fn simultaneous_register_and_error() { let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C( |obligation| match *obligation { "A" => ProcessResult::Error("An error"), - "B" => ProcessResult::Changed(vec!["A"]), + "B" => ProcessResult::Changed(thin_vec!["A"]), _ => unreachable!(), }, |_| {}, diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 1f616710200f..ef5a1468c87e 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -21,5 +21,6 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 2d02391c57a7..ac641ef56522 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::traits::solve::Certainty; pub use rustc_middle::traits::*; use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::Span; +use thin_vec::ThinVec; pub use self::ImplSource::*; pub use self::SelectionError::*; @@ -84,7 +85,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>; pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; -pub type PredicateObligations<'tcx> = Vec>; +pub type PredicateObligations<'tcx> = ThinVec>; impl<'tcx> PredicateObligation<'tcx> { /// Flips the polarity of the inner predicate. diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index caa86da8a858..8ee8b4c4823a 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -25,6 +25,7 @@ use rustc_span::{DUMMY_SP, Span}; // FIXME: Remove this import and import via `solve::` pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal}; use smallvec::{SmallVec, smallvec}; +use thin_vec::ThinVec; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; use crate::mir::ConstraintCategory; @@ -625,14 +626,14 @@ pub enum ImplSource<'tcx, N> { /// for some type parameter. The `Vec` represents the /// obligations incurred from normalizing the where-clause (if /// any). - Param(Vec), + Param(ThinVec), /// Successful resolution for a builtin impl. - Builtin(BuiltinImplSource, Vec), + Builtin(BuiltinImplSource, ThinVec), } impl<'tcx, N> ImplSource<'tcx, N> { - pub fn nested_obligations(self) -> Vec { + pub fn nested_obligations(self) -> ThinVec { match self { ImplSource::UserDefined(i) => i.nested, ImplSource::Param(n) | ImplSource::Builtin(_, n) => n, @@ -686,7 +687,7 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub struct ImplSourceUserDefinedData<'tcx, N> { pub impl_def_id: DefId, pub args: GenericArgsRef<'tcx>, - pub nested: Vec, + pub nested: ThinVec, } #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index f023a0eb53ae..d4bb84838cc9 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -26,5 +26,6 @@ rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 8ec4427091d0..d9dc772eca9e 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -2,6 +2,7 @@ use std::marker::PhantomData; use std::mem; use std::ops::ControlFlow; +use rustc_data_structures::thinvec::ExtractIf; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; @@ -81,7 +82,8 @@ impl<'tcx> ObligationStorage<'tcx> { // we get all obligations involved in the overflow. We pretty much check: if // we were to do another step of `select_where_possible`, which goals would // change. - self.overflowed.extend(self.pending.extract_if(|o| { + // FIXME: is merged, this can be removed. + self.overflowed.extend(ExtractIf::new(&mut self.pending, |o| { let goal = o.clone().into(); let result = <&SolverDelegate<'tcx>>::from(infcx) .evaluate_root_goal(goal, GenerateProofTree::No) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 3e3834a11c62..e56f18669707 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -14,6 +14,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt}; +use thin_vec::ThinVec; use tracing::{debug, debug_span, instrument}; use super::project::{self, ProjectAndUnifyResult}; @@ -28,7 +29,7 @@ use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _}; use crate::traits::query::evaluate_obligation::InferCtxtExt; -pub(crate) type PendingPredicateObligations<'tcx> = Vec>; +pub(crate) type PendingPredicateObligations<'tcx> = ThinVec>; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { /// Note that we include both the `ParamEnv` and the `Predicate`, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 98cc116bd004..8d97ec728304 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -17,6 +17,7 @@ rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } smallvec = { version = "1.8.1", default-features = false } +thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end @@ -30,7 +31,7 @@ nightly = [ "smallvec/may_dangle", "smallvec/union", "rustc_index/nightly", - "rustc_ast_ir/nightly" + "rustc_ast_ir/nightly", ] [lints.rust] diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 64ce6fd69e6b..8209d6f5fe3b 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -48,6 +48,7 @@ use std::mem; use rustc_index::{Idx, IndexVec}; +use thin_vec::ThinVec; use tracing::instrument; use crate::data_structures::Lrc; @@ -322,6 +323,12 @@ impl> TypeFoldable for Vec { } } +impl> TypeFoldable for ThinVec { + fn try_fold_with>(self, folder: &mut F) -> Result { + self.into_iter().map(|t| t.try_fold_with(folder)).collect() + } +} + impl> TypeFoldable for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { Vec::from(self).try_fold_with(folder).map(Vec::into_boxed_slice) diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 0ba7e2bd5523..71c3646498b9 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,6 +47,7 @@ use std::ops::ControlFlow; use rustc_ast_ir::visit::VisitorResult; use rustc_ast_ir::{try_visit, walk_visitable_list}; use rustc_index::{Idx, IndexVec}; +use thin_vec::ThinVec; use crate::data_structures::Lrc; use crate::inherent::*; @@ -184,6 +185,13 @@ impl> TypeVisitable for Vec { } } +impl> TypeVisitable for ThinVec { + fn visit_with>(&self, visitor: &mut V) -> V::Result { + walk_visitable_list!(visitor, self.iter()); + V::Result::output() + } +} + // `TypeFoldable` isn't impl'd for `&[T]`. It doesn't make sense in the general // case, because we can't return a new slice. But note that there are a couple // of trivial impls of `TypeFoldable` for specific slice types elsewhere. From cae29b2fc3a1d3563ebfd3c9649b90902e3a3fa1 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 12 Oct 2024 10:48:43 -0400 Subject: [PATCH 035/118] Import another update --- RELEASES.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 4bdee5f66ed0..df61e649a5b4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -7,6 +7,7 @@ Language -------- - [Don't make statement nonterminals match pattern nonterminals](https://github.com/rust-lang/rust/pull/120221/) - [Patterns matching empty types can now be omitted in common cases](https://github.com/rust-lang/rust/pull/122792) +- [Enforce supertrait outlives obligations when using trait impls](https://github.com/rust-lang/rust/pull/124336) - [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) - [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/) - [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/) @@ -27,6 +28,8 @@ Compiler -------- - [Promote riscv64gc-unknown-linux-musl to tier 2](https://github.com/rust-lang/rust/pull/122049) - [Promote Mac Catalyst targets `aarch64-apple-ios-macabi` and `x86_64-apple-ios-macabi` to Tier 2, and ship them with rustup](https://github.com/rust-lang/rust/pull/126450) +- [Add tier 3 NuttX based targets for RISC-V and ARM](https://github.com/rust-lang/rust/pull/127755) +- [Add tier 3 powerpc-unknown-linux-muslspe target](https://github.com/rust-lang/rust/pull/127905) - [Improved diagnostics to explain why a pattern is unreachable](https://github.com/rust-lang/rust/pull/128034) - [The compiler now triggers the unreachable code warning properly for async functions that don't return/are `-> !`](https://github.com/rust-lang/rust/pull/128443) - [Promote `aarch64-apple-darwin` to Tier 1](https://github.com/rust-lang/rust/pull/128592) @@ -41,7 +44,7 @@ Libraries - [Implement DoubleEnded and ExactSize for Take and Take](https://github.com/rust-lang/rust/pull/106943/) - [Stabilize Wasm relaxed SIMD](https://github.com/rust-lang/rust/pull/117468/) - [Stabilize const `{integer}::from_str_radix` i.e. `const_int_from_str`](https://github.com/rust-lang/rust/pull/124941/) -- [CloneToUninit impls](https://github.com/rust-lang/rust/pull/126877/) +- [Generalize `{Rc,Arc}::make_mut()` to `Path`, `OsStr`, and `CStr`.](https://github.com/rust-lang/rust/pull/126877) - [impl `Default` for collection iterators that don't already have it](https://github.com/rust-lang/rust/pull/128261/) From 276d112d664ec7b584ce3768accb91c702552513 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 12 Oct 2024 15:20:06 -0400 Subject: [PATCH 036/118] Add stabilized APIs --- RELEASES.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index df61e649a5b4..79881c46bdee 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -41,18 +41,94 @@ Compiler Libraries --------- -- [Implement DoubleEnded and ExactSize for Take and Take](https://github.com/rust-lang/rust/pull/106943/) -- [Stabilize Wasm relaxed SIMD](https://github.com/rust-lang/rust/pull/117468/) -- [Stabilize const `{integer}::from_str_radix` i.e. `const_int_from_str`](https://github.com/rust-lang/rust/pull/124941/) - [Generalize `{Rc,Arc}::make_mut()` to `Path`, `OsStr`, and `CStr`.](https://github.com/rust-lang/rust/pull/126877) -- [impl `Default` for collection iterators that don't already have it](https://github.com/rust-lang/rust/pull/128261/) - Stabilized APIs --------------- +- [`std::thread::Builder::spawn_unchecked`](https://doc.rust-lang.org/stable/std/thread/struct.Builder.html#method.spawn_unchecked) +- [`std::str::CharIndices::offset`](https://doc.rust-lang.org/nightly/std/str/struct.CharIndices.html#method.offset) +- [`std::option::Option::is_none_or`](https://doc.rust-lang.org/nightly/std/option/enum.Option.html#method.is_none_or) +- [`[T]::is_sorted`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted) +- [`[T]::is_sorted_by`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by) +- [`[T]::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.is_sorted_by_key) +- [`Iterator::is_sorted`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted) +- [`Iterator::is_sorted_by`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by) +- [`Iterator::is_sorted_by_key`](https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.is_sorted_by_key) +- [`std::future::Ready::into_inner`](https://doc.rust-lang.org/nightly/std/future/struct.Ready.html#method.into_inner) +- [`std::iter::repeat_n`](https://doc.rust-lang.org/nightly/std/iter/fn.repeat_n.html) +- [`impl DoubleEndedIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-DoubleEndedIterator-for-Take%3CRepeat%3CT%3E%3E) +- [`impl ExactSizeIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeat%3CT%3E%3E) +- [`impl ExactSizeIterator for Take>`](https://doc.rust-lang.org/nightly/std/iter/struct.Take.html#impl-ExactSizeIterator-for-Take%3CRepeatWith%3CF%3E%3E) +- [`impl Default for std::collections::binary_heap::Iter`](https://doc.rust-lang.org/nightly/std/collections/binary_heap/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E) +- [`impl Default for std::collections::btree_map::RangeMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.RangeMut.html#impl-Default-for-RangeMut%3C'_,+K,+V%3E) +- [`impl Default for std::collections::btree_map::ValuesMut`](https://doc.rust-lang.org/nightly/std/collections/btree_map/struct.ValuesMut.html#impl-Default-for-ValuesMut%3C'_,+K,+V%3E) +- [`impl Default for std::collections::vec_deque::Iter`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.Iter.html#impl-Default-for-Iter%3C'_,+T%3E) +- [`impl Default for std::collections::vec_deque::IterMut`](https://doc.rust-lang.org/nightly/std/collections/vec_deque/struct.IterMut.html#impl-Default-for-IterMut%3C'_,+T%3E) +- [`Rc::new_uninit`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit) +- [`Rc::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init) +- [`Rc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new_uninit_slice) +- [`Rc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.assume_init-1) +- [`Arc::new_uninit`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit) +- [`Arc::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init) +- [`Arc<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.new_uninit_slice) +- [`Arc<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.assume_init-1) +- [`Box::new_uninit`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit) +- [`Box::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init) +- [`Box<[T]>::new_uninit_slice`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.new_uninit_slice) +- [`Box<[MaybeUninit]>::assume_init`](https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html#method.assume_init-1) +- [`core::arch::x86_64::_bextri_u64`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u64.html) +- [`core::arch::x86_64::_bextri_u32`](https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bextri_u32.html) +- [`core::arch::x86::_mm_broadcastsi128_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_broadcastsi128_si256.html) +- [`core::arch::x86::_mm256_stream_load_si256`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm256_stream_load_si256.html) +- [`core::arch::x86::_tzcnt_u16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._tzcnt_u16.html) +- [`core::arch::x86::_mm_extracti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_extracti_si64.html) +- [`core::arch::x86::_mm_inserti_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_inserti_si64.html) +- [`core::arch::x86::_mm_storeu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si16.html) +- [`core::arch::x86::_mm_storeu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si32.html) +- [`core::arch::x86::_mm_storeu_si64`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_storeu_si64.html) +- [`core::arch::x86::_mm_loadu_si16`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si16.html) +- [`core::arch::x86::_mm_loadu_si32`](https://doc.rust-lang.org/stable/core/arch/x86/fn._mm_loadu_si32.html) +- [`core::arch::wasm32::u8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_swizzle.html) +- [`core::arch::wasm32::i8x16_relaxed_swizzle`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_swizzle.html) +- [`core::arch::wasm32::i32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f32x4.html) +- [`core::arch::wasm32::u32x4_relaxed_trunc_f32x4`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f32x4.html) +- [`core::arch::wasm32::i32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_trunc_f64x2_zero.html) +- [`core::arch::wasm32::u32x4_relaxed_trunc_f64x2_zero`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_trunc_f64x2_zero.html) +- [`core::arch::wasm32::f32x4_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_madd.html) +- [`core::arch::wasm32::f32x4_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_nmadd.html) +- [`core::arch::wasm32::f64x2_relaxed_madd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_madd.html) +- [`core::arch::wasm32::f64x2_relaxed_nmadd`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_nmadd.html) +- [`core::arch::wasm32::i8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i8x16_relaxed_laneselect.html) +- [`core::arch::wasm32::u8x16_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u8x16_relaxed_laneselect.html) +- [`core::arch::wasm32::i16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_laneselect.html) +- [`core::arch::wasm32::u16x8_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_laneselect.html) +- [`core::arch::wasm32::i32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_laneselect.html) +- [`core::arch::wasm32::u32x4_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_laneselect.html) +- [`core::arch::wasm32::i64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i64x2_relaxed_laneselect.html) +- [`core::arch::wasm32::u64x2_relaxed_laneselect`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u64x2_relaxed_laneselect.html) +- [`core::arch::wasm32::f32x4_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_min.html) +- [`core::arch::wasm32::f32x4_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f32x4_relaxed_max.html) +- [`core::arch::wasm32::f64x2_relaxed_min`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_min.html) +- [`core::arch::wasm32::f64x2_relaxed_max`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.f64x2_relaxed_max.html) +- [`core::arch::wasm32::i16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_q15mulr.html) +- [`core::arch::wasm32::u16x8_relaxed_q15mulr`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_q15mulr.html) +- [`core::arch::wasm32::i16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i16x8_relaxed_dot_i8x16_i7x16.html) +- [`core::arch::wasm32::u16x8_relaxed_dot_i8x16_i7x16`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u16x8_relaxed_dot_i8x16_i7x16.html) +- [`core::arch::wasm32::i32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.i32x4_relaxed_dot_i8x16_i7x16_add.html) +- [`core::arch::wasm32::u32x4_relaxed_dot_i8x16_i7x16_add`](https://doc.rust-lang.org/nightly/core/arch/wasm32/fn.u32x4_relaxed_dot_i8x16_i7x16_add.html) + +These APIs are now stable in const contexts: + +- [`std::task::Waker::from_raw`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw) +- [`std::task::Waker::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Waker.html#method.from_raw) +- [`std::task::Context::from_waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.from_waker) +- [`std::task::Context::waker`](https://doc.rust-lang.org/nightly/std/task/struct.Context.html#method.waker) +- [`$integer::from_str_radix`](https://doc.rust-lang.org/nightly/std/primitive.u32.html#method.from_str_radix) +- [`std::num::ParseIntError::kind`](https://doc.rust-lang.org/nightly/std/num/struct.ParseIntError.html#method.kind) + Cargo From 5b2985f8df7cfd6497cd7ea60e3ea4b129cb0f2f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 12 Oct 2024 15:20:58 -0400 Subject: [PATCH 037/118] Add explicit link to PR --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 79881c46bdee..1213a596024c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -140,7 +140,7 @@ Cargo Compatibility Notes ------------------- - We now [disallow setting some built-in cfgs via the command-line](https://github.com/rust-lang/rust/pull/126158) with the newly added [`explicit_builtin_cfgs_in_flags`](https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#explicit-builtin-cfgs-in-flags) lint in order to prevent incoherent state, eg. `windows` cfg active but target is Linux based. The appropriate [`rustc` flag](https://doc.rust-lang.org/rustc/command-line-arguments.html) should be used instead. -- The standard library has a new implementation of `binary_search` which is significantly improves performance (#128254). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. +- The standard library has a new implementation of `binary_search` which is significantly improves performance ([#128254](https://github.com/rust-lang/rust/pull/128254)). However when a sorted slice has multiple values which compare equal, the new implementation may select a different value among the equal ones than the old implementation. - [illumos/Solaris now sets `MSG_NOSIGNAL` when writing to sockets](https://github.com/rust-lang/rust/pull/128259). This avoids killing the process with SIGPIPE when writing to a closed socket, which matches the existing behavior on other UNIX targets. - [Removes a problematic hack that always passed the --whole-archive linker flag for tests, which may cause linker errors for code accidentally relying on it.](https://github.com/rust-lang/rust/pull/128400) - The WebAssembly target features `multivalue` and `reference-types` are now From c128b4c4334fc0ed67c242eaf60a369df6bea054 Mon Sep 17 00:00:00 2001 From: Andreas Molzer Date: Sun, 13 Oct 2024 02:35:09 +0200 Subject: [PATCH 038/118] Fix typo thing->thin referring to pointer --- library/core/src/ptr/const_ptr.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 7b91b1bcb3b8..0122c00f890a 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -72,7 +72,7 @@ impl *const T { /// /// The resulting pointer will have provenance of `self`. This operation is semantically the /// same as creating a new pointer with the data pointer value of `self` but the metadata of - /// `meta`, being fat or thing depending on the `meta` operand. + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e1a181158afc..a57097f8cbd1 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -54,7 +54,7 @@ impl *mut T { /// /// The resulting pointer will have provenance of `self`. This operation is semantically the /// same as creating a new pointer with the data pointer value of `self` but the metadata of - /// `meta`, being fat or thing depending on the `meta` operand. + /// `meta`, being fat or thin depending on the `meta` operand. /// /// # Examples /// From feecfaa18d87e3f5dc9258fafa9d9ab9c1ebe5f6 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 18 Mar 2024 00:02:49 +0000 Subject: [PATCH 039/118] Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode --- compiler/rustc_builtin_macros/src/env.rs | 34 +++++++++++++++---- compiler/rustc_builtin_macros/src/util.rs | 32 +++++++++++++---- library/core/src/macros/mod.rs | 18 +++++----- .../non-unicode-env/non_unicode_env.rs | 1 + .../non-unicode-env/non_unicode_env.stderr | 10 +++++- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 25583cda5a20..43e2bf1796fc 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::{Ident, Symbol, kw, sym}; use thin_vec::thin_vec; use crate::errors; -use crate::util::{expr_to_string, get_exprs_from_tts, get_single_str_from_tts}; +use crate::util::{expr_to_string, get_exprs_from_tts, get_single_expr_from_tts}; fn lookup_env<'cx>(cx: &'cx ExtCtxt<'_>, var: Symbol) -> Result { let var = var.as_str(); @@ -32,19 +32,28 @@ pub(crate) fn expand_option_env<'cx>( sp: Span, tts: TokenStream, ) -> MacroExpanderResult<'cx> { - let ExpandResult::Ready(mac) = get_single_str_from_tts(cx, sp, tts, "option_env!") else { + let ExpandResult::Ready(mac_expr) = get_single_expr_from_tts(cx, sp, tts, "option_env!") else { + return ExpandResult::Retry(()); + }; + let var_expr = match mac_expr { + Ok(var_expr) => var_expr, + Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), + }; + let ExpandResult::Ready(mac) = + expr_to_string(cx, var_expr.clone(), "argument must be a string literal") + else { return ExpandResult::Retry(()); }; let var = match mac { - Ok(var) => var, + Ok((var, _)) => var, Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; let sp = cx.with_def_site_ctxt(sp); - let value = lookup_env(cx, var).ok(); - cx.sess.psess.env_depinfo.borrow_mut().insert((var, value)); + let value = lookup_env(cx, var); + cx.sess.psess.env_depinfo.borrow_mut().insert((var, value.as_ref().ok().copied())); let e = match value { - None => { + Err(VarError::NotPresent) => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); cx.expr_path(cx.path_all( sp, @@ -58,7 +67,18 @@ pub(crate) fn expand_option_env<'cx>( ))], )) } - Some(value) => { + Err(VarError::NotUnicode(_)) => { + let ExprKind::Lit(token::Lit { + kind: LitKind::Str | LitKind::StrRaw(..), symbol, .. + }) = &var_expr.kind + else { + unreachable!("`expr_to_string` ensures this is a string lit") + }; + + let guar = cx.dcx().emit_err(errors::EnvNotUnicode { span: sp, var: *symbol }); + return ExpandResult::Ready(DummyResult::any(sp, guar)); + } + Ok(value) => { cx.expr_call_global(sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), thin_vec![ cx.expr_str(sp, value) ]) diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index d7b03a43ecb0..2a28dfaf3c43 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -171,6 +171,30 @@ pub(crate) fn get_single_str_spanned_from_tts( tts: TokenStream, name: &str, ) -> ExpandResult, ()> { + let ExpandResult::Ready(ret) = get_single_expr_from_tts(cx, span, tts, name) else { + return ExpandResult::Retry(()); + }; + let ret = match ret { + Ok(ret) => ret, + Err(e) => return ExpandResult::Ready(Err(e)), + }; + expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { + res.map_err(|err| match err { + Ok((err, _)) => err.emit(), + Err(guar) => guar, + }) + .map(|(symbol, _style, span)| (symbol, span)) + }) +} + +/// Interpreting `tts` as a comma-separated sequence of expressions, +/// expect exactly one expression, or emit an error and return `Err`. +pub(crate) fn get_single_expr_from_tts( + cx: &mut ExtCtxt<'_>, + span: Span, + tts: TokenStream, + name: &str, +) -> ExpandResult, ErrorGuaranteed>, ()> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); @@ -185,13 +209,7 @@ pub(crate) fn get_single_str_spanned_from_tts( if p.token != token::Eof { cx.dcx().emit_err(errors::OnlyOneArgument { span, name }); } - expr_to_spanned_string(cx, ret, "argument must be a string literal").map(|res| { - res.map_err(|err| match err { - Ok((err, _)) => err.emit(), - Err(guar) => guar, - }) - .map(|(symbol, _style, span)| (symbol, span)) - }) + ExpandResult::Ready(Ok(ret)) } /// Extracts comma-separated expressions from `tts`. diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index aa0646846e43..2839a242a901 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1107,17 +1107,19 @@ pub(crate) mod builtin { /// /// If the named environment variable is present at compile time, this will /// expand into an expression of type `Option<&'static str>` whose value is - /// `Some` of the value of the environment variable. If the environment - /// variable is not present, then this will expand to `None`. See - /// [`Option`][Option] for more information on this type. Use - /// [`std::env::var`] instead if you want to read the value at runtime. + /// `Some` of the value of the environment variable (a compilation error + /// will be emitted if the environment variable is not a valid Unicode + /// string). If the environment variable is not present, then this will + /// expand to `None`. See [`Option`][Option] for more information on this + /// type. Use [`std::env::var`] instead if you want to read the value at + /// runtime. /// /// [`std::env::var`]: ../std/env/fn.var.html /// - /// A compile time error is never emitted when using this macro regardless - /// of whether the environment variable is present or not. - /// To emit a compile error if the environment variable is not present, - /// use the [`env!`] macro instead. + /// A compile time error is only emitted when using this macro if the + /// environment variable exists and is not a valid Unicode string. To also + /// emit a compile error if the environment variable is not present, use the + /// [`env!`] macro instead. /// /// # Examples /// diff --git a/tests/run-make/non-unicode-env/non_unicode_env.rs b/tests/run-make/non-unicode-env/non_unicode_env.rs index 865fc9373657..3efa4842d94a 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.rs +++ b/tests/run-make/non-unicode-env/non_unicode_env.rs @@ -1,3 +1,4 @@ fn main() { let _ = env!("NON_UNICODE_VAR"); + let _ = option_env!("NON_UNICODE_VAR"); } diff --git a/tests/run-make/non-unicode-env/non_unicode_env.stderr b/tests/run-make/non-unicode-env/non_unicode_env.stderr index c4dcd7b2eb70..1f260ac9c07b 100644 --- a/tests/run-make/non-unicode-env/non_unicode_env.stderr +++ b/tests/run-make/non-unicode-env/non_unicode_env.stderr @@ -6,5 +6,13 @@ error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string | = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error: environment variable `NON_UNICODE_VAR` is not a valid Unicode string + --> non_unicode_env.rs:3:13 + | +3 | let _ = option_env!("NON_UNICODE_VAR"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `option_env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors From 9e0a7b99b5d3677d3c90b11b57ec56a6a2c4f162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Sun, 13 Oct 2024 21:08:47 +0200 Subject: [PATCH 040/118] rename rcbox in other places as per review comments --- library/alloc/src/rc.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index e6f27f536399..e98ae7c31ad0 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -289,7 +289,7 @@ struct RcInner { } /// Calculate layout for `RcInner` using the inner value's layout -fn rcbox_layout_for_value_layout(layout: Layout) -> Layout { +fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout { // Calculate layout using the given value layout. // Previously, layout was calculated on the expression // `&*(ptr as *const RcInner)`, but this created a misaligned @@ -2009,17 +2009,17 @@ impl Rc { /// Allocates an `RcInner` with sufficient space for /// a possibly-unsized inner value where the value has the layout provided. /// - /// The function `mem_to_rcbox` is called with the data pointer + /// The function `mem_to_rc_inner` is called with the data pointer /// and must return back a (potentially fat)-pointer for the `RcInner`. #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_layout( value_layout: Layout, allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcInner, + mem_to_rc_inner: impl FnOnce(*mut u8) -> *mut RcInner, ) -> *mut RcInner { - let layout = rcbox_layout_for_value_layout(value_layout); + let layout = rc_inner_layout_for_value_layout(value_layout); unsafe { - Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rcbox) + Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rc_inner) .unwrap_or_else(|_| handle_alloc_error(layout)) } } @@ -2028,21 +2028,21 @@ impl Rc { /// a possibly-unsized inner value where the value has the layout provided, /// returning an error if allocation fails. /// - /// The function `mem_to_rcbox` is called with the data pointer + /// The function `mem_to_rc_inner` is called with the data pointer /// and must return back a (potentially fat)-pointer for the `RcInner`. #[inline] unsafe fn try_allocate_for_layout( value_layout: Layout, allocate: impl FnOnce(Layout) -> Result, AllocError>, - mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcInner, + mem_to_rc_inner: impl FnOnce(*mut u8) -> *mut RcInner, ) -> Result<*mut RcInner, AllocError> { - let layout = rcbox_layout_for_value_layout(value_layout); + let layout = rc_inner_layout_for_value_layout(value_layout); // Allocate for the layout. let ptr = allocate(layout)?; // Initialize the RcInner - let inner = mem_to_rcbox(ptr.as_non_null_ptr().as_ptr()); + let inner = mem_to_rc_inner(ptr.as_non_null_ptr().as_ptr()); unsafe { debug_assert_eq!(Layout::for_value_raw(inner), layout); @@ -3784,7 +3784,7 @@ impl UniqueRcUninit { let ptr = unsafe { Rc::allocate_for_layout( layout, - |layout_for_rcbox| alloc.allocate(layout_for_rcbox), + |layout_for_rc_inner| alloc.allocate(layout_for_rc_inner), |mem| mem.with_metadata_of(ptr::from_ref(for_value) as *const RcInner), ) }; @@ -3820,10 +3820,10 @@ impl Drop for UniqueRcUninit { // * new() produced a pointer safe to deallocate. // * We own the pointer unless into_rc() was called, which forgets us. unsafe { - self.alloc - .take() - .unwrap() - .deallocate(self.ptr.cast(), rcbox_layout_for_value_layout(self.layout_for_value)); + self.alloc.take().unwrap().deallocate( + self.ptr.cast(), + rc_inner_layout_for_value_layout(self.layout_for_value), + ); } } } From d858dfedbbde119f2ea707fea253e99c824ec252 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 14 Oct 2024 05:30:45 +0900 Subject: [PATCH 041/118] Fix clobber_abi and disallow SVE-related registers in Arm64EC inline assembly --- compiler/rustc_target/src/asm/aarch64.rs | 37 ++++++++++++------------ compiler/rustc_target/src/asm/mod.rs | 17 +++++++++-- tests/codegen/asm-arm64ec-clobbers.rs | 36 +++++++++++++++++++++++ tests/ui/asm/aarch64/aarch64-sve.rs | 28 ++++++++++++++++++ tests/ui/asm/aarch64/arm64ec-sve.rs | 31 ++++++++++++++++++++ tests/ui/asm/aarch64/arm64ec-sve.stderr | 14 +++++++++ 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 tests/codegen/asm-arm64ec-clobbers.rs create mode 100644 tests/ui/asm/aarch64/aarch64-sve.rs create mode 100644 tests/ui/asm/aarch64/arm64ec-sve.rs create mode 100644 tests/ui/asm/aarch64/arm64ec-sve.stderr diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 74970a26b23b..fdd9adabc8e2 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -64,6 +64,7 @@ impl AArch64InlineAsmRegClass { neon: I8, I16, I32, I64, F16, F32, F64, F128, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF16(4), VecF32(2), VecF64(1), VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF16(8), VecF32(4), VecF64(2); + // Note: When adding support for SVE vector types, they must be rejected for Arm64EC. }, Self::preg => &[], } @@ -96,7 +97,7 @@ fn restricted_for_arm64ec( _is_clobber: bool, ) -> Result<(), &'static str> { if arch == InlineAsmArch::Arm64EC { - Err("x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC") + Err("x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC") } else { Ok(()) } @@ -165,23 +166,23 @@ def_regs! { v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"] % restricted_for_arm64ec, v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"] % restricted_for_arm64ec, v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"] % restricted_for_arm64ec, - p0: preg = ["p0"], - p1: preg = ["p1"], - p2: preg = ["p2"], - p3: preg = ["p3"], - p4: preg = ["p4"], - p5: preg = ["p5"], - p6: preg = ["p6"], - p7: preg = ["p7"], - p8: preg = ["p8"], - p9: preg = ["p9"], - p10: preg = ["p10"], - p11: preg = ["p11"], - p12: preg = ["p12"], - p13: preg = ["p13"], - p14: preg = ["p14"], - p15: preg = ["p15"], - ffr: preg = ["ffr"], + p0: preg = ["p0"] % restricted_for_arm64ec, + p1: preg = ["p1"] % restricted_for_arm64ec, + p2: preg = ["p2"] % restricted_for_arm64ec, + p3: preg = ["p3"] % restricted_for_arm64ec, + p4: preg = ["p4"] % restricted_for_arm64ec, + p5: preg = ["p5"] % restricted_for_arm64ec, + p6: preg = ["p6"] % restricted_for_arm64ec, + p7: preg = ["p7"] % restricted_for_arm64ec, + p8: preg = ["p8"] % restricted_for_arm64ec, + p9: preg = ["p9"] % restricted_for_arm64ec, + p10: preg = ["p10"] % restricted_for_arm64ec, + p11: preg = ["p11"] % restricted_for_arm64ec, + p12: preg = ["p12"] % restricted_for_arm64ec, + p13: preg = ["p13"] % restricted_for_arm64ec, + p14: preg = ["p14"] % restricted_for_arm64ec, + p15: preg = ["p15"] % restricted_for_arm64ec, + ffr: preg = ["ffr"] % restricted_for_arm64ec, #error = ["x19", "w19"] => "x19 is used internally by LLVM and cannot be used as an operand for inline asm", #error = ["x29", "w29", "fp", "wfp"] => diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 73ae1ae96ae2..4b539eb8e208 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -890,6 +890,7 @@ pub enum InlineAsmClobberAbi { Arm, AArch64, AArch64NoX18, + Arm64EC, RiscV, LoongArch, S390x, @@ -932,7 +933,7 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::Arm64EC => match name { - "C" | "system" => Ok(InlineAsmClobberAbi::AArch64NoX18), + "C" | "system" => Ok(InlineAsmClobberAbi::Arm64EC), _ => Err(&["C", "system"]), }, InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name { @@ -1033,7 +1034,6 @@ impl InlineAsmClobberAbi { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, ffr, - } }, InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! { @@ -1052,7 +1052,20 @@ impl InlineAsmClobberAbi { p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, ffr, + } + }, + InlineAsmClobberAbi::Arm64EC => clobbered_regs! { + AArch64 AArch64InlineAsmReg { + // x13 and x14 cannot be used in Arm64EC. + x0, x1, x2, x3, x4, x5, x6, x7, + x8, x9, x10, x11, x12, x15, + x16, x17, x30, + // Technically the low 64 bits of v8-v15 are preserved, but + // we have no way of expressing this using clobbers. + v0, v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, + // v16-v31, p*, and ffr cannot be used in Arm64EC. } }, InlineAsmClobberAbi::Arm => clobbered_regs! { diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm-arm64ec-clobbers.rs new file mode 100644 index 000000000000..2ec61907947c --- /dev/null +++ b/tests/codegen/asm-arm64ec-clobbers.rs @@ -0,0 +1,36 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target arm64ec-pc-windows-msvc +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/ui/asm/aarch64/aarch64-sve.rs b/tests/ui/asm/aarch64/aarch64-sve.rs new file mode 100644 index 000000000000..8cdc9dd4266e --- /dev/null +++ b/tests/ui/asm/aarch64/aarch64-sve.rs @@ -0,0 +1,28 @@ +//@ only-aarch64 +//@ build-pass +//@ needs-asm-support + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items)] +#![no_core] + +// AArch64 test corresponding to arm64ec-sve.rs. + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +impl Copy for f64 {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +fn f(x: f64) { + unsafe { + asm!("", out("p0") _); + asm!("", out("ffr") _); + } +} diff --git a/tests/ui/asm/aarch64/arm64ec-sve.rs b/tests/ui/asm/aarch64/arm64ec-sve.rs new file mode 100644 index 000000000000..389b365a7540 --- /dev/null +++ b/tests/ui/asm/aarch64/arm64ec-sve.rs @@ -0,0 +1,31 @@ +//@ compile-flags: --target arm64ec-pc-windows-msvc +//@ needs-asm-support +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +// SVE cannot be used for Arm64EC +// https://github.com/rust-lang/rust/pull/131332#issuecomment-2401189142 + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +impl Copy for f64 {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +fn f(x: f64) { + unsafe { + asm!("", out("p0") _); + //~^ ERROR cannot use register `p0` + asm!("", out("ffr") _); + //~^ ERROR cannot use register `ffr` + } +} diff --git a/tests/ui/asm/aarch64/arm64ec-sve.stderr b/tests/ui/asm/aarch64/arm64ec-sve.stderr new file mode 100644 index 000000000000..3e1a5d570040 --- /dev/null +++ b/tests/ui/asm/aarch64/arm64ec-sve.stderr @@ -0,0 +1,14 @@ +error: cannot use register `p0`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC + --> $DIR/arm64ec-sve.rs:26:18 + | +LL | asm!("", out("p0") _); + | ^^^^^^^^^^^ + +error: cannot use register `ffr`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC + --> $DIR/arm64ec-sve.rs:28:18 + | +LL | asm!("", out("ffr") _); + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 67ebb6c20b0cf8dfb587fd1085413232ccd8260c Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 14 Oct 2024 06:04:07 +0900 Subject: [PATCH 042/118] Fix AArch64InlineAsmReg::emit --- compiler/rustc_codegen_llvm/src/asm.rs | 51 ++------------------ compiler/rustc_target/src/asm/aarch64.rs | 60 ++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 298cac2fd6e7..d1d7d0cf4ce4 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -542,57 +542,16 @@ fn xmm_reg_index(reg: InlineAsmReg) -> Option { /// If the register is an AArch64 integer register then return its index. fn a64_reg_index(reg: InlineAsmReg) -> Option { - use AArch64InlineAsmReg::*; - // Unlike `a64_vreg_index`, we can't subtract `x0` to get the u32 because - // `x19` and `x29` are missing and the integer constants for the - // `x0`..`x30` enum variants don't all match the register number. E.g. the - // integer constant for `x18` is 18, but the constant for `x20` is 19. - Some(match reg { - InlineAsmReg::AArch64(r) => match r { - x0 => 0, - x1 => 1, - x2 => 2, - x3 => 3, - x4 => 4, - x5 => 5, - x6 => 6, - x7 => 7, - x8 => 8, - x9 => 9, - x10 => 10, - x11 => 11, - x12 => 12, - x13 => 13, - x14 => 14, - x15 => 15, - x16 => 16, - x17 => 17, - x18 => 18, - // x19 is reserved - x20 => 20, - x21 => 21, - x22 => 22, - x23 => 23, - x24 => 24, - x25 => 25, - x26 => 26, - x27 => 27, - x28 => 28, - // x29 is reserved - x30 => 30, - _ => return None, - }, - _ => return None, - }) + match reg { + InlineAsmReg::AArch64(r) => r.reg_index(), + _ => None, + } } /// If the register is an AArch64 vector register then return its index. fn a64_vreg_index(reg: InlineAsmReg) -> Option { - use AArch64InlineAsmReg::*; match reg { - InlineAsmReg::AArch64(reg) if reg as u32 >= v0 as u32 && reg as u32 <= v31 as u32 => { - Some(reg as u32 - v0 as u32) - } + InlineAsmReg::AArch64(reg) => reg.vreg_index(), _ => None, } } diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 74970a26b23b..8b173f9bb996 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -200,12 +200,66 @@ impl AArch64InlineAsmReg { _arch: InlineAsmArch, modifier: Option, ) -> fmt::Result { - let (prefix, index) = if (self as u32) < Self::v0 as u32 { - (modifier.unwrap_or('x'), self as u32 - Self::x0 as u32) + let (prefix, index) = if let Some(index) = self.reg_index() { + (modifier.unwrap_or('x'), index) + } else if let Some(index) = self.vreg_index() { + (modifier.unwrap_or('v'), index) } else { - (modifier.unwrap_or('v'), self as u32 - Self::v0 as u32) + return out.write_str(self.name()); }; assert!(index < 32); write!(out, "{prefix}{index}") } + + /// If the register is an integer register then return its index. + pub fn reg_index(self) -> Option { + // Unlike `vreg_index`, we can't subtract `x0` to get the u32 because + // `x19` and `x29` are missing and the integer constants for the + // `x0`..`x30` enum variants don't all match the register number. E.g. the + // integer constant for `x18` is 18, but the constant for `x20` is 19. + use AArch64InlineAsmReg::*; + Some(match self { + x0 => 0, + x1 => 1, + x2 => 2, + x3 => 3, + x4 => 4, + x5 => 5, + x6 => 6, + x7 => 7, + x8 => 8, + x9 => 9, + x10 => 10, + x11 => 11, + x12 => 12, + x13 => 13, + x14 => 14, + x15 => 15, + x16 => 16, + x17 => 17, + x18 => 18, + // x19 is reserved + x20 => 20, + x21 => 21, + x22 => 22, + x23 => 23, + x24 => 24, + x25 => 25, + x26 => 26, + x27 => 27, + x28 => 28, + // x29 is reserved + x30 => 30, + _ => return None, + }) + } + + /// If the register is a vector register then return its index. + pub fn vreg_index(self) -> Option { + use AArch64InlineAsmReg::*; + if self as u32 >= v0 as u32 && self as u32 <= v31 as u32 { + return Some(self as u32 - v0 as u32); + } + None + } } From ceced5322c9d2e3957e33e1944a3486731ccfa1e Mon Sep 17 00:00:00 2001 From: surechen Date: Wed, 9 Oct 2024 11:14:59 +0800 Subject: [PATCH 043/118] Special treatment empty tuple when suggest adding a string literal in format macro. For example: ```rust let s = "123"; println!({}, "sss", s); ``` Suggest: `println!("{:?} {} {}", {}, "sss", s);` fixes #130170 --- compiler/rustc_builtin_macros/src/format.rs | 22 +++++++-- ...y-block-unit-tuple-suggestion-130170.fixed | 13 ++++++ ...mpty-block-unit-tuple-suggestion-130170.rs | 13 ++++++ ...-block-unit-tuple-suggestion-130170.stderr | 46 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.fixed create mode 100644 tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.rs create mode 100644 tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.stderr diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 9501e93bad53..32730ac3867f 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -195,12 +195,26 @@ fn make_format_args( Applicability::MaybeIncorrect, ); } else { - let sugg_fmt = match args.explicit_args().len() { - 0 => "{}".to_string(), - count => { - format!("{}{{}}", "{} ".repeat(count)) + // `{}` or `()` + let should_suggest = |kind: &ExprKind| -> bool { + match kind { + ExprKind::Block(b, None) if b.stmts.is_empty() => true, + ExprKind::Tup(v) if v.is_empty() => true, + _ => false, } }; + + let mut sugg_fmt = String::new(); + for kind in std::iter::once(&efmt.kind) + .chain(args.explicit_args().into_iter().map(|a| &a.expr.kind)) + { + sugg_fmt.push_str(if should_suggest(kind) { + "{:?} " + } else { + "{} " + }); + } + sugg_fmt = sugg_fmt.trim_end().to_string(); err.span_suggestion( unexpanded_fmt_span.shrink_to_lo(), "you might be missing a string literal to format with", diff --git a/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.fixed b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.fixed new file mode 100644 index 000000000000..1ca5125fe8bc --- /dev/null +++ b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.fixed @@ -0,0 +1,13 @@ +//@ run-rustfix + +fn main() { + let s = "123"; + println!("{:?} {} {}", {}, "sss", s); + //~^ ERROR format argument must be a string literal + println!("{:?}", {}); + //~^ ERROR format argument must be a string literal + println!("{} {} {} {:?}", s, "sss", s, {}); + //~^ ERROR format argument must be a string literal + println!("{:?} {} {:?}", (), s, {}); + //~^ ERROR format argument must be a string literal +} diff --git a/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.rs b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.rs new file mode 100644 index 000000000000..c09b2a040610 --- /dev/null +++ b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.rs @@ -0,0 +1,13 @@ +//@ run-rustfix + +fn main() { + let s = "123"; + println!({}, "sss", s); + //~^ ERROR format argument must be a string literal + println!({}); + //~^ ERROR format argument must be a string literal + println!(s, "sss", s, {}); + //~^ ERROR format argument must be a string literal + println!((), s, {}); + //~^ ERROR format argument must be a string literal +} diff --git a/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.stderr b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.stderr new file mode 100644 index 000000000000..81fca8c03cc1 --- /dev/null +++ b/tests/ui/macros/format-empty-block-unit-tuple-suggestion-130170.stderr @@ -0,0 +1,46 @@ +error: format argument must be a string literal + --> $DIR/format-empty-block-unit-tuple-suggestion-130170.rs:5:14 + | +LL | println!({}, "sss", s); + | ^^ + | +help: you might be missing a string literal to format with + | +LL | println!("{:?} {} {}", {}, "sss", s); + | +++++++++++++ + +error: format argument must be a string literal + --> $DIR/format-empty-block-unit-tuple-suggestion-130170.rs:7:14 + | +LL | println!({}); + | ^^ + | +help: you might be missing a string literal to format with + | +LL | println!("{:?}", {}); + | +++++++ + +error: format argument must be a string literal + --> $DIR/format-empty-block-unit-tuple-suggestion-130170.rs:9:14 + | +LL | println!(s, "sss", s, {}); + | ^ + | +help: you might be missing a string literal to format with + | +LL | println!("{} {} {} {:?}", s, "sss", s, {}); + | ++++++++++++++++ + +error: format argument must be a string literal + --> $DIR/format-empty-block-unit-tuple-suggestion-130170.rs:11:14 + | +LL | println!((), s, {}); + | ^^ + | +help: you might be missing a string literal to format with + | +LL | println!("{:?} {} {:?}", (), s, {}); + | +++++++++++++++ + +error: aborting due to 4 previous errors + From f8ac1c44dba23d425cb630a9e8b334a5781462fb Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sat, 31 Aug 2024 03:02:30 +0530 Subject: [PATCH 044/118] uefi: Implement getcwd and chdir - Using EFI Shell Protocol. These functions do not make much sense unless a shell is present. - Return the exe dir in case shell protocol is missing. Signed-off-by: Ayush Singh --- library/std/src/sys/pal/uefi/helpers.rs | 24 ++++++---- library/std/src/sys/pal/uefi/os.rs | 63 +++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index bd8a6684b64f..4ced7065c826 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -177,16 +177,8 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R ) }; - // SAFETY: `convert_device_path_to_text` returns a pointer to a null-terminated UTF-16 - // string, and that string cannot be deallocated prior to dropping the `WStrUnits`, so - // it's safe for `WStrUnits` to use. - let path_len = unsafe { - WStrUnits::new(path_ptr) - .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))? - .count() - }; - - let path = OsString::from_wide(unsafe { slice::from_raw_parts(path_ptr.cast(), path_len) }); + let path = os_string_from_raw(path_ptr) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull = boot_services.cast(); @@ -420,3 +412,15 @@ impl Drop for OwnedTable { unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) }; } } + +/// Create OsString from a pointer to NULL terminated UTF-16 string +pub(crate) fn os_string_from_raw(ptr: *mut r_efi::efi::Char16) -> Option { + let path_len = unsafe { WStrUnits::new(ptr)?.count() }; + Some(OsString::from_wide(unsafe { slice::from_raw_parts(ptr.cast(), path_len) })) +} + +/// Create NULL terminated UTF-16 string +pub(crate) fn os_string_to_raw(s: &OsStr) -> Option> { + let temp = s.encode_wide().chain(Some(0)).collect::>(); + if temp[..temp.len() - 1].contains(&0) { None } else { Some(temp) } +} diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 9aee67d622fa..4eb7698b43aa 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -1,7 +1,7 @@ use r_efi::efi::Status; use r_efi::efi::protocols::{device_path, loaded_image_device_path}; -use super::{RawOsError, helpers, unsupported}; +use super::{RawOsError, helpers, unsupported_err}; use crate::error::Error as StdError; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; @@ -125,11 +125,32 @@ pub fn error_string(errno: RawOsError) -> String { } pub fn getcwd() -> io::Result { - unsupported() + match uefi_shell::open_shell() { + Some(shell) => { + // SAFETY: path_ptr is managed by UEFI shell and should not be deallocated + let path_ptr = unsafe { ((*shell.as_ptr()).get_cur_dir)(crate::ptr::null_mut()) }; + helpers::os_string_from_raw(path_ptr) + .map(PathBuf::from) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path")) + } + None => { + let mut t = current_exe()?; + // SAFETY: This should never fail since the disk prefix will be present even for root + // executables + assert!(t.pop()); + Ok(t) + } + } } -pub fn chdir(_: &path::Path) -> io::Result<()> { - unsupported() +pub fn chdir(p: &path::Path) -> io::Result<()> { + let shell = uefi_shell::open_shell().ok_or(unsupported_err())?; + + let mut p = helpers::os_string_to_raw(p.as_os_str()) + .ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?; + + let r = unsafe { ((*shell.as_ptr()).set_cur_dir)(crate::ptr::null_mut(), p.as_mut_ptr()) }; + if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); @@ -239,3 +260,37 @@ pub fn exit(code: i32) -> ! { pub fn getpid() -> u32 { panic!("no pids on this platform") } + +mod uefi_shell { + use r_efi::protocols::shell; + + use super::super::helpers; + use crate::ptr::NonNull; + use crate::sync::atomic::{AtomicPtr, Ordering}; + + pub fn open_shell() -> Option> { + static LAST_VALID_HANDLE: AtomicPtr = + AtomicPtr::new(crate::ptr::null_mut()); + + if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) { + if let Ok(protocol) = helpers::open_protocol::( + handle, + r_efi::protocols::shell::PROTOCOL_GUID, + ) { + return Some(protocol); + } + } + + let handles = helpers::locate_handles(shell::PROTOCOL_GUID).ok()?; + for handle in handles { + if let Ok(protocol) = + helpers::open_protocol::(handle, shell::PROTOCOL_GUID) + { + LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release); + return Some(protocol); + } + } + + None + } +} From 874b03ec28beba617951efef505fe3e320900454 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 11:21:16 +1100 Subject: [PATCH 045/118] Remove `ResultsCursor::contains`. It's hardly worth it, and it needs to be removed so that `GenKillAnalysis` can be removed. --- compiler/rustc_mir_dataflow/src/framework/cursor.rs | 11 ----------- .../rustc_mir_dataflow/src/impls/storage_liveness.rs | 2 +- compiler/rustc_mir_transform/src/elaborate_drops.rs | 2 +- compiler/rustc_mir_transform/src/ref_prop.rs | 2 +- .../clippy/clippy_utils/src/mir/possible_borrower.rs | 4 ++-- 5 files changed, 5 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 7cfaef22689f..5ebb343f4e19 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -7,7 +7,6 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::{self, BasicBlock, Location}; use super::{Analysis, Direction, Effect, EffectIndex, Results}; -use crate::framework::BitSetExt; /// Allows random access inspection of the results of a dataflow analysis. /// @@ -221,16 +220,6 @@ where } } -impl<'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A> -where - A: crate::GenKillAnalysis<'tcx>, - A::Domain: BitSetExt, -{ - pub fn contains(&self, elem: A::Idx) -> bool { - self.get().contains(elem) - } -} - #[derive(Clone, Copy, Debug)] struct CursorPosition { block: BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 34ac5809a2e2..fe223a3abd8a 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -364,7 +364,7 @@ where fn visit_local(&mut self, local: Local, context: PlaceContext, loc: Location) { if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context { self.borrowed_locals.seek_before_primary_effect(loc); - if !self.borrowed_locals.contains(local) { + if !self.borrowed_locals.get().contains(local) { self.trans.kill(local); } } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index c35aec42408c..f4ac4d9fee6f 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -133,7 +133,7 @@ impl InitializationData<'_, '_> { } fn maybe_live_dead(&self, path: MovePathIndex) -> (bool, bool) { - (self.inits.contains(path), self.uninits.contains(path)) + (self.inits.get().contains(path), self.uninits.get().contains(path)) } } diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index a62a892716fb..53e53d9d5ba8 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -179,7 +179,7 @@ fn compute_replacement<'tcx>( } else { // This is a proper dereference. We can only allow it if `target` is live. maybe_dead.seek_after_primary_effect(loc); - let maybe_dead = maybe_dead.contains(target.local); + let maybe_dead = maybe_dead.get().contains(target.local); !maybe_dead } }; diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index 6bb434a466fd..a00196c4b511 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -213,7 +213,7 @@ impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> { self.bitset.0.clear(); let maybe_live = &mut self.maybe_live; if let Some(bitset) = self.map.get(&borrowed) { - for b in bitset.iter().filter(move |b| maybe_live.contains(*b)) { + for b in bitset.iter().filter(move |b| maybe_live.get().contains(*b)) { self.bitset.0.insert(b); } } else { @@ -238,6 +238,6 @@ impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> { pub fn local_is_alive_at(&mut self, local: mir::Local, at: mir::Location) -> bool { self.maybe_live.seek_after_primary_effect(at); - self.maybe_live.contains(local) + self.maybe_live.get().contains(local) } } From e0b83c34c3320de1f16c8f888d12f3b1aee18a26 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 06:41:03 +1100 Subject: [PATCH 046/118] Remove `Engine::new_gen_kill`. This is an alternative to `Engine::new_generic` for gen/kill analyses. It's supposed to be an optimization, but it has negligible effect. The commit merges `Engine::new_generic` into `Engine::new`. This allows the removal of various other things: `GenKillSet`, `gen_kill_statement_effects_in_block`, `is_cfg_cyclic`. --- compiler/rustc_middle/src/mir/basic_blocks.rs | 7 -- .../src/framework/direction.rs | 66 ++------------ .../src/framework/engine.rs | 88 ++----------------- .../rustc_mir_dataflow/src/framework/mod.rs | 53 +---------- 4 files changed, 17 insertions(+), 197 deletions(-) diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 4602c918160b..3eb563d7d6e5 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -26,7 +26,6 @@ type SwitchSources = FxHashMap<(BasicBlock, BasicBlock), SmallVec<[Option; struct Cache { predecessors: OnceLock, switch_sources: OnceLock, - is_cyclic: OnceLock, reverse_postorder: OnceLock>, dominators: OnceLock>, } @@ -37,12 +36,6 @@ impl<'tcx> BasicBlocks<'tcx> { BasicBlocks { basic_blocks, cache: Cache::default() } } - /// Returns true if control-flow graph contains a cycle reachable from the `START_BLOCK`. - #[inline] - pub fn is_cfg_cyclic(&self) -> bool { - *self.cache.is_cyclic.get_or_init(|| graph::is_cyclic(self)) - } - pub fn dominators(&self) -> &Dominators { self.cache.dominators.get_or_init(|| dominators(self)) } diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 88a9a78f8ad6..3e01f0512c46 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::{ }; use super::visitor::{ResultsVisitable, ResultsVisitor}; -use super::{Analysis, Effect, EffectIndex, GenKillAnalysis, GenKillSet, SwitchIntTarget}; +use super::{Analysis, Effect, EffectIndex, SwitchIntTarget}; pub trait Direction { const IS_FORWARD: bool; @@ -29,19 +29,10 @@ pub trait Direction { state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - statement_effect: Option<&dyn Fn(BasicBlock, &mut A::Domain)>, ) -> TerminatorEdges<'mir, 'tcx> where A: Analysis<'tcx>; - fn gen_kill_statement_effects_in_block<'tcx, A>( - analysis: &mut A, - trans: &mut GenKillSet, - block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - ) where - A: GenKillAnalysis<'tcx>; - fn visit_results_in_block<'mir, 'tcx, D, R>( state: &mut D, block: BasicBlock, @@ -73,7 +64,6 @@ impl Direction for Backward { state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - statement_effect: Option<&dyn Fn(BasicBlock, &mut A::Domain)>, ) -> TerminatorEdges<'mir, 'tcx> where A: Analysis<'tcx>, @@ -82,31 +72,12 @@ impl Direction for Backward { let location = Location { block, statement_index: block_data.statements.len() }; analysis.apply_before_terminator_effect(state, terminator, location); let edges = analysis.apply_terminator_effect(state, terminator, location); - if let Some(statement_effect) = statement_effect { - statement_effect(block, state) - } else { - for (statement_index, statement) in block_data.statements.iter().enumerate().rev() { - let location = Location { block, statement_index }; - analysis.apply_before_statement_effect(state, statement, location); - analysis.apply_statement_effect(state, statement, location); - } - } - edges - } - - fn gen_kill_statement_effects_in_block<'tcx, A>( - analysis: &mut A, - trans: &mut GenKillSet, - block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - ) where - A: GenKillAnalysis<'tcx>, - { for (statement_index, statement) in block_data.statements.iter().enumerate().rev() { let location = Location { block, statement_index }; - analysis.before_statement_effect(trans, statement, location); - analysis.statement_effect(trans, statement, location); + analysis.apply_before_statement_effect(state, statement, location); + analysis.apply_statement_effect(state, statement, location); } + edges } fn apply_effects_in_range<'tcx, A>( @@ -330,42 +301,21 @@ impl Direction for Forward { state: &mut A::Domain, block: BasicBlock, block_data: &'mir mir::BasicBlockData<'tcx>, - statement_effect: Option<&dyn Fn(BasicBlock, &mut A::Domain)>, ) -> TerminatorEdges<'mir, 'tcx> where A: Analysis<'tcx>, { - if let Some(statement_effect) = statement_effect { - statement_effect(block, state) - } else { - for (statement_index, statement) in block_data.statements.iter().enumerate() { - let location = Location { block, statement_index }; - analysis.apply_before_statement_effect(state, statement, location); - analysis.apply_statement_effect(state, statement, location); - } + for (statement_index, statement) in block_data.statements.iter().enumerate() { + let location = Location { block, statement_index }; + analysis.apply_before_statement_effect(state, statement, location); + analysis.apply_statement_effect(state, statement, location); } - let terminator = block_data.terminator(); let location = Location { block, statement_index: block_data.statements.len() }; analysis.apply_before_terminator_effect(state, terminator, location); analysis.apply_terminator_effect(state, terminator, location) } - fn gen_kill_statement_effects_in_block<'tcx, A>( - analysis: &mut A, - trans: &mut GenKillSet, - block: BasicBlock, - block_data: &mir::BasicBlockData<'tcx>, - ) where - A: GenKillAnalysis<'tcx>, - { - for (statement_index, statement) in block_data.statements.iter().enumerate() { - let location = Location { block, statement_index }; - analysis.before_statement_effect(trans, statement, location); - analysis.statement_effect(trans, statement, location); - } - } - fn apply_effects_in_range<'tcx, A>( analysis: &mut A, state: &mut A::Domain, diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 9d50e57d6686..d6853b6ef829 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; use rustc_data_structures::work_queue::WorkQueue; use rustc_hir::def_id::DefId; -use rustc_index::{Idx, IndexVec}; +use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::mir::{self, BasicBlock, create_dump_file, dump_enabled, traversal}; use rustc_middle::ty::TyCtxt; @@ -16,13 +16,12 @@ use {rustc_ast as ast, rustc_graphviz as dot}; use super::fmt::DebugWithContext; use super::{ - Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis, GenKillSet, JoinSemiLattice, - ResultsCursor, ResultsVisitor, graphviz, visit_results, + Analysis, AnalysisDomain, Direction, JoinSemiLattice, ResultsCursor, ResultsVisitor, graphviz, + visit_results, }; use crate::errors::{ DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, }; -use crate::framework::BitSetExt; type EntrySets<'tcx, A> = IndexVec>::Domain>; @@ -82,53 +81,6 @@ where entry_sets: IndexVec, pass_name: Option<&'static str>, analysis: A, - - /// Cached, cumulative transfer functions for each block. - // - // FIXME(ecstaticmorse): This boxed `Fn` trait object is invoked inside a tight loop for - // gen/kill problems on cyclic CFGs. This is not ideal, but it doesn't seem to degrade - // performance in practice. I've tried a few ways to avoid this, but they have downsides. See - // the message for the commit that added this FIXME for more information. - apply_statement_trans_for_block: Option>, -} - -impl<'mir, 'tcx, A, D, T> Engine<'mir, 'tcx, A> -where - A: GenKillAnalysis<'tcx, Idx = T, Domain = D>, - D: Clone + JoinSemiLattice + GenKill + BitSetExt, - T: Idx, -{ - /// Creates a new `Engine` to solve a gen-kill dataflow problem. - pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, mut analysis: A) -> Self { - // If there are no back-edges in the control-flow graph, we only ever need to apply the - // transfer function for each block exactly once (assuming that we process blocks in RPO). - // - // In this case, there's no need to compute the block transfer functions ahead of time. - if !body.basic_blocks.is_cfg_cyclic() { - return Self::new(tcx, body, analysis, None); - } - - // Otherwise, compute and store the cumulative transfer function for each block. - - let identity = GenKillSet::identity(analysis.domain_size(body)); - let mut trans_for_block = IndexVec::from_elem(identity, &body.basic_blocks); - - for (block, block_data) in body.basic_blocks.iter_enumerated() { - let trans = &mut trans_for_block[block]; - A::Direction::gen_kill_statement_effects_in_block( - &mut analysis, - trans, - block, - block_data, - ); - } - - let apply_trans = Box::new(move |bb: BasicBlock, state: &mut A::Domain| { - trans_for_block[bb].apply(state); - }); - - Self::new(tcx, body, analysis, Some(apply_trans as Box<_>)) - } } impl<'mir, 'tcx, A, D> Engine<'mir, 'tcx, A> @@ -138,19 +90,7 @@ where { /// Creates a new `Engine` to solve a dataflow problem with an arbitrary transfer /// function. - /// - /// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for - /// better performance. - pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, analysis: A) -> Self { - Self::new(tcx, body, analysis, None) - } - - fn new( - tcx: TyCtxt<'tcx>, - body: &'mir mir::Body<'tcx>, - analysis: A, - apply_statement_trans_for_block: Option>, - ) -> Self { + pub(crate) fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, analysis: A) -> Self { let mut entry_sets = IndexVec::from_fn_n(|_| analysis.bottom_value(body), body.basic_blocks.len()); analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]); @@ -160,7 +100,7 @@ where bug!("`initialize_start_block` is not yet supported for backward dataflow analyses"); } - Engine { analysis, tcx, body, pass_name: None, entry_sets, apply_statement_trans_for_block } + Engine { analysis, tcx, body, pass_name: None, entry_sets } } /// Adds an identifier to the graphviz output for this particular run of a dataflow analysis. @@ -177,14 +117,7 @@ where where A::Domain: DebugWithContext, { - let Engine { - mut analysis, - body, - mut entry_sets, - tcx, - apply_statement_trans_for_block, - pass_name, - } = self; + let Engine { mut analysis, body, mut entry_sets, tcx, pass_name } = self; let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks.len()); @@ -213,13 +146,8 @@ where state.clone_from(&entry_sets[bb]); // Apply the block transfer function, using the cached one if it exists. - let edges = A::Direction::apply_effects_in_block( - &mut analysis, - &mut state, - bb, - bb_data, - apply_statement_trans_for_block.as_deref(), - ); + let edges = + A::Direction::apply_effects_in_block(&mut analysis, &mut state, bb, bb_data); A::Direction::join_state_into_successors_of( &mut analysis, diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index d0472e35fe00..459261a64ff4 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -242,7 +242,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { where Self: Sized, { - Engine::new_generic(tcx, body, self) + Engine::new(tcx, body, self) } } @@ -376,19 +376,6 @@ where ) { self.switch_int_edge_effects(block, discr, edge_effects); } - - /* Extension methods */ - #[inline] - fn into_engine<'mir>( - self, - tcx: TyCtxt<'tcx>, - body: &'mir mir::Body<'tcx>, - ) -> Engine<'mir, 'tcx, Self> - where - Self: Sized, - { - Engine::new_gen_kill(tcx, body, self) - } } /// The legal operations for a transfer function in a gen/kill problem. @@ -422,44 +409,6 @@ pub trait GenKill { } } -/// Stores a transfer function for a gen/kill problem. -/// -/// Calling `gen_`/`kill` on a `GenKillSet` will "build up" a transfer function so that it can be -/// applied multiple times efficiently. When there are multiple calls to `gen_` and/or `kill` for -/// the same element, the most recent one takes precedence. -#[derive(Clone)] -pub struct GenKillSet { - gen_: HybridBitSet, - kill: HybridBitSet, -} - -impl GenKillSet { - /// Creates a new transfer function that will leave the dataflow state unchanged. - pub fn identity(universe: usize) -> Self { - GenKillSet { - gen_: HybridBitSet::new_empty(universe), - kill: HybridBitSet::new_empty(universe), - } - } - - pub fn apply(&self, state: &mut impl BitSetExt) { - state.union(&self.gen_); - state.subtract(&self.kill); - } -} - -impl GenKill for GenKillSet { - fn gen_(&mut self, elem: T) { - self.gen_.insert(elem); - self.kill.remove(elem); - } - - fn kill(&mut self, elem: T) { - self.kill.insert(elem); - self.gen_.remove(elem); - } -} - impl GenKill for BitSet { fn gen_(&mut self, elem: T) { self.insert(elem); From 13968b4a70ad6be54efa8d9d388963040d5b6473 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 06:46:08 +1100 Subject: [PATCH 047/118] Tweak `GenKillAnalysis` method arguments. `GenKillAnalysis` has very similar methods to `Analysis`, but the first two have a notable difference: the second argument is `&mut impl GenKill` instead of `&mut Self::Domain`. But thanks to the previous commit, this difference is no longer necessary. --- compiler/rustc_borrowck/src/dataflow.rs | 4 ++-- .../rustc_mir_dataflow/src/framework/mod.rs | 9 ++++---- .../src/impls/borrowed_locals.rs | 2 +- .../src/impls/initialized.rs | 8 +++---- .../rustc_mir_dataflow/src/impls/liveness.rs | 2 +- .../src/impls/storage_liveness.rs | 23 ++++--------------- 6 files changed, 16 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 5ea48d3fc7e9..b0f5f638e676 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -518,7 +518,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { fn before_statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, location: Location, ) { @@ -527,7 +527,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, stmt: &mir::Statement<'tcx>, location: Location, ) { diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 459261a64ff4..9d79b6f44a68 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -260,19 +260,18 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { fn domain_size(&self, body: &mir::Body<'tcx>) -> usize; - /// See `Analysis::apply_statement_effect`. Note how the second arg differs. + /// See `Analysis::apply_statement_effect`. fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, statement: &mir::Statement<'tcx>, location: Location, ); - /// See `Analysis::apply_before_statement_effect`. Note how the second arg - /// differs. + /// See `Analysis::apply_before_statement_effect`. fn before_statement_effect( &mut self, - _trans: &mut impl GenKill, + _trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, _location: Location, ) { diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 8b082ef2667a..dc9a1d5f3ad9 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -43,7 +43,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, statement: &Statement<'tcx>, location: Location, ) { diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 25e8726cf616..bb61e7e94320 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -338,7 +338,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, statement: &mir::Statement<'tcx>, location: Location, ) { @@ -475,7 +475,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, location: Location, ) { @@ -602,7 +602,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, location: Location, ) { @@ -672,7 +672,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { #[instrument(skip(self, trans), level = "debug")] fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, stmt: &mir::Statement<'tcx>, location: Location, ) { diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 1559c131a378..af46d5543ba4 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -50,7 +50,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { fn statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, statement: &mir::Statement<'tcx>, location: Location, ) { diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index fe223a3abd8a..833cb968e360 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -46,12 +46,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { body.local_decls.len() } - fn statement_effect( - &mut self, - trans: &mut impl GenKill, - stmt: &Statement<'tcx>, - _: Location, - ) { + fn statement_effect(&mut self, trans: &mut Self::Domain, stmt: &Statement<'tcx>, _: Location) { match stmt.kind { StatementKind::StorageLive(l) => trans.gen_(l), StatementKind::StorageDead(l) => trans.kill(l), @@ -117,12 +112,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead<'a> { body.local_decls.len() } - fn statement_effect( - &mut self, - trans: &mut impl GenKill, - stmt: &Statement<'tcx>, - _: Location, - ) { + fn statement_effect(&mut self, trans: &mut Self::Domain, stmt: &Statement<'tcx>, _: Location) { match stmt.kind { StatementKind::StorageLive(l) => trans.kill(l), StatementKind::StorageDead(l) => trans.gen_(l), @@ -192,7 +182,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { fn before_statement_effect( &mut self, - trans: &mut impl GenKill, + trans: &mut Self::Domain, stmt: &Statement<'tcx>, loc: Location, ) { @@ -223,12 +213,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { } } - fn statement_effect( - &mut self, - trans: &mut impl GenKill, - _: &Statement<'tcx>, - loc: Location, - ) { + fn statement_effect(&mut self, trans: &mut Self::Domain, _: &Statement<'tcx>, loc: Location) { // If we move from a place then it only stops needing storage *after* // that statement. self.check_for_move(trans, loc); From 525f655866fe933937bd67e54b7f51a44781c7bb Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 10:14:58 +1100 Subject: [PATCH 048/118] Minimize use of `GenKill`. Thanks to the previous couple of commits, many uses of the `GenKill` trait can be replaced with a concrete type. --- compiler/rustc_borrowck/src/dataflow.rs | 8 +++++-- .../rustc_mir_dataflow/src/framework/mod.rs | 4 ++-- .../src/impls/initialized.rs | 14 +++++------ .../rustc_mir_dataflow/src/impls/liveness.rs | 24 +++++++------------ .../src/impls/storage_liveness.rs | 17 ++++++------- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index b0f5f638e676..bef7ad02113d 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -427,7 +427,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { /// That means they went out of a nonlexical scope fn kill_loans_out_of_scope_at_location( &self, - trans: &mut impl GenKill, + trans: &mut >::Domain, location: Location, ) { // NOTE: The state associated with a given `location` @@ -447,7 +447,11 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { } /// Kill any borrows that conflict with `place`. - fn kill_borrows_on_place(&self, trans: &mut impl GenKill, place: Place<'tcx>) { + fn kill_borrows_on_place( + &self, + trans: &mut >::Domain, + place: Place<'tcx>, + ) { debug!("kill_borrows_on_place: place={:?}", place); let other_borrows_of_local = self diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 9d79b6f44a68..9e419f3ff9a9 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -305,11 +305,11 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { ); /// See `Analysis::apply_switch_int_edge_effects`. - fn switch_int_edge_effects>( + fn switch_int_edge_effects( &mut self, _block: BasicBlock, _discr: &mir::Operand<'tcx>, - _edge_effects: &mut impl SwitchIntEdgeEffects, + _edge_effects: &mut impl SwitchIntEdgeEffects, ) { } } diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index bb61e7e94320..e5bcb64d6415 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -270,7 +270,7 @@ impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> { impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { fn update_bits( - trans: &mut impl GenKill, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -283,7 +283,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { fn update_bits( - trans: &mut impl GenKill, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -296,7 +296,7 @@ impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { fn update_bits( - trans: &mut impl GenKill, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -399,11 +399,11 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { }); } - fn switch_int_edge_effects>( + fn switch_int_edge_effects( &mut self, block: mir::BasicBlock, discr: &mir::Operand<'tcx>, - edge_effects: &mut impl SwitchIntEdgeEffects, + edge_effects: &mut impl SwitchIntEdgeEffects, ) { if !self.tcx.sess.opts.unstable_opts.precise_enum_drop_elaboration { return; @@ -524,11 +524,11 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { }); } - fn switch_int_edge_effects>( + fn switch_int_edge_effects( &mut self, block: mir::BasicBlock, discr: &mir::Operand<'tcx>, - edge_effects: &mut impl SwitchIntEdgeEffects, + edge_effects: &mut impl SwitchIntEdgeEffects, ) { if !self.tcx.sess.opts.unstable_opts.precise_enum_drop_elaboration { return; diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index af46d5543ba4..07ecedeac593 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -89,12 +89,9 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { } } -pub struct TransferFunction<'a, T>(pub &'a mut T); +pub struct TransferFunction<'a>(pub &'a mut BitSet); -impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T> -where - T: GenKill, -{ +impl<'tcx> Visitor<'tcx> for TransferFunction<'_> { fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) { if let PlaceContext::MutatingUse(MutatingUseContext::Yield) = context { // The resume place is evaluated and assigned to only after coroutine resumes, so its @@ -108,10 +105,10 @@ where MutatingUseContext::Call | MutatingUseContext::AsmOutput, ) = context { - // For the associated terminators, this is only a `Def` when the terminator returns - // "successfully." As such, we handle this case separately in `call_return_effect` - // above. However, if the place looks like `*_5`, this is still unconditionally a use of - // `_5`. + // For the associated terminators, this is only a `Def` when the terminator + // returns "successfully." As such, we handle this case separately in + // `call_return_effect` above. However, if the place looks like `*_5`, this is + // still unconditionally a use of `_5`. } else { self.0.kill(place.local); } @@ -128,12 +125,9 @@ where } } -struct YieldResumeEffect<'a, T>(&'a mut T); +struct YieldResumeEffect<'a>(&'a mut BitSet); -impl<'tcx, T> Visitor<'tcx> for YieldResumeEffect<'_, T> -where - T: GenKill, -{ +impl<'tcx> Visitor<'tcx> for YieldResumeEffect<'_> { fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) { DefUse::apply(self.0, *place, context); self.visit_projection(place.as_ref(), context, location); @@ -151,7 +145,7 @@ enum DefUse { } impl DefUse { - fn apply(trans: &mut impl GenKill, place: Place<'_>, context: PlaceContext) { + fn apply(trans: &mut BitSet, place: Place<'_>, context: PlaceContext) { match DefUse::for_place(place, context) { Some(DefUse::Def) => trans.kill(place.local), Some(DefUse::Use) => trans.gen_(place.local), diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 833cb968e360..0f94defb1abb 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use super::MaybeBorrowedLocals; -use crate::{GenKill, ResultsCursor}; +use crate::{AnalysisDomain, GenKill, ResultsCursor}; pub struct MaybeStorageLive<'a> { always_live_locals: Cow<'a, BitSet>, @@ -330,22 +330,23 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { impl<'tcx> MaybeRequiresStorage<'_, 'tcx> { /// Kill locals that are fully moved and have not been borrowed. - fn check_for_move(&mut self, trans: &mut impl GenKill, loc: Location) { + fn check_for_move( + &mut self, + trans: &mut >::Domain, + loc: Location, + ) { let body = self.borrowed_locals.body(); let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals }; visitor.visit_location(body, loc); } } -struct MoveVisitor<'a, 'mir, 'tcx, T> { +struct MoveVisitor<'a, 'mir, 'tcx> { borrowed_locals: &'a mut BorrowedLocalsResults<'mir, 'tcx>, - trans: &'a mut T, + trans: &'a mut BitSet, } -impl<'tcx, T> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx, T> -where - T: GenKill, -{ +impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx> { fn visit_local(&mut self, local: Local, context: PlaceContext, loc: Location) { if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context { self.borrowed_locals.seek_before_primary_effect(loc); From 4dc1b4d0b1c0e96102f6d9b3a0ea91e46feaf8e9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 09:49:33 +1100 Subject: [PATCH 049/118] Remove `GenKillAnalysis`. It's now functionally identical to `Analysis`. --- compiler/rustc_borrowck/src/dataflow.rs | 18 +- .../rustc_mir_dataflow/src/framework/mod.rs | 159 ++---------------- .../src/impls/borrowed_locals.rs | 16 +- .../src/impls/initialized.rs | 62 +++---- .../rustc_mir_dataflow/src/impls/liveness.rs | 16 +- .../src/impls/storage_liveness.rs | 71 ++++---- compiler/rustc_mir_dataflow/src/lib.rs | 6 +- 7 files changed, 82 insertions(+), 266 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index bef7ad02113d..2eef200e24c8 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -513,14 +513,8 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { /// region stops containing the CFG points reachable from the issuing location. /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// `a.b.c` when `a` is overwritten. -impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { - type Idx = BorrowIndex; - - fn domain_size(&self, _: &mir::Body<'tcx>) -> usize { - self.borrow_set.len() - } - - fn before_statement_effect( +impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { + fn apply_before_statement_effect( &mut self, trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, @@ -529,7 +523,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { self.kill_loans_out_of_scope_at_location(trans, location); } - fn statement_effect( + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, stmt: &mir::Statement<'tcx>, @@ -577,7 +571,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { } } - fn before_terminator_effect( + fn apply_before_terminator_effect( &mut self, trans: &mut Self::Domain, _terminator: &mir::Terminator<'tcx>, @@ -586,7 +580,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { self.kill_loans_out_of_scope_at_location(trans, location); } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -604,7 +598,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, _trans: &mut Self::Domain, _block: mir::BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 9e419f3ff9a9..d7a62ecd2c18 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -1,9 +1,11 @@ //! A framework that can express both [gen-kill] and generic dataflow problems. //! -//! To use this framework, implement either the [`Analysis`] or the -//! [`GenKillAnalysis`] trait. If your transfer function can be expressed with only gen/kill -//! operations, prefer `GenKillAnalysis` since it will run faster while iterating to fixpoint. The -//! `impls` module contains several examples of gen/kill dataflow analyses. +//! To use this framework, implement the [`Analysis`] trait. There used to be a `GenKillAnalysis` +//! alternative trait for gen-kill analyses that would pre-compute the transfer function for each +//! block. It was intended as an optimization, but it ended up not being any faster than +//! `Analysis`. +//! +//! The `impls` module contains several examples of dataflow analyses. //! //! Create an `Engine` for your analysis using the `into_engine` method on the `Analysis` trait, //! then call `iterate_to_fixpoint`. From there, you can use a `ResultsCursor` to inspect the @@ -122,9 +124,9 @@ pub trait AnalysisDomain<'tcx> { /// /// # Convergence /// -/// When implementing this trait directly (not via [`GenKillAnalysis`]), it's possible to choose a -/// transfer function such that the analysis does not reach fixpoint. To guarantee convergence, -/// your transfer functions must maintain the following invariant: +/// When implementing this trait it's possible to choose a transfer function such that the analysis +/// does not reach fixpoint. To guarantee convergence, your transfer functions must maintain the +/// following invariant: /// /// > If the dataflow state **before** some point in the program changes to be greater /// than the prior state **before** that point, the dataflow state **after** that point must @@ -223,9 +225,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { /// Creates an `Engine` to find the fixpoint for this dataflow problem. /// - /// You shouldn't need to override this outside this module, since the combination of the - /// default impl and the one for all `A: GenKillAnalysis` will do the right thing. - /// Its purpose is to enable method chaining like so: + /// You shouldn't need to override this. Its purpose is to enable method chaining like so: /// /// ```ignore (cross-crate-imports) /// let results = MyAnalysis::new(tcx, body) @@ -246,146 +246,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { } } -/// A gen/kill dataflow problem. -/// -/// Each method in this trait has a corresponding one in `Analysis`. However, the first two methods -/// here only allow modification of the dataflow state via "gen" and "kill" operations. By defining -/// transfer functions for each statement in this way, the transfer function for an entire basic -/// block can be computed efficiently. The remaining methods match up with `Analysis` exactly. -/// -/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis` via a blanket -/// impl below. -pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> { - type Idx: Idx; - - fn domain_size(&self, body: &mir::Body<'tcx>) -> usize; - - /// See `Analysis::apply_statement_effect`. - fn statement_effect( - &mut self, - trans: &mut Self::Domain, - statement: &mir::Statement<'tcx>, - location: Location, - ); - - /// See `Analysis::apply_before_statement_effect`. - fn before_statement_effect( - &mut self, - _trans: &mut Self::Domain, - _statement: &mir::Statement<'tcx>, - _location: Location, - ) { - } - - /// See `Analysis::apply_terminator_effect`. - fn terminator_effect<'mir>( - &mut self, - trans: &mut Self::Domain, - terminator: &'mir mir::Terminator<'tcx>, - location: Location, - ) -> TerminatorEdges<'mir, 'tcx>; - - /// See `Analysis::apply_before_terminator_effect`. - fn before_terminator_effect( - &mut self, - _trans: &mut Self::Domain, - _terminator: &mir::Terminator<'tcx>, - _location: Location, - ) { - } - - /* Edge-specific effects */ - - /// See `Analysis::apply_call_return_effect`. - fn call_return_effect( - &mut self, - trans: &mut Self::Domain, - block: BasicBlock, - return_places: CallReturnPlaces<'_, 'tcx>, - ); - - /// See `Analysis::apply_switch_int_edge_effects`. - fn switch_int_edge_effects( - &mut self, - _block: BasicBlock, - _discr: &mir::Operand<'tcx>, - _edge_effects: &mut impl SwitchIntEdgeEffects, - ) { - } -} - -// Blanket impl: any impl of `GenKillAnalysis` automatically impls `Analysis`. -impl<'tcx, A> Analysis<'tcx> for A -where - A: GenKillAnalysis<'tcx>, - A::Domain: GenKill + BitSetExt, -{ - fn apply_statement_effect( - &mut self, - state: &mut A::Domain, - statement: &mir::Statement<'tcx>, - location: Location, - ) { - self.statement_effect(state, statement, location); - } - - fn apply_before_statement_effect( - &mut self, - state: &mut A::Domain, - statement: &mir::Statement<'tcx>, - location: Location, - ) { - self.before_statement_effect(state, statement, location); - } - - fn apply_terminator_effect<'mir>( - &mut self, - state: &mut A::Domain, - terminator: &'mir mir::Terminator<'tcx>, - location: Location, - ) -> TerminatorEdges<'mir, 'tcx> { - self.terminator_effect(state, terminator, location) - } - - fn apply_before_terminator_effect( - &mut self, - state: &mut A::Domain, - terminator: &mir::Terminator<'tcx>, - location: Location, - ) { - self.before_terminator_effect(state, terminator, location); - } - - /* Edge-specific effects */ - - fn apply_call_return_effect( - &mut self, - state: &mut A::Domain, - block: BasicBlock, - return_places: CallReturnPlaces<'_, 'tcx>, - ) { - self.call_return_effect(state, block, return_places); - } - - fn apply_switch_int_edge_effects( - &mut self, - block: BasicBlock, - discr: &mir::Operand<'tcx>, - edge_effects: &mut impl SwitchIntEdgeEffects, - ) { - self.switch_int_edge_effects(block, discr, edge_effects); - } -} - /// The legal operations for a transfer function in a gen/kill problem. -/// -/// This abstraction exists because there are two different contexts in which we call the methods in -/// `GenKillAnalysis`. Sometimes we need to store a single transfer function that can be efficiently -/// applied multiple times, such as when computing the cumulative transfer function for each block. -/// These cases require a `GenKillSet`, which in turn requires two `BitSet`s of storage. Oftentimes, -/// however, we only need to apply an effect once. In *these* cases, it is more efficient to pass the -/// `BitSet` representing the state vector directly into the `*_effect` methods as opposed to -/// building up a `GenKillSet` and then throwing it away. pub trait GenKill { /// Inserts `elem` into the state vector. fn gen_(&mut self, elem: T); diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index dc9a1d5f3ad9..f4edbaf056ce 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -2,7 +2,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use crate::{AnalysisDomain, GenKill, GenKillAnalysis}; +use crate::{Analysis, AnalysisDomain, GenKill}; /// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points /// to a given local. This analysis ignores fake borrows, so it should not be used by @@ -34,14 +34,8 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeBorrowedLocals { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals { - type Idx = Local; - - fn domain_size(&self, body: &Body<'tcx>) -> usize { - body.local_decls.len() - } - - fn statement_effect( +impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, statement: &Statement<'tcx>, @@ -50,7 +44,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals { self.transfer_function(trans).visit_statement(statement, location); } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir Terminator<'tcx>, @@ -60,7 +54,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, _trans: &mut Self::Domain, _block: BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index e5bcb64d6415..18a5ca3f6be5 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -11,7 +11,7 @@ use crate::elaborate_drops::DropFlagState; use crate::framework::SwitchIntEdgeEffects; use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex}; use crate::{ - AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable, drop_flag_effects, + Analysis, AnalysisDomain, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry, drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits, }; @@ -329,14 +329,8 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { - type Idx = MovePathIndex; - - fn domain_size(&self, _: &Body<'tcx>) -> usize { - self.move_data().move_paths.len() - } - - fn statement_effect( +impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, statement: &mir::Statement<'tcx>, @@ -360,7 +354,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, state: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -380,7 +374,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { edges } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, _block: mir::BasicBlock, @@ -399,7 +393,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { }); } - fn switch_int_edge_effects( + fn apply_switch_int_edge_effects( &mut self, block: mir::BasicBlock, discr: &mir::Operand<'tcx>, @@ -466,14 +460,8 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { - type Idx = MovePathIndex; - - fn domain_size(&self, _: &Body<'tcx>) -> usize { - self.move_data().move_paths.len() - } - - fn statement_effect( +impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, @@ -487,7 +475,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { // mutable borrow occurs. Places cannot become uninitialized through a mutable reference. } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -505,7 +493,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, _block: mir::BasicBlock, @@ -524,7 +512,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { }); } - fn switch_int_edge_effects( + fn apply_switch_int_edge_effects( &mut self, block: mir::BasicBlock, discr: &mir::Operand<'tcx>, @@ -593,14 +581,8 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { - type Idx = MovePathIndex; - - fn domain_size(&self, _: &Body<'tcx>) -> usize { - self.move_data().move_paths.len() - } - - fn statement_effect( +impl<'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, _statement: &mir::Statement<'tcx>, @@ -611,7 +593,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { }) } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -623,7 +605,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, _block: mir::BasicBlock, @@ -662,15 +644,9 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { - type Idx = InitIndex; - - fn domain_size(&self, _: &Body<'tcx>) -> usize { - self.move_data().inits.len() - } - +impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { #[instrument(skip(self, trans), level = "debug")] - fn statement_effect( + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, stmt: &mir::Statement<'tcx>, @@ -698,7 +674,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { } #[instrument(skip(self, trans, terminator), level = "debug")] - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -720,7 +696,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, block: mir::BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 07ecedeac593..452fae379be6 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -4,7 +4,7 @@ use rustc_middle::mir::{ self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges, }; -use crate::{Analysis, AnalysisDomain, Backward, GenKill, GenKillAnalysis}; +use crate::{Analysis, AnalysisDomain, Backward, GenKill}; /// A [live-variable dataflow analysis][liveness]. /// @@ -41,14 +41,8 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals { } } -impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { - type Idx = Local; - - fn domain_size(&self, body: &mir::Body<'tcx>) -> usize { - body.local_decls.len() - } - - fn statement_effect( +impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { + fn apply_statement_effect( &mut self, trans: &mut Self::Domain, statement: &mir::Statement<'tcx>, @@ -57,7 +51,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { TransferFunction(trans).visit_statement(statement, location); } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, @@ -67,7 +61,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, _block: mir::BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 0f94defb1abb..6ccd7dc17a22 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use super::MaybeBorrowedLocals; -use crate::{AnalysisDomain, GenKill, ResultsCursor}; +use crate::{Analysis, AnalysisDomain, GenKill, ResultsCursor}; pub struct MaybeStorageLive<'a> { always_live_locals: Cow<'a, BitSet>, @@ -17,7 +17,7 @@ impl<'a> MaybeStorageLive<'a> { } } -impl<'a, 'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageLive<'a> { +impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageLive<'a> { type Domain = BitSet; const NAME: &'static str = "maybe_storage_live"; @@ -39,14 +39,13 @@ impl<'a, 'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageLive<'a> { } } -impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { - type Idx = Local; - - fn domain_size(&self, body: &Body<'tcx>) -> usize { - body.local_decls.len() - } - - fn statement_effect(&mut self, trans: &mut Self::Domain, stmt: &Statement<'tcx>, _: Location) { +impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> { + fn apply_statement_effect( + &mut self, + trans: &mut Self::Domain, + stmt: &Statement<'tcx>, + _: Location, + ) { match stmt.kind { StatementKind::StorageLive(l) => trans.gen_(l), StatementKind::StorageDead(l) => trans.kill(l), @@ -54,7 +53,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { } } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, _trans: &mut Self::Domain, terminator: &'mir Terminator<'tcx>, @@ -64,7 +63,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, _trans: &mut Self::Domain, _block: BasicBlock, @@ -84,7 +83,7 @@ impl<'a> MaybeStorageDead<'a> { } } -impl<'a, 'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead<'a> { +impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageDead<'a> { type Domain = BitSet; const NAME: &'static str = "maybe_storage_dead"; @@ -105,14 +104,13 @@ impl<'a, 'tcx> crate::AnalysisDomain<'tcx> for MaybeStorageDead<'a> { } } -impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead<'a> { - type Idx = Local; - - fn domain_size(&self, body: &Body<'tcx>) -> usize { - body.local_decls.len() - } - - fn statement_effect(&mut self, trans: &mut Self::Domain, stmt: &Statement<'tcx>, _: Location) { +impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> { + fn apply_statement_effect( + &mut self, + trans: &mut Self::Domain, + stmt: &Statement<'tcx>, + _: Location, + ) { match stmt.kind { StatementKind::StorageLive(l) => trans.kill(l), StatementKind::StorageDead(l) => trans.gen_(l), @@ -120,7 +118,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead<'a> { } } - fn terminator_effect<'mir>( + fn apply_terminator_effect<'mir>( &mut self, _: &mut Self::Domain, terminator: &'mir Terminator<'tcx>, @@ -130,7 +128,7 @@ impl<'a, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead<'a> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, _trans: &mut Self::Domain, _block: BasicBlock, @@ -154,7 +152,7 @@ impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> { } } -impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> { +impl<'tcx> AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> { type Domain = BitSet; const NAME: &'static str = "requires_storage"; @@ -173,21 +171,15 @@ impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> { } } -impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { - type Idx = Local; - - fn domain_size(&self, body: &Body<'tcx>) -> usize { - body.local_decls.len() - } - - fn before_statement_effect( +impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { + fn apply_before_statement_effect( &mut self, trans: &mut Self::Domain, stmt: &Statement<'tcx>, loc: Location, ) { // If a place is borrowed in a statement, it needs storage for that statement. - self.borrowed_locals.mut_analysis().statement_effect(trans, stmt, loc); + self.borrowed_locals.mut_analysis().apply_statement_effect(trans, stmt, loc); match &stmt.kind { StatementKind::StorageDead(l) => trans.kill(*l), @@ -213,13 +205,18 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { } } - fn statement_effect(&mut self, trans: &mut Self::Domain, _: &Statement<'tcx>, loc: Location) { + fn apply_statement_effect( + &mut self, + trans: &mut Self::Domain, + _: &Statement<'tcx>, + loc: Location, + ) { // If we move from a place then it only stops needing storage *after* // that statement. self.check_for_move(trans, loc); } - fn before_terminator_effect( + fn apply_before_terminator_effect( &mut self, trans: &mut Self::Domain, terminator: &Terminator<'tcx>, @@ -277,7 +274,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { } } - fn terminator_effect<'t>( + fn apply_terminator_effect<'t>( &mut self, trans: &mut Self::Domain, terminator: &'t Terminator<'tcx>, @@ -318,7 +315,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { terminator.edges() } - fn call_return_effect( + fn apply_call_return_effect( &mut self, trans: &mut Self::Domain, _block: BasicBlock, diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index cd926c076412..d07928dcdc99 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -18,9 +18,9 @@ pub use self::drop_flag_effects::{ move_path_children_matching, on_all_children_bits, on_lookup_result_bits, }; pub use self::framework::{ - Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, GenKill, GenKillAnalysis, - JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, - SwitchIntEdgeEffects, fmt, graphviz, lattice, visit_results, + Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, GenKill, JoinSemiLattice, + MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, + fmt, graphviz, lattice, visit_results, }; use self::move_paths::MoveData; From ba13775319fa51933da6e90053a9f96778b15b6b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 11:46:29 +1100 Subject: [PATCH 050/118] Merge `AnalysisDomain` into `Analysis`. With `GenKillAnalysis` gone, there is no need for them to be separate. --- compiler/rustc_borrowck/src/dataflow.rs | 30 +++++++------- .../src/check_consts/resolver.rs | 9 +--- .../src/framework/engine.rs | 5 +-- .../rustc_mir_dataflow/src/framework/mod.rs | 41 +++++++++---------- .../rustc_mir_dataflow/src/framework/tests.rs | 4 +- .../src/impls/borrowed_locals.rs | 6 +-- .../src/impls/initialized.rs | 27 ++++-------- .../rustc_mir_dataflow/src/impls/liveness.rs | 10 ++--- .../src/impls/storage_liveness.rs | 20 +++------ compiler/rustc_mir_dataflow/src/lib.rs | 6 +-- .../rustc_mir_dataflow/src/value_analysis.rs | 9 +--- 11 files changed, 62 insertions(+), 105 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 2eef200e24c8..216cf8ac9888 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -7,7 +7,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::fmt::DebugWithContext; use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces}; -use rustc_mir_dataflow::{Analysis, AnalysisDomain, Forward, GenKill, Results, ResultsVisitable}; +use rustc_mir_dataflow::{Analysis, Forward, GenKill, Results, ResultsVisitable}; use tracing::debug; use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict}; @@ -22,9 +22,9 @@ pub(crate) struct BorrowckResults<'a, 'tcx> { /// The transient state of the dataflow analyses used by the borrow checker. #[derive(Debug)] pub(crate) struct BorrowckDomain<'a, 'tcx> { - pub(crate) borrows: as AnalysisDomain<'tcx>>::Domain, - pub(crate) uninits: as AnalysisDomain<'tcx>>::Domain, - pub(crate) ever_inits: as AnalysisDomain<'tcx>>::Domain, + pub(crate) borrows: as Analysis<'tcx>>::Domain, + pub(crate) uninits: as Analysis<'tcx>>::Domain, + pub(crate) ever_inits: as Analysis<'tcx>>::Domain, } impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> { @@ -427,7 +427,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { /// That means they went out of a nonlexical scope fn kill_loans_out_of_scope_at_location( &self, - trans: &mut >::Domain, + trans: &mut >::Domain, location: Location, ) { // NOTE: The state associated with a given `location` @@ -449,7 +449,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { /// Kill any borrows that conflict with `place`. fn kill_borrows_on_place( &self, - trans: &mut >::Domain, + trans: &mut >::Domain, place: Place<'tcx>, ) { debug!("kill_borrows_on_place: place={:?}", place); @@ -490,7 +490,14 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { } } -impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { +/// Forward dataflow computation of the set of borrows that are in scope at a particular location. +/// - we gen the introduced loans +/// - we kill loans on locals going out of (regular) scope +/// - we kill the loans going out of their region's NLL scope: in NLL terms, the frontier where a +/// region stops containing the CFG points reachable from the issuing location. +/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of +/// `a.b.c` when `a` is overwritten. +impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { type Domain = BitSet; const NAME: &'static str = "borrows"; @@ -504,16 +511,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { // no borrows of code region_scopes have been taken prior to // function execution, so this method has no effect. } -} -/// Forward dataflow computation of the set of borrows that are in scope at a particular location. -/// - we gen the introduced loans -/// - we kill loans on locals going out of (regular) scope -/// - we kill the loans going out of their region's NLL scope: in NLL terms, the frontier where a -/// region stops containing the CFG points reachable from the issuing location. -/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of -/// `a.b.c` when `a` is overwritten. -impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { fn apply_before_statement_effect( &mut self, trans: &mut Self::Domain, diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index eb5024c36f4b..74eb6b37fbba 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::{ self, BasicBlock, CallReturnPlaces, Local, Location, Statement, StatementKind, TerminatorEdges, }; use rustc_mir_dataflow::fmt::DebugWithContext; -use rustc_mir_dataflow::{Analysis, AnalysisDomain, JoinSemiLattice}; +use rustc_mir_dataflow::{Analysis, JoinSemiLattice}; use super::{ConstCx, Qualif, qualifs}; @@ -310,7 +310,7 @@ impl JoinSemiLattice for State { } } -impl<'tcx, Q> AnalysisDomain<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> +impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> where Q: Qualif, { @@ -328,12 +328,7 @@ where fn initialize_start_block(&self, _body: &mir::Body<'tcx>, state: &mut Self::Domain) { self.transfer_function(state).initialize_state(); } -} -impl<'tcx, Q> Analysis<'tcx> for FlowSensitiveAnalysis<'_, '_, 'tcx, Q> -where - Q: Qualif, -{ fn apply_statement_effect( &mut self, state: &mut Self::Domain, diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index d6853b6ef829..cbd1083d037d 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -16,14 +16,13 @@ use {rustc_ast as ast, rustc_graphviz as dot}; use super::fmt::DebugWithContext; use super::{ - Analysis, AnalysisDomain, Direction, JoinSemiLattice, ResultsCursor, ResultsVisitor, graphviz, - visit_results, + Analysis, Direction, JoinSemiLattice, ResultsCursor, ResultsVisitor, graphviz, visit_results, }; use crate::errors::{ DuplicateValuesFor, PathMustEndInFilename, RequiresAnArgument, UnknownFormatter, }; -type EntrySets<'tcx, A> = IndexVec>::Domain>; +type EntrySets<'tcx, A> = IndexVec>::Domain>; /// A dataflow analysis that has converged to fixpoint. #[derive(Clone)] diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index d7a62ecd2c18..4e72ffabc6e0 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -89,11 +89,26 @@ impl BitSetExt for ChunkedBitSet { } } -/// Defines the domain of a dataflow problem. +/// A dataflow problem with an arbitrarily complex transfer function. /// -/// This trait specifies the lattice on which this analysis operates (the domain) as well as its -/// initial value at the entry point of each basic block. -pub trait AnalysisDomain<'tcx> { +/// This trait specifies the lattice on which this analysis operates (the domain), its +/// initial value at the entry point of each basic block, and various operations. +/// +/// # Convergence +/// +/// When implementing this trait it's possible to choose a transfer function such that the analysis +/// does not reach fixpoint. To guarantee convergence, your transfer functions must maintain the +/// following invariant: +/// +/// > If the dataflow state **before** some point in the program changes to be greater +/// than the prior state **before** that point, the dataflow state **after** that point must +/// also change to be greater than the prior state **after** that point. +/// +/// This invariant guarantees that the dataflow state at a given point in the program increases +/// monotonically until fixpoint is reached. Note that this monotonicity requirement only applies +/// to the same point in the program at different points in time. The dataflow state at a given +/// point in the program may or may not be greater than the state at any preceding point. +pub trait Analysis<'tcx> { /// The type that holds the dataflow state at any given point in the program. type Domain: Clone + JoinSemiLattice; @@ -118,25 +133,7 @@ pub trait AnalysisDomain<'tcx> { // block where control flow could exit the MIR body (e.g., those terminated with `return` or // `resume`). It's not obvious how to handle `yield` points in coroutines, however. fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain); -} -/// A dataflow problem with an arbitrarily complex transfer function. -/// -/// # Convergence -/// -/// When implementing this trait it's possible to choose a transfer function such that the analysis -/// does not reach fixpoint. To guarantee convergence, your transfer functions must maintain the -/// following invariant: -/// -/// > If the dataflow state **before** some point in the program changes to be greater -/// than the prior state **before** that point, the dataflow state **after** that point must -/// also change to be greater than the prior state **after** that point. -/// -/// This invariant guarantees that the dataflow state at a given point in the program increases -/// monotonically until fixpoint is reached. Note that this monotonicity requirement only applies -/// to the same point in the program at different points in time. The dataflow state at a given -/// point in the program may or may not be greater than the state at any preceding point. -pub trait Analysis<'tcx>: AnalysisDomain<'tcx> { /// Updates the current dataflow state with the effect of evaluating a statement. fn apply_statement_effect( &mut self, diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 1861f4cffc71..de171dbc3138 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -154,7 +154,7 @@ impl MockAnalysis<'_, D> { } } -impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> { +impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> { type Domain = BitSet; type Direction = D; @@ -167,9 +167,7 @@ impl<'tcx, D: Direction> AnalysisDomain<'tcx> for MockAnalysis<'tcx, D> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { unimplemented!("This is never called since `MockAnalysis` is never iterated to fixpoint"); } -} -impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> { fn apply_statement_effect( &mut self, state: &mut Self::Domain, diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index f4edbaf056ce..56c38cb02f92 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -2,7 +2,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use crate::{Analysis, AnalysisDomain, GenKill}; +use crate::{Analysis, GenKill}; /// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points /// to a given local. This analysis ignores fake borrows, so it should not be used by @@ -20,7 +20,7 @@ impl MaybeBorrowedLocals { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeBorrowedLocals { +impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { type Domain = BitSet; const NAME: &'static str = "maybe_borrowed_locals"; @@ -32,9 +32,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeBorrowedLocals { fn initialize_start_block(&self, _: &Body<'tcx>, _: &mut Self::Domain) { // No locals are aliased on function entry } -} -impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 18a5ca3f6be5..9bb50d1e056b 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -11,9 +11,8 @@ use crate::elaborate_drops::DropFlagState; use crate::framework::SwitchIntEdgeEffects; use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex}; use crate::{ - Analysis, AnalysisDomain, GenKill, MaybeReachable, drop_flag_effects, - drop_flag_effects_for_function_entry, drop_flag_effects_for_location, lattice, - on_all_children_bits, on_lookup_result_bits, + Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry, + drop_flag_effects_for_location, lattice, on_all_children_bits, on_lookup_result_bits, }; /// `MaybeInitializedPlaces` tracks all places that might be @@ -270,7 +269,7 @@ impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> { impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { fn update_bits( - trans: &mut >::Domain, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -283,7 +282,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { fn update_bits( - trans: &mut >::Domain, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -296,7 +295,7 @@ impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> { impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { fn update_bits( - trans: &mut >::Domain, + trans: &mut >::Domain, path: MovePathIndex, state: DropFlagState, ) { @@ -307,7 +306,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { +impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = MaybeReachable>; @@ -327,9 +326,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { state.gen_(path); }); } -} -impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -436,7 +433,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { +impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { /// There can be many more `MovePathIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -458,9 +455,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { state.remove(path); }); } -} -impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -559,7 +554,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { } } -impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { +impl<'a, 'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { /// Use set intersection as the join operator. type Domain = lattice::Dual>; @@ -579,9 +574,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { state.0.insert(path); }); } -} -impl<'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -625,7 +618,7 @@ impl<'tcx> Analysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { +impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { /// There can be many more `InitIndex` than there are locals in a MIR body. /// We use a chunked bitset to avoid paying too high a memory footprint. type Domain = ChunkedBitSet; @@ -642,9 +635,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> { state.insert(InitIndex::new(arg_init)); } } -} -impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { #[instrument(skip(self, trans), level = "debug")] fn apply_statement_effect( &mut self, diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 452fae379be6..e06c1f2bb49e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -4,7 +4,7 @@ use rustc_middle::mir::{ self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges, }; -use crate::{Analysis, AnalysisDomain, Backward, GenKill}; +use crate::{Analysis, Backward, GenKill}; /// A [live-variable dataflow analysis][liveness]. /// @@ -25,7 +25,7 @@ use crate::{Analysis, AnalysisDomain, Backward, GenKill}; /// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis pub struct MaybeLiveLocals; -impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals { +impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { type Domain = BitSet; type Direction = Backward; @@ -39,9 +39,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals { fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { // No variables are live until we observe a use } -} -impl<'tcx> Analysis<'tcx> for MaybeLiveLocals { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -219,7 +217,7 @@ impl<'a> MaybeTransitiveLiveLocals<'a> { } } -impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> { +impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { type Domain = BitSet; type Direction = Backward; @@ -233,9 +231,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { // No variables are live until we observe a use } -} -impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 6ccd7dc17a22..07769057096e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use super::MaybeBorrowedLocals; -use crate::{Analysis, AnalysisDomain, GenKill, ResultsCursor}; +use crate::{Analysis, GenKill, ResultsCursor}; pub struct MaybeStorageLive<'a> { always_live_locals: Cow<'a, BitSet>, @@ -17,7 +17,7 @@ impl<'a> MaybeStorageLive<'a> { } } -impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageLive<'a> { +impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> { type Domain = BitSet; const NAME: &'static str = "maybe_storage_live"; @@ -37,9 +37,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageLive<'a> { on_entry.insert(arg); } } -} -impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -83,7 +81,7 @@ impl<'a> MaybeStorageDead<'a> { } } -impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageDead<'a> { +impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> { type Domain = BitSet; const NAME: &'static str = "maybe_storage_dead"; @@ -102,9 +100,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeStorageDead<'a> { } } } -} -impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> { fn apply_statement_effect( &mut self, trans: &mut Self::Domain, @@ -152,7 +148,7 @@ impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> { } } -impl<'tcx> AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> { +impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { type Domain = BitSet; const NAME: &'static str = "requires_storage"; @@ -169,9 +165,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> { on_entry.insert(arg); } } -} -impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { fn apply_before_statement_effect( &mut self, trans: &mut Self::Domain, @@ -327,11 +321,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> { impl<'tcx> MaybeRequiresStorage<'_, 'tcx> { /// Kill locals that are fully moved and have not been borrowed. - fn check_for_move( - &mut self, - trans: &mut >::Domain, - loc: Location, - ) { + fn check_for_move(&mut self, trans: &mut >::Domain, loc: Location) { let body = self.borrowed_locals.body(); let mut visitor = MoveVisitor { trans, borrowed_locals: &mut self.borrowed_locals }; visitor.visit_location(body, loc); diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index d07928dcdc99..b284f0308f97 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -18,9 +18,9 @@ pub use self::drop_flag_effects::{ move_path_children_matching, on_all_children_bits, on_lookup_result_bits, }; pub use self::framework::{ - Analysis, AnalysisDomain, Backward, Direction, Engine, Forward, GenKill, JoinSemiLattice, - MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, - fmt, graphviz, lattice, visit_results, + Analysis, Backward, Direction, Engine, Forward, GenKill, JoinSemiLattice, MaybeReachable, + Results, ResultsCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, fmt, graphviz, + lattice, visit_results, }; use self::move_paths::MoveData; diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index aa09fe1dd45e..faee40faa3f5 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -51,7 +51,7 @@ use tracing::debug; use crate::fmt::DebugWithContext; use crate::lattice::{HasBottom, HasTop}; -use crate::{Analysis, AnalysisDomain, JoinSemiLattice, SwitchIntEdgeEffects}; +use crate::{Analysis, JoinSemiLattice, SwitchIntEdgeEffects}; pub trait ValueAnalysis<'tcx> { /// For each place of interest, the analysis tracks a value of the given type. @@ -334,7 +334,7 @@ pub trait ValueAnalysis<'tcx> { pub struct ValueAnalysisWrapper(pub T); -impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper { +impl<'tcx, T: ValueAnalysis<'tcx>> Analysis<'tcx> for ValueAnalysisWrapper { type Domain = State; const NAME: &'static str = T::NAME; @@ -351,12 +351,7 @@ impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map()); } } -} -impl<'tcx, T> Analysis<'tcx> for ValueAnalysisWrapper -where - T: ValueAnalysis<'tcx>, -{ fn apply_statement_effect( &mut self, state: &mut Self::Domain, From 33abf6a0c8b9a051c06dcb43935f3e15c96ade45 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2024 12:06:25 +1100 Subject: [PATCH 051/118] Add defaults for `Analysis::apply_{call_return_effect,terminator_effect}`. To avoid some low-value boilerplate code. --- compiler/rustc_borrowck/src/dataflow.rs | 12 +----- .../rustc_mir_dataflow/src/framework/mod.rs | 17 +++++---- .../rustc_mir_dataflow/src/framework/tests.rs | 8 ---- .../src/impls/borrowed_locals.rs | 8 ---- .../src/impls/storage_liveness.rs | 38 ------------------- 5 files changed, 11 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 216cf8ac9888..89ff12c1479a 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -1,9 +1,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::graph; use rustc_index::bit_set::BitSet; -use rustc_middle::mir::{ - self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges, -}; +use rustc_middle::mir::{self, BasicBlock, Body, Location, Place, TerminatorEdges}; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::fmt::DebugWithContext; use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces}; @@ -595,14 +593,6 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { } terminator.edges() } - - fn apply_call_return_effect( - &mut self, - _trans: &mut Self::Domain, - _block: mir::BasicBlock, - _return_places: CallReturnPlaces<'_, 'tcx>, - ) { - } } impl DebugWithContext for BorrowIndex {} diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 4e72ffabc6e0..959f1ea53409 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -164,10 +164,12 @@ pub trait Analysis<'tcx> { /// initialized here. fn apply_terminator_effect<'mir>( &mut self, - state: &mut Self::Domain, + _state: &mut Self::Domain, terminator: &'mir mir::Terminator<'tcx>, - location: Location, - ) -> TerminatorEdges<'mir, 'tcx>; + _location: Location, + ) -> TerminatorEdges<'mir, 'tcx> { + terminator.edges() + } /// Updates the current dataflow state with an effect that occurs immediately *before* the /// given terminator. @@ -192,10 +194,11 @@ pub trait Analysis<'tcx> { /// edges. fn apply_call_return_effect( &mut self, - state: &mut Self::Domain, - block: BasicBlock, - return_places: CallReturnPlaces<'_, 'tcx>, - ); + _state: &mut Self::Domain, + _block: BasicBlock, + _return_places: CallReturnPlaces<'_, 'tcx>, + ) { + } /// Updates the current dataflow state with the effect of taking a particular branch in a /// `SwitchInt` terminator. diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index de171dbc3138..14fb6dfb50c8 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -208,14 +208,6 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> { let idx = self.effect(Effect::Before.at_index(location.statement_index)); assert!(state.insert(idx)); } - - fn apply_call_return_effect( - &mut self, - _state: &mut Self::Domain, - _block: BasicBlock, - _return_places: CallReturnPlaces<'_, 'tcx>, - ) { - } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 56c38cb02f92..859019fd1f6e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -51,14 +51,6 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals { self.transfer_function(trans).visit_terminator(terminator, location); terminator.edges() } - - fn apply_call_return_effect( - &mut self, - _trans: &mut Self::Domain, - _block: BasicBlock, - _return_places: CallReturnPlaces<'_, 'tcx>, - ) { - } } /// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`. diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 07769057096e..c5fd2a631ff7 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -50,25 +50,6 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> { _ => (), } } - - fn apply_terminator_effect<'mir>( - &mut self, - _trans: &mut Self::Domain, - terminator: &'mir Terminator<'tcx>, - _: Location, - ) -> TerminatorEdges<'mir, 'tcx> { - // Terminators have no effect - terminator.edges() - } - - fn apply_call_return_effect( - &mut self, - _trans: &mut Self::Domain, - _block: BasicBlock, - _return_places: CallReturnPlaces<'_, 'tcx>, - ) { - // Nothing to do when a call returns successfully - } } pub struct MaybeStorageDead<'a> { @@ -113,25 +94,6 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> { _ => (), } } - - fn apply_terminator_effect<'mir>( - &mut self, - _: &mut Self::Domain, - terminator: &'mir Terminator<'tcx>, - _: Location, - ) -> TerminatorEdges<'mir, 'tcx> { - // Terminators have no effect - terminator.edges() - } - - fn apply_call_return_effect( - &mut self, - _trans: &mut Self::Domain, - _block: BasicBlock, - _return_places: CallReturnPlaces<'_, 'tcx>, - ) { - // Nothing to do when a call returns successfully - } } type BorrowedLocalsResults<'mir, 'tcx> = ResultsCursor<'mir, 'tcx, MaybeBorrowedLocals>; From b6b6c12819bbffca3aa75298afb79cf1a70e0312 Mon Sep 17 00:00:00 2001 From: Tamme Dittrich Date: Mon, 14 Oct 2024 08:07:41 +0200 Subject: [PATCH 052/118] Update lint message for ABI not supported --- .../rustc_hir_analysis/src/check/check.rs | 6 +++--- compiler/rustc_lint_defs/src/builtin.rs | 2 +- tests/ui/abi/unsupported.aarch64.stderr | 20 +++++++++---------- tests/ui/abi/unsupported.arm.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.i686.stderr | 14 ++++++------- tests/ui/abi/unsupported.riscv32.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.riscv64.stderr | 18 ++++++++--------- tests/ui/abi/unsupported.x64.stderr | 18 ++++++++--------- 8 files changed, 57 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4429f6346e88..94da3d4ea840 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -61,9 +61,9 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab Some(true) => (), Some(false) | None => { tcx.node_span_lint(UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.primary_message( - "use of calling convention not supported on this target on function pointer", - ); + lint.primary_message(format!( + "the calling convention {abi} is not supported on this target" + )); }); } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 23dc5214fe2e..da603df9a9a9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3859,7 +3859,7 @@ declare_lint! { /// This will produce: /// /// ```text - /// warning: use of calling convention not supported on this target on function pointer + /// warning: the calling convention `"stdcall"` is not supported on this target /// --> $DIR/unsupported.rs:34:15 /// | /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) { diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 00a5b4b2ee14..82908ef88a8b 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -104,7 +104,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -123,7 +123,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -132,7 +132,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index dfb5ceb0c337..39ec5d16fcd0 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 6537ce660577..1dc01a66aabc 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -83,7 +83,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index a53f85f28bce..e7d5197feebb 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index a53f85f28bce..e7d5197feebb 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "x86-interrupt" is not supported on this target --> $DIR/unsupported.rs:116:15 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 45ba9a6649c5..bbca754dd41f 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,4 +1,4 @@ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "ptx-kernel" is not supported on this target --> $DIR/unsupported.rs:35:15 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { @@ -14,7 +14,7 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "aapcs" is not supported on this target --> $DIR/unsupported.rs:49:17 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { @@ -29,7 +29,7 @@ error[E0570]: `"aapcs"` is not a supported ABI for the current target LL | extern "aapcs" {} | ^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "msp430-interrupt" is not supported on this target --> $DIR/unsupported.rs:71:18 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { @@ -44,7 +44,7 @@ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "avr-interrupt" is not supported on this target --> $DIR/unsupported.rs:81:15 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { @@ -59,7 +59,7 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "riscv-interrupt-m" is not supported on this target --> $DIR/unsupported.rs:94:17 | LL | fn riscv_ptr(f: extern "riscv-interrupt-m" fn()) { @@ -74,7 +74,7 @@ error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current targe LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "thiscall" is not supported on this target --> $DIR/unsupported.rs:139:20 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { @@ -89,7 +89,7 @@ error[E0570]: `"thiscall"` is not a supported ABI for the current target LL | extern "thiscall" {} | ^^^^^^^^^^^^^^^^^^^^ -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "stdcall" is not supported on this target --> $DIR/unsupported.rs:170:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { @@ -108,7 +108,7 @@ LL | extern "stdcall" {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target --> $DIR/unsupported.rs:195:21 | LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { @@ -117,7 +117,7 @@ LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" fn()) { = 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 #130260 -warning: use of calling convention not supported on this target on function pointer +warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target --> $DIR/unsupported.rs:203:22 | LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" fn()) { From cec59864393bfd7efab2834b895fc73fbb59f78e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 13 Oct 2024 23:22:57 +1100 Subject: [PATCH 053/118] Document various parts of compiletest's `lib.rs` --- src/tools/compiletest/src/lib.rs | 127 +++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 13 deletions(-) diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 18000e5602cb..2e66c084dd75 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -43,6 +43,11 @@ use crate::common::{ use crate::header::HeadersCache; use crate::util::logv; +/// Creates the `Config` instance for this invocation of compiletest. +/// +/// The config mostly reflects command-line arguments, but there might also be +/// some code here that inspects environment variables or even runs executables +/// (e.g. when discovering debugger versions). pub fn parse_config(args: Vec) -> Config { let mut opts = Options::new(); opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH") @@ -413,6 +418,7 @@ pub fn opt_str2(maybestr: Option) -> String { } } +/// Called by `main` after the config has been parsed. pub fn run_tests(config: Arc) { // If we want to collect rustfix coverage information, // we first make sure that the coverage file does not exist. @@ -454,6 +460,8 @@ pub fn run_tests(config: Arc) { configs.push(config.clone()); }; + // Discover all of the tests in the test suite directory, and build a libtest + // structure for each test (or each revision of a multi-revision test). let mut tests = Vec::new(); for c in configs { let mut found_paths = HashSet::new(); @@ -463,7 +471,12 @@ pub fn run_tests(config: Arc) { tests.sort_by(|a, b| a.desc.name.as_slice().cmp(&b.desc.name.as_slice())); + // Delegate to libtest to filter and run the big list of structures created + // during test discovery. When libtest decides to run a test, it will invoke + // the corresponding closure created by `make_test_closure`. let res = test::run_tests_console(&opts, tests); + + // Check the outcome reported by libtest. match res { Ok(true) => {} Ok(false) => { @@ -532,6 +545,11 @@ pub fn test_opts(config: &Config) -> test::TestOpts { } } +/// Creates libtest structures for every test/revision in the test suite directory. +/// +/// This always inspects _all_ test files in the suite (e.g. all 17k+ ui tests), +/// regardless of whether any filters/tests were specified on the command-line, +/// because filtering is handled later by libtest. pub fn make_tests( config: Arc, tests: &mut Vec, @@ -610,10 +628,17 @@ fn common_inputs_stamp(config: &Config) -> Stamp { stamp } +/// Returns a list of modified/untracked test files that should be run when +/// the `--only-modified` flag is in use. +/// +/// (Might be inaccurate in some cases.) fn modified_tests(config: &Config, dir: &Path) -> Result, String> { + // If `--only-modified` wasn't passed, the list of modified tests won't be + // used for anything, so avoid some work and just return an empty list. if !config.only_modified { return Ok(vec![]); } + let files = get_git_modified_files(&config.git_config(), Some(dir), &vec!["rs", "stderr", "fixed"])? .unwrap_or(vec![]); @@ -634,6 +659,8 @@ fn modified_tests(config: &Config, dir: &Path) -> Result, String> { Ok(full_paths) } +/// Recursively scans a directory to find test files and create test structures +/// that will be handed over to libtest. fn collect_tests_from_dir( config: Arc, cache: &HeadersCache, @@ -650,6 +677,8 @@ fn collect_tests_from_dir( return Ok(()); } + // For run-make tests, a "test file" is actually a directory that contains + // an `rmake.rs` or `Makefile`" if config.mode == Mode::RunMake { if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() { return Err(io::Error::other( @@ -663,6 +692,7 @@ fn collect_tests_from_dir( relative_dir: relative_dir_path.parent().unwrap().to_path_buf(), }; tests.extend(make_test(config, cache, &paths, inputs, poisoned)); + // This directory is a test, so don't try to find other tests inside it. return Ok(()); } } @@ -677,22 +707,27 @@ fn collect_tests_from_dir( fs::create_dir_all(&build_dir).unwrap(); // Add each `.rs` file as a test, and recurse further on any - // subdirectories we find, except for `aux` directories. + // subdirectories we find, except for `auxiliary` directories. // FIXME: this walks full tests tree, even if we have something to ignore // use walkdir/ignore like in tidy? for file in fs::read_dir(dir)? { let file = file?; let file_path = file.path(); let file_name = file.file_name(); + if is_test(&file_name) && (!config.only_modified || modified_tests.contains(&file_path)) { + // We found a test file, so create the corresponding libtest structures. debug!("found test file: {:?}", file_path.display()); + + // Record the stem of the test file, to check for overlaps later. let rel_test_path = relative_dir_path.join(file_path.file_stem().unwrap()); found_paths.insert(rel_test_path); + let paths = TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() }; - tests.extend(make_test(config.clone(), cache, &paths, inputs, poisoned)) } else if file_path.is_dir() { + // Recurse to find more tests in a subdirectory. let relative_file_path = relative_dir_path.join(file.file_name()); if &file_name != "auxiliary" { debug!("found directory: {:?}", file_path.display()); @@ -728,6 +763,8 @@ pub fn is_test(file_name: &OsString) -> bool { !invalid_prefixes.iter().any(|p| file_name.starts_with(p)) } +/// For a single test file, creates one or more test structures (one per revision) +/// that can be handed over to libtest to run, possibly in parallel. fn make_test( config: Arc, cache: &HeadersCache, @@ -735,6 +772,9 @@ fn make_test( inputs: &Stamp, poisoned: &mut bool, ) -> Vec { + // For run-make tests, each "test file" is actually a _directory_ containing + // an `rmake.rs` or `Makefile`. But for the purposes of directive parsing, + // we want to look at that recipe file, not the directory itself. let test_path = if config.mode == Mode::RunMake { if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() { panic!("run-make tests cannot have both `rmake.rs` and `Makefile`"); @@ -750,26 +790,40 @@ fn make_test( } else { PathBuf::from(&testpaths.file) }; + + // Scan the test file to discover its revisions, if any. let early_props = EarlyProps::from_file(&config, &test_path); - // Incremental tests are special, they inherently cannot be run in parallel. - // `runtest::run` will be responsible for iterating over revisions. + // Normally we create one libtest structure per revision, with two exceptions: + // - If a test doesn't use revisions, create a dummy revision (None) so that + // the test can still run. + // - Incremental tests inherently can't run their revisions in parallel, so + // we treat them like non-revisioned tests here. Incremental revisions are + // handled internally by `runtest::run` instead. let revisions = if early_props.revisions.is_empty() || config.mode == Mode::Incremental { vec![None] } else { early_props.revisions.iter().map(|r| Some(r.as_str())).collect() }; + // For each revision (or the sole dummy revision), create and return a + // `test::TestDescAndFn` that can be handed over to libtest. revisions .into_iter() .map(|revision| { + // Create a test name and description to hand over to libtest. let src_file = std::fs::File::open(&test_path).expect("open test file to parse ignores"); let test_name = crate::make_test_name(&config, testpaths, revision); + // Create a libtest description for the test/revision. + // This is where `ignore-*`/`only-*`/`needs-*` directives are handled, + // because they need to set the libtest ignored flag. let mut desc = make_test_description( &config, cache, test_name, &test_path, src_file, revision, poisoned, ); - // Ignore tests that already run and are up to date with respect to inputs. + + // If a test's inputs haven't changed since the last time it ran, + // mark it as ignored so that libtest will skip it. if !config.force_rerun && is_up_to_date(&config, testpaths, &early_props, revision, inputs) { @@ -777,18 +831,25 @@ fn make_test( // Keep this in sync with the "up-to-date" message detected by bootstrap. desc.ignore_message = Some("up-to-date"); } - test::TestDescAndFn { - desc, - testfn: make_test_closure(config.clone(), testpaths, revision), - } + + // Create the callback that will run this test/revision when libtest calls it. + let testfn = make_test_closure(config.clone(), testpaths, revision); + + test::TestDescAndFn { desc, testfn } }) .collect() } +/// The path of the `stamp` file that gets created or updated whenever a +/// particular test completes successfully. fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf { output_base_dir(config, testpaths, revision).join("stamp") } +/// Returns a list of files that, if modified, would cause this test to no +/// longer be up-to-date. +/// +/// (Might be inaccurate in some cases.) fn files_related_to_test( config: &Config, testpaths: &TestPaths, @@ -824,46 +885,61 @@ fn files_related_to_test( related } +/// Checks whether a particular test/revision is "up-to-date", meaning that no +/// relevant files/settings have changed since the last time the test succeeded. +/// +/// (This is not very reliable in some circumstances, so the `--force-rerun` +/// flag can be used to ignore up-to-date checking and always re-run tests.) fn is_up_to_date( config: &Config, testpaths: &TestPaths, props: &EarlyProps, revision: Option<&str>, - inputs: &Stamp, + inputs: &Stamp, // Last-modified timestamp of the compiler, compiletest etc ) -> bool { let stamp_name = stamp(config, testpaths, revision); - // Check hash. + // Check the config hash inside the stamp file. let contents = match fs::read_to_string(&stamp_name) { Ok(f) => f, Err(ref e) if e.kind() == ErrorKind::InvalidData => panic!("Can't read stamp contents"), + // The test hasn't succeeded yet, so it is not up-to-date. Err(_) => return false, }; let expected_hash = runtest::compute_stamp_hash(config); if contents != expected_hash { + // Some part of compiletest configuration has changed since the test + // last succeeded, so it is not up-to-date. return false; } - // Check timestamps. + // Check the timestamp of the stamp file against the last modified time + // of all files known to be relevant to the test. let mut inputs = inputs.clone(); for path in files_related_to_test(config, testpaths, props, revision) { inputs.add_path(&path); } + // If no relevant files have been modified since the stamp file was last + // written, the test is up-to-date. inputs < Stamp::from_path(&stamp_name) } +/// The maximum of a set of file-modified timestamps. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] struct Stamp { time: SystemTime, } impl Stamp { + /// Creates a timestamp holding the last-modified time of the specified file. fn from_path(path: &Path) -> Self { let mut stamp = Stamp { time: SystemTime::UNIX_EPOCH }; stamp.add_path(path); stamp } + /// Updates this timestamp to the last-modified time of the specified file, + /// if it is later than the currently-stored timestamp. fn add_path(&mut self, path: &Path) { let modified = fs::metadata(path) .and_then(|metadata| metadata.modified()) @@ -871,6 +947,9 @@ impl Stamp { self.time = self.time.max(modified); } + /// Updates this timestamp to the most recent last-modified time of all files + /// recursively contained in the given directory, if it is later than the + /// currently-stored timestamp. fn add_dir(&mut self, path: &Path) { for entry in WalkDir::new(path) { let entry = entry.unwrap(); @@ -886,6 +965,7 @@ impl Stamp { } } +/// Creates a name for this test/revision that can be handed over to libtest. fn make_test_name( config: &Config, testpaths: &TestPaths, @@ -914,20 +994,41 @@ fn make_test_name( )) } +/// Creates a callback for this test/revision that libtest will call when it +/// decides to actually run the underlying test. fn make_test_closure( config: Arc, testpaths: &TestPaths, revision: Option<&str>, ) -> test::TestFn { - let config = config.clone(); let testpaths = testpaths.clone(); let revision = revision.map(str::to_owned); + + // This callback is the link between compiletest's test discovery code, + // and the parts of compiletest that know how to run an individual test. test::DynTestFn(Box::new(move || { runtest::run(config, &testpaths, revision.as_deref()); Ok(()) })) } +/// Checks that test discovery didn't find any tests whose name stem is a prefix +/// of some other tests's name. +/// +/// For example, suppose the test suite contains these two test files: +/// - `tests/rustdoc/primitive.rs` +/// - `tests/rustdoc/primitive/no_std.rs` +/// +/// The test runner might put the output from those tests in these directories: +/// - `$build/test/rustdoc/primitive/` +/// - `$build/test/rustdoc/primitive/no_std/` +/// +/// Because one output path is a subdirectory of the other, the two tests might +/// interfere with each other in unwanted ways, especially if the test runner +/// decides to delete test output directories to clean them between runs. +/// To avoid problems, we forbid test names from overlapping in this way. +/// +/// See for more context. fn check_overlapping_tests(found_paths: &HashSet) { let mut collisions = Vec::new(); for path in found_paths { From 9f42f9491dd291fcd57ee0646d98c3d31440fc15 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?= <39484203+jieyouxu@users.noreply.github.com> Date: Mon, 14 Oct 2024 19:33:40 +0800 Subject: [PATCH 054/118] triagebot: tag PRs affecting compiletest with `A-compiletest` --- triagebot.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 60ec1043aadb..33dcbfa55a4f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -431,6 +431,11 @@ trigger_files = [ "src/tools/run-make-support" ] +[autolabel."A-compiletest"] +trigger_files = [ + "src/tools/compiletest" +] + [notify-zulip."I-prioritize"] zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts topic = "#{number} {title}" From c6e1fbf8ebbbec0d7b2deee86a1bc67ec98e1541 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 14 Oct 2024 22:40:13 +1100 Subject: [PATCH 055/118] Fix up-to-date checking for run-make tests This special case in `output_base_dir` had the unfortunate side-effect of causing all run-make tests to share the same `stamp` file. So as soon as any one of them succeeded, all of the failed tests would be considered up-to-date and would no longer run in subsequent test invocations. --- src/tools/compiletest/src/common.rs | 10 ++-------- tests/run-make/README.md | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index a5418ad83848..1ee00a3a4e8f 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -759,14 +759,8 @@ pub fn output_testname_unique( /// test/revision should reside. Example: /// /path/to/build/host-triple/test/ui/relative/testname.revision.mode/ pub fn output_base_dir(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> PathBuf { - // In run-make tests, constructing a relative path + unique testname causes a double layering - // since revisions are not supported, causing unnecessary nesting. - if config.mode == Mode::RunMake { - output_relative_path(config, &testpaths.relative_dir) - } else { - output_relative_path(config, &testpaths.relative_dir) - .join(output_testname_unique(config, testpaths, revision)) - } + output_relative_path(config, &testpaths.relative_dir) + .join(output_testname_unique(config, testpaths, revision)) } /// Absolute path to the base filename used as output for the given diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 403599034738..9e1eaa881c94 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process: structure within `build//test/run-make/` ``` - / + // rmake.exe # recipe binary rmake_out/ # sources from test sources copied over ``` From 7500e09b8baa6d21c85a699ef359c8c4e6175629 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Oct 2024 09:16:03 -0400 Subject: [PATCH 056/118] Move trait bound modifiers into hir::PolyTraitRef --- compiler/rustc_ast_lowering/src/lib.rs | 43 +++++++++---------- .../src/diagnostics/region_errors.rs | 4 +- .../src/diagnostics/region_name.rs | 2 +- compiler/rustc_hir/src/hir.rs | 15 ++++--- compiler/rustc_hir/src/intravisit.rs | 4 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/collect/predicates_of.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 4 +- .../src/hir_ty_lowering/bounds.rs | 8 ++-- .../src/hir_ty_lowering/dyn_compatibility.rs | 9 ++-- .../src/hir_ty_lowering/errors.rs | 8 ++-- .../src/hir_ty_lowering/lint.rs | 4 +- compiler/rustc_hir_pretty/src/lib.rs | 14 +++--- .../src/fn_ctxt/suggestions.rs | 4 +- compiler/rustc_lint/src/traits.rs | 5 ++- compiler/rustc_middle/src/ty/diagnostics.rs | 3 +- .../infer/nice_region_error/find_anon_type.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 2 +- .../error_reporting/infer/note_and_explain.rs | 4 +- .../src/error_reporting/infer/suggest.rs | 5 ++- .../src/error_reporting/traits/mod.rs | 2 +- .../src/error_reporting/traits/suggestions.rs | 6 +-- .../src/traits/dyn_compatibility.rs | 2 +- src/librustdoc/clean/mod.rs | 8 ++-- .../src/implied_bounds_in_impls.rs | 6 ++- src/tools/clippy/clippy_lints/src/len_zero.rs | 2 +- .../clippy/clippy_lints/src/lifetimes.rs | 4 +- .../clippy_lints/src/manual_async_fn.rs | 2 +- .../clippy_lints/src/needless_maybe_sized.rs | 8 ++-- .../clippy/clippy_lints/src/trait_bounds.rs | 15 ++++--- .../clippy_lints/src/types/borrowed_box.rs | 2 +- .../clippy_lints/src/types/type_complexity.rs | 1 - 32 files changed, 102 insertions(+), 100 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 365924ef782e..b19ccc59a710 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1225,7 +1225,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx, TraitBoundModifiers::NONE, ); - let bound = (bound, hir::TraitBoundModifier::None); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); (bounds, lifetime_bound) @@ -1328,8 +1327,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // const trait bounds in trait object types. GenericBound::Trait(ty, modifiers) => { let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers); - let polarity = this.lower_trait_bound_modifiers(*modifiers); - Some((trait_ref, polarity)) + Some(trait_ref) } GenericBound::Outlives(lifetime) => { if lifetime_bound.is_none() { @@ -1958,21 +1956,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span_ext: DUMMY_SP, }); - hir::GenericBound::Trait( - hir::PolyTraitRef { - bound_generic_params: &[], - trait_ref: hir::TraitRef { - path: self.make_lang_item_path( - trait_lang_item, - opaque_ty_span, - Some(bound_args), - ), - hir_ref_id: self.next_id(), - }, - span: opaque_ty_span, + hir::GenericBound::Trait(hir::PolyTraitRef { + bound_generic_params: &[], + modifiers: hir::TraitBoundModifier::None, + trait_ref: hir::TraitRef { + path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)), + hir_ref_id: self.next_id(), }, - hir::TraitBoundModifier::None, - ) + span: opaque_ty_span, + }) } #[instrument(level = "trace", skip(self))] @@ -1982,10 +1974,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { - GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(p, itctx, *modifiers), - self.lower_trait_bound_modifiers(*modifiers), - ), + GenericBound::Trait(p, modifiers) => { + hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx, *modifiers)) + } GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) } @@ -2194,7 +2185,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx); - hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } + let modifiers = self.lower_trait_bound_modifiers(modifiers); + hir::PolyTraitRef { + bound_generic_params, + modifiers, + trait_ref, + span: self.lower_span(p.span), + } } fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> { @@ -2634,10 +2631,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => { let principal = hir::PolyTraitRef { bound_generic_params: &[], + modifiers: hir::TraitBoundModifier::None, trait_ref: hir::TraitRef { path, hir_ref_id: hir_id }, span: self.lower_span(span), }; - let principal = (principal, hir::TraitBoundModifier::None); // The original ID is taken by the `PolyTraitRef`, // so the `Ty` itself needs a different one. diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 39175b406a4a..6333d59a1bc8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -254,7 +254,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { debug!(?hrtb_bounds); hrtb_bounds.iter().for_each(|bound| { - let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { + let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }) = bound else { return; }; diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static); @@ -277,7 +277,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return; }; bounds.iter().for_each(|bd| { - if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }, _) = bd + if let Trait(PolyTraitRef { trait_ref: tr_ref, .. }) = bd && let Def(_, res_defid) = tr_ref.path.res && res_defid == trait_res_defid // trait id matches && let TyKind::Path(Resolved(_, path)) = bounded_ty.kind diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 1a5f9bdb154c..b4b8373ac974 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -837,7 +837,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { hir_ty ); }; - if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref, _)], .. } = opaque_ty + if let hir::OpaqueTy { bounds: [hir::GenericBound::Trait(trait_ref)], .. } = opaque_ty && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(args) = segment.args && let [constraint] = args.constraints diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 2ef6fa53f4ed..1e9cbba94c77 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -520,7 +520,7 @@ pub enum TraitBoundModifier { #[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { - Trait(PolyTraitRef<'hir>, TraitBoundModifier), + Trait(PolyTraitRef<'hir>), Outlives(&'hir Lifetime), Use(&'hir [PreciseCapturingArg<'hir>], Span), } @@ -528,7 +528,7 @@ pub enum GenericBound<'hir> { impl GenericBound<'_> { pub fn trait_ref(&self) -> Option<&TraitRef<'_>> { match self { - GenericBound::Trait(data, _) => Some(&data.trait_ref), + GenericBound::Trait(data) => Some(&data.trait_ref), _ => None, } } @@ -2874,11 +2874,7 @@ pub enum TyKind<'hir> { OpaqueDef(&'hir OpaqueTy<'hir>, &'hir [GenericArg<'hir>]), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. - TraitObject( - &'hir [(PolyTraitRef<'hir>, TraitBoundModifier)], - &'hir Lifetime, - TraitObjectSyntax, - ), + TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax), /// Unused for now. Typeof(&'hir AnonConst), /// `TyKind::Infer` means the type should be inferred instead of it having been @@ -3182,6 +3178,11 @@ pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], + /// The constness and polarity of the trait ref. + /// + /// The `async` modifier is lowered directly into a different trait for now. + pub modifiers: TraitBoundModifier, + /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`. pub trait_ref: TraitRef<'hir>, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 58916d058659..ffe519b0e7dd 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -905,7 +905,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul try_visit!(visitor.visit_array_length(length)); } TyKind::TraitObject(bounds, ref lifetime, _syntax) => { - for (bound, _modifier) in bounds { + for bound in bounds { try_visit!(visitor.visit_poly_trait_ref(bound)); } try_visit!(visitor.visit_lifetime(lifetime)); @@ -1160,7 +1160,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>( bound: &'v GenericBound<'v>, ) -> V::Result { match *bound { - GenericBound::Trait(ref typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Trait(ref typ) => visitor.visit_poly_trait_ref(typ), GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime), GenericBound::Use(args, _) => { walk_list!(visitor, visit_precise_capturing_arg, args); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3a9d2640eee9..1d78ea0c919e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -832,7 +832,7 @@ impl<'tcx> TypeVisitor> for GATArgsCollector<'tcx> { fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { match ty.kind { - hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments { + hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments { [s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()), _ => false, }, diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 6d30f7c7b9d0..a87b29b3093d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -866,7 +866,7 @@ impl<'tcx> ItemCtxt<'tcx> { #[instrument(level = "trace", skip(self))] fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool { match b { - hir::GenericBound::Trait(poly_trait_ref, _) => { + hir::GenericBound::Trait(poly_trait_ref) => { let trait_ref = &poly_trait_ref.trait_ref; if let Some(trait_did) = trait_ref.trait_def_id() { self.tcx.trait_may_define_assoc_item(trait_did, assoc_name) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c8852a3a3695..cb7f0901c7e4 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -644,7 +644,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { debug!(?bounds, ?lifetime, "TraitObject"); let scope = Scope::TraitRefBoundary { s: self.scope }; self.with(scope, |this| { - for (bound, _) in bounds { + for bound in bounds { this.visit_poly_trait_ref_inner( bound, NonLifetimeBinderAllowed::Deny("trait object types"), @@ -1918,7 +1918,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { return None; } predicate.bounds.iter().find_map(|bound| { - let hir::GenericBound::Trait(trait_, _) = bound else { + let hir::GenericBound::Trait(trait_) = bound else { return None; }; BoundVarContext::supertrait_hrtb_vars( 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 45cd46e3df29..8f7ca089c918 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -44,10 +44,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut unbounds: SmallVec<[_; 1]> = SmallVec::new(); let mut search_bounds = |hir_bounds: &'tcx [hir::GenericBound<'tcx>]| { for hir_bound in hir_bounds { - let hir::GenericBound::Trait(ptr, modifier) = hir_bound else { + let hir::GenericBound::Trait(ptr) = hir_bound else { continue; }; - match modifier { + match ptr.modifiers { hir::TraitBoundModifier::Maybe => unbounds.push(ptr), hir::TraitBoundModifier::Negative => { if let Some(sized_def_id) = sized_def_id @@ -156,8 +156,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { { for hir_bound in hir_bounds { match hir_bound { - hir::GenericBound::Trait(poly_trait_ref, modifier) => { - let (constness, polarity) = match modifier { + hir::GenericBound::Trait(poly_trait_ref) => { + let (constness, polarity) = match poly_trait_ref.modifiers { hir::TraitBoundModifier::Const => { (ty::BoundConstness::Const, ty::PredicatePolarity::Positive) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 394a263fbb59..98822eec2ac4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, span: Span, hir_id: hir::HirId, - hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)], + hir_trait_bounds: &[hir::PolyTraitRef<'tcx>], lifetime: &hir::Lifetime, representation: DynKind, ) -> Ty<'tcx> { @@ -39,8 +39,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let mut bounds = Bounds::default(); let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; - for (trait_bound, modifier) in hir_trait_bounds.iter().rev() { - if *modifier == hir::TraitBoundModifier::Maybe { + for trait_bound in hir_trait_bounds.iter().rev() { + // FIXME: This doesn't handle `? const`. + if trait_bound.modifiers == hir::TraitBoundModifier::Maybe { continue; } if let GenericArgCountResult { @@ -263,7 +264,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let args = tcx.mk_args(&args); let span = i.bottom().1; - let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| { + let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id) && hir_bound.span.contains(span) }); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index a735b8cc2a45..01768c89cca8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -718,7 +718,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, associated_types: FxIndexMap>, potential_assoc_types: Vec, - trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)], + trait_bounds: &[hir::PolyTraitRef<'_>], ) { if associated_types.values().all(|v| v.is_empty()) { return; @@ -764,12 +764,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // related to issue #91997, turbofishes added only when in an expr or pat let mut in_expr_or_pat = false; if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) { - let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.0.trait_ref.hir_ref_id)); + let grandparent = tcx.parent_hir_node(tcx.parent_hir_id(bound.trait_ref.hir_ref_id)); in_expr_or_pat = match grandparent { hir::Node::Expr(_) | hir::Node::Pat(_) => true, _ => false, }; - match bound.0.trait_ref.path.segments { + match bound.trait_ref.path.segments { // FIXME: `trait_ref.path.span` can point to a full path with multiple // segments, even though `trait_ref.path.segments` is of length `1`. Work // around that bug here, even though it should be fixed elsewhere. @@ -810,7 +810,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // and we can then use their span to indicate this to the user. let bound_names = trait_bounds .iter() - .filter_map(|(poly_trait_ref, _)| { + .filter_map(|poly_trait_ref| { let path = poly_trait_ref.trait_ref.path.segments.last()?; let args = path.args?; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 11c0450bfe21..fd49e7e44398 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -50,7 +50,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .ok() .is_some_and(|s| s.trim_end().ends_with('<')); - let is_global = poly_trait_ref.0.trait_ref.path.is_global(); + let is_global = poly_trait_ref.trait_ref.path.is_global(); let mut sugg = vec![( self_ty.span.shrink_to_lo(), @@ -211,7 +211,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Check if trait object is safe for suggesting dynamic dispatch. let is_dyn_compatible = match self_ty.kind { hir::TyKind::TraitObject(objects, ..) => { - objects.iter().all(|(o, _)| match o.trait_ref.path.res { + objects.iter().all(|o| match o.trait_ref.path.res { Res::Def(DefKind::Trait, id) => tcx.is_dyn_compatible(id), _ => false, }) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 9fe6a8ee3425..9ebfd4f15abd 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -301,16 +301,13 @@ impl<'a> State<'a> { self.word_space("dyn"); } let mut first = true; - for (bound, modifier) in bounds { + for bound in bounds { if first { first = false; } else { self.nbsp(); self.word_space("+"); } - if *modifier == TraitBoundModifier::Maybe { - self.word("?"); - } self.print_poly_trait_ref(bound); } if !lifetime.is_elided() { @@ -679,6 +676,10 @@ impl<'a> State<'a> { } fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) { + // FIXME: This isn't correct! + if t.modifiers == TraitBoundModifier::Maybe { + self.word("?"); + } self.print_formal_generic_params(t.bound_generic_params); self.print_trait_ref(&t.trait_ref); } @@ -2077,10 +2078,7 @@ impl<'a> State<'a> { } match bound { - GenericBound::Trait(tref, modifier) => { - if modifier == &TraitBoundModifier::Maybe { - self.word("?"); - } + GenericBound::Trait(tref) => { self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1df4d32f3cba..3e9e53261562 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -849,7 +849,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::FnRetTy::Return(hir_ty) => { if let hir::TyKind::OpaqueDef(op_ty, ..) = hir_ty.kind // FIXME: account for RPITIT. - && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds + && let [hir::GenericBound::Trait(trait_ref)] = op_ty.bounds && let Some(hir::PathSegment { args: Some(generic_args), .. }) = trait_ref.trait_ref.path.segments.last() && let [constraint] = generic_args.constraints @@ -1035,7 +1035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // extract all bounds from the source code using their spans let all_matching_bounds_strs = predicates_from_where .filter_map(|bound| match bound { - GenericBound::Trait(_, _) => { + GenericBound::Trait(_) => { self.tcx.sess.source_map().span_to_snippet(bound.span()).ok() } _ => None, diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index c0a01b0065ef..5a3666dcbd43 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -112,10 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) { let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return }; - for (bound, modifier) in &bounds[..] { + for bound in &bounds[..] { let def_id = bound.trait_ref.trait_def_id(); if def_id.is_some_and(|def_id| cx.tcx.is_lang_item(def_id, LangItem::Drop)) - && *modifier != hir::TraitBoundModifier::Maybe + // FIXME: ?Drop is not a thing. + && bound.modifiers != hir::TraitBoundModifier::Maybe { let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return }; cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id }); diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 354ca746b466..4f408ee15748 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -192,7 +192,8 @@ fn suggest_changing_unsized_bound( .iter() .enumerate() .filter(|(_, bound)| { - if let hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe) = bound + if let hir::GenericBound::Trait(poly) = bound + && poly.modifiers == hir::TraitBoundModifier::Maybe && poly.trait_ref.trait_def_id() == def_id { true diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs index 7a44c2ad661d..2ecd28f48681 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/find_anon_type.rs @@ -86,7 +86,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { } hir::TyKind::TraitObject(bounds, ..) => { - for (bound, _) in bounds { + for bound in bounds { self.current_index.shift_in(1); self.visit_poly_trait_ref(bound); self.current_index.shift_out(1); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index a6ecd1cc9871..8541621b23b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> { _, ) = t.kind { - for (ptr, _) in poly_trait_refs { + for ptr in poly_trait_refs { if Some(self.1) == ptr.trait_ref.trait_def_id() { self.0.push(ptr.span); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index cf0ab630f2e2..62204f63dd09 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -894,7 +894,9 @@ fn foo(&self) -> Self::T { String::new() } // FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting. let trait_bounds = bounds.iter().filter_map(|bound| match bound { - hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr), + hir::GenericBound::Trait(ptr) if ptr.modifiers == hir::TraitBoundModifier::None => { + Some(ptr) + } _ => None, }); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 709b6eb18e35..fc2d0ba36f04 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -740,9 +740,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match ( left, right, ) { - (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr)) + // FIXME: Suspicious + (hir::GenericBound::Trait(tl), hir::GenericBound::Trait(tr)) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id() - && ml == mr => + && tl.modifiers == tr.modifiers => { true } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index becc1acfb664..ba57909fc23a 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -439,7 +439,7 @@ pub fn report_dyn_incompatibility<'tcx>( if tcx.parent_hir_node(hir_id).fn_sig().is_some() { // Do not suggest `impl Trait` when dealing with things like super-traits. err.span_suggestion_verbose( - ty.span.until(trait_ref.0.span), + ty.span.until(trait_ref.span), "consider using an opaque type instead", "impl ", Applicability::MaybeIncorrect, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 87834c329e19..733baaa99e52 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3074,11 +3074,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { match ty.kind { hir::TyKind::TraitObject(traits, _, _) => { let (span, kw) = match traits { - [(first, _), ..] if first.span.lo() == ty.span.lo() => { + [first, ..] if first.span.lo() == ty.span.lo() => { // Missing `dyn` in front of trait object. (ty.span.shrink_to_lo(), "dyn ") } - [(first, _), ..] => (ty.span.until(first.span), ""), + [first, ..] => (ty.span.until(first.span), ""), [] => span_bug!(ty.span, "trait object with no traits: {ty:?}"), }; let needs_parens = traits.len() != 1; @@ -5162,7 +5162,7 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>( let async_span = tcx.sess.source_map().span_extend_while_whitespace(async_span); let future = tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty(); - let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else { + let [hir::GenericBound::Trait(trait_ref)] = future.bounds else { // `async fn` should always lower to a single bound... but don't ICE. return None; }; diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index 45e7de942fb6..364a13b3a759 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -125,7 +125,7 @@ fn sized_trait_bound_spans<'tcx>( bounds: hir::GenericBounds<'tcx>, ) -> impl 'tcx + Iterator { bounds.iter().filter_map(move |b| match b { - hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + hir::GenericBound::Trait(trait_ref) if trait_has_sized_self( tcx, trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fa73733360ca..1ddad917b783 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -214,15 +214,15 @@ fn clean_generic_bound<'tcx>( ) -> Option { Some(match *bound { hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)), - hir::GenericBound::Trait(ref t, modifier) => { + hir::GenericBound::Trait(ref t) => { // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op. - if modifier == hir::TraitBoundModifier::MaybeConst + if t.modifiers == hir::TraitBoundModifier::MaybeConst && cx.tcx.lang_items().destruct_trait() == Some(t.trait_ref.trait_def_id().unwrap()) { return None; } - GenericBound::TraitBound(clean_poly_trait_ref(t, cx), modifier) + GenericBound::TraitBound(clean_poly_trait_ref(t, cx), t.modifiers) } hir::GenericBound::Use(args, ..) => { GenericBound::Use(args.iter().map(|arg| arg.name()).collect()) @@ -1833,7 +1833,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Path(_) => clean_qpath(ty, cx), TyKind::TraitObject(bounds, lifetime, _) => { - let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect(); + let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect(); let lifetime = if !lifetime.is_elided() { Some(clean_lifetime(lifetime, cx)) } else { None }; DynTrait(bounds, lifetime) diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs index 5f349d780537..590d9afd1b43 100644 --- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs +++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs @@ -242,7 +242,8 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds bounds .iter() .filter_map(|bound| { - if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound + if let GenericBound::Trait(poly_trait) = bound + && let TraitBoundModifier::None = poly_trait.modifiers && let [.., path] = poly_trait.trait_ref.path.segments && poly_trait.bound_generic_params.is_empty() && let Some(trait_def_id) = path.res.opt_def_id() @@ -307,7 +308,8 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) { // This involves some extra logic when generic arguments are present, since // simply comparing trait `DefId`s won't be enough. We also need to compare the generics. for (index, bound) in bounds.iter().enumerate() { - if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound + if let GenericBound::Trait(poly_trait) = bound + && let TraitBoundModifier::None = poly_trait.modifiers && let [.., path] = poly_trait.trait_ref.path.segments && let implied_args = path.args.map_or([].as_slice(), |a| a.args) && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints) diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 311bbce14bd7..035ee40348c7 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -310,7 +310,7 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<& if let ty::Alias(_, alias_ty) = ty.kind() && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id) && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin - && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds + && let [GenericBound::Trait(trait_ref)] = &opaque.bounds && let Some(segment) = trait_ref.trait_ref.path.segments.last() && let Some(generic_args) = segment.args && let [constraint] = generic_args.constraints diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index ec28671a061e..a7c48eb216aa 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -163,7 +163,7 @@ fn check_fn_inner<'tcx>( if visitor.lts.iter().any(|lt| matches!(lt.res, LifetimeName::Param(_))) { return; } - if let GenericBound::Trait(ref trait_ref, _) = *bound { + if let GenericBound::Trait(ref trait_ref) = *bound { let params = &trait_ref .trait_ref .path @@ -438,7 +438,7 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> { if !lt.is_elided() { self.unelided_trait_object_lifetime = true; } - for (bound, _) in bounds { + for bound in bounds { self.visit_poly_trait_ref(bound); } }, diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index 81115cffdca8..67255c1af793 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -107,7 +107,7 @@ fn future_trait_ref<'tcx>( ) -> Option<(&'tcx TraitRef<'tcx>, Vec)> { if let TyKind::OpaqueDef(opaque, bounds) = ty.kind && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| { - if let GenericBound::Trait(poly, _) = bound { + if let GenericBound::Trait(poly) = bound { Some(&poly.trait_ref) } else { None diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs index bb44ff37b203..a56024f08d50 100644 --- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs +++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs @@ -40,7 +40,6 @@ struct Bound<'tcx> { ident: Ident, trait_bound: &'tcx PolyTraitRef<'tcx>, - modifier: TraitBoundModifier, predicate_pos: usize, bound_pos: usize, @@ -65,11 +64,10 @@ fn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator Some(Bound { + &GenericBound::Trait(ref trait_bound) => Some(Bound { param, ident, trait_bound, - modifier, predicate_pos, bound_pos, }), @@ -120,13 +118,13 @@ impl LateLintPass<'_> for NeedlessMaybeSized { let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics) .filter(|bound| { bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait) - && bound.modifier == TraitBoundModifier::Maybe + && bound.trait_bound.modifiers == TraitBoundModifier::Maybe }) .map(|bound| (bound.param, bound)) .collect(); for bound in type_param_bounds(generics) { - if bound.modifier == TraitBoundModifier::None + if bound.trait_bound.modifiers == TraitBoundModifier::None && let Some(sized_bound) = maybe_sized_params.get(&bound.param) && let Some(path) = path_to_sized_bound(cx, bound.trait_bound) { diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 3c3973857e79..38befdee5747 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -182,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { // Iterate the bounds and add them to our seen hash // If we haven't yet seen it, add it to the fixed traits - for (bound, _) in bounds { + for bound in bounds { let Some(def_id) = bound.trait_ref.trait_def_id() else { continue; }; @@ -197,9 +197,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { // If the number of unique traits isn't the same as the number of traits in the bounds, // there must be 1 or more duplicates if bounds.len() != unique_traits.len() { - let mut bounds_span = bounds[0].0.span; + let mut bounds_span = bounds[0].span; - for (bound, _) in bounds.iter().skip(1) { + for bound in bounds.iter().skip(1) { bounds_span = bounds_span.to(bound.span); } @@ -229,7 +229,8 @@ impl TraitBounds { /// this MSRV? See for details. fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool { if !self.msrv.meets(msrvs::MAYBE_BOUND_IN_WHERE) - && let GenericBound::Trait(tr, TraitBoundModifier::Maybe) = bound + && let GenericBound::Trait(tr) = bound + && let TraitBoundModifier::Maybe = tr.modifiers { cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id() } else { @@ -375,11 +376,11 @@ impl Default for ComparableTraitRef { } fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> { - if let GenericBound::Trait(t, tbm) = bound { + if let GenericBound::Trait(t) = bound { let trait_path = t.trait_ref.path; let trait_span = { let path_span = trait_path.span; - if let TraitBoundModifier::Maybe = tbm { + if let TraitBoundModifier::Maybe = t.modifiers { path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?` } else { path_span @@ -430,7 +431,7 @@ fn rollup_traits( let mut repeated_res = false; let only_comparable_trait_refs = |bound: &GenericBound<'_>| { - if let GenericBound::Trait(t, _) = bound { + if let GenericBound::Trait(t) = bound { Some((into_comparable_trait_ref(&t.trait_ref), t.span)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 2fcfc71a8c76..eb7ffbbe360d 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -82,7 +82,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m // Returns true if given type is `Any` trait. fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool { if let TyKind::TraitObject(traits, ..) = t.kind { - return traits.iter().any(|(bound, _)| { + return traits.iter().any(|bound| { if let Some(trait_did) = bound.trait_ref.trait_def_id() && cx.tcx.is_diagnostic_item(sym::Any, trait_did) { diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs index 0b64fddb447b..b89bd6a8d058 100644 --- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs @@ -55,7 +55,6 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor { TyKind::TraitObject(param_bounds, _, _) => { let has_lifetime_parameters = param_bounds.iter().any(|bound| { bound - .0 .bound_generic_params .iter() .any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) From 95dba280b9e471fc2dce93195d3b6f4aeb31279c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Oct 2024 09:31:22 -0400 Subject: [PATCH 057/118] Move trait bound modifiers into ast::PolyTraitRef --- compiler/rustc_ast/src/ast.rs | 21 ++++++-- compiler/rustc_ast/src/mut_visit.rs | 4 +- compiler/rustc_ast/src/util/classify.rs | 2 +- compiler/rustc_ast/src/visit.rs | 4 +- compiler/rustc_ast_lowering/src/item.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 15 +++--- .../rustc_ast_passes/src/ast_validation.rs | 16 ++++--- compiler/rustc_ast_pretty/src/pprust/state.rs | 48 +++++++++---------- .../src/deriving/smart_ptr.rs | 10 ++-- compiler/rustc_expand/src/build.rs | 21 ++++---- .../rustc_parse/src/parser/diagnostics.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 4 +- compiler/rustc_parse/src/parser/ty.rs | 14 ++++-- .../rustc_resolve/src/late/diagnostics.rs | 37 +++++++------- .../clippy/clippy_utils/src/ast_utils.rs | 5 +- src/tools/rustfmt/src/spanned.rs | 2 +- src/tools/rustfmt/src/types.rs | 12 ++--- 17 files changed, 118 insertions(+), 103 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 937031324f57..883391a2b60e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -308,7 +308,7 @@ impl TraitBoundModifiers { #[derive(Clone, Encodable, Decodable, Debug)] pub enum GenericBound { - Trait(PolyTraitRef, TraitBoundModifiers), + Trait(PolyTraitRef), Outlives(Lifetime), /// Precise capturing syntax: `impl Sized + use<'a>` Use(ThinVec, Span), @@ -1213,10 +1213,12 @@ impl Expr { pub fn to_bound(&self) -> Option { match &self.kind { - ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(ThinVec::new(), path.clone(), self.span), + ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new( + ThinVec::new(), + path.clone(), TraitBoundModifiers::NONE, - )), + self.span, + ))), _ => None, } } @@ -2965,6 +2967,9 @@ pub struct PolyTraitRef { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: ThinVec, + // Optional constness, asyncness, or polarity. + pub modifiers: TraitBoundModifiers, + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, @@ -2972,9 +2977,15 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(generic_params: ThinVec, path: Path, span: Span) -> Self { + pub fn new( + generic_params: ThinVec, + path: Path, + modifiers: TraitBoundModifiers, + span: Span, + ) -> Self { PolyTraitRef { bound_generic_params: generic_params, + modifiers, trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, span, } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 1a7da46913d7..b03c8aaa53b9 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -913,7 +913,7 @@ fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { - GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), + GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), GenericBound::Use(args, span) => { for arg in args { @@ -1034,7 +1034,7 @@ fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut Tr } fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, trait_ref, span } = p; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p; bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index a517f17c82c3..695ebd168ee0 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -263,7 +263,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> { ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => { match bounds.last() { - Some(ast::GenericBound::Trait(bound, _)) => { + Some(ast::GenericBound::Trait(bound)) => { match path_return_type(&bound.trait_ref.path) { Some(trailing_ty) => ty = trailing_ty, None => break None, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4dcadb8517eb..6593d5dbb5c5 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) where V: Visitor<'a>, { - let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref; + let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref; walk_list!(visitor, visit_generic_param, bound_generic_params); visitor.visit_trait_ref(trait_ref) } @@ -720,7 +720,7 @@ impl WalkItemKind for ForeignItemKind { pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { match bound { - GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref), GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), GenericBound::Use(args, _span) => { walk_list!(visitor, visit_precise_capturing_arg, args); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 1273b50dff81..ce744cc56e1a 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> { for bound in &bound_pred.bounds { if !matches!( *bound, - GenericBound::Trait(_, TraitBoundModifiers { - polarity: BoundPolarity::Maybe(_), + GenericBound::Trait(PolyTraitRef { + modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. }, .. }) ) { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b19ccc59a710..cc15a48ddc6a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1219,11 +1219,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let bound = this.lower_poly_trait_ref( &PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: TraitBoundModifiers::NONE, trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, span: t.span, }, itctx, - TraitBoundModifiers::NONE, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1325,8 +1325,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // We can safely ignore constness here since AST validation // takes care of rejecting invalid modifier combinations and // const trait bounds in trait object types. - GenericBound::Trait(ty, modifiers) => { - let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers); + GenericBound::Trait(ty) => { + let trait_ref = this.lower_poly_trait_ref(ty, itctx); Some(trait_ref) } GenericBound::Outlives(lifetime) => { @@ -1974,9 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext, ) -> hir::GenericBound<'hir> { match tpb { - GenericBound::Trait(p, modifiers) => { - hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx, *modifiers)) - } + GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)), GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(self.lower_lifetime(lifetime)) } @@ -2180,12 +2178,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &mut self, p: &PolyTraitRef, itctx: ImplTraitContext, - modifiers: ast::TraitBoundModifiers, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx); - let modifiers = self.lower_trait_bound_modifiers(modifiers); + let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx); + let modifiers = self.lower_trait_bound_modifiers(p.modifiers); hir::PolyTraitRef { bound_generic_params, modifiers, diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 87e3a6871b9e..40276a13eeb8 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1260,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if !bound_pred.bound_generic_params.is_empty() { for bound in &bound_pred.bounds { match bound { - GenericBound::Trait(t, _) => { + GenericBound::Trait(t) => { if !t.bound_generic_params.is_empty() { self.dcx() .emit_err(errors::NestedLifetimes { span: t.span }); @@ -1280,8 +1280,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { match bound { - GenericBound::Trait(trait_ref, modifiers) => { - match (ctxt, modifiers.constness, modifiers.polarity) { + GenericBound::Trait(trait_ref) => { + match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) { (BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) if !self.features.more_maybe_bounds => { @@ -1321,7 +1321,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } // Negative trait bounds are not allowed to have associated constraints - if let BoundPolarity::Negative(_) = modifiers.polarity + if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity && let Some(segment) = trait_ref.trait_ref.path.segments.last() { match segment.args.as_deref() { @@ -1669,7 +1669,9 @@ fn deny_equality_constraints( }), ) { for bound in bounds { - if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { if full_path.segments[..full_path.segments.len() - 1] .iter() .map(|segment| segment.ident.name) @@ -1697,7 +1699,9 @@ fn deny_equality_constraints( ) { if ident == potential_param.ident { for bound in bounds { - if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound { + if let ast::GenericBound::Trait(poly) = bound + && poly.modifiers == TraitBoundModifiers::NONE + { suggest(poly, potential_assoc, predicate); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 44a5a2d0baf2..f1f2784ad605 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -8,7 +8,6 @@ mod item; use std::borrow::Cow; -use ast::TraitBoundModifiers; use rustc_ast::attr::AttrIdGenerator; use rustc_ast::ptr::P; use rustc_ast::token::{ @@ -1253,6 +1252,27 @@ impl<'a> State<'a> { fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) { self.print_formal_generic_params(&t.bound_generic_params); + + let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers; + match constness { + ast::BoundConstness::Never => {} + ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { + self.word_space(constness.as_str()); + } + } + match asyncness { + ast::BoundAsyncness::Normal => {} + ast::BoundAsyncness::Async(_) => { + self.word_space(asyncness.as_str()); + } + } + match polarity { + ast::BoundPolarity::Positive => {} + ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { + self.word(polarity.as_str()); + } + } + self.print_trait_ref(&t.trait_ref) } @@ -1740,31 +1760,7 @@ impl<'a> State<'a> { } match bound { - GenericBound::Trait( - tref, - TraitBoundModifiers { constness, asyncness, polarity }, - ) => { - match constness { - ast::BoundConstness::Never => {} - ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => { - self.word_space(constness.as_str()); - } - } - - match asyncness { - ast::BoundAsyncness::Normal => {} - ast::BoundAsyncness::Async(_) => { - self.word_space(asyncness.as_str()); - } - } - - match polarity { - ast::BoundPolarity::Positive => {} - ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => { - self.word(polarity.as_str()); - } - } - + GenericBound::Trait(tref) => { self.print_poly_trait_ref(tref); } GenericBound::Outlives(lt) => self.print_lifetime(*lt), diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs index e3878d90e414..731945f5cbfb 100644 --- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs +++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs @@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: } fn is_maybe_sized_bound(bound: &GenericBound) -> bool { - if let GenericBound::Trait( - trait_ref, - TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. }, - ) = bound + if let GenericBound::Trait(trait_ref) = bound + && let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } = + trait_ref.modifiers + && is_sized_marker(&trait_ref.trait_ref.path) { - is_sized_marker(&trait_ref.trait_ref.path) + true } else { false } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b5945759d43a..2c1ee004e1d6 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } } - pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers { + polarity: ast::BoundPolarity::Positive, + constness: if is_const { + ast::BoundConstness::Maybe(DUMMY_SP) + } else { + ast::BoundConstness::Never + }, + asyncness: ast::BoundAsyncness::Normal, + }, trait_ref: self.trait_ref(path), span, } } pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound { - ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers { - polarity: ast::BoundPolarity::Positive, - constness: if is_const { - ast::BoundConstness::Maybe(DUMMY_SP) - } else { - ast::BoundConstness::Never - }, - asyncness: ast::BoundAsyncness::Normal, - }) + ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const)) } pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f32307f6ed4d..a9384501547e 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> { && let Some(poly) = bounds .iter() .filter_map(|bound| match bound { - ast::GenericBound::Trait(poly, _) => Some(poly), + ast::GenericBound::Trait(poly) => Some(poly), _ => None, }) .last() diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 162ff3b94de5..2f19a9b6b20b 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -948,8 +948,8 @@ impl<'a> Parser<'a> { { return Ok((false, seg.ident, seg.args.as_deref().cloned())); } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind - && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] = - bounds.as_slice() + && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice() + && trait_ref.modifiers == ast::TraitBoundModifiers::NONE && let [seg] = trait_ref.trait_ref.path.segments.as_slice() { return Ok((true, seg.ident, seg.args.as_deref().cloned())); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 625a4cabdf27..6820ccaa18b0 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -419,8 +419,13 @@ impl<'a> Parser<'a> { lo: Span, parse_plus: bool, ) -> PResult<'a, TyKind> { - let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span)); - let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)]; + let poly_trait_ref = PolyTraitRef::new( + generic_params, + path, + TraitBoundModifiers::NONE, + lo.to(self.prev_token.span), + ); + let bounds = vec![GenericBound::Trait(poly_trait_ref)]; self.parse_remaining_bounds(bounds, parse_plus) } @@ -1085,8 +1090,9 @@ impl<'a> Parser<'a> { } } - let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span)); - Ok(GenericBound::Trait(poly_trait, modifiers)) + let poly_trait = + PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span)); + Ok(GenericBound::Trait(poly_trait)) } // recovers a `Fn(..)` parenthesized-style path from `fn(..)` diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fce5ec36c661..5fbc817b91a7 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { continue; }; for bound in bounds { - let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound - else { + let ast::GenericBound::Trait(trait_ref) = bound else { continue; }; - if base_error.span == trait_ref.span { + if trait_ref.modifiers == ast::TraitBoundModifiers::NONE + && base_error.span == trait_ref.span + { err.span_suggestion_verbose( constraint.ident.span.between(trait_ref.span), "you might have meant to write a path instead of an associated type bound", @@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ); if bounds.iter().all(|bound| match bound { ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true, - ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, + ast::GenericBound::Trait(tr) => tr.span == base_error.span, }) { let mut sugg = vec![]; if base_error.span != start_span { @@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let param = generics.params.iter().find_map(|param| { // Only consider type params with exactly one trait bound. if let [bound] = &*param.bounds - && let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound + && let ast::GenericBound::Trait(tref) = bound + && tref.modifiers == ast::TraitBoundModifiers::NONE && tref.span == span && param.ident.span.eq_ctxt(span) { @@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } if let ( [ast::PathSegment { args: None, .. }], - [ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)], + [ast::GenericBound::Trait(poly_trait_ref)], ) = (&type_param_path.segments[..], &bounds[..]) + && poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE { if let [ast::PathSegment { ident, args: None, .. }] = &poly_trait_ref.trait_ref.path.segments[..] @@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { && bounded_ty.id == binder { for bound in bounds { - if let ast::GenericBound::Trait(poly_trait_ref, _) = bound + if let ast::GenericBound::Trait(poly_trait_ref) = bound && let span = poly_trait_ref .span .with_hi(poly_trait_ref.trait_ref.path.span.lo()) @@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let mut lt_finder = LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] }; for bound in arg_refs { - if let ast::GenericBound::Trait(trait_ref, _) = bound { + if let ast::GenericBound::Trait(trait_ref) = bound { lt_finder.visit_trait_ref(&trait_ref.trait_ref); } } @@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate( span: DUMMY_SP, bound_generic_params: ThinVec::new(), bounded_ty: ast::ptr::P(ty.clone()), - bounds: vec![ast::GenericBound::Trait( - ast::PolyTraitRef { - bound_generic_params: ThinVec::new(), - trait_ref: ast::TraitRef { - path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, - ref_id: DUMMY_NODE_ID, - }, - span: DUMMY_SP, + bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef { + bound_generic_params: ThinVec::new(), + modifiers: ast::TraitBoundModifiers::NONE, + trait_ref: ast::TraitRef { + path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None }, + ref_id: DUMMY_NODE_ID, }, - ast::TraitBoundModifiers::NONE, - )], + span: DUMMY_SP, + })], }; Some(new_where_bound_predicate) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 68f74e52ed7b..315856984751 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -783,7 +783,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool { } pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool { - eq_path(&l.trait_ref.path, &r.trait_ref.path) + l.modifiers == r.modifiers + && eq_path(&l.trait_ref.path, &r.trait_ref.path) && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| { eq_generic_param(l, r) }) @@ -817,7 +818,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { use GenericBound::*; match (l, r) { - (Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2), + (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2), (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident), _ => false, } diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 555a92407987..4d684f3c6350 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg { impl Spanned for ast::GenericBound { fn span(&self) -> Span { match *self { - ast::GenericBound::Trait(ref ptr, _) => ptr.span, + ast::GenericBound::Trait(ref ptr) => ptr.span, ast::GenericBound::Outlives(ref l) => l.ident.span, ast::GenericBound::Use(_, span) => span, } diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index f75c4f0fad74..a7bd8312bb8d 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound { fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { match *self { - ast::GenericBound::Trait( - ref poly_trait_ref, - ast::TraitBoundModifiers { + ast::GenericBound::Trait(ref poly_trait_ref) => { + let snippet = context.snippet(self.span()); + let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + let ast::TraitBoundModifiers { constness, asyncness, polarity, - }, - ) => { - let snippet = context.snippet(self.span()); - let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); + } = poly_trait_ref.modifiers; let mut constness = constness.as_str().to_string(); if !constness.is_empty() { constness.push(' '); From 67b85e2a1f4e7632e5805fcc6e6a6f53501dd357 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 14 Oct 2024 16:37:54 +0200 Subject: [PATCH 058/118] Add fast-path when computing the default visibility --- compiler/rustc_monomorphize/src/partitioning.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 5bd484d7bb00..9bf7e67417ef 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -119,6 +119,7 @@ use rustc_middle::util::Providers; use rustc_session::CodegenUnits; use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath}; use rustc_span::symbol::Symbol; +use rustc_target::spec::SymbolVisibility; use tracing::debug; use crate::collector::{self, MonoItemCollectionStrategy, UsageMap}; @@ -904,6 +905,11 @@ fn mono_item_visibility<'tcx>( } fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility { + // Fast-path to avoid expensive query call below + if tcx.sess.default_visibility() == SymbolVisibility::Interposable { + return Visibility::Default; + } + let export_level = if is_generic { // Generic functions never have export-level C. SymbolExportLevel::Rust @@ -913,6 +919,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit _ => SymbolExportLevel::Rust, } }; + match export_level { // C-export level items remain at `Default` to allow C code to // access and interpose them. From 73fc00ff8c497af386cce222fe467371dc335885 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Oct 2024 17:51:08 +0200 Subject: [PATCH 059/118] Delay ambiguous intra-doc link resolution after `Cache` has been populated --- src/librustdoc/clean/types.rs | 13 +- src/librustdoc/core.rs | 24 +- .../passes/calculate_doc_coverage.rs | 2 +- .../passes/check_doc_test_visibility.rs | 2 +- .../passes/collect_intra_doc_links.rs | 260 +++++++++++++++--- src/librustdoc/passes/collect_trait_impls.rs | 2 +- src/librustdoc/passes/lint.rs | 2 +- src/librustdoc/passes/mod.rs | 2 +- src/librustdoc/passes/propagate_doc_cfg.rs | 2 +- src/librustdoc/passes/propagate_stability.rs | 2 +- .../passes/strip_aliased_non_local.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- src/librustdoc/passes/strip_priv_imports.rs | 2 +- src/librustdoc/passes/strip_private.rs | 2 +- 14 files changed, 263 insertions(+), 56 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bc5bf4c05838..44d9a5fdbe8a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1228,15 +1228,14 @@ impl Attributes { for attr in self.other_attrs.lists(sym::doc).filter(|a| a.has_name(sym::alias)) { if let Some(values) = attr.meta_item_list() { for l in values { - match l.lit().unwrap().kind { - ast::LitKind::Str(s, _) => { - aliases.insert(s); - } - _ => unreachable!(), + if let Some(lit) = l.lit() + && let ast::LitKind::Str(s, _) = lit.kind + { + aliases.insert(s); } } - } else { - aliases.insert(attr.value_str().unwrap()); + } else if let Some(value) = attr.value_str() { + aliases.insert(value); } } aliases.into_iter().collect::>().into() diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index aaf4c80f9976..9bebe1fb4c1d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -29,8 +29,9 @@ use crate::clean::inline::build_external_trait; use crate::clean::{self, ItemId}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; +use crate::passes; use crate::passes::Condition::*; -use crate::passes::{self}; +use crate::passes::collect_intra_doc_links::LinkCollector; pub(crate) struct DocContext<'tcx> { pub(crate) tcx: TyCtxt<'tcx>, @@ -427,6 +428,9 @@ pub(crate) fn run_global_ctxt( info!("Executing passes"); + let mut visited = FxHashMap::default(); + let mut ambiguous = FxIndexMap::default(); + for p in passes::defaults(show_coverage) { let run = match p.condition { Always => true, @@ -436,18 +440,30 @@ pub(crate) fn run_global_ctxt( }; if run { debug!("running pass {}", p.pass.name); - krate = tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &mut ctxt)); + if let Some(run_fn) = p.pass.run { + krate = tcx.sess.time(p.pass.name, || run_fn(krate, &mut ctxt)); + } else { + let (k, LinkCollector { visited_links, ambiguous_links, .. }) = + passes::collect_intra_doc_links::collect_intra_doc_links(krate, &mut ctxt); + krate = k; + visited = visited_links; + ambiguous = ambiguous_links; + } } } tcx.sess.time("check_lint_expectations", || tcx.check_expectations(Some(sym::rustdoc))); + krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate)); + + let mut collector = + LinkCollector { cx: &mut ctxt, visited_links: visited, ambiguous_links: ambiguous }; + collector.resolve_ambiguities(); + if let Some(guar) = tcx.dcx().has_errors() { return Err(guar); } - krate = tcx.sess.time("create_format_cache", || Cache::populate(&mut ctxt, krate)); - Ok((krate, ctxt.render_options, ctxt.cache)) } diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index abea5bcbc51e..d27e737764dc 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -20,7 +20,7 @@ use crate::visit::DocVisitor; pub(crate) const CALCULATE_DOC_COVERAGE: Pass = Pass { name: "calculate-doc-coverage", - run: calculate_doc_coverage, + run: Some(calculate_doc_coverage), description: "counts the number of items with and without documentation", }; diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 1dc9af7ebe59..f4579d855315 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -20,7 +20,7 @@ use crate::visit::DocVisitor; pub(crate) const CHECK_DOC_TEST_VISIBILITY: Pass = Pass { name: "check_doc_test_visibility", - run: check_doc_test_visibility, + run: Some(check_doc_test_visibility), description: "run various visibility-related lints on doctests", }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index db235786cf49..81e7bcbd7d87 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -9,12 +9,12 @@ use std::ops::Range; use pulldown_cmark::LinkType; use rustc_ast::util::comments::may_have_doc_links; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::{Applicability, Diag, DiagMessage}; use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, Namespace, PerNS}; -use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; +use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE}; use rustc_hir::{Mutability, Safety}; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; @@ -30,23 +30,27 @@ use smallvec::{SmallVec, smallvec}; use tracing::{debug, info, instrument, trace}; use crate::clean::utils::find_nearest_parent_module; -use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType}; +use crate::clean::{self, Crate, Item, ItemId, ItemLink, PrimitiveType}; use crate::core::DocContext; use crate::html::markdown::{MarkdownLink, MarkdownLinkRange, markdown_links}; use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS}; use crate::passes::Pass; use crate::visit::DocVisitor; -pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = Pass { - name: "collect-intra-doc-links", - run: collect_intra_doc_links, - description: "resolves intra-doc links", -}; +pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = + Pass { name: "collect-intra-doc-links", run: None, description: "resolves intra-doc links" }; -fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate { - let mut collector = LinkCollector { cx, visited_links: FxHashMap::default() }; +pub(crate) fn collect_intra_doc_links<'a, 'tcx>( + krate: Crate, + cx: &'a mut DocContext<'tcx>, +) -> (Crate, LinkCollector<'a, 'tcx>) { + let mut collector = LinkCollector { + cx, + visited_links: FxHashMap::default(), + ambiguous_links: FxIndexMap::default(), + }; collector.visit_crate(&krate); - krate + (krate, collector) } fn filter_assoc_items_by_name_and_namespace<'a>( @@ -61,7 +65,7 @@ fn filter_assoc_items_by_name_and_namespace<'a>( } #[derive(Copy, Clone, Debug, Hash, PartialEq)] -enum Res { +pub(crate) enum Res { Def(DefKind, DefId), Primitive(PrimitiveType), } @@ -234,7 +238,7 @@ impl UrlFragment { } #[derive(Clone, Debug, Hash, PartialEq, Eq)] -struct ResolutionInfo { +pub(crate) struct ResolutionInfo { item_id: DefId, module_id: DefId, dis: Option, @@ -243,18 +247,63 @@ struct ResolutionInfo { } #[derive(Clone)] -struct DiagnosticInfo<'a> { +pub(crate) struct DiagnosticInfo<'a> { item: &'a Item, dox: &'a str, ori_link: &'a str, link_range: MarkdownLinkRange, } -struct LinkCollector<'a, 'tcx> { - cx: &'a mut DocContext<'tcx>, +pub(crate) struct OwnedDiagnosticInfo { + item: Item, + dox: String, + ori_link: String, + link_range: MarkdownLinkRange, +} + +impl From> for OwnedDiagnosticInfo { + fn from(f: DiagnosticInfo<'_>) -> Self { + Self { + item: f.item.clone(), + dox: f.dox.to_string(), + ori_link: f.ori_link.to_string(), + link_range: f.link_range.clone(), + } + } +} + +impl OwnedDiagnosticInfo { + pub(crate) fn into_info(&self) -> DiagnosticInfo<'_> { + DiagnosticInfo { + item: &self.item, + ori_link: &self.ori_link, + dox: &self.dox, + link_range: self.link_range.clone(), + } + } +} + +pub(crate) struct LinkCollector<'a, 'tcx> { + pub(crate) cx: &'a mut DocContext<'tcx>, /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link. /// The link will be `None` if it could not be resolved (i.e. the error was cached). - visited_links: FxHashMap)>>, + pub(crate) visited_links: FxHashMap)>>, + /// These links are ambiguous. We need for the cache to have its paths filled. Unfortunately, + /// if we run the `LinkCollector` pass after `Cache::populate`, a lot of items that we need + /// to go through will be removed, making a lot of intra-doc links to not be inferred. + /// + /// So instead, we store the ambiguous links and we wait for cache paths to be filled before + /// inferring them (if possible). + /// + /// Key is `(item ID, path str)`. + pub(crate) ambiguous_links: FxIndexMap<(ItemId, String), Vec>, +} + +pub(crate) struct AmbiguousLinks { + disambiguator: Option, + link_text: Box, + diag_info: OwnedDiagnosticInfo, + resolved: Vec<(Res, Option)>, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { @@ -1001,6 +1050,10 @@ impl LinkCollector<'_, '_> { } } + pub(crate) fn save_link(&mut self, item_id: ItemId, link: ItemLink) { + self.cx.cache.intra_doc_links.entry(item_id).or_default().insert(link); + } + /// This is the entry point for resolving an intra-doc link. /// /// FIXME(jynelson): this is way too many arguments @@ -1024,7 +1077,7 @@ impl LinkCollector<'_, '_> { pp_link.as_ref().map_err(|err| err.report(self.cx, diag_info.clone())).ok()?; let disambiguator = *disambiguator; - let (mut res, fragment) = self.resolve_with_disambiguator_cached( + let mut resolved = self.resolve_with_disambiguator_cached( ResolutionInfo { item_id, module_id, @@ -1040,6 +1093,142 @@ impl LinkCollector<'_, '_> { false, )?; + if resolved.len() > 1 { + let links = AmbiguousLinks { + disambiguator, + link_text: link_text.clone(), + diag_info: diag_info.into(), + resolved, + }; + + self.ambiguous_links + .entry((item.item_id, path_str.to_string())) + .or_default() + .push(links); + None + } else if let Some((res, fragment)) = resolved.pop() { + self.compute_link(res, fragment, path_str, disambiguator, diag_info, link_text) + } else { + None + } + } + + /// Returns `true` if a link could be generated from the given intra-doc information. + /// + /// This is a very light version of `format::href_with_root_path` since we're only interested + /// about whether we can generate a link to an item or not. + /// + /// * If `original_did` is local, then we check if the item is reexported or public. + /// * If `original_did` is not local, then we check if the crate it comes from is a direct + /// public dependency. + fn validate_link(&self, original_did: DefId) -> bool { + let tcx = self.cx.tcx; + let def_kind = tcx.def_kind(original_did); + let did = match def_kind { + DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => { + // documented on their parent's page + tcx.parent(original_did) + } + // If this a constructor, we get the parent (either a struct or a variant) and then + // generate the link for this item. + DefKind::Ctor(..) => return self.validate_link(tcx.parent(original_did)), + DefKind::ExternCrate => { + // Link to the crate itself, not the `extern crate` item. + if let Some(local_did) = original_did.as_local() { + tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id() + } else { + original_did + } + } + _ => original_did, + }; + + let cache = &self.cx.cache; + if !original_did.is_local() + && !cache.effective_visibilities.is_directly_public(tcx, did) + && !cache.document_private + && !cache.primitive_locations.values().any(|&id| id == did) + { + return false; + } + + cache.paths.get(&did).is_some() + || cache.external_paths.get(&did).is_some() + || !did.is_local() + } + + #[allow(rustc::potential_query_instability)] + pub(crate) fn resolve_ambiguities(&mut self) { + let mut ambiguous_links = mem::take(&mut self.ambiguous_links); + + for ((item_id, path_str), info_items) in ambiguous_links.iter_mut() { + for info in info_items { + info.resolved.retain(|(res, _)| match res { + Res::Def(_, def_id) => self.validate_link(*def_id), + // Primitive types are always valid. + Res::Primitive(_) => true, + }); + let diag_info = info.diag_info.into_info(); + match info.resolved.len() { + 1 => { + let (res, fragment) = info.resolved.pop().unwrap(); + if let Some(link) = self.compute_link( + res, + fragment, + path_str, + info.disambiguator, + diag_info, + &info.link_text, + ) { + self.save_link(*item_id, link); + } + } + 0 => { + report_diagnostic( + self.cx.tcx, + BROKEN_INTRA_DOC_LINKS, + format!( + "all items matching `{path_str}` are either private or doc(hidden)" + ), + &diag_info, + |diag, sp, _| { + if let Some(sp) = sp { + diag.span_label(sp, "unresolved link"); + } else { + diag.note("unresolved link"); + } + }, + ); + } + _ => { + let candidates = info + .resolved + .iter() + .map(|(res, fragment)| { + let def_id = if let Some(UrlFragment::Item(def_id)) = fragment { + Some(*def_id) + } else { + None + }; + (*res, def_id) + }) + .collect::>(); + ambiguity_error(self.cx, &diag_info, path_str, &candidates, true); + } + } + } + } + } + + fn compute_link( + &mut self, + mut res: Res, + fragment: Option, + path_str: &str, + disambiguator: Option, + diag_info: DiagnosticInfo<'_>, + link_text: &Box, + ) -> Option { // Check for a primitive which might conflict with a module // Report the ambiguity and require that the user specify which one they meant. // FIXME: could there ever be a primitive not in the type namespace? @@ -1055,7 +1244,7 @@ impl LinkCollector<'_, '_> { } else { // `[char]` when a `char` module is in scope let candidates = &[(res, res.def_id(self.cx.tcx)), (prim, None)]; - ambiguity_error(self.cx, &diag_info, path_str, candidates); + ambiguity_error(self.cx, &diag_info, path_str, candidates, true); return None; } } @@ -1085,7 +1274,7 @@ impl LinkCollector<'_, '_> { } res.def_id(self.cx.tcx).map(|page_id| ItemLink { - link: Box::::from(&*ori_link.link), + link: Box::::from(&*diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1107,7 +1296,7 @@ impl LinkCollector<'_, '_> { let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); Some(ItemLink { - link: Box::::from(&*ori_link.link), + link: Box::::from(&*diag_info.ori_link), link_text: link_text.clone(), page_id, fragment, @@ -1220,10 +1409,10 @@ impl LinkCollector<'_, '_> { // If this call is intended to be recoverable, then pass true to silence. // This is only recoverable when path is failed to resolved. recoverable: bool, - ) -> Option<(Res, Option)> { + ) -> Option)>> { if let Some(res) = self.visited_links.get(&key) { if res.is_some() || cache_errors { - return res.clone(); + return res.clone().map(|r| vec![r]); } } @@ -1248,13 +1437,14 @@ impl LinkCollector<'_, '_> { // and after removing duplicated kinds, only one remains, the `ambiguity_error` function // won't emit an error. So at this point, we can just take the first candidate as it was // the first retrieved and use it to generate the link. - if let [candidate, _candidate2, ..] = *candidates - && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates) - { - candidates = vec![candidate]; + if let [candidate, _candidate2, ..] = *candidates { + if !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) { + candidates = vec![candidate]; + } } - if let &[(res, def_id)] = candidates.as_slice() { + let mut out = Vec::with_capacity(candidates.len()); + for (res, def_id) in candidates { let fragment = match (&key.extra_fragment, def_id) { (Some(_), Some(def_id)) => { report_anchor_conflict(self.cx, diag, def_id); @@ -1264,15 +1454,14 @@ impl LinkCollector<'_, '_> { (None, Some(def_id)) => Some(UrlFragment::Item(def_id)), (None, None) => None, }; - let r = Some((res, fragment)); - self.visited_links.insert(key, r.clone()); - return r; + out.push((res, fragment)); } - - if cache_errors { + if let [r] = out.as_slice() { + self.visited_links.insert(key, Some(r.clone())); + } else if cache_errors { self.visited_links.insert(key, None); } - None + Some(out) } /// After parsing the disambiguator, resolve the main part of the link. @@ -2046,6 +2235,7 @@ fn ambiguity_error( diag_info: &DiagnosticInfo<'_>, path_str: &str, candidates: &[(Res, Option)], + emit_error: bool, ) -> bool { let mut descrs = FxHashSet::default(); let kinds = candidates @@ -2061,6 +2251,8 @@ fn ambiguity_error( // There is no way for users to disambiguate at this point, so better return the first // candidate and not show a warning. return false; + } else if !emit_error { + return true; } let mut msg = format!("`{path_str}` is "); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index d1a1f0df3e7e..f35890803228 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -16,7 +16,7 @@ use crate::visit::DocVisitor; pub(crate) const COLLECT_TRAIT_IMPLS: Pass = Pass { name: "collect-trait-impls", - run: collect_trait_impls, + run: Some(collect_trait_impls), description: "retrieves trait impls for items in the crate", }; diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs index 593027ef7d29..35b62370abb2 100644 --- a/src/librustdoc/passes/lint.rs +++ b/src/librustdoc/passes/lint.rs @@ -14,7 +14,7 @@ use crate::core::DocContext; use crate::visit::DocVisitor; pub(crate) const RUN_LINTS: Pass = - Pass { name: "run-lints", run: run_lints, description: "runs some of rustdoc's lints" }; + Pass { name: "run-lints", run: Some(run_lints), description: "runs some of rustdoc's lints" }; struct Linter<'a, 'tcx> { cx: &'a mut DocContext<'tcx>, diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index f5b780237214..9ba63d34144a 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -47,7 +47,7 @@ pub(crate) use self::lint::RUN_LINTS; #[derive(Copy, Clone)] pub(crate) struct Pass { pub(crate) name: &'static str, - pub(crate) run: fn(clean::Crate, &mut DocContext<'_>) -> clean::Crate, + pub(crate) run: Option) -> clean::Crate>, pub(crate) description: &'static str, } diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 6be51dd15606..350be37f553d 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -13,7 +13,7 @@ use crate::passes::Pass; pub(crate) const PROPAGATE_DOC_CFG: Pass = Pass { name: "propagate-doc-cfg", - run: propagate_doc_cfg, + run: Some(propagate_doc_cfg), description: "propagates `#[doc(cfg(...))]` to child items", }; diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index f51e993bfa5d..f55479687f8e 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -16,7 +16,7 @@ use crate::passes::Pass; pub(crate) const PROPAGATE_STABILITY: Pass = Pass { name: "propagate-stability", - run: propagate_stability, + run: Some(propagate_stability), description: "propagates stability to child items", }; diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index 155ad5438314..a078eec048ec 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -8,7 +8,7 @@ use crate::passes::Pass; pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { name: "strip-aliased-non-local", - run: strip_aliased_non_local, + run: Some(strip_aliased_non_local), description: "strips all non-local private aliased items from the output", }; diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 430f3d8a574c..aba04283e59d 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -16,7 +16,7 @@ use crate::passes::{ImplStripper, Pass}; pub(crate) const STRIP_HIDDEN: Pass = Pass { name: "strip-hidden", - run: strip_hidden, + run: Some(strip_hidden), description: "strips all `#[doc(hidden)]` items from the output", }; diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs index 7b05756ae215..2e9f06bd0a30 100644 --- a/src/librustdoc/passes/strip_priv_imports.rs +++ b/src/librustdoc/passes/strip_priv_imports.rs @@ -8,7 +8,7 @@ use crate::passes::{ImportStripper, Pass}; pub(crate) const STRIP_PRIV_IMPORTS: Pass = Pass { name: "strip-priv-imports", - run: strip_priv_imports, + run: Some(strip_priv_imports), description: "strips all private import statements (`use`, `extern crate`) from a crate", }; diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 1bafa450be90..78f0ad277408 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -8,7 +8,7 @@ use crate::passes::{ImplStripper, ImportStripper, Pass, Stripper}; pub(crate) const STRIP_PRIVATE: Pass = Pass { name: "strip-private", - run: strip_private, + run: Some(strip_private), description: "strips all private items from a crate which cannot be seen externally, \ implies strip-priv-imports", }; From d540e7285ca14393d2b51f486ecc0f26d2f986c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Oct 2024 17:51:37 +0200 Subject: [PATCH 060/118] Add regression tests for #130233 --- .../intra-doc/filter-out-private-2.rs | 15 +++++++++++ .../intra-doc/filter-out-private-2.stderr | 14 ++++++++++ .../intra-doc/filter-out-private.rs | 13 ++++++++++ .../intra-doc/filter-out-private.stderr | 22 ++++++++++++++++ tests/rustdoc/intra-doc/filter-out-private.rs | 26 +++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private-2.rs create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private.rs create mode 100644 tests/rustdoc-ui/intra-doc/filter-out-private.stderr create mode 100644 tests/rustdoc/intra-doc/filter-out-private.rs diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs new file mode 100644 index 000000000000..9209203c99ee --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs @@ -0,0 +1,15 @@ +// This test ensures that ambiguities (not) resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +#[doc(hidden)] +pub struct Thing {} + +#[allow(non_snake_case)] +#[doc(hidden)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR all items matching `Thing` are either private or doc(hidden) +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr new file mode 100644 index 000000000000..394f919de943 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr @@ -0,0 +1,14 @@ +error: all items matching `Thing` are either private or doc(hidden) + --> $DIR/filter-out-private-2.rs:13:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ unresolved link + | +note: the lint level is defined here + --> $DIR/filter-out-private-2.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.rs b/tests/rustdoc-ui/intra-doc/filter-out-private.rs new file mode 100644 index 000000000000..f481b51dad06 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.rs @@ -0,0 +1,13 @@ +// This test ensures that ambiguities resolved at a later stage still emit an error. + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Thing {} + +#[allow(non_snake_case)] +pub fn Thing() {} + +/// Do stuff with [`Thing`]. +//~^ ERROR `Thing` is both a function and a struct +pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr new file mode 100644 index 000000000000..1d1830b1f1c3 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/filter-out-private.stderr @@ -0,0 +1,22 @@ +error: `Thing` is both a function and a struct + --> $DIR/filter-out-private.rs:11:21 + | +LL | /// Do stuff with [`Thing`]. + | ^^^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/filter-out-private.rs:3:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the function, add parentheses + | +LL | /// Do stuff with [`Thing()`]. + | ++ +help: to link to the struct, prefix with `struct@` + | +LL | /// Do stuff with [`struct@Thing`]. + | +++++++ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc/intra-doc/filter-out-private.rs b/tests/rustdoc/intra-doc/filter-out-private.rs new file mode 100644 index 000000000000..70591b120d82 --- /dev/null +++ b/tests/rustdoc/intra-doc/filter-out-private.rs @@ -0,0 +1,26 @@ +// This test ensures that private/hidden items don't create ambiguity. +// This is a regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Thing {} + +#[doc(hidden)] +#[allow(non_snake_case)] +pub fn Thing() {} + +pub struct Bar {} + +#[allow(non_snake_case)] +fn Bar() {} + +//@ has 'foo/fn.repro.html' +//@ has - '//*[@class="toggle top-doc"]/*[@class="docblock"]//a/@href' 'struct.Thing.html' +/// Do stuff with [`Thing`]. +pub fn repro(_: Thing) {} + +//@ has 'foo/fn.repro2.html' +//@ has - '//*[@class="toggle top-doc"]/*[@class="docblock"]//a/@href' 'struct.Bar.html' +/// Do stuff with [`Bar`]. +pub fn repro2(_: Bar) {} From f708d6de79a3e17074d03a641633e2f12972dc1a Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Mon, 14 Oct 2024 15:37:59 +0200 Subject: [PATCH 061/118] Fix match_same_arms in stable_mir --- compiler/stable_mir/src/mir/pretty.rs | 10 +++----- compiler/stable_mir/src/mir/visit.rs | 36 ++++++++++----------------- compiler/stable_mir/src/visitor.rs | 16 ++++++------ 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 74081af1d86d..d71d96804f3e 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -189,7 +189,9 @@ fn pretty_terminator_head(writer: &mut W, terminator: &TerminatorKind) fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec { use self::TerminatorKind::*; match terminator { - Resume | Abort | Return | Unreachable => vec![], + Call { target: None, unwind: UnwindAction::Cleanup(_), .. } + | InlineAsm { destination: None, .. } => vec!["unwind".into()], + Resume | Abort | Return | Unreachable | Call { target: None, unwind: _, .. } => vec![], Goto { .. } => vec!["".to_string()], SwitchInt { targets, .. } => targets .branches() @@ -197,19 +199,15 @@ fn pretty_successor_labels(terminator: &TerminatorKind) -> Vec { .chain(iter::once("otherwise".into())) .collect(), Drop { unwind: UnwindAction::Cleanup(_), .. } => vec!["return".into(), "unwind".into()], - Drop { unwind: _, .. } => vec!["return".into()], Call { target: Some(_), unwind: UnwindAction::Cleanup(_), .. } => { vec!["return".into(), "unwind".into()] } - Call { target: Some(_), unwind: _, .. } => vec!["return".into()], - Call { target: None, unwind: UnwindAction::Cleanup(_), .. } => vec!["unwind".into()], - Call { target: None, unwind: _, .. } => vec![], + Drop { unwind: _, .. } | Call { target: Some(_), unwind: _, .. } => vec!["return".into()], Assert { unwind: UnwindAction::Cleanup(_), .. } => { vec!["success".into(), "unwind".into()] } Assert { unwind: _, .. } => vec!["success".into()], InlineAsm { destination: Some(_), .. } => vec!["goto".into(), "unwind".into()], - InlineAsm { destination: None, .. } => vec!["unwind".into()], } } diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index e2d1ff7fdd3a..08fcfa01a06c 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -194,27 +194,17 @@ pub trait MirVisitor { self.visit_place(place, PlaceContext::MUTATING, location); self.visit_rvalue(rvalue, location); } - StatementKind::FakeRead(_, place) => { + StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => { self.visit_place(place, PlaceContext::NON_MUTATING, location); } - StatementKind::SetDiscriminant { place, .. } => { + StatementKind::SetDiscriminant { place, .. } + | StatementKind::Deinit(place) + | StatementKind::Retag(_, place) => { self.visit_place(place, PlaceContext::MUTATING, location); } - StatementKind::Deinit(place) => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - StatementKind::StorageLive(local) => { + StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { self.visit_local(local, PlaceContext::NON_USE, location); } - StatementKind::StorageDead(local) => { - self.visit_local(local, PlaceContext::NON_USE, location); - } - StatementKind::Retag(_, place) => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - StatementKind::PlaceMention(place) => { - self.visit_place(place, PlaceContext::NON_MUTATING, location); - } StatementKind::AscribeUserType { place, projections, variance: _ } => { self.visit_place(place, PlaceContext::NON_USE, location); self.visit_user_type_projection(projections); @@ -234,8 +224,7 @@ pub trait MirVisitor { self.visit_operand(count, location); } }, - StatementKind::ConstEvalCounter => {} - StatementKind::Nop => {} + StatementKind::ConstEvalCounter | StatementKind::Nop => {} } } @@ -304,14 +293,15 @@ pub trait MirVisitor { location: Location, ) { match elem { - ProjectionElem::Deref => {} + ProjectionElem::Downcast(_idx) => {} + ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } + | ProjectionElem::Deref + | ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), ProjectionElem::Index(local) => self.visit_local(local, ptx, location), - ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {} - ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} - ProjectionElem::Downcast(_idx) => {} - ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), - ProjectionElem::Subtype(ty) => self.visit_ty(ty, location), + ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => { + self.visit_ty(ty, location) + } } } diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 3c769b2d37cf..48260285408c 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -35,8 +35,7 @@ impl Visitable for Ty { match self.kind() { super::ty::TyKind::RigidTy(ty) => ty.visit(visitor)?, super::ty::TyKind::Alias(_, alias) => alias.args.visit(visitor)?, - super::ty::TyKind::Param(_) => {} - super::ty::TyKind::Bound(_, _) => {} + super::ty::TyKind::Param(_) | super::ty::TyKind::Bound(_, _) => {} } ControlFlow::Continue(()) } @@ -48,8 +47,7 @@ impl Visitable for TyConst { } fn super_visit(&self, visitor: &mut V) -> ControlFlow { match &self.kind { - crate::ty::TyConstKind::Param(_) => {} - crate::ty::TyConstKind::Bound(_, _) => {} + crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {} crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?, crate::ty::TyConstKind::Value(ty, alloc) => { alloc.visit(visitor)?; @@ -166,17 +164,17 @@ impl Visitable for RigidTy { reg.visit(visitor); ty.visit(visitor) } - RigidTy::FnDef(_, args) => args.visit(visitor), + RigidTy::Adt(_, args) + | RigidTy::Closure(_, args) + | RigidTy::Coroutine(_, args, _) + | RigidTy::CoroutineWitness(_, args) + | RigidTy::FnDef(_, args) => args.visit(visitor), RigidTy::FnPtr(sig) => sig.visit(visitor), - RigidTy::Closure(_, args) => args.visit(visitor), - RigidTy::Coroutine(_, args, _) => args.visit(visitor), - RigidTy::CoroutineWitness(_, args) => args.visit(visitor), RigidTy::Dynamic(pred, r, _) => { pred.visit(visitor)?; r.visit(visitor) } RigidTy::Tuple(fields) => fields.visit(visitor), - RigidTy::Adt(_, args) => args.visit(visitor), } } } From 5a8405a5fa55526af743a44abf9c57d1452afbaa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 14:18:13 -0400 Subject: [PATCH 062/118] Don't report on_unimplemented for negative traits --- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- .../traits/fulfillment_errors.rs | 2 +- .../traits/on_unimplemented.rs | 20 +++++++++++-------- .../negative-bounds/on-unimplemented.rs | 12 +++++++++++ .../negative-bounds/on-unimplemented.stderr | 18 +++++++++++++++++ 5 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 tests/ui/traits/negative-bounds/on-unimplemented.rs create mode 100644 tests/ui/traits/negative-bounds/on-unimplemented.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4f726f3ed386..0933e90f8ba2 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -952,7 +952,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } unimplemented_traits.entry(p.trait_ref.def_id).or_insert(( - predicate.kind().rebind(p.trait_ref), + predicate.kind().rebind(p), Obligation { cause: cause.clone(), param_env: self.param_env, diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 824c25db07d2..26b0faca2585 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -202,7 +202,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { notes, parent_label, append_const_msg, - } = self.on_unimplemented_note(main_trait_ref, o, &mut long_ty_file); + } = self.on_unimplemented_note(main_trait_predicate, o, &mut long_ty_file); let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id()); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index c3100c48b0aa..cd41ab9fa6cb 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::LintDiagnostic; use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; -use rustc_middle::ty::{self, GenericArgsRef, GenericParamDefKind, TyCtxt}; +use rustc_middle::ty::{self, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES; use rustc_span::Span; @@ -108,14 +108,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { pub fn on_unimplemented_note( &self, - trait_ref: ty::PolyTraitRef<'tcx>, + trait_pred: ty::PolyTraitPredicate<'tcx>, obligation: &PredicateObligation<'tcx>, long_ty_file: &mut Option, ) -> OnUnimplementedNote { + if trait_pred.polarity() != ty::PredicatePolarity::Positive { + return OnUnimplementedNote::default(); + } + let (def_id, args) = self - .impl_similar_to(trait_ref, obligation) - .unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().args)); - let trait_ref = trait_ref.skip_binder(); + .impl_similar_to(trait_pred.to_poly_trait_ref(), obligation) + .unwrap_or_else(|| (trait_pred.def_id(), trait_pred.skip_binder().trait_ref.args)); + let trait_pred = trait_pred.skip_binder(); let mut flags = vec![]; // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): HIR is not present for RPITITs, @@ -144,13 +148,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { flags.push((sym::cause, Some("MainFunctionType".to_string()))); } - flags.push((sym::Trait, Some(trait_ref.print_trait_sugared().to_string()))); + flags.push((sym::Trait, Some(trait_pred.trait_ref.print_trait_sugared().to_string()))); // Add all types without trimmed paths or visible paths, ensuring they end up with // their "canonical" def path. ty::print::with_no_trimmed_paths!(ty::print::with_no_visible_paths!({ let generics = self.tcx.generics_of(def_id); - let self_ty = trait_ref.self_ty(); + let self_ty = trait_pred.self_ty(); // This is also included through the generics list as `Self`, // but the parser won't allow you to use it flags.push((sym::_Self, Some(self_ty.to_string()))); @@ -266,7 +270,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { })); if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, def_id) { - command.evaluate(self.tcx, trait_ref, &flags, long_ty_file) + command.evaluate(self.tcx, trait_pred.trait_ref, &flags, long_ty_file) } else { OnUnimplementedNote::default() } diff --git a/tests/ui/traits/negative-bounds/on-unimplemented.rs b/tests/ui/traits/negative-bounds/on-unimplemented.rs new file mode 100644 index 000000000000..34582590861f --- /dev/null +++ b/tests/ui/traits/negative-bounds/on-unimplemented.rs @@ -0,0 +1,12 @@ +#![feature(negative_bounds)] + +#[diagnostic::on_unimplemented(message = "this ain't fooing")] +trait Foo {} +struct NotFoo; + +fn hello() -> impl !Foo { + //~^ ERROR the trait bound `NotFoo: !Foo` is not satisfied + NotFoo +} + +fn main() {} diff --git a/tests/ui/traits/negative-bounds/on-unimplemented.stderr b/tests/ui/traits/negative-bounds/on-unimplemented.stderr new file mode 100644 index 000000000000..07483e788e5b --- /dev/null +++ b/tests/ui/traits/negative-bounds/on-unimplemented.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `NotFoo: !Foo` is not satisfied + --> $DIR/on-unimplemented.rs:7:15 + | +LL | fn hello() -> impl !Foo { + | ^^^^^^^^^ the trait bound `NotFoo: !Foo` is not satisfied +LL | +LL | NotFoo + | ------ return type was inferred to be `NotFoo` here + | +help: this trait has no implementations, consider adding one + --> $DIR/on-unimplemented.rs:4:1 + | +LL | trait Foo {} + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From c3b696dec99e7646b84d8b43c05a113acf7d249c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 14:40:07 -0400 Subject: [PATCH 063/118] Suppress import errors for traits that couldve applied in method lookup on error --- compiler/rustc_hir_typeck/src/method/mod.rs | 2 ++ .../rustc_hir_typeck/src/method/suggest.rs | 8 ++++++++ tests/ui/use/unused-trait-with-method-err.rs | 17 +++++++++++++++++ .../use/unused-trait-with-method-err.stderr | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 tests/ui/use/unused-trait-with-method-err.rs create mode 100644 tests/ui/use/unused-trait-with-method-err.stderr diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index cb8b1df2c6e4..1b65dc8214cf 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -199,6 +199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, segment, span, call_expr, self_expr, &pick, args, ); + // NOTE: on the failure path, we also record the possibly-used trait methods + // since an unused import warning is kinda distracting from the method error. for &import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4f726f3ed386..05c8912aec12 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -191,6 +191,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, trait_missing_method: bool, ) -> ErrorGuaranteed { + // NOTE: Reporting a method error should also suppress any unused trait errors, + // since the method error is very possibly the reason why the trait wasn't used. + for &import_id in + self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| &c.import_ids) + { + self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); + } + 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, _), diff --git a/tests/ui/use/unused-trait-with-method-err.rs b/tests/ui/use/unused-trait-with-method-err.rs new file mode 100644 index 000000000000..37684e1bf81e --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.rs @@ -0,0 +1,17 @@ +// Test that we don't issue an unused import warning when there's +// a method lookup error and that trait was possibly applicable. + +use foo::Bar; + +mod foo { + pub trait Bar { + fn uwu(&self) {} + } +} + +struct Foo; + +fn main() { + Foo.uwu(); + //~^ ERROR no method named `uwu` found for struct `Foo` in the current scope +} diff --git a/tests/ui/use/unused-trait-with-method-err.stderr b/tests/ui/use/unused-trait-with-method-err.stderr new file mode 100644 index 000000000000..7ca4563673bb --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `uwu` found for struct `Foo` in the current scope + --> $DIR/unused-trait-with-method-err.rs:15:9 + | +LL | struct Foo; + | ---------- method `uwu` not found for this struct +... +LL | Foo.uwu(); + | ^^^ method not found in `Foo` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bar` defines an item `uwu`, perhaps you need to implement it + --> $DIR/unused-trait-with-method-err.rs:7:5 + | +LL | pub trait Bar { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. From eb6062ce00cce6fa1973466e6b2fb376e3e89cc8 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 14 Oct 2024 15:27:37 -0400 Subject: [PATCH 064/118] Resolved python deprecation warning in publish_toolstate.py `utcnow()` is deprecated in favor of passing a timezone to `now()`. `utcnow()` would return a tz-naive datetime, while this returns a tz-aware datetime. For the purposes of the formatting we do, these are the same. --- src/tools/publish_toolstate.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 860d21876de0..328b48e04d2e 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -235,7 +235,9 @@ try: exit(0) cur_commit = sys.argv[1] - cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') + cur_datetime = datetime.datetime.now(datetime.timezone.utc).strftime( + '%Y-%m-%dT%H:%M:%SZ' + ) cur_commit_msg = sys.argv[2] save_message_to_path = sys.argv[3] github_token = sys.argv[4] From b73e613e008fd4a07a52ec7cef7c3af7db716b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Mon, 14 Oct 2024 20:58:32 +0200 Subject: [PATCH 065/118] De-duplicate and move `adjust_nan` to `InterpCx` --- .../rustc_const_eval/src/interpret/cast.rs | 27 +++++++------------ .../src/interpret/eval_context.rs | 8 ++++++ .../src/interpret/operator.rs | 3 +-- src/tools/miri/src/operator.rs | 4 --- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 30b5a8d70bc3..1def3d08328a 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -334,19 +334,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { { use rustc_type_ir::TyKind::*; - fn adjust_nan< - 'tcx, - M: Machine<'tcx>, - F1: rustc_apfloat::Float + FloatConvert, - F2: rustc_apfloat::Float, - >( - ecx: &InterpCx<'tcx, M>, - f1: F1, - f2: F2, - ) -> F2 { - if f2.is_nan() { M::generate_nan(ecx, &[f1]) } else { f2 } - } - match *dest_ty.kind() { // float -> uint Uint(t) => { @@ -367,11 +354,17 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // float -> float Float(fty) => match fty { - FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), + FloatTy::F16 => { + Scalar::from_f16(self.adjust_nan(f.convert(&mut false).value, &[f])) + } + FloatTy::F32 => { + Scalar::from_f32(self.adjust_nan(f.convert(&mut false).value, &[f])) + } + FloatTy::F64 => { + Scalar::from_f64(self.adjust_nan(f.convert(&mut false).value, &[f])) + } FloatTy::F128 => { - Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value)) + Scalar::from_f128(self.adjust_nan(f.convert(&mut false).value, &[f])) } }, // That's it. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 5165f95afd5b..02dd7821ef66 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -599,6 +599,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn generate_stacktrace(&self) -> Vec> { Frame::generate_stacktrace_from_stack(self.stack()) } + + pub fn adjust_nan(&self, f: F2, inputs: &[F1]) -> F2 + where + F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert, + F2: rustc_apfloat::Float, + { + if f.is_nan() { M::generate_nan(self, inputs) } else { f } + } } #[doc(hidden)] diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 52cd9b898bb7..b28ac68ac54a 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -64,8 +64,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { use rustc_middle::mir::BinOp::*; // Performs appropriate non-deterministic adjustments of NaN results. - let adjust_nan = - |f: F| -> F { if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f } }; + let adjust_nan = |f: F| -> F { self.adjust_nan(f, &[l, r]) }; match bin_op { Eq => ImmTy::from_bool(l == r, *self.tcx), diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index c0911fa717f5..8e06f4258d61 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -115,8 +115,4 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { nan } } - - fn adjust_nan, F2: Float>(&self, f: F2, inputs: &[F1]) -> F2 { - if f.is_nan() { self.generate_nan(inputs) } else { f } - } } From 4e438f7d6b7f6fbf2bb0c1ffe6ffe0b6bfc7fa38 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Mon, 14 Oct 2024 20:47:24 +0100 Subject: [PATCH 066/118] Fix two const-hacks --- library/core/src/time.rs | 8 +++----- library/std/src/sys/pal/windows/args.rs | 19 ++++--------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index f7ea7e06e9cd..51005ff795c6 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -213,11 +213,9 @@ impl Duration { // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } } else { - // FIXME(const-hack): use `.expect` once that is possible. - let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { - Some(secs) => secs, - None => panic!("overflow in Duration::new"), - }; + let secs = secs + .checked_add((nanos / NANOS_PER_SEC) as u64) + .expect("overflow in Duration::new"); let nanos = nanos % NANOS_PER_SEC; // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs index 848632ec2a7e..e9fc19bcb99c 100644 --- a/library/std/src/sys/pal/windows/args.rs +++ b/library/std/src/sys/pal/windows/args.rs @@ -18,17 +18,6 @@ use crate::sys_common::AsInner; use crate::sys_common::wstr::WStrUnits; use crate::{fmt, io, iter, vec}; -/// This is the const equivalent to `NonZero::new(n).unwrap()` -/// -/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const. -/// See the `const_option` feature (#67441). -const fn non_zero_u16(n: u16) -> NonZero { - match NonZero::new(n) { - Some(n) => n, - None => panic!("called `unwrap` on a `None` value"), - } -} - pub fn args() -> Args { // SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16 // string so it's safe for `WStrUnits` to use. @@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( lp_cmd_line: Option>, exe_name: F, ) -> Vec { - const BACKSLASH: NonZero = non_zero_u16(b'\\' as u16); - const QUOTE: NonZero = non_zero_u16(b'"' as u16); - const TAB: NonZero = non_zero_u16(b'\t' as u16); - const SPACE: NonZero = non_zero_u16(b' ' as u16); + const BACKSLASH: NonZero = NonZero::new(b'\\' as u16).unwrap(); + const QUOTE: NonZero = NonZero::new(b'"' as u16).unwrap(); + const TAB: NonZero = NonZero::new(b'\t' as u16).unwrap(); + const SPACE: NonZero = NonZero::new(b' ' as u16).unwrap(); let mut ret_val = Vec::new(); // If the cmd line pointer is null or it points to an empty string then From 10aa255541964bceddaac8f49d7a11f1d736e24d Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 14 Oct 2024 22:32:32 +0200 Subject: [PATCH 067/118] improve error messages for `C-cmse-nonsecure-entry` functions --- compiler/rustc_hir_analysis/messages.ftl | 15 +- compiler/rustc_hir_analysis/src/errors.rs | 17 +- .../src/hir_ty_lowering/cmse.rs | 157 +++++++++++------- .../cmse-nonsecure-entry/generics.rs | 77 +++++++++ .../cmse-nonsecure-entry/generics.stderr | 78 +++++++++ .../params-on-registers.rs | 16 -- .../cmse-nonsecure-entry/params-on-stack.rs | 21 --- .../params-on-stack.stderr | 4 - .../cmse-nonsecure-entry/params-via-stack.rs | 26 +++ .../params-via-stack.stderr | 43 +++++ .../cmse-nonsecure-entry/return-via-stack.rs | 84 ++++++++++ .../return-via-stack.stderr | 84 ++++++++++ .../trustzone-only.stderr | 9 + .../cmse-nonsecure-entry/via-registers.rs | 89 ++++++++++ 14 files changed, 612 insertions(+), 108 deletions(-) create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr delete mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs delete mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs delete mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.stderr create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr create mode 100644 tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index da814cd2d690..a9f30ffd6dac 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -68,18 +68,21 @@ hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are fo hir_analysis_cmse_call_generic = function pointers with the `"C-cmse-nonsecure-call"` ABI cannot contain generics in their type -hir_analysis_cmse_call_inputs_stack_spill = - arguments for `"C-cmse-nonsecure-call"` function too large to pass via registers +hir_analysis_cmse_entry_generic = + functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + +hir_analysis_cmse_inputs_stack_spill = + arguments for `"{$abi_name}"` function too large to pass via registers .label = {$plural -> [false] this argument doesn't *[true] these arguments don't } fit in the available registers - .note = functions with the `"C-cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + .note = functions with the `"{$abi_name}"` ABI must pass all their arguments via the 4 32-bit available argument registers -hir_analysis_cmse_call_output_stack_spill = - return value of `"C-cmse-nonsecure-call"` function too large to pass via registers +hir_analysis_cmse_output_stack_spill = + return value of `"{$abi_name}"` function too large to pass via registers .label = this type doesn't fit in the available registers - .note1 = functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers + .note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers .note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 9099703e8129..af4445a7fd48 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1627,23 +1627,25 @@ pub(crate) struct InvalidReceiverTy<'tcx> { pub(crate) struct EffectsWithoutNextSolver; #[derive(Diagnostic)] -#[diag(hir_analysis_cmse_call_inputs_stack_spill, code = E0798)] +#[diag(hir_analysis_cmse_inputs_stack_spill, code = E0798)] #[note] -pub(crate) struct CmseCallInputsStackSpill { +pub(crate) struct CmseInputsStackSpill { #[primary_span] #[label] pub span: Span, pub plural: bool, + pub abi_name: &'static str, } #[derive(Diagnostic)] -#[diag(hir_analysis_cmse_call_output_stack_spill, code = E0798)] +#[diag(hir_analysis_cmse_output_stack_spill, code = E0798)] #[note(hir_analysis_note1)] #[note(hir_analysis_note2)] -pub(crate) struct CmseCallOutputStackSpill { +pub(crate) struct CmseOutputStackSpill { #[primary_span] #[label] pub span: Span, + pub abi_name: &'static str, } #[derive(Diagnostic)] @@ -1659,3 +1661,10 @@ pub(crate) struct BadReturnTypeNotation { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_cmse_entry_generic, code = E0798)] +pub(crate) struct CmseEntryGeneric { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index a562759da111..672dc8ddeda1 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -1,8 +1,8 @@ use rustc_errors::{DiagCtxtHandle, E0781, struct_span_code_err}; use rustc_hir::{self as hir, HirId}; +use rustc_middle::bug; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self, ParamEnv, TyCtxt}; -use rustc_span::Span; use rustc_target::spec::abi; use crate::errors; @@ -17,61 +17,104 @@ pub(crate) fn validate_cmse_abi<'tcx>( abi: abi::Abi, fn_sig: ty::PolyFnSig<'tcx>, ) { - if let abi::Abi::CCmseNonSecureCall = abi { - let hir_node = tcx.hir_node(hir_id); - let hir::Node::Ty(hir::Ty { - span: bare_fn_span, - kind: hir::TyKind::BareFn(bare_fn_ty), - .. - }) = hir_node - else { - let span = match tcx.parent_hir_node(hir_id) { - hir::Node::Item(hir::Item { - kind: hir::ItemKind::ForeignMod { .. }, span, .. - }) => *span, - _ => tcx.hir().span(hir_id), + let abi_name = abi.name(); + + match abi { + abi::Abi::CCmseNonSecureCall => { + let hir_node = tcx.hir_node(hir_id); + let hir::Node::Ty(hir::Ty { + span: bare_fn_span, + kind: hir::TyKind::BareFn(bare_fn_ty), + .. + }) = hir_node + else { + let span = match tcx.parent_hir_node(hir_id) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::ForeignMod { .. }, + span, + .. + }) => *span, + _ => tcx.hir().span(hir_id), + }; + struct_span_code_err!( + tcx.dcx(), + span, + E0781, + "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers" + ) + .emit(); + return; }; - struct_span_code_err!( - tcx.dcx(), - span, - E0781, - "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers" - ) - .emit(); - return; - }; - match is_valid_cmse_inputs(tcx, fn_sig) { - Ok(Ok(())) => {} - Ok(Err(index)) => { - // fn(x: u32, u32, u32, u16, y: u16) -> u32, - // ^^^^^^ - let span = bare_fn_ty.param_names[index] - .span - .to(bare_fn_ty.decl.inputs[index].span) - .to(bare_fn_ty.decl.inputs.last().unwrap().span); - let plural = bare_fn_ty.param_names.len() - index != 1; - dcx.emit_err(errors::CmseCallInputsStackSpill { span, plural }); - } - Err(layout_err) => { - if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) { - dcx.emit_err(err); + match is_valid_cmse_inputs(tcx, fn_sig) { + Ok(Ok(())) => {} + Ok(Err(index)) => { + // fn(x: u32, u32, u32, u16, y: u16) -> u32, + // ^^^^^^ + let span = bare_fn_ty.param_names[index] + .span + .to(bare_fn_ty.decl.inputs[index].span) + .to(bare_fn_ty.decl.inputs.last().unwrap().span); + let plural = bare_fn_ty.param_names.len() - index != 1; + dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name }); + } + Err(layout_err) => { + if should_emit_generic_error(abi, layout_err) { + dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span }); + } } } + + match is_valid_cmse_output(tcx, fn_sig) { + Ok(true) => {} + Ok(false) => { + let span = bare_fn_ty.decl.output.span(); + dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name }); + } + Err(layout_err) => { + if should_emit_generic_error(abi, layout_err) { + dcx.emit_err(errors::CmseCallGeneric { span: *bare_fn_span }); + } + } + }; } + abi::Abi::CCmseNonSecureEntry => { + let hir_node = tcx.hir_node(hir_id); + let Some(hir::FnSig { decl, span: fn_sig_span, .. }) = hir_node.fn_sig() else { + // might happen when this ABI is used incorrectly. That will be handled elsewhere + return; + }; - match is_valid_cmse_output(tcx, fn_sig) { - Ok(true) => {} - Ok(false) => { - let span = bare_fn_ty.decl.output.span(); - dcx.emit_err(errors::CmseCallOutputStackSpill { span }); - } - Err(layout_err) => { - if let Some(err) = cmse_layout_err(layout_err, *bare_fn_span) { - dcx.emit_err(err); + match is_valid_cmse_inputs(tcx, fn_sig) { + Ok(Ok(())) => {} + Ok(Err(index)) => { + // fn f(x: u32, y: u32, z: u32, w: u16, q: u16) -> u32, + // ^^^^^^ + let span = decl.inputs[index].span.to(decl.inputs.last().unwrap().span); + let plural = decl.inputs.len() - index != 1; + dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi_name }); + } + Err(layout_err) => { + if should_emit_generic_error(abi, layout_err) { + dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span }); + } } } - }; + + match is_valid_cmse_output(tcx, fn_sig) { + Ok(true) => {} + Ok(false) => { + let span = decl.output.span(); + dcx.emit_err(errors::CmseOutputStackSpill { span, abi_name }); + } + Err(layout_err) => { + if should_emit_generic_error(abi, layout_err) { + dcx.emit_err(errors::CmseEntryGeneric { span: *fn_sig_span }); + } + } + }; + } + _ => (), } } @@ -152,22 +195,22 @@ fn is_valid_cmse_output<'tcx>( Ok(ret_ty == tcx.types.i64 || ret_ty == tcx.types.u64 || ret_ty == tcx.types.f64) } -fn cmse_layout_err<'tcx>( - layout_err: &'tcx LayoutError<'tcx>, - span: Span, -) -> Option { +fn should_emit_generic_error<'tcx>(abi: abi::Abi, layout_err: &'tcx LayoutError<'tcx>) -> bool { use LayoutError::*; match layout_err { Unknown(ty) => { - if ty.is_impl_trait() { - None // prevent double reporting of this error - } else { - Some(errors::CmseCallGeneric { span }) + match abi { + abi::Abi::CCmseNonSecureCall => { + // prevent double reporting of this error + !ty.is_impl_trait() + } + abi::Abi::CCmseNonSecureEntry => true, + _ => bug!("invalid ABI: {abi}"), } } SizeOverflow(..) | NormalizationFailure(..) | ReferencesError(..) | Cycle(..) => { - None // not our job to report these + false // not our job to report these } } } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs new file mode 100644 index 000000000000..a264bba6f3cd --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -0,0 +1,77 @@ +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] +#![no_core] +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy {} +impl Copy for u32 {} + +#[repr(C)] +struct Wrapper(T); + +impl Wrapper { + extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { + //~^ ERROR [E0798] + 0 + } + + extern "C-cmse-nonsecure-entry" fn ambient_generic_nested( + //~^ ERROR [E0798] + _: Wrapper, + _: u32, + _: u32, + _: u32, + ) -> u64 { + 0 + } +} + +extern "C-cmse-nonsecure-entry" fn introduced_generic( + //~^ ERROR [E0798] + _: U, + _: u32, + _: u32, + _: u32, +) -> u64 { + 0 +} + +extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { + //~^ ERROR [E0798] + 0 +} + +extern "C-cmse-nonsecure-entry" fn reference(x: &usize) -> usize { + *x +} + +trait Trait {} + +extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { + //~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798] + x +} + +extern "C-cmse-nonsecure-entry" fn static_trait_object( + x: &'static dyn Trait, +) -> &'static dyn Trait { + //~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798] + x +} + +#[repr(transparent)] +struct WrapperTransparent<'a>(&'a dyn Trait); + +extern "C-cmse-nonsecure-entry" fn wrapped_trait_object( + x: WrapperTransparent, +) -> WrapperTransparent { + //~^ ERROR return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers [E0798] + x +} + +extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + //~^ ERROR only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + //~| ERROR requires `va_list` lang_item +} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr new file mode 100644 index 000000000000..9e67f881f75c --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -0,0 +1,78 @@ +error: only foreign, `unsafe extern "C"`, or `unsafe extern "C-unwind"` functions may have a C-variadic arg + --> $DIR/generics.rs:74:55 + | +LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ^^^^^^ + +error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + --> $DIR/generics.rs:31:1 + | +LL | / extern "C-cmse-nonsecure-entry" fn introduced_generic( +LL | | +LL | | _: U, +LL | | _: u32, +LL | | _: u32, +LL | | _: u32, +LL | | ) -> u64 { + | |________^ + +error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + --> $DIR/generics.rs:41:1 + | +LL | extern "C-cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + --> $DIR/generics.rs:15:5 + | +LL | extern "C-cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0798]: functions with the `"C-cmse-nonsecure-entry"` ABI cannot contain generics in their type + --> $DIR/generics.rs:20:5 + | +LL | / extern "C-cmse-nonsecure-entry" fn ambient_generic_nested( +LL | | +LL | | _: Wrapper, +LL | | _: u32, +LL | | _: u32, +LL | | _: u32, +LL | | ) -> u64 { + | |____________^ + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/generics.rs:52:67 + | +LL | extern "C-cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { + | ^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/generics.rs:59:6 + | +LL | ) -> &'static dyn Trait { + | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/generics.rs:69:6 + | +LL | ) -> WrapperTransparent { + | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error: requires `va_list` lang_item + --> $DIR/generics.rs:74:55 + | +LL | extern "C-cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ^^^^^^ + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs deleted file mode 100644 index de6888fae623..000000000000 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-registers.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ build-pass -//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -//@ needs-llvm-components: arm -#![feature(cmse_nonsecure_entry, no_core, lang_items)] -#![no_core] -#![crate_type = "lib"] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} - -#[no_mangle] -pub extern "C-cmse-nonsecure-entry" fn entry_function(_: u32, _: u32, _: u32, d: u32) -> u32 { - d -} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs deleted file mode 100644 index 4413c461c044..000000000000 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ build-fail -//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib -//@ needs-llvm-components: arm -#![feature(cmse_nonsecure_entry, no_core, lang_items)] -#![no_core] -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} -impl Copy for u32 {} - -#[no_mangle] -pub extern "C-cmse-nonsecure-entry" fn entry_function( - _: u32, - _: u32, - _: u32, - _: u32, - e: u32, -) -> u32 { - e -} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.stderr deleted file mode 100644 index cfbdda509e58..000000000000 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-on-stack.stderr +++ /dev/null @@ -1,4 +0,0 @@ -error: :0:0: in function entry_function i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack - -error: aborting due to 1 previous error - diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs new file mode 100644 index 000000000000..572d792d5a5d --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs @@ -0,0 +1,26 @@ +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, no_core, lang_items)] +#![no_core] +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} +impl Copy for u32 {} + +#[repr(C, align(16))] +#[allow(unused)] +pub struct AlignRelevant(u32); + +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} //~ ERROR [E0798] +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} //~ ERROR [E0798] +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} //~ ERROR [E0798] +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} //~ ERROR [E0798] + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr new file mode 100644 index 000000000000..b77e64c6bfba --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr @@ -0,0 +1,43 @@ +error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:16:78 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} + | ^^^^^^^^^^^ these arguments don't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + +error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:18:78 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} + | ^^^ this argument doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + +error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:20:62 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} + | ^^^ this argument doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + +error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:22:64 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} + | ^^^ this argument doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + +error[E0798]: arguments for `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:26:46 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} + | ^^^^^^^^ this argument doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs new file mode 100644 index 000000000000..5746d14f9b1a --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs @@ -0,0 +1,84 @@ +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, no_core, lang_items)] +#![no_core] +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +pub trait Copy {} +impl Copy for u32 {} +impl Copy for u8 {} + +#[repr(C)] +pub struct ReprCU64(u64); + +#[repr(C)] +pub struct ReprCBytes(u8, u8, u8, u8, u8); + +#[repr(C)] +pub struct U64Compound(u32, u32); + +#[repr(C, align(16))] +pub struct ReprCAlign16(u16); + +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 { + //~^ ERROR [E0798] + ReprCU64(0) +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes { + //~^ ERROR [E0798] + ReprCBytes(0, 1, 2, 3, 4) +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound { + //~^ ERROR [E0798] + U64Compound(2, 3) +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { + //~^ ERROR [E0798] + ReprCAlign16(4) +} + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] { + //~^ ERROR [E0798] + [0xAA; 5] +} +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 { + //~^ ERROR [E0798] + 123 +} +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 { + //~^ ERROR [E0798] + 456 +} + +#[repr(Rust)] +pub union ReprRustUnionU64 { + _unused: u64, +} + +#[repr(C)] +pub union ReprCUnionU64 { + _unused: u64, +} + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { + //~^ ERROR [E0798] + ReprRustUnionU64 { _unused: 1 } +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { + //~^ ERROR [E0798] + ReprCUnionU64 { _unused: 2 } +} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr new file mode 100644 index 000000000000..9c885d953181 --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr @@ -0,0 +1,84 @@ +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:25:48 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f1() -> ReprCU64 { + | ^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:30:48 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f2() -> ReprCBytes { + | ^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:35:48 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f3() -> U64Compound { + | ^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:40:48 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { + | ^^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:47:48 + | +LL | pub extern "C-cmse-nonsecure-entry" fn f5() -> [u8; 5] { + | ^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:53:50 + | +LL | pub extern "C-cmse-nonsecure-entry" fn u128() -> u128 { + | ^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:59:50 + | +LL | pub extern "C-cmse-nonsecure-entry" fn i128() -> i128 { + | ^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:76:56 + | +LL | pub extern "C-cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { + | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"C-cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/return-via-stack.rs:81:53 + | +LL | pub extern "C-cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { + | ^^^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"C-cmse-nonsecure-entry"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr new file mode 100644 index 000000000000..77379f7049d0 --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.stderr @@ -0,0 +1,9 @@ +error[E0570]: `"C-cmse-nonsecure-entry"` is not a supported ABI for the current target + --> $DIR/trustzone-only.rs:5:1 + | +LL | pub extern "C-cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs new file mode 100644 index 000000000000..8978b35d356f --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs @@ -0,0 +1,89 @@ +//@ build-pass +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, no_core, lang_items)] +#![no_core] +#![crate_type = "lib"] +#[lang = "sized"] +pub trait Sized {} +#[lang = "copy"] +trait Copy {} +impl Copy for u32 {} +impl Copy for u8 {} + +#[repr(transparent)] +pub struct ReprTransparentStruct { + _marker1: (), + _marker2: (), + field: T, + _marker3: (), +} + +#[repr(transparent)] +pub enum ReprTransparentEnumU64 { + A(u64), +} + +#[repr(C)] +pub struct U32Compound(u16, u16); + +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn inputs1() {} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn inputs2(_: u32, _: u32, _: u32, _: u32) {} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn inputs3(_: u64, _: u64) {} +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn inputs4(_: u128) {} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn inputs5(_: f64, _: f32, _: f32) {} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn inputs6(_: ReprTransparentStruct, _: U32Compound) {} +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn inputs7(_: [u32; 4]) {} + +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs1() -> u32 { + 0 +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs2() -> u64 { + 0 +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs3() -> i64 { + 0 +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs4() -> f64 { + 0.0 +} +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C-cmse-nonsecure-entry" fn outputs5() -> [u8; 4] { + [0xAA; 4] +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs6() -> ReprTransparentStruct { + ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () } +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs7( +) -> ReprTransparentStruct> { + ReprTransparentStruct { + _marker1: (), + _marker2: (), + field: ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () }, + _marker3: (), + } +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs8() -> ReprTransparentEnumU64 { + ReprTransparentEnumU64::A(0) +} +#[no_mangle] +pub extern "C-cmse-nonsecure-entry" fn outputs9() -> U32Compound { + U32Compound(1, 2) +} From 373142aaa1e64f8a1e9071deaf0675c181ca3b47 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 14 Oct 2024 17:15:53 -0400 Subject: [PATCH 068/118] Mark LazyCell::into_inner unstably const Other cell `into_inner` functions are const and there shouldn't be any problem here. Make the unstable `LazyCell::into_inner` const under the same gate as its stability (`lazy_cell_into_inner`). Tracking issue: https://github.com/rust-lang/rust/issues/125623 --- library/core/src/cell/lazy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 5bc13779af9f..d323fbeac9c1 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -79,7 +79,7 @@ impl T> LazyCell { /// assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string())); /// ``` #[unstable(feature = "lazy_cell_into_inner", issue = "125623")] - pub fn into_inner(this: Self) -> Result { + pub const fn into_inner(this: Self) -> Result { match this.state.into_inner() { State::Init(data) => Ok(data), State::Uninit(f) => Err(f), @@ -306,6 +306,6 @@ impl fmt::Debug for LazyCell { #[cold] #[inline(never)] -fn panic_poisoned() -> ! { +const fn panic_poisoned() -> ! { panic!("LazyCell instance has previously been poisoned") } From dda3066805ef0a0ad5f2d0d2cdb6bc0b66d8c19b Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:22:51 +0200 Subject: [PATCH 069/118] Remove `'apostrophes'` from `rustc_parse_format` --- compiler/rustc_index_macros/Cargo.toml | 2 +- compiler/rustc_parse_format/src/lib.rs | 8 +-- .../session-diagnostic/diagnostic-derive.rs | 2 +- .../diagnostic-derive.stderr | 4 +- .../on_unimplemented/broken_format.rs | 4 +- .../on_unimplemented/broken_format.stderr | 4 +- tests/ui/fmt/closing-brace-as-fill.rs | 2 +- tests/ui/fmt/closing-brace-as-fill.stderr | 6 +- tests/ui/fmt/format-string-error-2.rs | 2 +- tests/ui/fmt/format-string-error-2.stderr | 56 +++++++++---------- tests/ui/fmt/format-string-error.rs | 6 +- tests/ui/fmt/format-string-error.stderr | 24 ++++---- tests/ui/fmt/format-string-wrong-order.rs | 4 +- tests/ui/fmt/format-string-wrong-order.stderr | 8 +-- tests/ui/fmt/ifmt-bad-arg.rs | 2 +- tests/ui/fmt/ifmt-bad-arg.stderr | 8 +-- tests/ui/fmt/issue-91556.rs | 4 +- tests/ui/fmt/issue-91556.stderr | 4 +- .../ui/fmt/respanned-literal-issue-106191.rs | 4 +- .../fmt/respanned-literal-issue-106191.stderr | 8 +-- tests/ui/macros/issue-51848.stderr | 4 +- 21 files changed, 83 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index 07ee81788ce4..a7c2a1804ddb 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" proc-macro = true [dependencies] -syn = { version = "2.0.9", features = ["full"] } +syn = { version = "2.0.9", features = ["full", "extra-traits"] } proc-macro2 = "1" quote = "1" diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index e7ef4385baf4..1716f417969e 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -473,19 +473,19 @@ impl<'a> Parser<'a> { } pos = peek_pos; - description = format!("expected `'}}'`, found `{maybe:?}`"); + description = format!("expected `}}`, found `{}`", maybe.escape_debug()); } else { - description = "expected `'}'` but string was terminated".to_owned(); + description = "expected `}` but string was terminated".to_owned(); // point at closing `"` pos = self.input.len() - if self.append_newline { 1 } else { 0 }; } let pos = self.to_span_index(pos); - let label = "expected `'}'`".to_owned(); + let label = "expected `}`".to_owned(); let (note, secondary_label) = if arg.format.fill == Some('}') { ( - Some("the character `'}'` is interpreted as a fill character because of the `:` that precedes it".to_owned()), + Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()), arg.format.fill_span.map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)), ) } else { diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index e8cec6321772..1577b68e748f 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -178,7 +178,7 @@ struct ErrorWithNonexistentField { } #[derive(Diagnostic)] -//~^ ERROR invalid format string: expected `'}'` +//~^ ERROR invalid format string: expected `}` #[diag(no_crate_example, code = E0123)] struct ErrorMissingClosingBrace { #[suggestion(no_crate_suggestion, code = "{name")] diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 97f9896f3a72..ff7af3885148 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -184,11 +184,11 @@ error: `name` doesn't refer to a field on this type LL | #[suggestion(no_crate_suggestion, code = "{name}")] | ^^^^^^^^ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/diagnostic-derive.rs:180:10 | LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs index 8d8917fd319c..3ca58b28181c 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.rs @@ -19,8 +19,8 @@ trait ImportantTrait3 {} trait ImportantTrait4 {} #[diagnostic::on_unimplemented(message = "Test {Self:!}")] -//~^WARN expected `'}'`, found `'!'` -//~|WARN expected `'}'`, found `'!'` +//~^WARN expected `}`, found `!` +//~|WARN expected `}`, found `!` //~|WARN unmatched `}` found //~|WARN unmatched `}` found trait ImportantTrait5 {} diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr index 932e81ca48e4..b4ed06cb63d8 100644 --- a/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr +++ b/tests/ui/diagnostic_namespace/on_unimplemented/broken_format.stderr @@ -30,7 +30,7 @@ LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")] | = help: no format specifier are supported in this position -warning: expected `'}'`, found `'!'` +warning: expected `}`, found `!` --> $DIR/broken_format.rs:21:32 | LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")] @@ -153,7 +153,7 @@ note: required by a bound in `check_4` LL | fn check_4(_: impl ImportantTrait4) {} | ^^^^^^^^^^^^^^^ required by this bound in `check_4` -warning: expected `'}'`, found `'!'` +warning: expected `}`, found `!` --> $DIR/broken_format.rs:21:32 | LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")] diff --git a/tests/ui/fmt/closing-brace-as-fill.rs b/tests/ui/fmt/closing-brace-as-fill.rs index 6ad257f943e9..5865ee31c43d 100644 --- a/tests/ui/fmt/closing-brace-as-fill.rs +++ b/tests/ui/fmt/closing-brace-as-fill.rs @@ -4,5 +4,5 @@ fn main() { println!("Hello, world! {0:}<3", 2); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated } diff --git a/tests/ui/fmt/closing-brace-as-fill.stderr b/tests/ui/fmt/closing-brace-as-fill.stderr index 70068fa3aadc..aa22beddf45a 100644 --- a/tests/ui/fmt/closing-brace-as-fill.stderr +++ b/tests/ui/fmt/closing-brace-as-fill.stderr @@ -1,12 +1,12 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/closing-brace-as-fill.rs:6:35 | LL | println!("Hello, world! {0:}<3", 2); - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | this is not interpreted as a formatting closing brace | - = note: the character `'}'` is interpreted as a fill character because of the `:` that precedes it + = note: the character `}` is interpreted as a fill character because of the `:` that precedes it error: aborting due to 1 previous error diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs index 1f7f0d8f6be6..357dd7b10a3e 100644 --- a/tests/ui/fmt/format-string-error-2.rs +++ b/tests/ui/fmt/format-string-error-2.rs @@ -72,7 +72,7 @@ raw { \n // note: `\x7B` is `{` println!("\x7B}\u{8} {", 1); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated println!("\x7B}\u8 {", 1); //~^ ERROR incorrect unicode escape sequence diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index d5fe4081ac81..a2d142e0baba 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -9,138 +9,138 @@ help: format of unicode escape sequences uses braces LL | println!("\x7B}\u{8} {", 1); | ~~~~~ -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:5:5 | LL | format!("{ | - because of this opening brace LL | a"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:9:5 | LL | format!("{ \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:11:18 | LL | format!(r#"{ \ - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:15:18 | LL | format!(r#"{ \n - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'e'` +error: invalid format string: expected `}`, found `e` --> $DIR/format-string-error-2.rs:21:5 | LL | format!("{ \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:25:5 | LL | { | - because of this opening brace LL | a"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:29:5 | LL | { | - because of this opening brace LL | a - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:35:5 | LL | { \ | - because of this opening brace LL | \ LL | b"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'b'` +error: invalid format string: expected `}`, found `b` --> $DIR/format-string-error-2.rs:40:5 | LL | { \ | - because of this opening brace LL | \ LL | b \ - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:45:8 | LL | raw { \ - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error-2.rs:50:8 | LL | raw { \n - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'e'` +error: invalid format string: expected `}`, found `e` --> $DIR/format-string-error-2.rs:57:5 | LL | { \n | - because of this opening brace LL | \n LL | e"); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'a'` +error: invalid format string: expected `}`, found `a` --> $DIR/format-string-error-2.rs:67:5 | LL | { | - because of this opening brace LL | asdf} - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` @@ -150,11 +150,11 @@ error: 1 positional argument in format string, but no arguments were given LL | println!("\t{}"); | ^^ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error-2.rs:74:27 | LL | println!("\x7B}\u{8} {", 1); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/format-string-error.rs b/tests/ui/fmt/format-string-error.rs index 9b436e2c479f..cb9449be5320 100644 --- a/tests/ui/fmt/format-string-error.rs +++ b/tests/ui/fmt/format-string-error.rs @@ -2,7 +2,7 @@ fn main() { println!("{"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated println!("{{}}"); println!("}"); //~^ ERROR invalid format string: unmatched `}` found @@ -13,11 +13,11 @@ fn main() { let _ = format!("{a:._$}", a = "", _ = 0); //~^ ERROR invalid format string: invalid argument name `_` let _ = format!("{"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated let _ = format!("}"); //~^ ERROR invalid format string: unmatched `}` found let _ = format!("{\\}"); - //~^ ERROR invalid format string: expected `'}'`, found `'\'` + //~^ ERROR invalid format string: expected `}`, found `\` let _ = format!("\n\n\n{\n\n\n"); //~^ ERROR invalid format string let _ = format!(r###" diff --git a/tests/ui/fmt/format-string-error.stderr b/tests/ui/fmt/format-string-error.stderr index 37a181e6fcb2..9d6a91413d00 100644 --- a/tests/ui/fmt/format-string-error.stderr +++ b/tests/ui/fmt/format-string-error.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:4:16 | LL | println!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -40,11 +40,11 @@ LL | let _ = format!("{a:._$}", a = "", _ = 0); | = note: argument name cannot be a single underscore -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:15:23 | LL | let _ = format!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -58,44 +58,44 @@ LL | let _ = format!("}"); | = note: if you intended to print `}`, you can escape it using `}}` -error: invalid format string: expected `'}'`, found `'\'` +error: invalid format string: expected `}`, found `\` --> $DIR/format-string-error.rs:19:23 | LL | let _ = format!("{\}"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:21:35 | LL | let _ = format!("\n\n\n{\n\n\n"); - | - ^ expected `'}'` in format string + | - ^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:27:3 | LL | {"###); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/format-string-error.rs:35:1 | LL | { | - because of this opening brace LL | LL | "###); - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/fmt/format-string-wrong-order.rs b/tests/ui/fmt/format-string-wrong-order.rs index da775be3ffd6..891279b97e4d 100644 --- a/tests/ui/fmt/format-string-wrong-order.rs +++ b/tests/ui/fmt/format-string-wrong-order.rs @@ -7,9 +7,9 @@ fn main() { format!("{?:?}", bar); //~^ ERROR invalid format string: expected format parameter to occur after `:` format!("{??}", bar); - //~^ ERROR invalid format string: expected `'}'`, found `'?'` + //~^ ERROR invalid format string: expected `}`, found `?` format!("{?;bar}"); - //~^ ERROR invalid format string: expected `'}'`, found `'?'` + //~^ ERROR invalid format string: expected `}`, found `?` format!("{?:#?}", bar); //~^ ERROR invalid format string: expected format parameter to occur after `:` format!("Hello {<5:}!", "x"); diff --git a/tests/ui/fmt/format-string-wrong-order.stderr b/tests/ui/fmt/format-string-wrong-order.stderr index 3ef07720c153..7f017511761f 100644 --- a/tests/ui/fmt/format-string-wrong-order.stderr +++ b/tests/ui/fmt/format-string-wrong-order.stderr @@ -22,21 +22,21 @@ LL | format!("{?:?}", bar); | = note: `?` comes after `:`, try `:?` instead -error: invalid format string: expected `'}'`, found `'?'` +error: invalid format string: expected `}`, found `?` --> $DIR/format-string-wrong-order.rs:9:15 | LL | format!("{??}", bar); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'`, found `'?'` +error: invalid format string: expected `}`, found `?` --> $DIR/format-string-wrong-order.rs:11:15 | LL | format!("{?;bar}"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | diff --git a/tests/ui/fmt/ifmt-bad-arg.rs b/tests/ui/fmt/ifmt-bad-arg.rs index 68861d7bf3fa..e39ffb8fe1b3 100644 --- a/tests/ui/fmt/ifmt-bad-arg.rs +++ b/tests/ui/fmt/ifmt-bad-arg.rs @@ -48,7 +48,7 @@ fn main() { // bad syntax of the format string - format!("{"); //~ ERROR: expected `'}'` but string was terminated + format!("{"); //~ ERROR: expected `}` but string was terminated format!("foo } bar"); //~ ERROR: unmatched `}` found format!("foo }"); //~ ERROR: unmatched `}` found diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index 09ce3dca4117..4344aee83c2b 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -136,11 +136,11 @@ LL | format!("{valuea} {valueb}", valuea=5, valuec=7); | | | formatting specifier missing -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/ifmt-bad-arg.rs:51:15 | LL | format!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace | @@ -172,13 +172,13 @@ LL | format!("foo %s baz", "bar"); | = note: printf formatting is not supported; see the documentation for `std::fmt` -error: invalid format string: expected `'}'`, found `'t'` +error: invalid format string: expected `}`, found `t` --> $DIR/ifmt-bad-arg.rs:75:1 | LL | ninth number: { | - because of this opening brace LL | tenth number: {}", - | ^ expected `'}'` in format string + | ^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` diff --git a/tests/ui/fmt/issue-91556.rs b/tests/ui/fmt/issue-91556.rs index e782e6f90763..fcf8909859c6 100644 --- a/tests/ui/fmt/issue-91556.rs +++ b/tests/ui/fmt/issue-91556.rs @@ -1,8 +1,8 @@ fn main() { let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i); - //~^ ERROR: invalid format string: expected `'}'` but string was terminated + //~^ ERROR: invalid format string: expected `}` but string was terminated //~| NOTE: if you intended to print `{`, you can escape it using `{{` //~| NOTE: in this expansion of concat! //~| NOTE: in this expansion of concat! - //~| NOTE: expected `'}'` in format string + //~| NOTE: expected `}` in format string } diff --git a/tests/ui/fmt/issue-91556.stderr b/tests/ui/fmt/issue-91556.stderr index beab3db0d94c..52917fb8c424 100644 --- a/tests/ui/fmt/issue-91556.stderr +++ b/tests/ui/fmt/issue-91556.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/issue-91556.rs:2:19 | LL | let _ = format!(concat!("{0}𝖳𝖾𝗌𝗍{"), i); - | ^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/fmt/respanned-literal-issue-106191.rs b/tests/ui/fmt/respanned-literal-issue-106191.rs index b0c0855a8709..0a127b1a0ca2 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.rs +++ b/tests/ui/fmt/respanned-literal-issue-106191.rs @@ -4,7 +4,7 @@ extern crate format_string_proc_macro; fn main() { format_string_proc_macro::respan_to_invalid_format_literal!("¡"); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated format_args!(r#concat!("¡ {")); - //~^ ERROR invalid format string: expected `'}'` but string was terminated + //~^ ERROR invalid format string: expected `}` but string was terminated } diff --git a/tests/ui/fmt/respanned-literal-issue-106191.stderr b/tests/ui/fmt/respanned-literal-issue-106191.stderr index 73a3af65a384..17ab29e799bb 100644 --- a/tests/ui/fmt/respanned-literal-issue-106191.stderr +++ b/tests/ui/fmt/respanned-literal-issue-106191.stderr @@ -1,16 +1,16 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/respanned-literal-issue-106191.rs:6:65 | LL | format_string_proc_macro::respan_to_invalid_format_literal!("¡"); - | ^^^ expected `'}'` in format string + | ^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/respanned-literal-issue-106191.rs:8:18 | LL | format_args!(r#concat!("¡ {")); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `}` in format string | = note: if you intended to print `{`, you can escape it using `{{` = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/macros/issue-51848.stderr b/tests/ui/macros/issue-51848.stderr index c25bedf37b75..30b64113d731 100644 --- a/tests/ui/macros/issue-51848.stderr +++ b/tests/ui/macros/issue-51848.stderr @@ -1,8 +1,8 @@ -error: invalid format string: expected `'}'` but string was terminated +error: invalid format string: expected `}` but string was terminated --> $DIR/issue-51848.rs:6:20 | LL | println!("{"); - | -^ expected `'}'` in format string + | -^ expected `}` in format string | | | because of this opening brace ... From 3c31729887053411226fea3013c3a8825257c928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Wed, 9 Oct 2024 22:33:27 +0200 Subject: [PATCH 070/118] Stabilise 'const_make_ascii' --- library/core/src/char/methods.rs | 6 ++++-- library/core/src/lib.rs | 1 - library/core/src/num/mod.rs | 6 ++++-- library/core/src/slice/ascii.rs | 6 ++++-- library/core/src/str/mod.rs | 6 ++++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 6bedb0d0dc4e..04698193bba1 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1282,8 +1282,9 @@ impl char { /// /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -1308,8 +1309,9 @@ impl char { /// /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 08c0d6e34cd0..674bf075551d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -125,7 +125,6 @@ #![feature(const_heap)] #![feature(const_index_range_slice_index)] #![feature(const_likely)] -#![feature(const_make_ascii)] #![feature(const_nonnull_new)] #![feature(const_num_midpoint)] #![feature(const_option_ext)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 31e35015d2de..f55d55171f29 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -624,8 +624,9 @@ impl u8 { /// /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -650,8 +651,9 @@ impl u8 { /// /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 8f8050fdc3aa..8d8ac6a1d2a1 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -67,8 +67,9 @@ impl [u8] { /// /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; @@ -89,8 +90,9 @@ impl [u8] { /// /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index e93c52f27999..1d10015d75a2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2475,8 +2475,9 @@ impl str { /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; @@ -2503,8 +2504,9 @@ impl str { /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; From c09ed3e767a73d83673790f74c357432fa44d320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Mon, 14 Oct 2024 21:02:13 +0200 Subject: [PATCH 071/118] Make some float methods unstable `const fn` Some float methods are now `const fn` under the `const_float_methods` feature gate. In order to support `min`, `max`, `abs` and `copysign`, the implementation of some intrinsics had to be moved from Miri to rustc_const_eval. --- .../src/interpret/intrinsics.rs | 80 ++++ library/core/src/intrinsics.rs | 387 +++++++++++------- library/core/src/lib.rs | 1 + library/core/src/num/f128.rs | 42 +- library/core/src/num/f16.rs | 42 +- library/core/src/num/f32.rs | 33 +- library/core/src/num/f64.rs | 33 +- library/std/src/f128.rs | 9 +- library/std/src/f16.rs | 9 +- library/std/src/f32.rs | 9 +- library/std/src/f64.rs | 9 +- library/std/src/lib.rs | 1 + src/tools/miri/src/intrinsics/mod.rs | 39 -- tests/ui/consts/const-eval/float_methods.rs | 47 +++ 14 files changed, 498 insertions(+), 243 deletions(-) create mode 100644 tests/ui/consts/const-eval/float_methods.rs diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 52780cc6a3a6..540898ec6456 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -4,6 +4,7 @@ use std::assert_matches::assert_matches; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_hir::def_id::DefId; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement}; @@ -438,6 +439,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?; } + sym::minnumf16 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf32 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf64 => self.float_min_intrinsic::(args, dest)?, + sym::minnumf128 => self.float_min_intrinsic::(args, dest)?, + + sym::maxnumf16 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf32 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf64 => self.float_max_intrinsic::(args, dest)?, + sym::maxnumf128 => self.float_max_intrinsic::(args, dest)?, + + sym::copysignf16 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf32 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf64 => self.float_copysign_intrinsic::(args, dest)?, + sym::copysignf128 => self.float_copysign_intrinsic::(args, dest)?, + + sym::fabsf16 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf32 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf64 => self.float_abs_intrinsic::(args, dest)?, + sym::fabsf128 => self.float_abs_intrinsic::(args, dest)?, + // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), } @@ -697,4 +718,63 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let rhs_bytes = get_bytes(self, rhs)?; interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes)) } + + fn float_min_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = self.adjust_nan(a.min(b), &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_max_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let res = self.adjust_nan(a.max(b), &[a, b]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_copysign_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + // bitwise, no NaN adjustments + self.write_scalar(a.copy_sign(b), dest)?; + interp_ok(()) + } + + fn float_abs_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &MPlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let x: F = self.read_scalar(&args[0])?.to_float()?; + // bitwise, no NaN adjustments + self.write_scalar(x.abs(), dest)?; + interp_ok(()) + } } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 061fba9a1f78..3ae729e76e1c 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1848,154 +1848,6 @@ extern "rust-intrinsic" { #[cfg(not(bootstrap))] pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; - /// Returns the absolute value of an `f16`. - /// - /// The stabilized version of this intrinsic is - /// [`f16::abs`](../../std/primitive.f16.html#method.abs) - #[rustc_nounwind] - pub fn fabsf16(x: f16) -> f16; - /// Returns the absolute value of an `f32`. - /// - /// The stabilized version of this intrinsic is - /// [`f32::abs`](../../std/primitive.f32.html#method.abs) - #[rustc_nounwind] - pub fn fabsf32(x: f32) -> f32; - /// Returns the absolute value of an `f64`. - /// - /// The stabilized version of this intrinsic is - /// [`f64::abs`](../../std/primitive.f64.html#method.abs) - #[rustc_nounwind] - pub fn fabsf64(x: f64) -> f64; - /// Returns the absolute value of an `f128`. - /// - /// The stabilized version of this intrinsic is - /// [`f128::abs`](../../std/primitive.f128.html#method.abs) - #[rustc_nounwind] - pub fn fabsf128(x: f128) -> f128; - - /// Returns the minimum of two `f16` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f16::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf16(x: f16, y: f16) -> f16; - /// Returns the minimum of two `f32` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f32::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf32(x: f32, y: f32) -> f32; - /// Returns the minimum of two `f64` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f64::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf64(x: f64, y: f64) -> f64; - /// Returns the minimum of two `f128` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f128::min`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn minnumf128(x: f128, y: f128) -> f128; - - /// Returns the maximum of two `f16` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f16::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf16(x: f16, y: f16) -> f16; - /// Returns the maximum of two `f32` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f32::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf32(x: f32, y: f32) -> f32; - /// Returns the maximum of two `f64` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f64::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf64(x: f64, y: f64) -> f64; - /// Returns the maximum of two `f128` values. - /// - /// Note that, unlike most intrinsics, this is safe to call; - /// it does not require an `unsafe` block. - /// Therefore, implementations must not require the user to uphold - /// any safety invariants. - /// - /// The stabilized version of this intrinsic is - /// [`f128::max`] - #[rustc_safe_intrinsic] - #[rustc_nounwind] - pub fn maxnumf128(x: f128, y: f128) -> f128; - - /// Copies the sign from `y` to `x` for `f16` values. - /// - /// The stabilized version of this intrinsic is - /// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf16(x: f16, y: f16) -> f16; - /// Copies the sign from `y` to `x` for `f32` values. - /// - /// The stabilized version of this intrinsic is - /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf32(x: f32, y: f32) -> f32; - /// Copies the sign from `y` to `x` for `f64` values. - /// - /// The stabilized version of this intrinsic is - /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf64(x: f64, y: f64) -> f64; - /// Copies the sign from `y` to `x` for `f128` values. - /// - /// The stabilized version of this intrinsic is - /// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) - #[rustc_nounwind] - pub fn copysignf128(x: f128, y: f128) -> f128; - /// Returns the largest integer less than or equal to an `f16`. /// /// The stabilized version of this intrinsic is @@ -3550,6 +3402,245 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { } } +/// Returns the minimum of two `f16` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f16::min`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Returns the minimum of two `f32` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f32::min`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} + +/// Returns the minimum of two `f64` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f64::min`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Returns the minimum of two `f128` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f128::min`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn minnumf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + +/// Returns the maximum of two `f16` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f16::max`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Returns the maximum of two `f32` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f32::max`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} + +/// Returns the maximum of two `f64` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f64::max`] +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Returns the maximum of two `f128` values. +/// +/// Note that, unlike most intrinsics, this is safe to call; +/// it does not require an `unsafe` block. +/// Therefore, implementations must not require the user to uphold +/// any safety invariants. +/// +/// The stabilized version of this intrinsic is +/// [`f128::max`] +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const fn maxnumf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + +/// Returns the absolute value of an `f16`. +/// +/// The stabilized version of this intrinsic is +/// [`f16::abs`](../../std/primitive.f16.html#method.abs) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf16(_x: f16) -> f16 { + unimplemented!(); +} + +/// Returns the absolute value of an `f32`. +/// +/// The stabilized version of this intrinsic is +/// [`f32::abs`](../../std/primitive.f32.html#method.abs) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf32(_x: f32) -> f32 { + unimplemented!(); +} + +/// Returns the absolute value of an `f64`. +/// +/// The stabilized version of this intrinsic is +/// [`f64::abs`](../../std/primitive.f64.html#method.abs) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf64(_x: f64) -> f64 { + unimplemented!(); +} + +/// Returns the absolute value of an `f128`. +/// +/// The stabilized version of this intrinsic is +/// [`f128::abs`](../../std/primitive.f128.html#method.abs) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn fabsf128(_x: f128) -> f128 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f16` values. +/// +/// The stabilized version of this intrinsic is +/// [`f16::copysign`](../../std/primitive.f16.html#method.copysign) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f16", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf16(_x: f16, _y: f16) -> f16 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f32` values. +/// +/// The stabilized version of this intrinsic is +/// [`f32::copysign`](../../std/primitive.f32.html#method.copysign) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf32(_x: f32, _y: f32) -> f32 { + unimplemented!(); +} +/// Copies the sign from `y` to `x` for `f64` values. +/// +/// The stabilized version of this intrinsic is +/// [`f64::copysign`](../../std/primitive.f64.html#method.copysign) +#[rustc_nounwind] +#[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf64(_x: f64, _y: f64) -> f64 { + unimplemented!(); +} + +/// Copies the sign from `y` to `x` for `f128` values. +/// +/// The stabilized version of this intrinsic is +/// [`f128::copysign`](../../std/primitive.f128.html#method.copysign) +#[rustc_nounwind] +// #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] +#[rustc_const_unstable(feature = "f128", issue = "116909")] +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +pub const unsafe fn copysignf128(_x: f128, _y: f128) -> f128 { + unimplemented!(); +} + /// Inform Miri that a given pointer definitely has a certain alignment. #[cfg(miri)] pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) { diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7f9a21524265..482e1f30b7e9 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -120,6 +120,7 @@ #![feature(const_char_encode_utf16)] #![feature(const_eval_select)] #![feature(const_exact_div)] +#![feature(const_float_methods)] #![feature(const_fmt_arguments_new)] #![feature(const_hash)] #![feature(const_heap)] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 764df4fe4b05..5ab2ab50d7c6 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -471,7 +471,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -497,7 +497,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. // SAFETY: This is just transmuting to get the sign bit, it's fine. @@ -538,7 +538,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_up(self) -> Self { + pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -592,7 +592,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_down(self) -> Self { + pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -627,8 +627,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn recip(self) -> Self { + pub const fn recip(self) -> Self { 1.0 / self } @@ -647,8 +648,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_degrees(self) -> Self { + pub const fn to_degrees(self) -> Self { // Use a literal for better precision. const PIS_IN_180: f128 = 57.2957795130823208767981548141051703324054724665643215491602_f128; self * PIS_IN_180 @@ -670,8 +672,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_radians(self) -> f128 { + pub const fn to_radians(self) -> f128 { // Use a literal for better precision. const RADS_PER_DEG: f128 = 0.0174532925199432957692369076848861271344287188854172545609719_f128; @@ -698,8 +701,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn max(self, other: f128) -> f128 { + pub const fn max(self, other: f128) -> f128 { intrinsics::maxnumf128(self, other) } @@ -723,8 +727,9 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn min(self, other: f128) -> f128 { + pub const fn min(self, other: f128) -> f128 { intrinsics::minnumf128(self, other) } @@ -757,7 +762,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn maximum(self, other: f128) -> f128 { + pub const fn maximum(self, other: f128) -> f128 { if self > other { self } else if other > self { @@ -798,7 +803,7 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn minimum(self, other: f128) -> f128 { + pub const fn minimum(self, other: f128) -> f128 { if self < other { self } else if other < self { @@ -1269,9 +1274,20 @@ impl f128 { /// ``` #[inline] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn clamp(mut self, min: f128, max: f128) -> f128 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f128, max: f128) -> f128 { + #[inline] // inline to avoid LLVM crash + const fn assert_at_const(min: f128, max: f128) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f128, max: f128) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 897fc8c105d4..60a88496696c 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -459,7 +459,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] - pub fn is_sign_positive(self) -> bool { + pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() } @@ -488,7 +488,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] - pub fn is_sign_negative(self) -> bool { + pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. // SAFETY: This is just transmuting to get the sign bit, it's fine. @@ -529,7 +529,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_up(self) -> Self { + pub const fn next_up(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -583,7 +583,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_next_up_down", issue = "91399")] - pub fn next_down(self) -> Self { + pub const fn next_down(self) -> Self { // Some targets violate Rust's assumption of IEEE semantics, e.g. by flushing // denormals to zero. This is in general unsound and unsupported, but here // we do our best to still produce the correct result on such targets. @@ -618,8 +618,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn recip(self) -> Self { + pub const fn recip(self) -> Self { 1.0 / self } @@ -638,8 +639,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_degrees(self) -> Self { + pub const fn to_degrees(self) -> Self { // Use a literal for better precision. const PIS_IN_180: f16 = 57.2957795130823208767981548141051703_f16; self * PIS_IN_180 @@ -661,8 +663,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the operation, without modifying the original"] - pub fn to_radians(self) -> f16 { + pub const fn to_radians(self) -> f16 { // Use a literal for better precision. const RADS_PER_DEG: f16 = 0.017453292519943295769236907684886_f16; self * RADS_PER_DEG @@ -687,8 +690,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn max(self, other: f16) -> f16 { + pub const fn max(self, other: f16) -> f16 { intrinsics::maxnumf16(self, other) } @@ -711,8 +715,9 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn min(self, other: f16) -> f16 { + pub const fn min(self, other: f16) -> f16 { intrinsics::minnumf16(self, other) } @@ -744,7 +749,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn maximum(self, other: f16) -> f16 { + pub const fn maximum(self, other: f16) -> f16 { if self > other { self } else if other > self { @@ -784,7 +789,7 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] // #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[must_use = "this returns the result of the comparison, without modifying either input"] - pub fn minimum(self, other: f16) -> f16 { + pub const fn minimum(self, other: f16) -> f16 { if self < other { self } else if other < self { @@ -1244,9 +1249,20 @@ impl f16 { /// ``` #[inline] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn clamp(mut self, min: f16, max: f16) -> f16 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f16, max: f16) -> f16 { + #[inline] // inline to avoid LLVM crash + const fn assert_at_const(min: f16, max: f16) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f16, max: f16) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index a9a2595c25c2..05f5a08ad0ac 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -828,8 +828,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn recip(self) -> f32 { + pub const fn recip(self) -> f32 { 1.0 / self } @@ -845,8 +846,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_degrees(self) -> f32 { + pub const fn to_degrees(self) -> f32 { // Use a constant for better precision. const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32; self * PIS_IN_180 @@ -864,8 +866,9 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_radians(self) -> f32 { + pub const fn to_radians(self) -> f32 { const RADS_PER_DEG: f32 = consts::PI / 180.0; self * RADS_PER_DEG } @@ -885,8 +888,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn max(self, other: f32) -> f32 { + pub const fn max(self, other: f32) -> f32 { intrinsics::maxnumf32(self, other) } @@ -905,8 +909,9 @@ impl f32 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn min(self, other: f32) -> f32 { + pub const fn min(self, other: f32) -> f32 { intrinsics::minnumf32(self, other) } @@ -933,7 +938,7 @@ impl f32 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn maximum(self, other: f32) -> f32 { + pub const fn maximum(self, other: f32) -> f32 { if self > other { self } else if other > self { @@ -968,7 +973,7 @@ impl f32 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn minimum(self, other: f32) -> f32 { + pub const fn minimum(self, other: f32) -> f32 { if self < other { self } else if other < self { @@ -1401,9 +1406,19 @@ impl f32 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn clamp(mut self, min: f32, max: f32) -> f32 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f32, max: f32) -> f32 { + const fn assert_at_const(min: f32, max: f32) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f32, max: f32) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index aa7a54ca6508..89c6726d985e 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -845,8 +845,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn recip(self) -> f64 { + pub const fn recip(self) -> f64 { 1.0 / self } @@ -862,8 +863,9 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_degrees(self) -> f64 { + pub const fn to_degrees(self) -> f64 { // The division here is correctly rounded with respect to the true // value of 180/π. (This differs from f32, where a constant must be // used to ensure a correctly rounded result.) @@ -882,8 +884,9 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn to_radians(self) -> f64 { + pub const fn to_radians(self) -> f64 { const RADS_PER_DEG: f64 = consts::PI / 180.0; self * RADS_PER_DEG } @@ -903,8 +906,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn max(self, other: f64) -> f64 { + pub const fn max(self, other: f64) -> f64 { intrinsics::maxnumf64(self, other) } @@ -923,8 +927,9 @@ impl f64 { /// ``` #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn min(self, other: f64) -> f64 { + pub const fn min(self, other: f64) -> f64 { intrinsics::minnumf64(self, other) } @@ -951,7 +956,7 @@ impl f64 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn maximum(self, other: f64) -> f64 { + pub const fn maximum(self, other: f64) -> f64 { if self > other { self } else if other > self { @@ -986,7 +991,7 @@ impl f64 { #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] - pub fn minimum(self, other: f64) -> f64 { + pub const fn minimum(self, other: f64) -> f64 { if self < other { self } else if other < self { @@ -1401,9 +1406,19 @@ impl f64 { /// ``` #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "clamp", since = "1.50.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn clamp(mut self, min: f64, max: f64) -> f64 { - assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + pub const fn clamp(mut self, min: f64, max: f64) -> f64 { + const fn assert_at_const(min: f64, max: f64) { + // Note that we cannot format in constant expressions. + assert!(min <= max, "min > max, or either was NaN"); + } + #[inline] // inline to avoid codegen regression + fn assert_at_rt(min: f64, max: f64) { + assert!(min <= max, "min > max, or either was NaN. min = {min:?}, max = {max:?}"); + } + // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly. + intrinsics::const_eval_select((min, max), assert_at_const, assert_at_rt); if self < min { self = min; } diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index b436fe9929c3..229f979b5b10 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -210,8 +210,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn abs(self) -> Self { + pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available // We don't do this now because LLVM has lowering bugs for f128 math. Self::from_bits(self.to_bits() & !(1 << 127)) @@ -240,8 +241,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn signum(self) -> f128 { + pub const fn signum(self) -> f128 { if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } } @@ -278,8 +280,9 @@ impl f128 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn copysign(self, sign: f128) -> f128 { + pub const fn copysign(self, sign: f128) -> f128 { unsafe { intrinsics::copysignf128(self, sign) } } diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index b2cd5fae9d04..bed21cda1cd9 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -210,8 +210,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn abs(self) -> Self { + pub const fn abs(self) -> Self { // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available Self::from_bits(self.to_bits() & !(1 << 15)) } @@ -239,8 +240,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn signum(self) -> f16 { + pub const fn signum(self) -> f16 { if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } } @@ -277,8 +279,9 @@ impl f16 { #[inline] #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] - pub fn copysign(self, sign: f16) -> f16 { + pub const fn copysign(self, sign: f16) -> f16 { unsafe { intrinsics::copysignf16(self, sign) } } diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index fa0b3ef6484f..30cf4e1f756e 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -194,8 +194,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn abs(self) -> f32 { + pub const fn abs(self) -> f32 { unsafe { intrinsics::fabsf32(self) } } @@ -218,8 +219,9 @@ impl f32 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn signum(self) -> f32 { + pub const fn signum(self) -> f32 { if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } } @@ -253,7 +255,8 @@ impl f32 { #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "copysign", since = "1.35.0")] - pub fn copysign(self, sign: f32) -> f32 { + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + pub const fn copysign(self, sign: f32) -> f32 { unsafe { intrinsics::copysignf32(self, sign) } } diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 9fa43a6742ea..51d5476b372d 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -194,8 +194,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn abs(self) -> f64 { + pub const fn abs(self) -> f64 { unsafe { intrinsics::fabsf64(self) } } @@ -218,8 +219,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn signum(self) -> f64 { + pub const fn signum(self) -> f64 { if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } } @@ -252,8 +254,9 @@ impl f64 { #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] - pub fn copysign(self, sign: f64) -> f64 { + pub const fn copysign(self, sign: f64) -> f64 { unsafe { intrinsics::copysignf64(self, sign) } } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 65a9aa66c7cc..990d83513cfb 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -288,6 +288,7 @@ #![feature(cfg_target_thread_local)] #![feature(cfi_encoding)] #![feature(concat_idents)] +#![feature(const_float_methods)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] #![feature(doc_cfg)] diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 9f772cfa982d..e0d27f21dae9 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -145,20 +145,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_bool(branch), dest)?; } - // Floating-point operations - "fabsf32" => { - let [f] = check_arg_count(args)?; - let f = this.read_scalar(f)?.to_f32()?; - // This is a "bitwise" operation, so there's no NaN non-determinism. - this.write_scalar(Scalar::from_f32(f.abs()), dest)?; - } - "fabsf64" => { - let [f] = check_arg_count(args)?; - let f = this.read_scalar(f)?.to_f64()?; - // This is a "bitwise" operation, so there's no NaN non-determinism. - this.write_scalar(Scalar::from_f64(f.abs()), dest)?; - } - "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "rintf32" => { let [f] = check_arg_count(args)?; let f = this.read_scalar(f)?.to_f32()?; @@ -249,31 +235,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } - "minnumf32" | "maxnumf32" | "copysignf32" => { - let [a, b] = check_arg_count(args)?; - let a = this.read_scalar(a)?.to_f32()?; - let b = this.read_scalar(b)?.to_f32()?; - let res = match intrinsic_name { - "minnumf32" => this.adjust_nan(a.min(b), &[a, b]), - "maxnumf32" => this.adjust_nan(a.max(b), &[a, b]), - "copysignf32" => a.copy_sign(b), // bitwise, no NaN adjustments - _ => bug!(), - }; - this.write_scalar(Scalar::from_f32(res), dest)?; - } - "minnumf64" | "maxnumf64" | "copysignf64" => { - let [a, b] = check_arg_count(args)?; - let a = this.read_scalar(a)?.to_f64()?; - let b = this.read_scalar(b)?.to_f64()?; - let res = match intrinsic_name { - "minnumf64" => this.adjust_nan(a.min(b), &[a, b]), - "maxnumf64" => this.adjust_nan(a.max(b), &[a, b]), - "copysignf64" => a.copy_sign(b), // bitwise, no NaN adjustments - _ => bug!(), - }; - this.write_scalar(Scalar::from_f64(res), dest)?; - } - "fmaf32" => { let [a, b, c] = check_arg_count(args)?; let a = this.read_scalar(a)?.to_f32()?; diff --git a/tests/ui/consts/const-eval/float_methods.rs b/tests/ui/consts/const-eval/float_methods.rs new file mode 100644 index 000000000000..49c31f68c5fa --- /dev/null +++ b/tests/ui/consts/const-eval/float_methods.rs @@ -0,0 +1,47 @@ +//@ run-pass +//! Tests the float intrinsics: min, max, abs, copysign + +#![feature(const_float_methods)] +#![feature(f16, f128)] + +const F16_MIN: f16 = 1.0_f16.min(0.5_f16); +const F16_MAX: f16 = 1.0_f16.max(0.5_f16); +const F16_ABS: f16 = (-1.0_f16).abs(); +const F16_COPYSIGN: f16 = 1.0_f16.copysign(-2.0_f16); + +const F32_MIN: f32 = 1.0_f32.min(0.5_f32); +const F32_MAX: f32 = 1.0_f32.max(0.5_f32); +const F32_ABS: f32 = (-1.0_f32).abs(); +const F32_COPYSIGN: f32 = 1.0_f32.copysign(-2.0_f32); + +const F64_MIN: f64 = 1.0_f64.min(0.5_f64); +const F64_MAX: f64 = 1.0_f64.max(0.5_f64); +const F64_ABS: f64 = (-1.0_f64).abs(); +const F64_COPYSIGN: f64 = 1.0_f64.copysign(-2.0_f64); + +const F128_MIN: f128 = 1.0_f128.min(0.5_f128); +const F128_MAX: f128 = 1.0_f128.max(0.5_f128); +const F128_ABS: f128 = (-1.0_f128).abs(); +const F128_COPYSIGN: f128 = 1.0_f128.copysign(-2.0_f128); + +fn main() { + assert_eq!(F16_MIN, 0.5); + assert_eq!(F16_MAX, 1.0); + assert_eq!(F16_ABS, 1.0); + assert_eq!(F16_COPYSIGN, -1.0); + + assert_eq!(F32_MIN, 0.5); + assert_eq!(F32_MAX, 1.0); + assert_eq!(F32_ABS, 1.0); + assert_eq!(F32_COPYSIGN, -1.0); + + assert_eq!(F64_MIN, 0.5); + assert_eq!(F64_MAX, 1.0); + assert_eq!(F64_ABS, 1.0); + assert_eq!(F64_COPYSIGN, -1.0); + + assert_eq!(F128_MIN, 0.5); + assert_eq!(F128_MAX, 1.0); + assert_eq!(F128_ABS, 1.0); + assert_eq!(F128_COPYSIGN, -1.0); +} From 918dc38733985770d1cdcea76169340c620c1f32 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:23:39 +0900 Subject: [PATCH 072/118] Combine impl_int and impl_uint Two macros are exactly the same. --- library/core/src/fmt/num.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index aecd725eca56..cc94c392de58 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -31,22 +31,11 @@ macro_rules! impl_int { })* ) } -macro_rules! impl_uint { - ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* - ) -} -impl_int! { i8 i16 i32 i64 i128 isize } -impl_uint! { u8 u16 u32 u64 u128 usize } +impl_int! { + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize +} /// A type that represents a specific radix /// From 0637517da6802bcdc8df9a73a75edb8c41033f11 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:32:21 +0900 Subject: [PATCH 073/118] Rename debug! macro to impl_Debug! --- library/core/src/fmt/num.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index cc94c392de58..0f33d730a68e 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -167,7 +167,8 @@ integer! { i16, u16 } integer! { i32, u32 } integer! { i64, u64 } integer! { i128, u128 } -macro_rules! debug { + +macro_rules! impl_Debug { ($($T:ident)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for $T { @@ -184,10 +185,6 @@ macro_rules! debug { } )*}; } -debug! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize -} // 2 digit decimal look up table static DEC_DIGITS_LUT: &[u8; 200] = b"0001020304050607080910111213141516171819\ @@ -510,6 +507,11 @@ macro_rules! impl_Exp { }; } +impl_Debug! { + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize +} + // Include wasm32 in here since it doesn't reflect the native pointer size, and // often cares strongly about getting a smaller code size. #[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))] From 1a9d2d82a5ee24d05dac2287b87ffd96f77d6d77 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 21 Sep 2024 07:02:51 +0000 Subject: [PATCH 074/118] stabilize `-Znext-solver=coherence` --- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_session/src/config.rs | 5 ++ compiler/rustc_session/src/options.rs | 31 +++---- .../src/traits/engine.rs | 4 +- .../associated-types-coherence-failure.stderr | 8 +- .../opaque_type_candidate_selection.rs | 30 ------- ...e-negative-outlives-lifetimes.stock.stderr | 2 + ...s-lifetimes.with_negative_coherence.stderr | 2 + ...overlap-negate-not-use-feature-gate.stderr | 2 + ...unnormalizable-projection-0.classic.stderr | 1 - ...unnormalizable-projection-1.classic.stderr | 2 +- ...oherence-check-placeholder-outlives.stderr | 2 + ...oherence-considering-regions.any_lt.stderr | 2 + ...constraints-on-unification.explicit.stderr | 1 + .../normalize-for-errors.current.stderr | 5 +- tests/ui/coherence/normalize-for-errors.rs | 6 +- .../ui/coherence/normalize-for-errors.stderr | 15 ++++ .../occurs-check/associated-type.old.stderr | 8 +- .../occurs-check/opaques.current.stderr | 12 +++ .../occurs-check/opaques.next.stderr | 4 +- tests/ui/coherence/occurs-check/opaques.rs | 7 +- ...reporting-if-references-err.current.stderr | 17 +--- .../skip-reporting-if-references-err.rs | 6 -- .../skip-reporting-if-references-err.stderr | 14 ++++ .../super-trait-knowable-1.current.stderr | 13 --- .../super-traits/super-trait-knowable-1.rs | 6 +- .../super-trait-knowable-3.current.stderr | 13 --- .../super-traits/super-trait-knowable-3.rs | 6 +- .../unevaluated-const-ice-119731.rs | 1 + .../unevaluated-const-ice-119731.stderr | 23 +++-- ...nown-alias-defkind-anonconst-ice-116710.rs | 1 - ...-alias-defkind-anonconst-ice-116710.stderr | 14 +--- tests/ui/error-codes/e0119/issue-23563.stderr | 2 +- ...eature-gate-with_negative_coherence.stderr | 2 + .../structually-relate-aliases.rs | 3 +- .../structually-relate-aliases.stderr | 33 +++----- .../auto-trait-coherence.old.stderr | 4 +- tests/ui/impl-trait/auto-trait-coherence.rs | 6 +- .../ui/impl-trait/auto-trait-coherence.stderr | 12 +++ .../impl-trait/coherence-treats-tait-ambig.rs | 2 +- .../coherence-treats-tait-ambig.stderr | 2 +- tests/ui/impl-trait/negative-reasoning.rs | 2 +- tests/ui/impl-trait/negative-reasoning.stderr | 6 +- tests/ui/impl-unused-tps.rs | 46 +++++----- tests/ui/impl-unused-tps.stderr | 84 ++++++++++++------- tests/ui/issues/issue-48728.rs | 8 +- .../defaultimpl/specialization-no-default.rs | 3 +- ...efault-items-drop-coherence.current.stderr | 12 +++ ...n-default-items-drop-coherence.next.stderr | 2 +- ...ialization-default-items-drop-coherence.rs | 8 +- ...lization-overlap-projection.current.stderr | 22 ++++- ...cialization-overlap-projection.next.stderr | 6 +- .../specialization-overlap-projection.rs | 13 +-- .../specialization-overlap-projection.stderr | 30 +++++++ tests/ui/traits/alias/issue-83613.rs | 2 +- tests/ui/traits/alias/issue-83613.stderr | 4 +- tests/ui/traits/issue-105231.rs | 3 +- tests/ui/traits/issue-105231.stderr | 22 ++--- .../next-solver/coherence/issue-102048.rs | 10 +-- .../next-solver/coherence/issue-102048.stderr | 16 ++++ .../cycle-via-builtin-auto-trait-impl.rs | 2 +- .../cycle-via-builtin-auto-trait-impl.stderr | 26 ++---- .../impl_trait_for_same_tait.stderr | 2 - .../implied_lifetime_wf_check.error.stderr | 4 +- .../ui/type-alias-impl-trait/issue-104817.rs | 2 +- .../issue-104817.stock.stderr | 4 +- 68 files changed, 347 insertions(+), 329 deletions(-) delete mode 100644 tests/ui/auto-traits/opaque_type_candidate_selection.rs create mode 100644 tests/ui/coherence/normalize-for-errors.stderr create mode 100644 tests/ui/coherence/occurs-check/opaques.current.stderr create mode 100644 tests/ui/coherence/skip-reporting-if-references-err.stderr delete mode 100644 tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr delete mode 100644 tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr create mode 100644 tests/ui/impl-trait/auto-trait-coherence.stderr create mode 100644 tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr create mode 100644 tests/ui/specialization/specialization-overlap-projection.stderr create mode 100644 tests/ui/traits/next-solver/coherence/issue-102048.stderr diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 05850ca32602..f2773dcdc601 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -666,7 +666,7 @@ fn check_incompatible_features(sess: &Session, features: &Features) { } fn check_new_solver_banned_features(sess: &Session, features: &Features) { - if !sess.opts.unstable_opts.next_solver.is_some_and(|n| n.globally) { + if !sess.opts.unstable_opts.next_solver.globally { return; } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 536ce154cd07..3189620e969d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -810,7 +810,7 @@ fn test_unstable_options_tracking_hash() { tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); - tracked!(next_solver, Some(NextSolverConfig { coherence: true, globally: false })); + tracked!(next_solver, NextSolverConfig { coherence: true, globally: true }); tracked!(no_generate_arange_section, true); tracked!(no_jump_tables, true); tracked!(no_link, true); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1bdcae4dfb47..c2a550604906 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3128,11 +3128,11 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn next_trait_solver_globally(self) -> bool { - self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally) + self.sess.opts.unstable_opts.next_solver.globally } pub fn next_trait_solver_in_coherence(self) -> bool { - self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence) + self.sess.opts.unstable_opts.next_solver.coherence } pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d2c03e588ff3..d733e32f209d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -842,6 +842,11 @@ pub struct NextSolverConfig { /// This is only `true` if `coherence` is also enabled. pub globally: bool, } +impl Default for NextSolverConfig { + fn default() -> Self { + NextSolverConfig { coherence: true, globally: false } + } +} #[derive(Clone)] pub enum Input { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index d63276db4938..f9964b59a941 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -403,7 +403,7 @@ mod desc { pub(crate) const parse_unpretty: &str = "`string` or `string=string`"; pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number"; pub(crate) const parse_next_solver_config: &str = - "a comma separated list of solver configurations: `globally` (default), and `coherence`"; + "either `globally` (when used without an argument), `coherence` (default) or `no`"; pub(crate) const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub(crate) const parse_linker_plugin_lto: &str = @@ -1123,27 +1123,16 @@ mod parse { } } - pub(crate) fn parse_next_solver_config( - slot: &mut Option, - v: Option<&str>, - ) -> bool { + pub(crate) fn parse_next_solver_config(slot: &mut NextSolverConfig, v: Option<&str>) -> bool { if let Some(config) = v { - let mut coherence = false; - let mut globally = true; - for c in config.split(',') { - match c { - "globally" => globally = true, - "coherence" => { - globally = false; - coherence = true; - } - _ => return false, - } - } - - *slot = Some(NextSolverConfig { coherence: coherence || globally, globally }); + *slot = match config { + "no" => NextSolverConfig { coherence: false, globally: false }, + "coherence" => NextSolverConfig { coherence: true, globally: false }, + "globally" => NextSolverConfig { coherence: true, globally: true }, + _ => return false, + }; } else { - *slot = Some(NextSolverConfig { coherence: true, globally: true }); + *slot = NextSolverConfig { coherence: true, globally: true }; } true @@ -1914,7 +1903,7 @@ options! { "the size at which the `large_assignments` lint starts to be emitted"), mutable_noalias: bool = (true, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: yes)"), - next_solver: Option = (None, parse_next_solver_config, [TRACKED], + next_solver: NextSolverConfig = (NextSolverConfig::default(), parse_next_solver_config, [TRACKED], "enable and configure the next generation trait solver used by rustc"), nll_facts: bool = (false, parse_bool, [UNTRACKED], "dump facts from NLL analysis into side files (default: no)"), diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index d562692c1a86..7df9b6feb965 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -36,10 +36,8 @@ where if infcx.next_trait_solver() { Box::new(NextFulfillmentCtxt::new(infcx)) } else { - let new_solver_globally = - infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally); assert!( - !new_solver_globally, + !infcx.tcx.next_trait_solver_globally(), "using old solver even though new solver is enabled globally" ); Box::new(FulfillmentContext::new(infcx)) diff --git a/tests/ui/associated-types/associated-types-coherence-failure.stderr b/tests/ui/associated-types/associated-types-coherence-failure.stderr index 211613b37149..25c22e5f82ac 100644 --- a/tests/ui/associated-types/associated-types-coherence-failure.stderr +++ b/tests/ui/associated-types/associated-types-coherence-failure.stderr @@ -1,20 +1,20 @@ -error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `Cow<'_, _>` +error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned` --> $DIR/associated-types-coherence-failure.rs:21:1 | LL | impl<'a, B: ?Sized> IntoCow<'a, B> for ::Owned where B: ToOwned { | ----------------------------------------------------------------------------- first implementation here ... LL | impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cow<'_, _>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned` -error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `&_` +error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned` --> $DIR/associated-types-coherence-failure.rs:28:1 | LL | impl<'a, B: ?Sized> IntoCow<'a, B> for ::Owned where B: ToOwned { | ----------------------------------------------------------------------------- first implementation here ... LL | impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned` error: aborting due to 2 previous errors diff --git a/tests/ui/auto-traits/opaque_type_candidate_selection.rs b/tests/ui/auto-traits/opaque_type_candidate_selection.rs deleted file mode 100644 index d6973b76a6e1..000000000000 --- a/tests/ui/auto-traits/opaque_type_candidate_selection.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! used to ICE: #119272 - -//@ check-pass - -#![feature(type_alias_impl_trait)] -mod defining_scope { - use super::*; - pub type Alias = impl Sized; - - pub fn cast(x: Container, T>) -> Container { - x - } -} - -struct Container, U> { - x: >::Assoc, -} - -trait Trait { - type Assoc; -} - -impl Trait for T { - type Assoc = Box; -} -impl Trait for defining_scope::Alias { - type Assoc = usize; -} - -fn main() {} diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr index dbb22d8937d5..1d28bb46812c 100644 --- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr +++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr @@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here LL | impl<'a, T> MyTrait<'a> for &'a T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr index dbb22d8937d5..1d28bb46812c 100644 --- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr +++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr @@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {} | ---------------------------------------------- first implementation here LL | impl<'a, T> MyTrait<'a> for &'a T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr index 21c82eedd5df..c5bb695eb188 100644 --- a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr +++ b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr @@ -5,6 +5,8 @@ LL | impl Foo for T {} | --------------------------- first implementation here LL | impl Foo for &U {} | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr index 2ffb6000ec82..99abdf65abd5 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr @@ -12,7 +12,6 @@ LL | impl Trait for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` | = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - = note: downstream crates may implement trait `WhereBound` for type ` as WithAssoc<'a>>::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr index 49b236f9d2aa..781ab0fcbf76 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr @@ -12,7 +12,7 @@ LL | impl Trait for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` | = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box< as WithAssoc<'a>>::Assoc>` + = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<_>` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr index f515c39ea8d1..bf1ffcb5f000 100644 --- a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr +++ b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr @@ -5,6 +5,8 @@ LL | impl Bar for T where T: Foo {} | ------------------------------ first implementation here LL | impl Bar for Box {} | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` + | + = note: downstream crates may implement trait `Foo` for type `std::boxed::Box<_>` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr index f24de10f6ac4..97e2e9759c17 100644 --- a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr +++ b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr @@ -6,6 +6,8 @@ LL | impl Bar for T where T: Foo {} ... LL | impl Bar for &T {} | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `Foo` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr index 832c56a45549..8d59cbc3466b 100644 --- a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr +++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr @@ -8,6 +8,7 @@ LL | impl FnMarker for fn(&T) {} | = warning: the behavior may change in a future release = note: for more information, see issue #56105 + = note: downstream crates may implement trait `Marker` for type `&_` = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:4:11 diff --git a/tests/ui/coherence/normalize-for-errors.current.stderr b/tests/ui/coherence/normalize-for-errors.current.stderr index dcbb73bd1ff1..634a10b7a14c 100644 --- a/tests/ui/coherence/normalize-for-errors.current.stderr +++ b/tests/ui/coherence/normalize-for-errors.current.stderr @@ -1,12 +1,13 @@ -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, _)` +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)` --> $DIR/normalize-for-errors.rs:17:1 | LL | impl MyTrait for (T, S::Item) {} | ------------------------------------------------------ first implementation here LL | LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` | + = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions error: aborting due to 1 previous error diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs index c17bb766b5bc..3ef91eb0386c 100644 --- a/tests/ui/coherence/normalize-for-errors.rs +++ b/tests/ui/coherence/normalize-for-errors.rs @@ -1,7 +1,3 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver - struct MyType; trait MyTrait {} @@ -18,6 +14,6 @@ impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} //~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, //~| NOTE conflicting implementation for `(Box<(MyType,)>, //~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions -//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions +//~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions fn main() {} diff --git a/tests/ui/coherence/normalize-for-errors.stderr b/tests/ui/coherence/normalize-for-errors.stderr new file mode 100644 index 000000000000..6fbcf5b0e1ac --- /dev/null +++ b/tests/ui/coherence/normalize-for-errors.stderr @@ -0,0 +1,15 @@ +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)` + --> $DIR/normalize-for-errors.rs:13:1 + | +LL | impl MyTrait for (T, S::Item) {} + | ------------------------------------------------------ first implementation here +LL | +LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` + | + = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions + = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index ccc7f30fa6fd..6a4c6fe54a83 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -1,12 +1,8 @@ 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), .. } -error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` +error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` --> $DIR/associated-type.rs:31:1 | LL | impl Overlap for T { @@ -16,7 +12,7 @@ LL | / impl Overlap fn(&'a (), Assoc<'a, T>)> for T LL | | LL | | where LL | | for<'a> *const T: ToUnit<'a>, - | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), _)` + | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), ())` | = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr new file mode 100644 index 000000000000..96ef7cd4322b --- /dev/null +++ b/tests/ui/coherence/occurs-check/opaques.current.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait<_>` + --> $DIR/opaques.rs:27:1 + | +LL | impl Trait for T { + | ---------------------- first implementation here +... +LL | impl Trait for defining_scope::Alias { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index 757219398f18..2bedff25ecd9 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:30:1 + --> $DIR/opaques.rs:27:1 | LL | impl Trait for T { | ---------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Trait for defining_scope::Alias { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:13:23 + --> $DIR/opaques.rs:10:23 | LL | pub fn cast(x: Container, T>) -> Container { | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index 241a247c8413..d7032dd53d97 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -1,10 +1,7 @@ -//@revisions: old next +//@revisions: current next //@[next] compile-flags: -Znext-solver // A regression test for #105787 - -//@[old] known-bug: #105787 -//@[old] check-pass #![feature(type_alias_impl_trait)] mod defining_scope { use super::*; @@ -28,7 +25,7 @@ impl Trait for T { type Assoc = Box; } impl Trait for defining_scope::Alias { - //[next]~^ ERROR conflicting implementations of trait + //~^ ERROR conflicting implementations of trait type Assoc = usize; } diff --git a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr index 5eef3256b2c3..5de4cf626e48 100644 --- a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr +++ b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr @@ -9,19 +9,6 @@ help: indicate the anonymous lifetime LL | impl ToUnit<'_> for T {} | ++++ -error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied - --> $DIR/skip-reporting-if-references-err.rs:15:29 - | -LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()` +error: aborting due to 1 previous error -error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied - --> $DIR/skip-reporting-if-references-err.rs:15:18 - | -LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0726. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/skip-reporting-if-references-err.rs b/tests/ui/coherence/skip-reporting-if-references-err.rs index f9eaa498232d..dd8a71c4700f 100644 --- a/tests/ui/coherence/skip-reporting-if-references-err.rs +++ b/tests/ui/coherence/skip-reporting-if-references-err.rs @@ -1,8 +1,4 @@ // Regression test for #121006. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver - trait ToUnit<'a> { type Unit; } @@ -13,7 +9,5 @@ impl ToUnit for T {} trait Overlap {} impl Overlap for fn(U) {} impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {} -//[current]~^ ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied -//[current]~| ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/coherence/skip-reporting-if-references-err.stderr b/tests/ui/coherence/skip-reporting-if-references-err.stderr new file mode 100644 index 000000000000..0ff3e88a0af9 --- /dev/null +++ b/tests/ui/coherence/skip-reporting-if-references-err.stderr @@ -0,0 +1,14 @@ +error[E0726]: implicit elided lifetime not allowed here + --> $DIR/skip-reporting-if-references-err.rs:6:9 + | +LL | impl ToUnit for T {} + | ^^^^^^ expected lifetime parameter + | +help: indicate the anonymous lifetime + | +LL | impl ToUnit<'_> for T {} + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr deleted file mode 100644 index fb01cf158d98..000000000000 --- a/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` - --> $DIR/super-trait-knowable-1.rs:16:1 - | -LL | impl> Overlap for U {} - | ----------------------------------- first implementation here -LL | impl Overlap for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` - | - = note: downstream crates may implement trait `Sub<_>` for type `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs index 80df8c19ee51..77af4d0f2e3a 100644 --- a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs +++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs @@ -3,10 +3,7 @@ // We therefore elaborate super trait bounds in the implicit negative // overlap check. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass trait Super {} trait Sub: Super {} @@ -14,6 +11,5 @@ trait Sub: Super {} trait Overlap {} impl> Overlap for U {} impl Overlap for () {} -//[current]~^ ERROR conflicting implementations fn main() {} diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr deleted file mode 100644 index 542edb8b7f67..000000000000 --- a/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()` - --> $DIR/super-trait-knowable-3.rs:19:1 - | -LL | impl>> Overlap for U {} - | ---------------------------------------- first implementation here -LL | impl Overlap for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()` - | - = note: downstream crates may implement trait `Sub<_>` for type `()` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.rs b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs index 295d7ac48d8c..6198d3d303bd 100644 --- a/tests/ui/coherence/super-traits/super-trait-knowable-3.rs +++ b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs @@ -2,10 +2,7 @@ // super trait bound is in a nested goal so this would not // compile if we were to only elaborate root goals. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass trait Super {} trait Sub: Super {} @@ -17,6 +14,5 @@ impl, U> Bound> for T {} trait Overlap {} impl>> Overlap for U {} impl Overlap for () {} -//[current]~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()` fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs index d11b457a3f61..a55be99fc0be 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs @@ -22,6 +22,7 @@ mod v20 { impl v17<512, v0> { pub const fn v21() -> v18 {} //~^ ERROR cannot find type `v18` in this scope + //~| ERROR duplicate definitions with name `v21` } impl v17 { diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index 45be31c7ba35..30a45ce377e7 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `v20::v13` - --> $DIR/unevaluated-const-ice-119731.rs:37:15 + --> $DIR/unevaluated-const-ice-119731.rs:38:15 | LL | pub use v20::{v13, v17}; | ^^^ @@ -23,7 +23,7 @@ LL | pub const fn v21() -> v18 {} | ^^^ help: a type alias with a similar name exists: `v11` error[E0412]: cannot find type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:30:31 + --> $DIR/unevaluated-const-ice-119731.rs:31:31 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -32,7 +32,7 @@ LL | pub const fn v21() -> v18 { | ^^^ help: a type alias with a similar name exists: `v11` error[E0422]: cannot find struct, variant or union type `v18` in this scope - --> $DIR/unevaluated-const-ice-119731.rs:32:13 + --> $DIR/unevaluated-const-ice-119731.rs:33:13 | LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here @@ -73,20 +73,29 @@ LL + #![feature(adt_const_params)] | error: maximum number of nodes exceeded in constant v20::v17::::{constant#0} - --> $DIR/unevaluated-const-ice-119731.rs:27:37 + --> $DIR/unevaluated-const-ice-119731.rs:28:37 | LL | impl v17 { | ^^ error: maximum number of nodes exceeded in constant v20::v17::::{constant#0} - --> $DIR/unevaluated-const-ice-119731.rs:27:37 + --> $DIR/unevaluated-const-ice-119731.rs:28:37 | LL | impl v17 { | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 9 previous errors; 2 warnings emitted +error[E0592]: duplicate definitions with name `v21` + --> $DIR/unevaluated-const-ice-119731.rs:23:9 + | +LL | pub const fn v21() -> v18 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `v21` +... +LL | pub const fn v21() -> v18 { + | ------------------------- other definition for `v21` -Some errors have detailed explanations: E0412, E0422, E0425, E0432. +error: aborting due to 10 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0412, E0422, E0425, E0432, E0592. For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs index dd0b1e8c9f71..81ac9979bd8c 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs @@ -10,6 +10,5 @@ trait Trait {} impl Trait for A {} impl Trait for A {} -//~^ ERROR conflicting implementations of trait `Trait` for type `A<_>` pub fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr index 80ac96d48700..e29c49ff0422 100644 --- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr @@ -4,16 +4,6 @@ error[E0423]: expected value, found builtin type `u8` LL | struct A; | ^^ not a value -error[E0119]: conflicting implementations of trait `Trait` for type `A<_>` - --> $DIR/unknown-alias-defkind-anonconst-ice-116710.rs:12:1 - | -LL | impl Trait for A {} - | --------------------------------- first implementation here -LL | -LL | impl Trait for A {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A<_>` +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0119, E0423. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/error-codes/e0119/issue-23563.stderr b/tests/ui/error-codes/e0119/issue-23563.stderr index 86737742f749..a308769af131 100644 --- a/tests/ui/error-codes/e0119/issue-23563.stderr +++ b/tests/ui/error-codes/e0119/issue-23563.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>` +error[E0119]: conflicting implementations of trait `LolFrom<&[u8]>` for type `LocalType` --> $DIR/issue-23563.rs:13:1 | LL | impl<'a, T> LolFrom<&'a [T]> for LocalType { diff --git a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr index ba076568088b..b32f54aaecfa 100644 --- a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr +++ b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr @@ -6,6 +6,8 @@ LL | impl Foo for T { } LL | LL | impl Foo for &T { } | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_` + | + = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_` error: aborting due to 1 previous error diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs index 8df24702811d..698824509613 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.rs +++ b/tests/ui/higher-ranked/structually-relate-aliases.rs @@ -11,7 +11,6 @@ type Assoc<'a, T> = >::Unit; impl Overlap for T {} impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} -//~^ ERROR 13:17: 13:49: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277] -//~| ERROR 13:36: 13:48: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277] +//~^ ERROR conflicting implementations of trait `Overlap fn(&'a (), _)>` fn main() {} diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 7de30efae1cd..4ecd5829bc35 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,27 +1,18 @@ 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), .. } -error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied - --> $DIR/structually-relate-aliases.rs:13:36 + 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, '^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), .. } +error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` + --> $DIR/structually-relate-aliases.rs:13:1 | +LL | impl Overlap for T {} + | ------------------------ first implementation here +LL | LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)` | -help: consider restricting type parameter `T` - | -LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ++++++++++++++++++++ + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details -error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied - --> $DIR/structually-relate-aliases.rs:13:17 - | -LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ++++++++++++++++++++ +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/auto-trait-coherence.old.stderr b/tests/ui/impl-trait/auto-trait-coherence.old.stderr index 3f979d1a50b3..cd91bfcb48d7 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.old.stderr +++ b/tests/ui/impl-trait/auto-trait-coherence.old.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` --> $DIR/auto-trait-coherence.rs:24:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs index e3036fd0fe2c..0d7fef21cc92 100644 --- a/tests/ui/impl-trait/auto-trait-coherence.rs +++ b/tests/ui/impl-trait/auto-trait-coherence.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that type alias impls traits do not leak auto-traits for // the purposes of coherence checking #![feature(type_alias_impl_trait)] @@ -22,8 +19,7 @@ impl AnotherTrait for T {} // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D { - //[old]~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` - //[next]~^^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` } fn main() {} diff --git a/tests/ui/impl-trait/auto-trait-coherence.stderr b/tests/ui/impl-trait/auto-trait-coherence.stderr new file mode 100644 index 000000000000..e0f4c857717c --- /dev/null +++ b/tests/ui/impl-trait/auto-trait-coherence.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` + --> $DIR/auto-trait-coherence.rs:21:1 + | +LL | impl AnotherTrait for T {} + | -------------------------------- first implementation here +... +LL | impl AnotherTrait for D { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs index df47208bf367..e8c1fcdd2133 100644 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs @@ -5,7 +5,7 @@ type T = impl Sized; struct Foo; impl Into for Foo { -//~^ ERROR conflicting implementations of trait `Into` for type `Foo` +//~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo` fn into(self) -> T { Foo } diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr index faaad2769271..618bef1f2714 100644 --- a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr +++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `Into` for type `Foo` +error[E0119]: conflicting implementations of trait `Into<_>` for type `Foo` --> $DIR/coherence-treats-tait-ambig.rs:7:1 | LL | impl Into for Foo { diff --git a/tests/ui/impl-trait/negative-reasoning.rs b/tests/ui/impl-trait/negative-reasoning.rs index 70e24a3a9d02..0474dc0beda6 100644 --- a/tests/ui/impl-trait/negative-reasoning.rs +++ b/tests/ui/impl-trait/negative-reasoning.rs @@ -17,7 +17,7 @@ impl AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>` } fn main() {} diff --git a/tests/ui/impl-trait/negative-reasoning.stderr b/tests/ui/impl-trait/negative-reasoning.stderr index 3cb4be16fc3f..631784c817b8 100644 --- a/tests/ui/impl-trait/negative-reasoning.stderr +++ b/tests/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>` --> $DIR/negative-reasoning.rs:19:1 | LL | impl AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` - | - = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `OpaqueType` in future versions + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>` error: aborting due to 1 previous error diff --git a/tests/ui/impl-unused-tps.rs b/tests/ui/impl-unused-tps.rs index 3eb9daedf76d..a5836db3c8e6 100644 --- a/tests/ui/impl-unused-tps.rs +++ b/tests/ui/impl-unused-tps.rs @@ -1,34 +1,35 @@ -//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized - trait Foo { - fn get(&self, A: &A) { } + fn get(&self, A: &A) {} } trait Bar { type Out; } -impl Foo for [isize;0] { +impl Foo for [isize; 0] { // OK, T is used in `Foo`. } -impl Foo for [isize;1] { +impl Foo for [isize; 1] { //~^ ERROR the type parameter `U` is not constrained } -impl Foo for [isize;2] where T : Bar { +impl Foo for [isize; 2] +where + T: Bar, +{ // OK, `U` is now constrained by the output type parameter. } -impl,U> Foo for [isize;3] { +impl, U> Foo for [isize; 3] { // OK, same as above but written differently. } -impl Foo for U { +impl Foo for U { //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]` } -impl Bar for T { +impl Bar for T { //~^ ERROR the type parameter `U` is not constrained type Out = U; @@ -36,28 +37,33 @@ impl Bar for T { // Using `U` in an associated type within the impl is not good enough! } -impl Bar for T - where T : Bar +impl Bar for T +where + T: Bar, { - //~^^^ ERROR the type parameter `U` is not constrained - + //~^^^^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates + //~| ERROR conflicting implementations of trait `Bar` // This crafty self-referential attempt is still no good. } -impl Foo for T - where (T,U): Bar +impl Foo for T +where + (T, U): Bar, { - //~^^^ ERROR the type parameter `U` is not constrained - //~| ERROR the type parameter `V` is not constrained + //~^^^^ ERROR the type parameter `U` is not constrained + //~| ERROR the type parameter `V` is not constrained + //~| ERROR conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]` // Here, `V` is bound by an output type parameter, but the inputs // are not themselves constrained. } -impl Foo<(T,U)> for T - where (T,U): Bar +impl Foo<(T, U)> for T +where + (T, U): Bar, { + //~^^^^ ERROR conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]` // As above, but both T and U ARE constrained. } -fn main() { } +fn main() {} diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr index af427cb5f3e3..da4589dee827 100644 --- a/tests/ui/impl-unused-tps.stderr +++ b/tests/ui/impl-unused-tps.stderr @@ -1,56 +1,76 @@ error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` - --> $DIR/impl-unused-tps.rs:27:1 + --> $DIR/impl-unused-tps.rs:28:1 | -LL | impl Foo for [isize;0] { - | ---------------------------- first implementation here +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here ... -LL | impl Foo for U { - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` +LL | impl Foo for U { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` -error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` +error[E0119]: conflicting implementations of trait `Bar` + --> $DIR/impl-unused-tps.rs:40:1 | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) -note: required for `([isize; 0], _)` to implement `Bar` - --> $DIR/impl-unused-tps.rs:31:11 +LL | impl Bar for T { + | -------------------- first implementation here +... +LL | / impl Bar for T +LL | | where +LL | | T: Bar, + | |____________________^ conflicting implementation + +error[E0119]: conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]` + --> $DIR/impl-unused-tps.rs:49:1 | -LL | impl Bar for T { - | - ^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: 126 redundant requirements hidden - = note: required for `([isize; 0], _)` to implement `Bar` +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here +... +LL | / impl Foo for T +LL | | where +LL | | (T, U): Bar, + | |_________________________^ conflicting implementation for `[isize; 0]` + +error[E0119]: conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]` + --> $DIR/impl-unused-tps.rs:61:1 + | +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here +... +LL | / impl Foo<(T, U)> for T +LL | | where +LL | | (T, U): Bar, + | |_________________________^ conflicting implementation for `[isize; 0]` error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:15:8 + --> $DIR/impl-unused-tps.rs:13:9 | -LL | impl Foo for [isize;1] { - | ^ unconstrained type parameter +LL | impl Foo for [isize; 1] { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:31:8 + --> $DIR/impl-unused-tps.rs:32:9 | -LL | impl Bar for T { - | ^ unconstrained type parameter +LL | impl Bar for T { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:39:8 + --> $DIR/impl-unused-tps.rs:40:9 | -LL | impl Bar for T - | ^ unconstrained type parameter +LL | impl Bar for T + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:8 + --> $DIR/impl-unused-tps.rs:49:9 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:10 + --> $DIR/impl-unused-tps.rs:49:12 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0119, E0207, E0275. +Some errors have detailed explanations: E0119, E0207. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/issues/issue-48728.rs b/tests/ui/issues/issue-48728.rs index 7ef05f4277b2..8ad9289c65cf 100644 --- a/tests/ui/issues/issue-48728.rs +++ b/tests/ui/issues/issue-48728.rs @@ -1,12 +1,8 @@ // Regression test for #48728, an ICE that occurred computing // coherence "help" information. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[next] check-pass - -#[derive(Clone)] //[current]~ ERROR conflicting implementations of trait `Clone` +//@ check-pass +#[derive(Clone)] struct Node(Box); impl Clone for Node<[T]> { diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.rs b/tests/ui/specialization/defaultimpl/specialization-no-default.rs index 661724eef8a4..ddc32337306f 100644 --- a/tests/ui/specialization/defaultimpl/specialization-no-default.rs +++ b/tests/ui/specialization/defaultimpl/specialization-no-default.rs @@ -71,7 +71,8 @@ impl Redundant for T { } default impl Redundant for i32 { - fn redundant(&self) {} //~ ERROR E0520 + fn redundant(&self) {} + //~^ ERROR `redundant` specializes an item from a parent `impl`, but that item is not marked `default` } fn main() {} diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr new file mode 100644 index 000000000000..36df6bfd9fc1 --- /dev/null +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Overlap` for type `u32` + --> $DIR/specialization-default-items-drop-coherence.rs:26:1 + | +LL | impl Overlap for u32 { + | -------------------- first implementation here +... +LL | impl Overlap for ::Id { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr index e9498a003179..36df6bfd9fc1 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Overlap` for type `u32` - --> $DIR/specialization-default-items-drop-coherence.rs:29:1 + --> $DIR/specialization-default-items-drop-coherence.rs:26:1 | LL | impl Overlap for u32 { | -------------------- first implementation here diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs index 6dc012776391..b3c1f72777c4 100644 --- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs +++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs @@ -1,8 +1,5 @@ -//@ revisions: classic coherence next +//@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[coherence] compile-flags: -Znext-solver=coherence -//@[classic] check-pass -//@[classic] known-bug: #105782 // Should fail. Default items completely drop candidates instead of ambiguity, // which is unsound during coherence, since coherence requires completeness. @@ -27,8 +24,7 @@ impl Overlap for u32 { } impl Overlap for ::Id { - //[coherence]~^ ERROR conflicting implementations of trait `Overlap` for type `u32` - //[next]~^^ ERROR conflicting implementations of trait `Overlap` for type `u32` + //~^ ERROR conflicting implementations of trait `Overlap` for type `u32` type Assoc = Box; } diff --git a/tests/ui/specialization/specialization-overlap-projection.current.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr index a69826fa96b0..4e77cb17fbb0 100644 --- a/tests/ui/specialization/specialization-overlap-projection.current.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.current.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:10:12 + --> $DIR/specialization-overlap-projection.rs:4:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -8,5 +8,23 @@ LL | #![feature(specialization)] = help: consider using `min_specialization` instead, which is more stable and complete = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:19:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:21:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +... +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr index 5b17696162ed..4e77cb17fbb0 100644 --- a/tests/ui/specialization/specialization-overlap-projection.next.stderr +++ b/tests/ui/specialization/specialization-overlap-projection.next.stderr @@ -1,5 +1,5 @@ warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/specialization-overlap-projection.rs:10:12 + --> $DIR/specialization-overlap-projection.rs:4:12 | LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![feature(specialization)] = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:25:1 + --> $DIR/specialization-overlap-projection.rs:19:1 | LL | impl Foo for u32 {} | ---------------- first implementation here @@ -17,7 +17,7 @@ LL | impl Foo for ::Output {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` error[E0119]: conflicting implementations of trait `Foo` for type `u32` - --> $DIR/specialization-overlap-projection.rs:27:1 + --> $DIR/specialization-overlap-projection.rs:21:1 | LL | impl Foo for u32 {} | ---------------- first implementation here diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs index 16dccf82dcb9..f7a2a7922432 100644 --- a/tests/ui/specialization/specialization-overlap-projection.rs +++ b/tests/ui/specialization/specialization-overlap-projection.rs @@ -1,13 +1,8 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -//@[current] check-pass - // Test that impls on projected self types can resolve overlap, even when the // projections involve specialization, so long as the associated type is // provided by the most specialized impl. - -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes trait Assoc { type Output; @@ -23,8 +18,8 @@ impl Assoc for u16 { type Output = u16; } trait Foo {} impl Foo for u32 {} impl Foo for ::Output {} -//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` +//~^ ERROR conflicting implementations of trait `Foo` for type `u32` impl Foo for ::Output {} -//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32` +//~^ ERROR conflicting implementations of trait `Foo` for type `u32` fn main() {} diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.stderr new file mode 100644 index 000000000000..5f3cd9c66cfe --- /dev/null +++ b/tests/ui/specialization/specialization-overlap-projection.stderr @@ -0,0 +1,30 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-overlap-projection.rs:4:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:20:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error[E0119]: conflicting implementations of trait `Foo` for type `u32` + --> $DIR/specialization-overlap-projection.rs:22:1 + | +LL | impl Foo for u32 {} + | ---------------- first implementation here +... +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/alias/issue-83613.rs b/tests/ui/traits/alias/issue-83613.rs index 2462e703a716..6f0012bf0896 100644 --- a/tests/ui/traits/alias/issue-83613.rs +++ b/tests/ui/traits/alias/issue-83613.rs @@ -8,5 +8,5 @@ fn mk_opaque() -> OpaqueType { trait AnotherTrait {} impl AnotherTrait for T {} impl AnotherTrait for OpaqueType {} -//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +//~^ ERROR conflicting implementations of trait `AnotherTrait` fn main() {} diff --git a/tests/ui/traits/alias/issue-83613.stderr b/tests/ui/traits/alias/issue-83613.stderr index 847fda417766..47181c3f33ed 100644 --- a/tests/ui/traits/alias/issue-83613.stderr +++ b/tests/ui/traits/alias/issue-83613.stderr @@ -1,10 +1,10 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +error[E0119]: conflicting implementations of trait `AnotherTrait` --> $DIR/issue-83613.rs:10:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs index 7338642beefa..83c3158c106b 100644 --- a/tests/ui/traits/issue-105231.rs +++ b/tests/ui/traits/issue-105231.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow evaluating the requirement `A>>>>>>: Send` struct A(B); //~^ ERROR recursive types `A` and `B` have infinite size //~| ERROR `T` is only used recursively @@ -7,5 +6,5 @@ struct B(A>); trait Foo {} impl Foo for T where T: Send {} impl Foo for B {} - +//~^ ERROR conflicting implementations of trait `Foo` for type `B` fn main() {} diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr index d3014a79ad60..e113f8382b2f 100644 --- a/tests/ui/traits/issue-105231.stderr +++ b/tests/ui/traits/issue-105231.stderr @@ -1,5 +1,5 @@ error[E0072]: recursive types `A` and `B` have infinite size - --> $DIR/issue-105231.rs:2:1 + --> $DIR/issue-105231.rs:1:1 | LL | struct A(B); | ^^^^^^^^^^^ ---- recursive without indirection @@ -16,7 +16,7 @@ LL ~ struct B(Box>>); | error: type parameter `T` is only used recursively - --> $DIR/issue-105231.rs:2:15 + --> $DIR/issue-105231.rs:1:15 | LL | struct A(B); | - ^ @@ -27,7 +27,7 @@ LL | struct A(B); = note: all type parameters must be used in a non-recursive way in order to constrain their variance error: type parameter `T` is only used recursively - --> $DIR/issue-105231.rs:5:17 + --> $DIR/issue-105231.rs:4:17 | LL | struct B(A>); | - ^ @@ -37,16 +37,18 @@ LL | struct B(A>); = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = note: all type parameters must be used in a non-recursive way in order to constrain their variance -error[E0275]: overflow evaluating the requirement `A>>>>>>: Send` +error[E0119]: conflicting implementations of trait `Foo` for type `B` + --> $DIR/issue-105231.rs:8:1 | +LL | impl Foo for T where T: Send {} + | ------------------------------- first implementation here +LL | impl Foo for B {} + | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `B` + | + = note: overflow evaluating the requirement `B: Send` = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`) -note: required because it appears within the type `B>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-105231.rs:5:8 - | -LL | struct B(A>); - | ^ error: aborting due to 4 previous errors -Some errors have detailed explanations: E0072, E0275. +Some errors have detailed explanations: E0072, E0119. For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/traits/next-solver/coherence/issue-102048.rs b/tests/ui/traits/next-solver/coherence/issue-102048.rs index 16ae5d98488d..847816eba12f 100644 --- a/tests/ui/traits/next-solver/coherence/issue-102048.rs +++ b/tests/ui/traits/next-solver/coherence/issue-102048.rs @@ -1,7 +1,7 @@ // This must fail coherence. // // Getting this to pass was fairly difficult, so here's an explanation -// of what's happening: +// of what was previously happening for this to compile: // // Normalizing projections currently tries to replace them with inference variables // while emitting a nested `Projection` obligation. This cannot be done if the projection @@ -17,12 +17,6 @@ // that to `i32`. We then try to unify `i32` from `impl1` with `u32` from `impl2` which fails, // causing coherence to consider these two impls distinct. -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - -//@[classic] known-bug: #102048 -//@[classic] check-pass - pub trait Trait {} pub trait WithAssoc1<'a> { @@ -42,7 +36,7 @@ where // impl 2 impl Trait fn(>::Assoc, u32)> for (T, U) where - U: for<'a> WithAssoc1<'a> //[next]~^ ERROR conflicting implementations of trait + U: for<'a> WithAssoc1<'a> //~^ ERROR conflicting implementations of trait { } diff --git a/tests/ui/traits/next-solver/coherence/issue-102048.stderr b/tests/ui/traits/next-solver/coherence/issue-102048.stderr new file mode 100644 index 000000000000..e496517464b9 --- /dev/null +++ b/tests/ui/traits/next-solver/coherence/issue-102048.stderr @@ -0,0 +1,16 @@ +error[E0119]: conflicting implementations of trait `Trait fn(<_ as WithAssoc1<'a>>::Assoc, <_ as WithAssoc2<'a>>::Assoc)>` for type `(_, _)` + --> $DIR/issue-102048.rs:38:1 + | +LL | / impl Trait fn(>::Assoc, >::Assoc)> for (T, U) +LL | | where +LL | | T: for<'a> WithAssoc1<'a> + for<'a> WithAssoc2<'a, Assoc = i32>, +LL | | U: for<'a> WithAssoc2<'a>, + | |______________________________- first implementation here +... +LL | / impl Trait fn(>::Assoc, u32)> for (T, U) where +LL | | U: for<'a> WithAssoc1<'a> + | |_____________________________^ conflicting implementation for `(_, _)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs index d37943b929a1..43443be88df7 100644 --- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs +++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs @@ -1,4 +1,3 @@ -//~ ERROR overflow // A regression test for #111729 checking that we correctly // track recursion depth for obligations returned by confirmation. use std::panic::RefUnwindSafe; @@ -18,6 +17,7 @@ impl Database for T { type Storage = SalsaStorage; } impl Database for RootDatabase { + //~^ ERROR conflicting implementations of trait `Database` for type `RootDatabase` type Storage = SalsaStorage; } diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr index 2ab150fc0f62..1da7671b4519 100644 --- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr +++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr @@ -1,24 +1,12 @@ -error[E0275]: overflow evaluating the requirement `Runtime: RefUnwindSafe` - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`) -note: required because it appears within the type `RootDatabase` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8 - | -LL | struct RootDatabase { - | ^^^^^^^^^^^^ -note: required for `RootDatabase` to implement `Database` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24 +error[E0119]: conflicting implementations of trait `Database` for type `RootDatabase` + --> $DIR/cycle-via-builtin-auto-trait-impl.rs:19:1 | LL | impl Database for T { - | ------------- ^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required because it appears within the type `Runtime` - --> $DIR/cycle-via-builtin-auto-trait-impl.rs:24:8 - | -LL | struct Runtime { - | ^^^^^^^ + | ------------------------------------- first implementation here +... +LL | impl Database for RootDatabase { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `RootDatabase` 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 E0119`. diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr index e35913be899f..aaf75cc3db97 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr @@ -15,8 +15,6 @@ LL | impl Bop for Bar<()> {} ... LL | impl Bop for Barr {} | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>` - | - = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `Barr` in future versions error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>` --> $DIR/impl_trait_for_same_tait.rs:30:1 diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr index a97227e481ef..49997b073c95 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.error.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `Yay` for type `Alias` +error[E0119]: conflicting implementations of trait `Yay` for type `<() as HideIt>::Assoc` --> $DIR/implied_lifetime_wf_check.rs:26:1 | LL | impl Yay for <() as HideIt>::Assoc {} | ---------------------------------- first implementation here LL | #[cfg(error)] LL | impl Yay for i32 {} - | ^^^^^^^^^^^^^^^^ conflicting implementation for `Alias` + | ^^^^^^^^^^^^^^^^ conflicting implementation for `<() as HideIt>::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs index 4679d025fce0..491463216145 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.rs +++ b/tests/ui/type-alias-impl-trait/issue-104817.rs @@ -14,6 +14,6 @@ fn mk_opaque() -> OpaqueType { trait AnotherTrait {} impl AnotherTrait for T {} impl AnotherTrait for OpaqueType {} -//[stock]~^ conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +//[stock]~^ conflicting implementations of trait `AnotherTrait` fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr index 41c5206d9e88..df5a6c320a8a 100644 --- a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr +++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr @@ -1,10 +1,10 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType` +error[E0119]: conflicting implementations of trait `AnotherTrait` --> $DIR/issue-104817.rs:16:1 | LL | impl AnotherTrait for T {} | -------------------------------- first implementation here LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error From d3f982d46601c559c7f6ffd7155fcedfc1afc5e1 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 21 Sep 2024 07:04:42 +0000 Subject: [PATCH 075/118] rebase and update fixed `crashes` --- tests/crashes/118987.rs | 17 ------------ .../default-impl-normalization-ambig-2.rs} | 4 ++- .../default-impl-normalization-ambig-2.stderr | 21 +++++++++++++++ .../default-item-normalization-ambig-1.rs} | 5 ++-- .../default-item-normalization-ambig-1.stderr | 21 +++++++++++++++ .../coherence-bikeshed-intrinsic-from.rs} | 4 ++- .../coherence-bikeshed-intrinsic-from.stderr | 27 +++++++++++++++++++ 7 files changed, 78 insertions(+), 21 deletions(-) delete mode 100644 tests/crashes/118987.rs rename tests/{crashes/118987-2.rs => ui/specialization/coherence/default-impl-normalization-ambig-2.rs} (74%) create mode 100644 tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr rename tests/{crashes/74299.rs => ui/specialization/coherence/default-item-normalization-ambig-1.rs} (56%) create mode 100644 tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr rename tests/{crashes/124207.rs => ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs} (62%) create mode 100644 tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr diff --git a/tests/crashes/118987.rs b/tests/crashes/118987.rs deleted file mode 100644 index 4382a7bcb639..000000000000 --- a/tests/crashes/118987.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #118987 -#![feature(specialization)] //~ WARN the feature `specialization` is incomplete - -trait Assoc { - type Output; -} - -default impl Assoc for T { - type Output = bool; -} - -impl Assoc for u8 {} - -trait Foo {} - -impl Foo for ::Output {} -impl Foo for ::Output {} diff --git a/tests/crashes/118987-2.rs b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs similarity index 74% rename from tests/crashes/118987-2.rs rename to tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs index 4382a7bcb639..1691530fa0a5 100644 --- a/tests/crashes/118987-2.rs +++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs @@ -1,4 +1,4 @@ -//@ known-bug: #118987 +// regression test for #118987 #![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait Assoc { @@ -15,3 +15,5 @@ trait Foo {} impl Foo for ::Output {} impl Foo for ::Output {} +//~^ ERROR the trait bound `u16: Assoc` is not satisfied +fn main() {} diff --git a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr new file mode 100644 index 000000000000..a2fca2ef5b67 --- /dev/null +++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr @@ -0,0 +1,21 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-impl-normalization-ambig-2.rs:2:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `u16: Assoc` is not satisfied + --> $DIR/default-impl-normalization-ambig-2.rs:17:14 + | +LL | impl Foo for ::Output {} + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Assoc` is not implemented for `u16` + | + = help: the trait `Assoc` is implemented for `u8` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/crashes/74299.rs b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs similarity index 56% rename from tests/crashes/74299.rs rename to tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs index 0e2ddce1c5b1..af7cf332d5f4 100644 --- a/tests/crashes/74299.rs +++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs @@ -1,5 +1,5 @@ -//@ known-bug: #74299 -#![feature(specialization)] +// regression test for #73299. +#![feature(specialization)] //~ WARN the feature `specialization` is incomplete trait X { type U; @@ -18,6 +18,7 @@ trait Y { impl Y for <() as X>::U {} impl Y for ::U {} +//~^ ERROR conflicting implementations of trait `Y` for type `<() as X>::U` fn main() { ().f().g(); diff --git a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr new file mode 100644 index 000000000000..a15151cc9c41 --- /dev/null +++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr @@ -0,0 +1,21 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-item-normalization-ambig-1.rs:2:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0119]: conflicting implementations of trait `Y` for type `<() as X>::U` + --> $DIR/default-item-normalization-ambig-1.rs:20:1 + | +LL | impl Y for <() as X>::U {} + | ----------------------- first implementation here +LL | impl Y for ::U {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<() as X>::U` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/124207.rs b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs similarity index 62% rename from tests/crashes/124207.rs rename to tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs index a11eedb140a6..0cebc99cd419 100644 --- a/tests/crashes/124207.rs +++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs @@ -1,9 +1,11 @@ -//@ known-bug: #124207 #![feature(transmutability)] #![feature(type_alias_impl_trait)] trait OpaqueTrait {} type OpaqueType = impl OpaqueTrait; +//~^ ERROR unconstrained opaque type trait AnotherTrait {} impl> AnotherTrait for T {} +//~^ ERROR type provided when a constant was expected impl AnotherTrait for OpaqueType {} +//~^ ERROR conflicting implementations of trait `AnotherTrait` pub fn main() {} diff --git a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr new file mode 100644 index 000000000000..2424541af23e --- /dev/null +++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr @@ -0,0 +1,27 @@ +error: unconstrained opaque type + --> $DIR/coherence-bikeshed-intrinsic-from.rs:4:19 + | +LL | type OpaqueType = impl OpaqueTrait; + | ^^^^^^^^^^^^^^^^ + | + = note: `OpaqueType` must be used in combination with a concrete type within the same module + +error[E0747]: type provided when a constant was expected + --> $DIR/coherence-bikeshed-intrinsic-from.rs:7:37 + | +LL | impl> AnotherTrait for T {} + | ^^ + +error[E0119]: conflicting implementations of trait `AnotherTrait` + --> $DIR/coherence-bikeshed-intrinsic-from.rs:9:1 + | +LL | impl> AnotherTrait for T {} + | ----------------------------------------------------------- first implementation here +LL | +LL | impl AnotherTrait for OpaqueType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0747. +For more information about an error, try `rustc --explain E0119`. From 7aeb07a58326e9c2f1876de62877bd95a04ec35b Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 21 Sep 2024 07:05:19 +0000 Subject: [PATCH 076/118] remove unnecessary revisions --- ...nce-overlap-downstream-inherent.old.stderr | 23 ------------------- .../coherence-overlap-downstream-inherent.rs | 3 --- ...erence-overlap-downstream-inherent.stderr} | 4 ++-- .../coherence-overlap-downstream.old.stderr | 21 ----------------- .../coherence/coherence-overlap-downstream.rs | 3 --- ...rr => coherence-overlap-downstream.stderr} | 4 ++-- ...ce-overlap-issue-23516-inherent.old.stderr | 14 ----------- .../coherence-overlap-issue-23516-inherent.rs | 3 --- ...rence-overlap-issue-23516-inherent.stderr} | 2 +- .../coherence-overlap-issue-23516.old.stderr | 13 ----------- .../coherence-overlap-issue-23516.rs | 3 --- ...r => coherence-overlap-issue-23516.stderr} | 2 +- ...ap-unnormalizable-projection-0.next.stderr | 18 --------------- ...nce-overlap-unnormalizable-projection-0.rs | 3 --- ...verlap-unnormalizable-projection-0.stderr} | 2 +- ...ap-unnormalizable-projection-1.next.stderr | 19 --------------- ...nce-overlap-unnormalizable-projection-1.rs | 3 --- ...verlap-unnormalizable-projection-1.stderr} | 2 +- tests/ui/coherence/coherent-due-to-fulfill.rs | 2 -- .../incoherent-even-though-we-fulfill.rs | 2 -- .../incoherent-even-though-we-fulfill.stderr | 2 +- ...er-crate-ambiguity-causes-notes.old.stderr | 17 -------------- .../inter-crate-ambiguity-causes-notes.rs | 3 --- ...inter-crate-ambiguity-causes-notes.stderr} | 2 +- .../normalize-for-errors.current.stderr | 15 ------------ .../normalize-for-errors.next.stderr | 15 ------------ .../occurs-check/associated-type.next.stderr | 4 ++-- .../occurs-check/associated-type.old.stderr | 2 +- .../coherence/occurs-check/associated-type.rs | 1 + .../occurs-check/opaques.current.stderr | 2 +- .../occurs-check/opaques.next.stderr | 4 ++-- tests/ui/coherence/occurs-check/opaques.rs | 3 ++- ...heck-opaque-types-not-covering.next.stderr | 21 ----------------- .../orphan-check-opaque-types-not-covering.rs | 3 --- ...an-check-opaque-types-not-covering.stderr} | 4 ++-- .../orphan-check-projections-covering.rs | 3 --- ...heck-weak-aliases-not-covering.next.stderr | 12 ---------- .../orphan-check-weak-aliases-not-covering.rs | 3 --- ...an-check-weak-aliases-not-covering.stderr} | 2 +- ...reporting-if-references-err.current.stderr | 14 ----------- ...ip-reporting-if-references-err.next.stderr | 14 ----------- .../super-traits/super-trait-knowable-2.rs | 3 --- .../coherence-bikeshed-intrinsic-from.stderr | 16 ++++++------- 43 files changed, 30 insertions(+), 281 deletions(-) delete mode 100644 tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr rename tests/ui/coherence/{coherence-overlap-downstream-inherent.next.stderr => coherence-overlap-downstream-inherent.stderr} (87%) delete mode 100644 tests/ui/coherence/coherence-overlap-downstream.old.stderr rename tests/ui/coherence/{coherence-overlap-downstream.next.stderr => coherence-overlap-downstream.stderr} (88%) delete mode 100644 tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr rename tests/ui/coherence/{coherence-overlap-issue-23516-inherent.next.stderr => coherence-overlap-issue-23516-inherent.stderr} (90%) delete mode 100644 tests/ui/coherence/coherence-overlap-issue-23516.old.stderr rename tests/ui/coherence/{coherence-overlap-issue-23516.next.stderr => coherence-overlap-issue-23516.stderr} (90%) delete mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr rename tests/ui/coherence/{coherence-overlap-unnormalizable-projection-0.classic.stderr => coherence-overlap-unnormalizable-projection-0.stderr} (91%) delete mode 100644 tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr rename tests/ui/coherence/{coherence-overlap-unnormalizable-projection-1.classic.stderr => coherence-overlap-unnormalizable-projection-1.stderr} (92%) delete mode 100644 tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr rename tests/ui/coherence/{inter-crate-ambiguity-causes-notes.next.stderr => inter-crate-ambiguity-causes-notes.stderr} (90%) delete mode 100644 tests/ui/coherence/normalize-for-errors.current.stderr delete mode 100644 tests/ui/coherence/normalize-for-errors.next.stderr delete mode 100644 tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr rename tests/ui/coherence/{orphan-check-opaque-types-not-covering.classic.stderr => orphan-check-opaque-types-not-covering.stderr} (92%) delete mode 100644 tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr rename tests/ui/coherence/{orphan-check-weak-aliases-not-covering.classic.stderr => orphan-check-weak-aliases-not-covering.stderr} (92%) delete mode 100644 tests/ui/coherence/skip-reporting-if-references-err.current.stderr delete mode 100644 tests/ui/coherence/skip-reporting-if-references-err.next.stderr diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr b/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr deleted file mode 100644 index 2938bc629b2c..000000000000 --- a/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0592]: duplicate definitions with name `dummy` - --> $DIR/coherence-overlap-downstream-inherent.rs:10:26 - | -LL | impl Sweet { fn dummy(&self) { } } - | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` -LL | -LL | impl Sweet { fn dummy(&self) { } } - | --------------- other definition for `dummy` - -error[E0592]: duplicate definitions with name `f` - --> $DIR/coherence-overlap-downstream-inherent.rs:16:38 - | -LL | impl A where T: Bar { fn f(&self) {} } - | ^^^^^^^^^^^ duplicate definitions for `f` -LL | -LL | impl A { fn f(&self) {} } - | ----------- other definition for `f` - | - = note: downstream crates may implement trait `Bar<_>` for type `i32` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0592`. diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs index 3e90b7c7fdd3..5dea33e330b6 100644 --- a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs +++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even // though no impls are found. diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr b/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr similarity index 87% rename from tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr rename to tests/ui/coherence/coherence-overlap-downstream-inherent.stderr index 2938bc629b2c..bbce4b530b4d 100644 --- a/tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr +++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr @@ -1,5 +1,5 @@ error[E0592]: duplicate definitions with name `dummy` - --> $DIR/coherence-overlap-downstream-inherent.rs:10:26 + --> $DIR/coherence-overlap-downstream-inherent.rs:7:26 | LL | impl Sweet { fn dummy(&self) { } } | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` @@ -8,7 +8,7 @@ LL | impl Sweet { fn dummy(&self) { } } | --------------- other definition for `dummy` error[E0592]: duplicate definitions with name `f` - --> $DIR/coherence-overlap-downstream-inherent.rs:16:38 + --> $DIR/coherence-overlap-downstream-inherent.rs:13:38 | LL | impl A where T: Bar { fn f(&self) {} } | ^^^^^^^^^^^ duplicate definitions for `f` diff --git a/tests/ui/coherence/coherence-overlap-downstream.old.stderr b/tests/ui/coherence/coherence-overlap-downstream.old.stderr deleted file mode 100644 index 6c2e9466b4bd..000000000000 --- a/tests/ui/coherence/coherence-overlap-downstream.old.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0119]: conflicting implementations of trait `Sweet` - --> $DIR/coherence-overlap-downstream.rs:11:1 - | -LL | impl Sweet for T { } - | ------------------------- first implementation here -LL | impl Sweet for T { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation - -error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32` - --> $DIR/coherence-overlap-downstream.rs:17:1 - | -LL | impl Foo for T where T: Bar {} - | --------------------------------------- first implementation here -LL | impl Foo for i32 {} - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32` - | - = note: downstream crates may implement trait `Bar<_>` for type `i32` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-downstream.rs b/tests/ui/coherence/coherence-overlap-downstream.rs index 8b99296d12a4..738ec0e3d455 100644 --- a/tests/ui/coherence/coherence-overlap-downstream.rs +++ b/tests/ui/coherence/coherence-overlap-downstream.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even // though no impls are found. diff --git a/tests/ui/coherence/coherence-overlap-downstream.next.stderr b/tests/ui/coherence/coherence-overlap-downstream.stderr similarity index 88% rename from tests/ui/coherence/coherence-overlap-downstream.next.stderr rename to tests/ui/coherence/coherence-overlap-downstream.stderr index 6c2e9466b4bd..9ab099489d9e 100644 --- a/tests/ui/coherence/coherence-overlap-downstream.next.stderr +++ b/tests/ui/coherence/coherence-overlap-downstream.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Sweet` - --> $DIR/coherence-overlap-downstream.rs:11:1 + --> $DIR/coherence-overlap-downstream.rs:8:1 | LL | impl Sweet for T { } | ------------------------- first implementation here @@ -7,7 +7,7 @@ LL | impl Sweet for T { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32` - --> $DIR/coherence-overlap-downstream.rs:17:1 + --> $DIR/coherence-overlap-downstream.rs:14:1 | LL | impl Foo for T where T: Bar {} | --------------------------------------- first implementation here diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr deleted file mode 100644 index 2f3ad6278088..000000000000 --- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0592]: duplicate definitions with name `dummy` - --> $DIR/coherence-overlap-issue-23516-inherent.rs:12:25 - | -LL | impl Cake { fn dummy(&self) { } } - | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` -LL | -LL | impl Cake> { fn dummy(&self) { } } - | --------------- other definition for `dummy` - | - = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0592`. diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs index 53b0a40fa661..a272e620fcab 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs +++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that we consider `Box: !Sugar` to be ambiguous, even // though we see no impl of `Sugar` for `Box`. Therefore, an overlap // error is reported for the following pair of impls (#23516). diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr similarity index 90% rename from tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr rename to tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr index 2f3ad6278088..aacdeb5b0f97 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr +++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr @@ -1,5 +1,5 @@ error[E0592]: duplicate definitions with name `dummy` - --> $DIR/coherence-overlap-issue-23516-inherent.rs:12:25 + --> $DIR/coherence-overlap-issue-23516-inherent.rs:9:25 | LL | impl Cake { fn dummy(&self) { } } | ^^^^^^^^^^^^^^^ duplicate definitions for `dummy` diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr b/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr deleted file mode 100644 index b94947740254..000000000000 --- a/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>` - --> $DIR/coherence-overlap-issue-23516.rs:11:1 - | -LL | impl Sweet for T { } - | ------------------------- first implementation here -LL | impl Sweet for Box { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` - | - = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.rs b/tests/ui/coherence/coherence-overlap-issue-23516.rs index 620e00cd0572..63e42e8f412d 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516.rs +++ b/tests/ui/coherence/coherence-overlap-issue-23516.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - // Tests that we consider `Box: !Sugar` to be ambiguous, even // though we see no impl of `Sugar` for `Box`. Therefore, an overlap // error is reported for the following pair of impls (#23516). diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.next.stderr b/tests/ui/coherence/coherence-overlap-issue-23516.stderr similarity index 90% rename from tests/ui/coherence/coherence-overlap-issue-23516.next.stderr rename to tests/ui/coherence/coherence-overlap-issue-23516.stderr index b94947740254..7b1b240291a8 100644 --- a/tests/ui/coherence/coherence-overlap-issue-23516.next.stderr +++ b/tests/ui/coherence/coherence-overlap-issue-23516.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>` - --> $DIR/coherence-overlap-issue-23516.rs:11:1 + --> $DIR/coherence-overlap-issue-23516.rs:8:1 | LL | impl Sweet for T { } | ------------------------- first implementation here diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr deleted file mode 100644 index 99abdf65abd5..000000000000 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` - --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1 - | -LL | / impl Trait for T -LL | | where -LL | | T: 'static, -LL | | for<'a> T: WithAssoc<'a>, -LL | | for<'a> >::Assoc: WhereBound, - | |____________________________________________________- first implementation here -... -LL | impl Trait for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` - | - = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs index b8b6d8846ef7..0695076e221e 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs @@ -2,9 +2,6 @@ // "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could" #![crate_type = "lib"] -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - trait WhereBound {} impl WhereBound for () {} diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr similarity index 91% rename from tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr rename to tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr index 99abdf65abd5..57befbe6e68d 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` - --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1 + --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:24:1 | LL | / impl Trait for T LL | | where diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr deleted file mode 100644 index 781ab0fcbf76..000000000000 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` - --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1 - | -LL | / impl Trait for T -LL | | where -LL | | T: 'static, -LL | | for<'a> T: WithAssoc<'a>, -LL | | for<'a> Box<>::Assoc>: WhereBound, - | |_________________________________________________________- first implementation here -... -LL | impl Trait for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` - | - = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<_>` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs index 8eeadb3dc754..f5fb5aefb5c3 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs @@ -2,9 +2,6 @@ // "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could" #![crate_type = "lib"] -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - pub trait WhereBound {} impl WhereBound for () {} diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr similarity index 92% rename from tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr rename to tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr index 781ab0fcbf76..22673cef6407 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>` - --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1 + --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:23:1 | LL | / impl Trait for T LL | | where diff --git a/tests/ui/coherence/coherent-due-to-fulfill.rs b/tests/ui/coherence/coherent-due-to-fulfill.rs index 084f9be0a8c3..f4555ee5171c 100644 --- a/tests/ui/coherence/coherent-due-to-fulfill.rs +++ b/tests/ui/coherence/coherent-due-to-fulfill.rs @@ -1,6 +1,4 @@ -//@ compile-flags: -Znext-solver=coherence //@ check-pass - trait Mirror { type Assoc; } diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.rs b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs index b3c9cf328c21..28e5b6d3db09 100644 --- a/tests/ui/coherence/incoherent-even-though-we-fulfill.rs +++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs @@ -1,5 +1,3 @@ -//@ compile-flags: -Znext-solver=coherence - trait Mirror { type Assoc; } diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr index b16465d20114..0b15a4e100ed 100644 --- a/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr +++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Foo` for type `()` - --> $DIR/incoherent-even-though-we-fulfill.rs:17:1 + --> $DIR/incoherent-even-though-we-fulfill.rs:15:1 | LL | impl Foo for T where (): Mirror {} | --------------------------------------------- first implementation here diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr deleted file mode 100644 index 74be598c44c7..000000000000 --- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0119]: conflicting implementations of trait `From<()>` for type `S` - --> $DIR/inter-crate-ambiguity-causes-notes.rs:12:1 - | -LL | impl From<()> for S { - | ------------------- first implementation here -... -LL | / impl From for S -LL | | -LL | | where -LL | | I: Iterator, - | |___________________________^ conflicting implementation for `S` - | - = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs index 3dead2f0d19c..5b11c78ab260 100644 --- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs +++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs @@ -1,6 +1,3 @@ -//@ revisions: old next -//@[next] compile-flags: -Znext-solver - struct S; impl From<()> for S { diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr similarity index 90% rename from tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr rename to tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr index 74be598c44c7..b32283274c69 100644 --- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr +++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `From<()>` for type `S` - --> $DIR/inter-crate-ambiguity-causes-notes.rs:12:1 + --> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1 | LL | impl From<()> for S { | ------------------- first implementation here diff --git a/tests/ui/coherence/normalize-for-errors.current.stderr b/tests/ui/coherence/normalize-for-errors.current.stderr deleted file mode 100644 index 634a10b7a14c..000000000000 --- a/tests/ui/coherence/normalize-for-errors.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)` - --> $DIR/normalize-for-errors.rs:17:1 - | -LL | impl MyTrait for (T, S::Item) {} - | ------------------------------------------------------ first implementation here -LL | -LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` - | - = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `(MyType,)` in future versions - = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/normalize-for-errors.next.stderr b/tests/ui/coherence/normalize-for-errors.next.stderr deleted file mode 100644 index 44952dc19445..000000000000 --- a/tests/ui/coherence/normalize-for-errors.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)` - --> $DIR/normalize-for-errors.rs:17:1 - | -LL | impl MyTrait for (T, S::Item) {} - | ------------------------------------------------------ first implementation here -LL | -LL | impl MyTrait for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, <_ as Iterator>::Item)` - | - = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions - = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr index 9544bdbb468d..466b991471ed 100644 --- a/tests/ui/coherence/occurs-check/associated-type.next.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr @@ -3,7 +3,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), .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` - --> $DIR/associated-type.rs:31:1 + --> $DIR/associated-type.rs:32:1 | LL | impl Overlap for T { | ------------------------ first implementation here @@ -17,7 +17,7 @@ LL | | for<'a> *const T: ToUnit<'a>, = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details error[E0284]: type annotations needed: cannot normalize ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc` - --> $DIR/associated-type.rs:44:59 + --> $DIR/associated-type.rs:45:59 | LL | foo:: fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize); | ^^^^^^ cannot normalize ` fn(&'a (), ()) as Overlap fn(&'a (), ())>>::Assoc` diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr index 6a4c6fe54a83..1e0345f4ec05 100644 --- a/tests/ui/coherence/occurs-check/associated-type.old.stderr +++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr @@ -3,7 +3,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), .. } error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())` - --> $DIR/associated-type.rs:31:1 + --> $DIR/associated-type.rs:32:1 | LL | impl Overlap for T { | ------------------------ first implementation here diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs index 4441c38ba6d6..d56ccc5b3532 100644 --- a/tests/ui/coherence/occurs-check/associated-type.rs +++ b/tests/ui/coherence/occurs-check/associated-type.rs @@ -1,4 +1,5 @@ //@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver // A (partial) regression test for #105787 diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr index 96ef7cd4322b..f3fc22027c26 100644 --- a/tests/ui/coherence/occurs-check/opaques.current.stderr +++ b/tests/ui/coherence/occurs-check/opaques.current.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:27:1 + --> $DIR/opaques.rs:28:1 | LL | impl Trait for T { | ---------------------- first implementation here diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr index 2bedff25ecd9..04fd139f901b 100644 --- a/tests/ui/coherence/occurs-check/opaques.next.stderr +++ b/tests/ui/coherence/occurs-check/opaques.next.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait<_>` - --> $DIR/opaques.rs:27:1 + --> $DIR/opaques.rs:28:1 | LL | impl Trait for T { | ---------------------- first implementation here @@ -8,7 +8,7 @@ LL | impl Trait for defining_scope::Alias { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error[E0282]: type annotations needed - --> $DIR/opaques.rs:10:23 + --> $DIR/opaques.rs:11:23 | LL | pub fn cast(x: Container, T>) -> Container { | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs index d7032dd53d97..e197256c78c7 100644 --- a/tests/ui/coherence/occurs-check/opaques.rs +++ b/tests/ui/coherence/occurs-check/opaques.rs @@ -1,4 +1,5 @@ -//@revisions: current next +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver // A regression test for #105787 diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr deleted file mode 100644 index 44f76f321cf1..000000000000 --- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6 - | -LL | impl foreign::Trait0 for Identity {} - | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - | - = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type - = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last - -error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6 - | -LL | impl foreign::Trait1 for Opaque {} - | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - | - = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type - = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs index 8dc02b081c51..02e9eb65570c 100644 --- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs +++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs @@ -1,8 +1,5 @@ // Opaque types never cover type parameters. -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - //@ aux-crate:foreign=parametrized-trait.rs //@ edition:2021 diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr similarity index 92% rename from tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr rename to tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr index 44f76f321cf1..57f5bbd22787 100644 --- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr +++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6 + --> $DIR/orphan-check-opaque-types-not-covering.rs:14:6 | LL | impl foreign::Trait0 for Identity {} | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) @@ -8,7 +8,7 @@ LL | impl foreign::Trait0 for Identity {} = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6 + --> $DIR/orphan-check-opaque-types-not-covering.rs:23:6 | LL | impl foreign::Trait1 for Opaque {} | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) diff --git a/tests/ui/coherence/orphan-check-projections-covering.rs b/tests/ui/coherence/orphan-check-projections-covering.rs index ae1917ec161f..804784463a1b 100644 --- a/tests/ui/coherence/orphan-check-projections-covering.rs +++ b/tests/ui/coherence/orphan-check-projections-covering.rs @@ -5,9 +5,6 @@ // first which would've lead to real-word regressions. //@ check-pass -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - //@ aux-crate:foreign=parametrized-trait.rs //@ edition:2021 diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr deleted file mode 100644 index 276833fa1712..000000000000 --- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6 - | -LL | impl foreign::Trait1 for Identity {} - | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - | - = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type - = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0210`. diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs index 9ebc45a88293..6d9bccc4c689 100644 --- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs +++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs @@ -1,8 +1,5 @@ // Weak aliases might not cover type parameters. -//@ revisions: classic next -//@[next] compile-flags: -Znext-solver - //@ aux-crate:foreign=parametrized-trait.rs //@ edition:2021 diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr similarity index 92% rename from tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr rename to tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr index 276833fa1712..df915141a769 100644 --- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr +++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr @@ -1,5 +1,5 @@ error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`) - --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6 + --> $DIR/orphan-check-weak-aliases-not-covering.rs:13:6 | LL | impl foreign::Trait1 for Identity {} | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`) diff --git a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr deleted file mode 100644 index 5de4cf626e48..000000000000 --- a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0726]: implicit elided lifetime not allowed here - --> $DIR/skip-reporting-if-references-err.rs:10:9 - | -LL | impl ToUnit for T {} - | ^^^^^^ expected lifetime parameter - | -help: indicate the anonymous lifetime - | -LL | impl ToUnit<'_> for T {} - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/skip-reporting-if-references-err.next.stderr b/tests/ui/coherence/skip-reporting-if-references-err.next.stderr deleted file mode 100644 index 5de4cf626e48..000000000000 --- a/tests/ui/coherence/skip-reporting-if-references-err.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0726]: implicit elided lifetime not allowed here - --> $DIR/skip-reporting-if-references-err.rs:10:9 - | -LL | impl ToUnit for T {} - | ^^^^^^ expected lifetime parameter - | -help: indicate the anonymous lifetime - | -LL | impl ToUnit<'_> for T {} - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs index d1f2e8d1c1a1..323ee0b10c9f 100644 --- a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs +++ b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs @@ -9,9 +9,6 @@ // which caused the old solver to emit a `Tensor: TensorValue` goal in // `fn normalize_to_error` which then failed, causing this test to pass. -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver //@ check-pass pub trait TensorValue { diff --git a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr index 2424541af23e..cdf9deecd515 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr @@ -1,11 +1,3 @@ -error: unconstrained opaque type - --> $DIR/coherence-bikeshed-intrinsic-from.rs:4:19 - | -LL | type OpaqueType = impl OpaqueTrait; - | ^^^^^^^^^^^^^^^^ - | - = note: `OpaqueType` must be used in combination with a concrete type within the same module - error[E0747]: type provided when a constant was expected --> $DIR/coherence-bikeshed-intrinsic-from.rs:7:37 | @@ -21,6 +13,14 @@ LL | LL | impl AnotherTrait for OpaqueType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation +error: unconstrained opaque type + --> $DIR/coherence-bikeshed-intrinsic-from.rs:4:19 + | +LL | type OpaqueType = impl OpaqueTrait; + | ^^^^^^^^^^^^^^^^ + | + = note: `OpaqueType` must be used in combination with a concrete type within the same module + error: aborting due to 3 previous errors Some errors have detailed explanations: E0119, E0747. From 30ec8bb5e96faeb363b6c195f60e8a76f8c92374 Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 21 Sep 2024 07:05:51 +0000 Subject: [PATCH 077/118] update test description --- .../leak-check/leak-check-in-selection-5-ambig.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs index beda719ac208..9a44fd2e64a3 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs @@ -3,9 +3,9 @@ //@ check-pass // The new trait solver does not return region constraints if the goal -// is still ambiguous. This causes the following test to fail with ambiguity, -// even though `(): LeakCheckFailure<'!a, V>` would return `'!a: 'static` -// which would have caused a leak check failure. +// is still ambiguous. However, the `'!a = 'static` constraint from +// `(): LeakCheckFailure<'!a, V>` is also returned via the canonical +// var values, causing this test to compile. trait Ambig {} impl Ambig for u32 {} From d3d59055a9f8a7a34d70b581638ef8b56e68d0b4 Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Tue, 15 Oct 2024 13:49:07 +0200 Subject: [PATCH 078/118] Fix uninlined_format_args in stable_mir --- compiler/stable_mir/src/mir/pretty.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 74081af1d86d..05d11c71bbbe 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -22,7 +22,7 @@ impl Debug for Place { } pub(crate) fn function_body(writer: &mut W, body: &Body, name: &str) -> io::Result<()> { - write!(writer, "fn {}(", name)?; + write!(writer, "fn {name}(")?; body.arg_locals() .iter() .enumerate() @@ -54,7 +54,7 @@ pub(crate) fn function_body(writer: &mut W, body: &Body, name: &str) - .iter() .enumerate() .map(|(index, block)| -> io::Result<()> { - writeln!(writer, " bb{}: {{", index)?; + writeln!(writer, " bb{index}: {{")?; let _ = block .statements .iter() @@ -75,7 +75,7 @@ pub(crate) fn function_body(writer: &mut W, body: &Body, name: &str) - fn pretty_statement(writer: &mut W, statement: &StatementKind) -> io::Result<()> { match statement { StatementKind::Assign(place, rval) => { - write!(writer, " {:?} = ", place)?; + write!(writer, " {place:?} = ")?; pretty_rvalue(writer, rval)?; writeln!(writer, ";") } @@ -165,7 +165,7 @@ fn pretty_terminator_head(writer: &mut W, terminator: &TerminatorKind) Abort => write!(writer, "{INDENT}abort"), Return => write!(writer, "{INDENT}return"), Unreachable => write!(writer, "{INDENT}unreachable"), - Drop { place, .. } => write!(writer, "{INDENT}drop({:?})", place), + Drop { place, .. } => write!(writer, "{INDENT}drop({place:?})"), Call { func, args, destination, .. } => { write!(writer, "{INDENT}{:?} = {}(", destination, pretty_operand(func))?; let mut args_iter = args.iter(); @@ -304,10 +304,10 @@ fn pretty_assert_message(writer: &mut W, msg: &AssertMessage) -> io::R fn pretty_operand(operand: &Operand) -> String { match operand { Operand::Copy(copy) => { - format!("{:?}", copy) + format!("{copy:?}") } Operand::Move(mv) => { - format!("move {:?}", mv) + format!("move {mv:?}") } Operand::Constant(cnst) => pretty_mir_const(&cnst.const_), } @@ -344,13 +344,13 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { write!(writer, "Checked{:?}({}, {})", bin, pretty_operand(op1), pretty_operand(op2)) } Rvalue::CopyForDeref(deref) => { - write!(writer, "CopyForDeref({:?})", deref) + write!(writer, "CopyForDeref({deref:?})") } Rvalue::Discriminant(place) => { - write!(writer, "discriminant({:?})", place) + write!(writer, "discriminant({place:?})") } Rvalue::Len(len) => { - write!(writer, "len({:?})", len) + write!(writer, "len({len:?})") } Rvalue::Ref(_, borrowkind, place) => { let kind = match borrowkind { @@ -359,17 +359,17 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { BorrowKind::Fake(FakeBorrowKind::Shallow) => "&fake shallow ", BorrowKind::Mut { .. } => "&mut ", }; - write!(writer, "{kind}{:?}", place) + write!(writer, "{kind}{place:?}") } Rvalue::Repeat(op, cnst) => { write!(writer, "{} \" \" {}", pretty_operand(op), pretty_ty_const(cnst)) } Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::ThreadLocalRef(item) => { - write!(writer, "thread_local_ref{:?}", item) + write!(writer, "thread_local_ref{item:?}") } Rvalue::NullaryOp(nul, ty) => { - write!(writer, "{:?} {} \" \"", nul, ty) + write!(writer, "{nul:?} {ty} \" \"") } Rvalue::UnaryOp(un, op) => { write!(writer, "{} \" \" {:?}", pretty_operand(op), un) From 4e29e454a15cbfff91174332106e09d18a7a7da0 Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Tue, 15 Oct 2024 05:12:03 -0700 Subject: [PATCH 079/118] Update arm64e-apple-tvos maintainer Signed-off-by: Emmanuel Ferdman --- src/doc/rustc/src/platform-support/arm64e-apple-tvos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md index d49383fb853e..47234809e5f1 100644 --- a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md +++ b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md @@ -6,7 +6,7 @@ ARM64e tvOS (10.0+) ## Target maintainers -- Artyom Tetyukhin ([@arttet](https://github.com/https://github.com/arttet)) +- Artyom Tetyukhin ([@arttet](https://github.com/arttet)) ## Requirements From 1d6643c4f69ba31f91a385c51f46d615bd2b0d66 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Mon, 14 Oct 2024 21:16:27 +0200 Subject: [PATCH 080/118] Fix most ui tests on emscripten target To fix the linker errors, we need to set the output extension to `.js` instead of `.wasm`. Setting the output to a `.wasm` file puts Emscripten into standalone mode which is effectively a distinct target. We need to set the runner to be `node` as well. This fixes most of the ui tests. I fixed a few more tests with simple problems: - `intrinsics/intrinsic-alignment.rs` and `structs-enums/rec-align-u64.rs` -- Two `#[cfg]` macros match for Emscripten so we got a duplicate definition of `mod m`. - `issues/issue-12699.rs` -- Seems to hang so I disabled it - `process/process-sigpipe.rs` -- Not expected to work on Emscripten so I disabled it --- src/bootstrap/src/core/config/config.rs | 3 +++ src/tools/compiletest/src/runtest.rs | 4 +++- src/tools/tidy/src/issues.txt | 1 - src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/intrinsics/intrinsic-alignment.rs | 1 - tests/ui/process/process-sigpipe.rs | 8 ++------ .../ui/{issues/issue-12699.rs => std/thread-sleep-ms.rs} | 3 +++ tests/ui/structs-enums/rec-align-u64.rs | 1 - 8 files changed, 12 insertions(+), 11 deletions(-) rename tests/ui/{issues/issue-12699.rs => std/thread-sleep-ms.rs} (59%) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index f768470c4ff0..eb571f920df2 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -612,6 +612,9 @@ impl Target { if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") { target.no_std = true; } + if triple.contains("emscripten") { + target.runner = Some("node".into()); + } target } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 29f9925de16a..69a47fcd0fbe 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1643,7 +1643,9 @@ impl<'test> TestCx<'test> { // double the length. let mut f = self.output_base_dir().join("a"); // FIXME: This is using the host architecture exe suffix, not target! - if self.config.target.starts_with("wasm") { + if self.config.target.contains("emscripten") { + f = f.with_extra_extension("js"); + } else if self.config.target.starts_with("wasm") { f = f.with_extra_extension("wasm"); } else if self.config.target.contains("spirv") { f = f.with_extra_extension("spv"); diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 66c176c6f442..22126674c156 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1520,7 +1520,6 @@ ui/issues/issue-12567.rs ui/issues/issue-12612.rs ui/issues/issue-12660.rs ui/issues/issue-12677.rs -ui/issues/issue-12699.rs ui/issues/issue-12729.rs ui/issues/issue-12744.rs ui/issues/issue-12860.rs diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 41f7778c9527..11f9d5bb03df 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -17,7 +17,7 @@ use ignore::Walk; const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: u32 = 1673; +const ISSUES_ENTRY_LIMIT: u32 = 1672; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index 138273aadd2f..4cb05f6a8df3 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -13,7 +13,6 @@ mod rusti { #[cfg(any( target_os = "android", target_os = "dragonfly", - target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", target_os = "hurd", diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 11f363d625f0..9db130c26bd6 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -15,11 +15,12 @@ //@ ignore-vxworks no 'sh' //@ ignore-fuchsia no 'sh' +//@ ignore-emscripten No threads +//@ only-unix SIGPIPE is a unix feature use std::process; use std::thread; -#[cfg(unix)] fn main() { // Just in case `yes` doesn't check for EPIPE... thread::spawn(|| { @@ -34,8 +35,3 @@ fn main() { assert!(output.status.success()); assert!(output.stderr.len() == 0); } - -#[cfg(not(unix))] -fn main() { - // Not worried about signal masks on other platforms -} diff --git a/tests/ui/issues/issue-12699.rs b/tests/ui/std/thread-sleep-ms.rs similarity index 59% rename from tests/ui/issues/issue-12699.rs rename to tests/ui/std/thread-sleep-ms.rs index 4fc93735c3ce..0a3d0253a20e 100644 --- a/tests/ui/issues/issue-12699.rs +++ b/tests/ui/std/thread-sleep-ms.rs @@ -1,6 +1,9 @@ //@ run-pass //@ ignore-sgx not supported +//@ ignore-emscripten +// FIXME: test hangs on emscripten #![allow(deprecated)] +#![allow(unused_imports)] use std::thread; diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs index 8ea72fdf45c8..313ce6d578df 100644 --- a/tests/ui/structs-enums/rec-align-u64.rs +++ b/tests/ui/structs-enums/rec-align-u64.rs @@ -33,7 +33,6 @@ struct Outer { #[cfg(any( target_os = "android", target_os = "dragonfly", - target_os = "emscripten", target_os = "freebsd", target_os = "fuchsia", target_os = "hurd", From 99af761632420b2778e2b44465a396e28adf6103 Mon Sep 17 00:00:00 2001 From: zlfn Date: Tue, 15 Oct 2024 18:39:30 +0900 Subject: [PATCH 081/118] Refactor `floating` macro and nofloat panic message --- library/core/src/fmt/float.rs | 47 ++++++++++++++++--------------- library/core/src/fmt/nofloat.rs | 21 +++++++------- library/core/src/fmt/num.rs | 50 +++++++++++++++++---------------- 3 files changed, 60 insertions(+), 58 deletions(-) diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 20ea0352c2dc..c70dbf54304d 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -196,39 +196,40 @@ where } macro_rules! floating { - ($ty:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl Debug for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_general_debug(fmt, self) + ($($ty:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Debug for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_general_debug(fmt, self) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl Display for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_decimal_display(fmt, self) + #[stable(feature = "rust1", since = "1.0.0")] + impl Display for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_decimal_display(fmt, self) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl LowerExp for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_exponential_common(fmt, self, false) + #[stable(feature = "rust1", since = "1.0.0")] + impl LowerExp for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_exponential_common(fmt, self, false) + } } - } - #[stable(feature = "rust1", since = "1.0.0")] - impl UpperExp for $ty { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { - float_to_exponential_common(fmt, self, true) + #[stable(feature = "rust1", since = "1.0.0")] + impl UpperExp for $ty { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result { + float_to_exponential_common(fmt, self, true) + } } - } + )* }; } -floating! { f32 } -floating! { f64 } +floating! { f32 f64 } #[stable(feature = "rust1", since = "1.0.0")] impl Debug for f16 { diff --git a/library/core/src/fmt/nofloat.rs b/library/core/src/fmt/nofloat.rs index 6b07236f1da1..29aaee75d22b 100644 --- a/library/core/src/fmt/nofloat.rs +++ b/library/core/src/fmt/nofloat.rs @@ -1,18 +1,17 @@ use crate::fmt::{Debug, Formatter, Result}; macro_rules! floating { - ($ty:ident) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl Debug for $ty { - #[inline] - fn fmt(&self, _fmt: &mut Formatter<'_>) -> Result { - panic!("floating point support is turned off"); + ($($ty:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Debug for $ty { + #[inline] + fn fmt(&self, _fmt: &mut Formatter<'_>) -> Result { + panic!("floating point fmt support is turned off"); + } } - } + )* }; } -floating! { f16 } -floating! { f32 } -floating! { f64 } -floating! { f128 } +floating! { f16 f32 f64 f128 } diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 0f33d730a68e..f1540803f978 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -20,15 +20,15 @@ trait DisplayInt: macro_rules! impl_int { ($($t:ident)*) => ( - $(impl DisplayInt for $t { - fn zero() -> Self { 0 } - fn from_u8(u: u8) -> Self { u as Self } - fn to_u8(&self) -> u8 { *self as u8 } - #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] - fn to_u32(&self) -> u32 { *self as u32 } - fn to_u64(&self) -> u64 { *self as u64 } - fn to_u128(&self) -> u128 { *self as u128 } - })* + $(impl DisplayInt for $t { + fn zero() -> Self { 0 } + fn from_u8(u: u8) -> Self { u as Self } + fn to_u8(&self) -> u8 { *self as u8 } + #[cfg(not(any(target_pointer_width = "64", target_arch = "wasm32")))] + fn to_u32(&self) -> u32 { *self as u32 } + fn to_u64(&self) -> u64 { *self as u64 } + fn to_u128(&self) -> u128 { *self as u128 } + })* ) } @@ -169,21 +169,23 @@ integer! { i64, u64 } integer! { i128, u128 } macro_rules! impl_Debug { - ($($T:ident)*) => {$( - #[stable(feature = "rust1", since = "1.0.0")] - impl fmt::Debug for $T { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.debug_lower_hex() { - fmt::LowerHex::fmt(self, f) - } else if f.debug_upper_hex() { - fmt::UpperHex::fmt(self, f) - } else { - fmt::Display::fmt(self, f) + ($($T:ident)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl fmt::Debug for $T { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if f.debug_lower_hex() { + fmt::LowerHex::fmt(self, f) + } else if f.debug_upper_hex() { + fmt::UpperHex::fmt(self, f) + } else { + fmt::Display::fmt(self, f) + } } } - } - )*}; + )* + }; } // 2 digit decimal look up table @@ -508,8 +510,8 @@ macro_rules! impl_Exp { } impl_Debug! { - i8 i16 i32 i64 i128 isize - u8 u16 u32 u64 u128 usize + i8 i16 i32 i64 i128 isize + u8 u16 u32 u64 u128 usize } // Include wasm32 in here since it doesn't reflect the native pointer size, and From 2b9e41c1288a5e9f015be4f5da4c90d5a4d9c158 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Oct 2024 01:58:27 +0200 Subject: [PATCH 082/118] Improve documentation for intra-doc links computation --- .../passes/collect_intra_doc_links.rs | 18 +++++++++--------- .../intra-doc/filter-out-private-2.rs | 2 +- .../intra-doc/filter-out-private-2.stderr | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 81e7bcbd7d87..10026e9f05d2 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -288,14 +288,16 @@ pub(crate) struct LinkCollector<'a, 'tcx> { /// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link. /// The link will be `None` if it could not be resolved (i.e. the error was cached). pub(crate) visited_links: FxHashMap)>>, - /// These links are ambiguous. We need for the cache to have its paths filled. Unfortunately, - /// if we run the `LinkCollector` pass after `Cache::populate`, a lot of items that we need - /// to go through will be removed, making a lot of intra-doc links to not be inferred. + /// According to `rustc_resolve`, these links are ambiguous. /// - /// So instead, we store the ambiguous links and we wait for cache paths to be filled before - /// inferring them (if possible). + /// However, we cannot link to an item that has been stripped from the documentation. If all + /// but one of the "possibilities" are stripped, then there is no real ambiguity. To determine + /// if an ambiguity is real, we delay resolving them until after `Cache::populate`, then filter + /// every item that doesn't have a cached path. /// - /// Key is `(item ID, path str)`. + /// We could get correct results by simply delaying everything. This would have fewer happy + /// codepaths, but we want to distinguish different kinds of error conditions, and this is easy + /// to do by resolving links as soon as possible. pub(crate) ambiguous_links: FxIndexMap<(ItemId, String), Vec>, } @@ -1187,9 +1189,7 @@ impl LinkCollector<'_, '_> { report_diagnostic( self.cx.tcx, BROKEN_INTRA_DOC_LINKS, - format!( - "all items matching `{path_str}` are either private or doc(hidden)" - ), + format!("all items matching `{path_str}` are private or doc(hidden)"), &diag_info, |diag, sp, _| { if let Some(sp) = sp { diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs index 9209203c99ee..9d8edbf6b5dd 100644 --- a/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.rs @@ -11,5 +11,5 @@ pub struct Thing {} pub fn Thing() {} /// Do stuff with [`Thing`]. -//~^ ERROR all items matching `Thing` are either private or doc(hidden) +//~^ ERROR all items matching `Thing` are private or doc(hidden) pub fn repro(_: Thing) {} diff --git a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr index 394f919de943..1a49c90a1728 100644 --- a/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr +++ b/tests/rustdoc-ui/intra-doc/filter-out-private-2.stderr @@ -1,4 +1,4 @@ -error: all items matching `Thing` are either private or doc(hidden) +error: all items matching `Thing` are private or doc(hidden) --> $DIR/filter-out-private-2.rs:13:21 | LL | /// Do stuff with [`Thing`]. From 10f2395c9ee5849e3a769ce21d3e704191ec8085 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 15 Oct 2024 15:42:47 +0200 Subject: [PATCH 083/118] Remove `AmbiguousLinks::disambiguator` --- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 10026e9f05d2..cbc6e351fac5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -302,7 +302,6 @@ pub(crate) struct LinkCollector<'a, 'tcx> { } pub(crate) struct AmbiguousLinks { - disambiguator: Option, link_text: Box, diag_info: OwnedDiagnosticInfo, resolved: Vec<(Res, Option)>, @@ -1097,7 +1096,6 @@ impl LinkCollector<'_, '_> { if resolved.len() > 1 { let links = AmbiguousLinks { - disambiguator, link_text: link_text.clone(), diag_info: diag_info.into(), resolved, @@ -1178,7 +1176,7 @@ impl LinkCollector<'_, '_> { res, fragment, path_str, - info.disambiguator, + None, diag_info, &info.link_text, ) { From dca646ab0107fd311427b7f7c4eea448e9f4ee9e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Oct 2024 10:09:42 -0400 Subject: [PATCH 084/118] Rewrite for<..> async correctly --- src/tools/rustfmt/src/types.rs | 50 +++++++++++---------- src/tools/rustfmt/tests/target/asyncness.rs | 2 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 99b3fe60ee2f..e237662f5aa2 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -613,26 +613,8 @@ impl Rewrite for ast::GenericBound { ast::GenericBound::Trait(ref poly_trait_ref) => { let snippet = context.snippet(self.span()); let has_paren = snippet.starts_with('(') && snippet.ends_with(')'); - let ast::TraitBoundModifiers { - constness, - asyncness, - polarity, - } = poly_trait_ref.modifiers; - let mut constness = constness.as_str().to_string(); - if !constness.is_empty() { - constness.push(' '); - } - let mut asyncness = asyncness.as_str().to_string(); - if !asyncness.is_empty() { - asyncness.push(' '); - } - let polarity = polarity.as_str(); - let shape = shape - .offset_left(constness.len() + polarity.len()) - .max_width_error(shape.width, self.span())?; poly_trait_ref .rewrite_result(context, shape) - .map(|s| format!("{constness}{asyncness}{polarity}{s}")) .map(|s| if has_paren { format!("({})", s) } else { s }) } ast::GenericBound::Use(ref args, span) => { @@ -756,19 +738,41 @@ impl Rewrite for ast::PolyTraitRef { } fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult { - if let Some(lifetime_str) = rewrite_bound_params(context, shape, &self.bound_generic_params) + let (binder, shape) = if let Some(lifetime_str) = + rewrite_bound_params(context, shape, &self.bound_generic_params) { // 6 is "for<> ".len() let extra_offset = lifetime_str.len() + 6; let shape = shape .offset_left(extra_offset) .max_width_error(shape.width, self.span)?; - let path_str = self.trait_ref.rewrite_result(context, shape)?; - - Ok(format!("for<{lifetime_str}> {path_str}")) + (format!("for<{lifetime_str}> "), shape) } else { - self.trait_ref.rewrite_result(context, shape) + (String::new(), shape) + }; + + let ast::TraitBoundModifiers { + constness, + asyncness, + polarity, + } = self.modifiers; + let mut constness = constness.as_str().to_string(); + if !constness.is_empty() { + constness.push(' '); } + let mut asyncness = asyncness.as_str().to_string(); + if !asyncness.is_empty() { + asyncness.push(' '); + } + let polarity = polarity.as_str(); + let shape = shape + .offset_left(constness.len() + polarity.len()) + .max_width_error(shape.width, self.span)?; + + let path_str = self.trait_ref.rewrite_result(context, shape)?; + Ok(format!( + "{binder}{constness}{asyncness}{polarity}{path_str}" + )) } } diff --git a/src/tools/rustfmt/tests/target/asyncness.rs b/src/tools/rustfmt/tests/target/asyncness.rs index d91ac960499b..dd651ed6a620 100644 --- a/src/tools/rustfmt/tests/target/asyncness.rs +++ b/src/tools/rustfmt/tests/target/asyncness.rs @@ -1,3 +1,5 @@ // rustfmt-edition: 2018 fn foo() -> impl async Fn() {} + +fn bar() -> impl for<'a> async Fn(&'a ()) {} From 5d178e1d4da25110e72b297caaef6489e920f04f Mon Sep 17 00:00:00 2001 From: c6c7 Date: Mon, 14 Oct 2024 12:38:49 -0400 Subject: [PATCH 085/118] Make fuchsia-test-runner.py compatible with new JSON output from llvm-readelf [A recent commit in LLVM](https://github.com/llvm/llvm-project/commit/ab930ee7cad8b8bf7968bb8d0c0d72524e2313c4) modified the JSON output of LLVM. The LLVM change renamed "Notes" to "NoteSections" and inserted a new "Notes" key nested under each "NoteSection". This change shores up exceptions around reading the JSON output of llvm-readelf and reads from "NoteSections" instead of the non-existent "Notes". --- src/ci/docker/scripts/fuchsia-test-runner.py | 42 +++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index a5458b8645d7..1aa9a4a1794f 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -193,18 +193,38 @@ class TestEnvironment: stderr=subprocess.STDOUT, ) if process.returncode: - self.env_logger.error( - f"llvm-readelf failed for binary {binary} with output {process.stdout}" + e = f"llvm-readelf failed for binary {binary} with output {process.stdout}" + self.env_logger.error(e) + raise Exception(e) + + try: + elf_output = json.loads(process.stdout) + except Exception as e: + e.add_note(f"Failed to read JSON from llvm-readelf for binary {binary}") + e.add_note(f"stdout: {process.stdout}") + raise + + try: + note_sections = elf_output[0]["NoteSections"] + except Exception as e: + e.add_note( + f'Failed to read "NoteSections" from llvm-readelf for binary {binary}' ) - raise Exception(f"Unreadable build-id for binary {binary}") - data = json.loads(process.stdout) - if len(data) != 1: - raise Exception(f"Unreadable output from llvm-readelf for binary {binary}") - notes = data[0]["Notes"] - for note in notes: - note_section = note["NoteSection"] - if note_section["Name"] == ".note.gnu.build-id": - return note_section["Note"]["Build ID"] + e.add_note(f"elf_output: {elf_output}") + raise + + for entry in note_sections: + try: + note_section = entry["NoteSection"] + if note_section["Name"] == ".note.gnu.build-id": + return note_section["Notes"][0]["Build ID"] + except Exception as e: + e.add_note( + f'Failed to read ".note.gnu.build-id" from NoteSections \ + entry in llvm-readelf for binary {binary}' + ) + e.add_note(f"NoteSections: {note_sections}") + raise raise Exception(f"Build ID not found for binary {binary}") def generate_buildid_dir( From 937d13b8efc43f3f2e93f81360565d82f243ce15 Mon Sep 17 00:00:00 2001 From: Slanterns Date: Wed, 16 Oct 2024 00:22:05 +0800 Subject: [PATCH 086/118] relax a memory order in `once_box` --- library/std/src/sys/sync/once_box.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/sync/once_box.rs b/library/std/src/sys/sync/once_box.rs index 1422b5a17216..9d24db2245a0 100644 --- a/library/std/src/sys/sync/once_box.rs +++ b/library/std/src/sys/sync/once_box.rs @@ -8,7 +8,7 @@ use crate::mem::replace; use crate::ptr::null_mut; use crate::sync::atomic::AtomicPtr; -use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed}; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; pub(crate) struct OnceBox { ptr: AtomicPtr, @@ -60,7 +60,7 @@ impl OnceBox { #[cold] fn initialize(&self, f: impl FnOnce() -> Box) -> &T { let new_ptr = Box::into_raw(f()); - match self.ptr.compare_exchange(null_mut(), new_ptr, AcqRel, Acquire) { + match self.ptr.compare_exchange(null_mut(), new_ptr, Release, Acquire) { Ok(_) => unsafe { &*new_ptr }, Err(ptr) => { // Lost the race to another thread. From 2bf120de38f66631a5b2a792d76b3123ba62bcf6 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 15 Oct 2024 13:31:07 -0400 Subject: [PATCH 087/118] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 15fbd2f607d4..8c30ce53688e 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 15fbd2f607d4defc87053b8b76bf5038f2483cf4 +Subproject commit 8c30ce53688e25f7e9d860b33cc914fb2957ca9a From 4886e9a134aa7c8c9bb1fed42ebfe22d7f5b2a63 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 14:39:49 -0400 Subject: [PATCH 088/118] Unify secondary_span and swap_secondary_and_primary --- .../src/check/compare_impl_item.rs | 9 +++------ compiler/rustc_hir_analysis/src/check/mod.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 1 - compiler/rustc_passes/src/check_attr.rs | 1 - .../src/error_reporting/infer/mod.rs | 18 +++++++----------- .../traits/fulfillment_errors.rs | 3 +-- 6 files changed, 11 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 9ca5f25447b3..75956165e873 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -592,14 +592,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( &cause, hir.get_if_local(impl_m.def_id) .and_then(|node| node.fn_decl()) - .map(|decl| (decl.output.span(), Cow::from("return type in trait"))), + .map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)), Some(infer::ValuePairs::Terms(ExpectedFound { expected: trait_return_ty.into(), found: impl_return_ty.into(), })), terr, false, - false, ); return Err(diag.emit()); } @@ -1018,14 +1017,13 @@ fn report_trait_method_mismatch<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - trait_err_span.map(|sp| (sp, Cow::from("type in trait"))), + trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)), Some(infer::ValuePairs::PolySigs(ExpectedFound { expected: ty::Binder::dummy(trait_sig), found: ty::Binder::dummy(impl_sig), })), terr, false, - false, ); diag.emit() @@ -1825,14 +1823,13 @@ fn compare_const_predicate_entailment<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - trait_c_span.map(|span| (span, Cow::from("type in trait"))), + trait_c_span.map(|span| (span, Cow::from("type in trait"), false)), Some(infer::ValuePairs::Terms(ExpectedFound { expected: trait_ty.into(), found: impl_ty.into(), })), terr, false, - false, ); return Err(diag.emit()); }; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 004540b26430..959b17b2d407 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -652,7 +652,6 @@ pub fn check_function_signature<'tcx>( })), err, false, - false, ); return Err(diag.emit()); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index fa471647d02d..44c0da0744a2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1114,7 +1114,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, Some(trace.values), e, - false, true, ); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7ce29260e367..4516ea94cad7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2302,7 +2302,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { })), terr, false, - false, ); diag.emit(); self.abort.set(true); diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index bd78a6ee3aff..df5800ab58a6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -1127,18 +1127,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { /// the message in `secondary_span` as the primary label, and apply the message that would /// otherwise be used for the primary label on the `secondary_span` `Span`. This applies on /// E0271, like `tests/ui/issues/issue-39970.stderr`. - #[instrument( - level = "debug", - skip(self, diag, secondary_span, swap_secondary_and_primary, prefer_label) - )] + #[instrument(level = "debug", skip(self, diag, secondary_span, prefer_label))] pub fn note_type_err( &self, diag: &mut Diag<'_>, cause: &ObligationCause<'tcx>, - secondary_span: Option<(Span, Cow<'static, str>)>, + secondary_span: Option<(Span, Cow<'static, str>, bool)>, mut values: Option>, terr: TypeError<'tcx>, - swap_secondary_and_primary: bool, prefer_label: bool, ) { let span = cause.span(); @@ -1304,7 +1300,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { diag.span_note(span, msg); } }; - if let Some((sp, msg)) = secondary_span { + if let Some((secondary_span, secondary_msg, swap_secondary_and_primary)) = secondary_span { if swap_secondary_and_primary { let terr = if let Some(infer::ValuePairs::Terms(ExpectedFound { expected, .. @@ -1314,11 +1310,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } else { terr.to_string(self.tcx) }; - label_or_note(sp, terr); - label_or_note(span, msg); + label_or_note(secondary_span, terr); + label_or_note(span, secondary_msg); } else { label_or_note(span, terr.to_string(self.tcx)); - label_or_note(sp, msg); + label_or_note(secondary_span, secondary_msg); } } else if let Some(values) = values && let Some((e, f)) = values.ty() @@ -1788,7 +1784,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.type_error_additional_suggestions(&trace, terr), ); let mut diag = self.dcx().create_err(failure_code); - self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false); + self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false); diag } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 824c25db07d2..8a4c22fdf863 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -710,7 +710,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { None, TypeError::Sorts(ty::error::ExpectedFound::new(true, expected_ty, ct_ty)), false, - false, ); diag } @@ -1435,6 +1434,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { cx.into_buffer() } ))), + true, )), _ => None, } @@ -1452,7 +1452,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )) }), err, - true, false, ); self.note_obligation_cause(&mut diag, obligation); From 68885216b63f6e75e50b4c0f3c7250ca4ac7afda Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 14:58:41 -0400 Subject: [PATCH 089/118] Don't report bivariance error when nesting a struct with field errors into another struct --- .../rustc_hir_analysis/src/check/wfcheck.rs | 60 +++++++++++++++---- .../type-resolve-error-two-structs-deep.rs | 13 ++++ ...type-resolve-error-two-structs-deep.stderr | 9 +++ 3 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 tests/ui/variance/type-resolve-error-two-structs-deep.rs create mode 100644 tests/ui/variance/type-resolve-error-two-structs-deep.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 607068f162aa..f788456d4e9e 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1875,24 +1875,15 @@ fn check_variances_for_type_defn<'tcx>( item: &'tcx hir::Item<'tcx>, hir_generics: &hir::Generics<'tcx>, ) { - let identity_args = ty::GenericArgs::identity_for_item(tcx, item.owner_id); - match item.kind { ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => { - for field in tcx.adt_def(item.owner_id).all_fields() { - if field.ty(tcx, identity_args).references_error() { - return; - } - } + // Ok } ItemKind::TyAlias(..) => { assert!( tcx.type_alias_is_lazy(item.owner_id), "should not be computing variance of non-weak type alias" ); - if tcx.type_of(item.owner_id).skip_binder().references_error() { - return; - } } kind => span_bug!(item.span, "cannot compute the variances of {kind:?}"), } @@ -1955,6 +1946,15 @@ fn check_variances_for_type_defn<'tcx>( continue; } + // Look for `ErrorGuaranteed` deeply within this type. + if let ControlFlow::Break(ErrorGuaranteed { .. }) = tcx + .type_of(item.owner_id) + .instantiate_identity() + .visit_with(&mut HasErrorDeep { tcx, seen: Default::default() }) + { + continue; + } + match hir_param.name { hir::ParamName::Error => {} _ => { @@ -1965,6 +1965,46 @@ fn check_variances_for_type_defn<'tcx>( } } +/// Look for `ErrorGuaranteed` deeply within structs' (unsubstituted) fields. +struct HasErrorDeep<'tcx> { + tcx: TyCtxt<'tcx>, + seen: FxHashSet, +} +impl<'tcx> TypeVisitor> for HasErrorDeep<'tcx> { + type Result = ControlFlow; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { + match *ty.kind() { + ty::Adt(def, _) => { + if self.seen.insert(def.did()) { + for field in def.all_fields() { + self.tcx.type_of(field.did).instantiate_identity().visit_with(self)?; + } + } + } + ty::Error(guar) => return ControlFlow::Break(guar), + _ => {} + } + ty.super_visit_with(self) + } + + fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { + if let Err(guar) = r.error_reported() { + ControlFlow::Break(guar) + } else { + ControlFlow::Continue(()) + } + } + + fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result { + if let Err(guar) = c.error_reported() { + ControlFlow::Break(guar) + } else { + ControlFlow::Continue(()) + } + } +} + fn report_bivariance<'tcx>( tcx: TyCtxt<'tcx>, param: &'tcx hir::GenericParam<'tcx>, diff --git a/tests/ui/variance/type-resolve-error-two-structs-deep.rs b/tests/ui/variance/type-resolve-error-two-structs-deep.rs new file mode 100644 index 000000000000..47ec532ab968 --- /dev/null +++ b/tests/ui/variance/type-resolve-error-two-structs-deep.rs @@ -0,0 +1,13 @@ +// Make sure we don't report bivariance errors when nesting structs w/ unresolved +// fields into *other* structs. + +struct Hello<'a> { + missing: Missing<'a>, + //~^ ERROR cannot find type `Missing` in this scope +} + +struct Other<'a> { + hello: Hello<'a>, +} + +fn main() {} diff --git a/tests/ui/variance/type-resolve-error-two-structs-deep.stderr b/tests/ui/variance/type-resolve-error-two-structs-deep.stderr new file mode 100644 index 000000000000..3458d924bb15 --- /dev/null +++ b/tests/ui/variance/type-resolve-error-two-structs-deep.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/type-resolve-error-two-structs-deep.rs:5:14 + | +LL | missing: Missing<'a>, + | ^^^^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. From 50b8029ce143aa5ed67aab9d3c05533330df97d6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 12:40:08 -0400 Subject: [PATCH 090/118] Always recurse on predicates in BestObligation --- compiler/rustc_trait_selection/src/solve/fulfill.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 081d7a6a769a..0e2b081448e5 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -465,13 +465,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { polarity: ty::PredicatePolarity::Positive, })) } - ty::PredicateKind::Clause( - ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..), - ) - | ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough, - _ => { - return ControlFlow::Break(self.obligation.clone()); - } + _ => ChildMode::PassThrough, }; let mut impl_where_bound_count = 0; From fd2038d344c3abb34a0a7812c49f1730c3cee3b2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 10:52:34 -0400 Subject: [PATCH 091/118] Make sure the alias is actually rigid --- .../src/solve/normalizes_to/mod.rs | 53 ++++++++++++++- .../defaults-unsound-62211-1.next.stderr | 21 ++++-- .../defaults-unsound-62211-2.next.stderr | 21 ++++-- .../associated-types/issue-54108.next.stderr | 21 ++++-- tests/ui/for/issue-20605.next.stderr | 11 +-- ...mbig-hr-projection-issue-93340.next.stderr | 12 +++- .../in-trait/alias-bounds-when-not-wf.stderr | 28 ++++++-- .../impl-trait/method-resolution4.next.stderr | 50 +++++++++++--- .../recursive-coroutine-boxed.next.stderr | 68 +++++++++++++++---- .../impl-trait/unsized_coercion.next.stderr | 35 +++++++--- .../impl-trait/unsized_coercion3.next.stderr | 43 ++++++------ .../opaque-type-unsatisfied-bound.stderr | 62 +++++++++++++++-- .../opaque-type-unsatisfied-fn-bound.stderr | 28 +++++++- .../traits/next-solver/coroutine.fail.stderr | 41 ++++++++++- .../diagnostics/projection-trait-ref.stderr | 33 ++++++++- .../next-solver/dyn-incompatibility.stderr | 15 +++- tests/ui/traits/next-solver/fn-trait.stderr | 61 ++++++++++++++++- .../issue-118950-root-region.stderr | 18 ++--- ...ution_trait_method_from_opaque.next.stderr | 19 +++++- ...hod_resolution_trait_method_from_opaque.rs | 2 + 20 files changed, 530 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 005b293621af..bf1d2bf08b78 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate}; use crate::solve::inspect::ProbeKind; use crate::solve::{ BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause, - NoSolution, QueryResult, + NoSolution, QueryResult, Reveal, }; impl EvalCtxt<'_, D> @@ -39,11 +39,58 @@ where Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; + self.add_rigid_constraints(param_env, alias)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } } + /// Register any obligations that are used to validate that an alias should be + /// treated as rigid. + /// + /// An alias may be considered rigid if it fails normalization, but we also don't + /// want to consider aliases that are not well-formed to be rigid simply because + /// they fail normalization. + /// + /// For example, some `::Assoc` where `T: Trait` does not hold, or an + /// opaque type whose hidden type doesn't actually satisfy the opaque item bounds. + fn add_rigid_constraints( + &mut self, + param_env: I::ParamEnv, + rigid_alias: ty::AliasTerm, + ) -> Result<(), NoSolution> { + match rigid_alias.kind(self.cx()) { + // Projections are rigid only if their trait ref holds. + ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { + let trait_ref = rigid_alias.trait_ref(self.cx()); + self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref)); + Ok(()) + } + ty::AliasTermKind::OpaqueTy => { + match param_env.reveal() { + // In user-facing mode, paques are only rigid if we may not define it. + Reveal::UserFacing => { + if rigid_alias + .def_id + .as_local() + .is_some_and(|def_id| self.can_define_opaque_ty(def_id)) + { + Err(NoSolution) + } else { + Ok(()) + } + } + // Opaques are never rigid in reveal-all mode. + Reveal::All => Err(NoSolution), + } + } + // FIXME(generic_const_exprs): we would need to support generic consts here + ty::AliasTermKind::UnevaluatedConst => Err(NoSolution), + // Inherent and weak types are never rigid. This type must not be well-formed. + ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution), + } + } + /// Normalize the given alias by at least one step. If the alias is rigid, this /// returns `NoSolution`. #[instrument(level = "trace", skip(self), ret)] @@ -124,6 +171,7 @@ where ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); // Add GAT where clauses from the trait's definition + // FIXME: We don't need these, since these are the type's own WF obligations. ecx.add_goals( GoalSource::Misc, cx.own_predicates_of(goal.predicate.def_id()) @@ -179,7 +227,8 @@ where .map(|pred| goal.with(cx, pred)); ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); - // Add GAT where clauses from the trait's definition + // Add GAT where clauses from the trait's definition. + // FIXME: We don't need these, since these are the type's own WF obligations. ecx.add_goals( GoalSource::Misc, cx.own_predicates_of(goal.predicate.def_id()) diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index 010f51df15ad..4523fc3e037e 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -31,6 +31,18 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ +error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` + --> $DIR/defaults-unsound-62211-1.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ types differ + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-1.rs:24:31 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:24:96 | @@ -38,10 +50,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:24:31 + --> $DIR/defaults-unsound-62211-1.rs:24:25 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -63,6 +75,7 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index 934789465707..7a68f1ac8cc4 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -31,6 +31,18 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ +error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` + --> $DIR/defaults-unsound-62211-2.rs:24:96 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^ types differ + | +note: required by a bound in `UncheckedCopy::Output` + --> $DIR/defaults-unsound-62211-2.rs:24:31 + | +LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:24:96 | @@ -38,10 +50,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:24:31 + --> $DIR/defaults-unsound-62211-2.rs:24:25 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -63,6 +75,7 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr index 5e2fa551afe3..0866ed054514 100644 --- a/tests/ui/associated-types/issue-54108.next.stderr +++ b/tests/ui/associated-types/issue-54108.next.stderr @@ -1,3 +1,15 @@ +error[E0271]: type mismatch resolving `<::ActualSize as Add>::Output normalizes-to <::ActualSize as Add>::Output` + --> $DIR/issue-54108.rs:23:17 + | +LL | type Size = ::ActualSize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | +note: required by a bound in `Encoder::Size` + --> $DIR/issue-54108.rs:8:20 + | +LL | type Size: Add; + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + error[E0277]: cannot add `::ActualSize` to `::ActualSize` --> $DIR/issue-54108.rs:23:17 | @@ -6,15 +18,16 @@ LL | type Size = ::ActualSize; | = help: the trait `Add` is not implemented for `::ActualSize` note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:20 + --> $DIR/issue-54108.rs:8:16 | LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` help: consider further restricting the associated type | LL | T: SubEncoder, ::ActualSize: Add | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 98609211865c..1a66cb414649 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -11,13 +11,6 @@ help: consider mutably borrowing here LL | for item in &mut *things { *item = 0 } | ++++ -error[E0614]: type ` as IntoIterator>::Item` cannot be dereferenced - --> $DIR/issue-20605.rs:6:27 - | -LL | for item in *things { *item = 0 } - | ^^^^^ +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0277, E0614. -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/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr index d913b2e91ca0..bc57874bf850 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr @@ -15,6 +15,14 @@ help: consider specifying the generic arguments LL | cmp_eq:: | +++++++++++ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `build_expression::{opaque#0} normalizes-to _` + --> $DIR/ambig-hr-projection-issue-93340.rs:14:1 + | +LL | / fn build_expression( +LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + | |_________________________________________________^ types differ -For more information about this error, try `rustc --explain E0283`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0271, E0283. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index 9663fab3d8c3..cab6163803a4 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -7,14 +7,32 @@ LL | #![feature(lazy_type_alias)] = note: see issue #112792 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0277]: the size for values of type `A` cannot be known at compilation time +error[E0271]: type mismatch resolving `A normalizes-to _` --> $DIR/alias-bounds-when-not-wf.rs:16:13 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:10 | - = help: the trait `Sized` is not implemented for `A` +LL | fn hello(_: W>) {} + | ^ types differ -error: aborting due to 1 previous error; 1 warning emitted +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:10 + | +LL | fn hello(_: W>) {} + | ^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -For more information about this error, try `rustc --explain E0277`. +error[E0271]: type mismatch resolving `A normalizes-to _` + --> $DIR/alias-bounds-when-not-wf.rs:16:1 + | +LL | fn hello(_: W>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index b48de0af3579..5aa6931d371e 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -4,19 +4,51 @@ error[E0282]: type annotations needed LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:16:5 +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:13:9 + | +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time + --> $DIR/method-resolution4.rs:11:20 | LL | fn foo(b: bool) -> impl Iterator { - | ------------------------ the expected opaque type -... + | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Iterator` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:16:5 + | LL | std::iter::empty() | ^^^^^^^^^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time + --> $DIR/method-resolution4.rs:13:9 | - = note: expected opaque type `impl Iterator` - found struct `std::iter::Empty<_>` +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Iterator` + = note: the return type of a function must have a statically known size -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:13:9 + | +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/method-resolution4.rs:11:1 + | +LL | fn foo(b: bool) -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0271, E0277, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index 96db2030a405..5feef0b44b53 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -12,15 +12,37 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:14:18 + | +LL | #[coroutine] || { + | __________________^ +LL | | let mut gen = Box::pin(foo()); +LL | | +LL | | let mut r = gen.as_mut().resume(()); +... | +LL | | } +LL | | } + | |_____^ types differ + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ types differ + +error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time + --> $DIR/recursive-coroutine-boxed.rs:9:13 + | +LL | fn foo() -> impl Coroutine { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Coroutine` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` --> $DIR/recursive-coroutine-boxed.rs:14:18 | -LL | fn foo() -> impl Coroutine { - | --------------------------------------- - | | - | the expected opaque type - | expected `impl Coroutine` because of return type -... LL | #[coroutine] || { | __________________^ LL | | let mut gen = Box::pin(foo()); @@ -31,10 +53,32 @@ LL | | } LL | | } | |_____^ types differ | - = note: expected opaque type `impl Coroutine` - found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl Coroutine` + = note: the return type of a function must have a statically known size -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:15:32 + | +LL | let mut gen = Box::pin(foo()); + | ^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` + --> $DIR/recursive-coroutine-boxed.rs:9:1 + | +LL | fn foo() -> impl Coroutine { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0271, E0277, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr index 49ac3f1845fb..f31a2a806674 100644 --- a/tests/ui/impl-trait/unsized_coercion.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -1,26 +1,39 @@ -error[E0271]: type mismatch resolving `impl Trait <: dyn Trait` +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` --> $DIR/unsized_coercion.rs:14:17 | LL | let x = hello(); | ^^^^^^^ types differ error[E0308]: mismatched types - --> $DIR/unsized_coercion.rs:18:14 + --> $DIR/unsized_coercion.rs:18:5 | LL | fn hello() -> Box { - | ---------- the expected opaque type + | --------------- + | | | + | | the expected opaque type + | expected `Box` because of return type ... LL | Box::new(1u32) - | -------- ^^^^ types differ - | | - | arguments to this function are incorrect + | ^^^^^^^^^^^^^^ types differ | - = note: expected opaque type `impl Trait` - found type `u32` -note: associated function defined here - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: expected struct `Box` + found struct `Box` -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion.rs:14:17 + | +LL | let x = hello(); + | ^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion.rs:12:1 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index 586ae0760282..f5187a6256ef 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -1,38 +1,39 @@ -error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send` +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` --> $DIR/unsized_coercion3.rs:13:17 | LL | let x = hello(); | ^^^^^^^ types differ error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:18:14 + --> $DIR/unsized_coercion3.rs:18:5 | LL | fn hello() -> Box { - | ------------------- the expected opaque type + | ------------------------ + | | | + | | the expected opaque type + | expected `Box` because of return type ... LL | Box::new(1u32) - | -------- ^^^^ types differ - | | - | arguments to this function are incorrect + | ^^^^^^^^^^^^^^ types differ | - = note: expected opaque type `impl Trait + ?Sized` - found type `u32` -note: associated function defined here - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: expected struct `Box` + found struct `Box` -error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:18:14 +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion3.rs:13:17 | -LL | Box::new(1u32) - | -------- ^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call +LL | let x = hello(); + | ^^^^^^^ types differ | - = help: the trait `Sized` is not implemented for `impl Trait + ?Sized` -note: required by a bound in `Box::::new` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 3 previous errors +error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` + --> $DIR/unsized_coercion3.rs:11:1 + | +LL | fn hello() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ -Some errors have detailed explanations: E0271, E0277, E0308. +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 3dd2b27b55b6..561bf8eee228 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,21 +1,69 @@ -error[E0271]: type mismatch resolving `impl !Sized + Sized == ()` +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} | ^^^^^^^^^^^^^^^^^^^ types differ -error[E0271]: type mismatch resolving `impl !Sized + Sized == ()` +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^ types differ + +error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Sized + Sized` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 + | +LL | fn weird0() -> impl Sized + !Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ types differ -error[E0271]: type mismatch resolving `impl !Sized == ()` +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:17:36 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^ types differ + +error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Sized + Sized` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:17:1 + | +LL | fn weird1() -> impl !Sized + Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ types differ +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:19:28 + | +LL | fn weird2() -> impl !Sized {} + | ^^ types differ + error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | @@ -25,6 +73,12 @@ LL | fn weird2() -> impl !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized` = note: the return type of a function must have a statically known size +error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 + | +LL | fn weird2() -> impl !Sized {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 | @@ -39,7 +93,7 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 5 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0271, E0277. For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index e1b84e0df7a5..a7a83cf1d69c 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,9 +1,31 @@ -error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()` +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} | ^^^^^^^^^^^^^^^^ types differ -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^ types differ -For more information about this error, try `rustc --explain E0271`. +error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` + --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 + | +LL | fn produce() -> impl !Fn<(u32,)> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index 8c263e8644bd..b37dbc0e579e 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -16,6 +16,43 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine` -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield` + --> $DIR/coroutine.rs:20:9 + | +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { +LL | | +LL | | yield (); +LL | | }, + | |_________^ types differ + | +note: required by a bound in `needs_coroutine` + --> $DIR/coroutine.rs:14:41 + | +LL | fn needs_coroutine(_: impl Coroutine) {} + | ^^^^^^^^^ required by this bound in `needs_coroutine` -For more information about this error, try `rustc --explain E0277`. +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return` + --> $DIR/coroutine.rs:20:9 + | +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { +LL | | +LL | | yield (); +LL | | }, + | |_________^ types differ + | +note: required by a bound in `needs_coroutine` + --> $DIR/coroutine.rs:14:52 + | +LL | fn needs_coroutine(_: impl Coroutine) {} + | ^^^^^^^^^^ required by this bound in `needs_coroutine` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr index cd8d8b3ffcd3..dbd2880943c9 100644 --- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr @@ -9,6 +9,20 @@ help: consider restricting type parameter `T` LL | fn test_poly() { | +++++++ +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:8:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:8:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error[E0277]: the trait bound `i32: Trait` is not satisfied --> $DIR/projection-trait-ref.rs:13:12 | @@ -21,6 +35,21 @@ help: this trait has no implementations, consider adding one LL | trait Trait { | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:13:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ -For more information about this error, try `rustc --explain E0277`. +error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` + --> $DIR/projection-trait-ref.rs:13:12 + | +LL | let x: ::Assoc = (); + | ^^^^^^^^^^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr index 7f2c0646ef50..adf46686e081 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr +++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr @@ -43,7 +43,20 @@ help: consider restricting type parameter `T` LL | pub fn copy_any(t: &T) -> T { | +++++++++++++++++++ -error: aborting due to 3 previous errors +error[E0277]: the size for values of type ` as Setup>::From` cannot be known at compilation time + --> $DIR/dyn-incompatibility.rs:12:5 + | +LL | copy::>(t) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for ` as Setup>::From` + = note: the return type of a function must have a statically known size +help: consider further restricting the associated type + | +LL | pub fn copy_any(t: &T) -> T where as Setup>::From: Sized { + | +++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index 00243fd90595..0dee26d46727 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -15,6 +15,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:20:16 + | +LL | require_fn(f as unsafe fn() -> i32); + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}` --> $DIR/fn-trait.rs:22:16 | @@ -31,6 +45,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 {g} as FnOnce<()>>::Output normalizes-to i32 {g} as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:22:16 + | +LL | require_fn(g); + | ---------- ^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32` --> $DIR/fn-trait.rs:24:16 | @@ -47,6 +75,20 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` +error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:24:16 + | +LL | require_fn(g as extern "C" fn() -> i32); + | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` + error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}` --> $DIR/fn-trait.rs:26:16 | @@ -64,6 +106,21 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error: aborting due to 4 previous errors +error[E0271]: type mismatch resolving ` i32 {h} as FnOnce<()>>::Output normalizes-to i32 {h} as FnOnce<()>>::Output` + --> $DIR/fn-trait.rs:26:16 + | +LL | require_fn(h); + | ---------- ^ types differ + | | + | required by a bound introduced by this call + | +note: required by a bound in `require_fn` + --> $DIR/fn-trait.rs:3:31 + | +LL | fn require_fn(_: impl Fn() -> i32) {} + | ^^^ required by this bound in `require_fn` -For more information about this error, try `rustc --explain E0277`. +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. 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 7c3e22fb4014..82ec9e3a22f7 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,21 +26,13 @@ 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), .. } -error[E0119]: conflicting implementations of trait `Overlap` for type `fn(_)` - --> $DIR/issue-118950-root-region.rs:19:1 +error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _` + --> $DIR/issue-118950-root-region.rs:19:17 | -LL | impl Overlap for T {} - | ------------------------ first implementation here -LL | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` - | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0119, E0277, E0412. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0271, E0277, E0412. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index 2617ce124c10..f953111aef02 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -4,6 +4,21 @@ error[E0282]: type annotations needed LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type -error: aborting due to 1 previous error +error[E0271]: type mismatch resolving `Tait normalizes-to _` + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + | +LL | self.bar.next().unwrap(); + | ^^^^^^^^ types differ -For more information about this error, try `rustc --explain E0282`. +error[E0271]: type mismatch resolving `Tait normalizes-to _` + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + | +LL | self.bar.next().unwrap(); + | ^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0282. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index b6adf08853f2..5c9a3b7c2d29 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -25,6 +25,8 @@ impl Foo { //[current]~^ ERROR: item does not constrain self.bar.next().unwrap(); //[next]~^ ERROR: type annotations needed + //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` + //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` } } From 8528387743709360f1cb2d3b5538342ec71bd03a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 13:04:10 -0400 Subject: [PATCH 092/118] Be better at reporting alias errors --- .../src/solve/eval_ctxt/mod.rs | 2 +- .../src/solve/normalizes_to/mod.rs | 20 +++-- .../src/solve/fulfill.rs | 17 ++++- .../src/solve/inspect/analyse.rs | 6 +- .../rustc_trait_selection/src/solve/select.rs | 3 +- compiler/rustc_type_ir/src/solve/inspect.rs | 2 + compiler/rustc_type_ir/src/solve/mod.rs | 4 + .../defaults-unsound-62211-1.next.stderr | 21 +----- .../defaults-unsound-62211-2.next.stderr | 21 +----- .../associated-types/issue-54108.next.stderr | 21 +----- tests/ui/for/issue-20605.rs | 7 +- ...mbig-hr-projection-issue-93340.next.stderr | 12 +-- ...ambig-hr-projection-issue-93340.old.stderr | 2 +- .../ambig-hr-projection-issue-93340.rs | 1 + .../in-trait/alias-bounds-when-not-wf.rs | 4 +- .../in-trait/alias-bounds-when-not-wf.stderr | 38 ++++++---- .../impl-trait/method-resolution4.next.stderr | 36 ++------- tests/ui/impl-trait/method-resolution4.rs | 3 +- .../recursive-coroutine-boxed.next.stderr | 60 ++------------- .../impl-trait/recursive-coroutine-boxed.rs | 6 +- .../impl-trait/unsized_coercion.next.stderr | 30 ++++---- tests/ui/impl-trait/unsized_coercion.rs | 3 +- .../impl-trait/unsized_coercion3.next.stderr | 30 ++++---- .../impl-trait/unsized_coercion3.old.stderr | 2 +- tests/ui/impl-trait/unsized_coercion3.rs | 4 +- .../opaque-type-unsatisfied-bound.rs | 16 +++- .../opaque-type-unsatisfied-bound.stderr | 73 ++++++++++++------- .../opaque-type-unsatisfied-fn-bound.rs | 5 +- .../opaque-type-unsatisfied-fn-bound.stderr | 21 ++++-- .../traits/next-solver/coroutine.fail.stderr | 41 +---------- .../diagnostics/projection-trait-ref.stderr | 33 +-------- .../traits/next-solver/dyn-incompatibility.rs | 1 + tests/ui/traits/next-solver/fn-trait.stderr | 61 +--------------- .../next-solver/issue-118950-root-region.rs | 4 +- .../issue-118950-root-region.stderr | 14 +++- .../normalize/normalize-region-obligations.rs | 2 +- ...ution_trait_method_from_opaque.next.stderr | 19 +---- ...hod_resolution_trait_method_from_opaque.rs | 2 - tests/ui/typeck/issue-103899.rs | 10 +-- 39 files changed, 237 insertions(+), 420 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index daacc6691182..0f8b796d602a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -983,7 +983,7 @@ where hidden_ty, &mut goals, ); - self.add_goals(GoalSource::Misc, goals); + self.add_goals(GoalSource::AliasWellFormed, goals); } // Do something for each opaque/hidden pair defined with `def_id` in the diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index bf1d2bf08b78..4d8b193ee491 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -37,10 +37,12 @@ where match normalize_result { Ok(res) => Ok(res), Err(NoSolution) => { - let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; - self.add_rigid_constraints(param_env, alias)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| { + let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; + this.add_rigid_constraints(param_env, alias)?; + this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; + this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) } } } @@ -59,11 +61,13 @@ where param_env: I::ParamEnv, rigid_alias: ty::AliasTerm, ) -> Result<(), NoSolution> { - match rigid_alias.kind(self.cx()) { - // Projections are rigid only if their trait ref holds. + let cx = self.cx(); + match rigid_alias.kind(cx) { + // Projections are rigid only if their trait ref holds, + // and the GAT where-clauses hold. ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { - let trait_ref = rigid_alias.trait_ref(self.cx()); - self.add_goal(GoalSource::Misc, Goal::new(self.cx(), param_env, trait_ref)); + let trait_ref = rigid_alias.trait_ref(cx); + self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref)); Ok(()) } ty::AliasTermKind::OpaqueTy => { diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 0e2b081448e5..0f977beb85a9 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -13,7 +13,7 @@ use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _}; -use tracing::instrument; +use tracing::{instrument, trace}; use super::Certainty; use super::delegate::SolverDelegate; @@ -402,6 +402,7 @@ impl<'tcx> BestObligation<'tcx> { nested_goal.source(), GoalSource::ImplWhereBound | GoalSource::InstantiateHigherRanked + | GoalSource::AliasWellFormed ) && match self.consider_ambiguities { true => { matches!( @@ -416,6 +417,13 @@ impl<'tcx> BestObligation<'tcx> { }) }); } + + // Prefer a non-rigid candidate if there is one. + if candidates.len() > 1 { + candidates.retain(|candidate| { + !matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. }) + }); + } } } @@ -430,8 +438,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { self.obligation.cause.span } + #[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))] fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result { let candidates = self.non_trivial_candidates(goal); + trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::>()); + let [candidate] = candidates.as_slice() else { return ControlFlow::Break(self.obligation.clone()); }; @@ -470,6 +481,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { let mut impl_where_bound_count = 0; for nested_goal in candidate.instantiate_nested_goals(self.span()) { + trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result())); + let make_obligation = |cause| Obligation { cause, param_env: nested_goal.goal().param_env, @@ -496,7 +509,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { (_, GoalSource::InstantiateHigherRanked) => { obligation = self.obligation.clone(); } - (ChildMode::PassThrough, _) => { + (ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => { obligation = make_obligation(self.obligation.cause.clone()); } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 254620e0b597..4975a9ce0c75 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -292,7 +292,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { | inspect::ProbeKind::Root { .. } | inspect::ProbeKind::TryNormalizeNonRigid { .. } | inspect::ProbeKind::TraitCandidate { .. } - | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => { + | inspect::ProbeKind::OpaqueTypeStorageLookup { .. } + | inspect::ProbeKind::RigidAlias { .. } => { // Nested probes have to prove goals added in their parent // but do not leak them, so we truncate the added goals // afterwards. @@ -316,7 +317,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { inspect::ProbeKind::Root { result } | inspect::ProbeKind::TryNormalizeNonRigid { result } | inspect::ProbeKind::TraitCandidate { source: _, result } - | inspect::ProbeKind::OpaqueTypeStorageLookup { result } => { + | inspect::ProbeKind::OpaqueTypeStorageLookup { result } + | inspect::ProbeKind::RigidAlias { result } => { // We only add a candidate if `shallow_certainty` was set, which means // that we ended up calling `evaluate_added_goals_and_make_canonical_response`. if let Some(shallow_certainty) = shallow_certainty { diff --git a/compiler/rustc_trait_selection/src/solve/select.rs b/compiler/rustc_trait_selection/src/solve/select.rs index 257fd263b944..1661852903c4 100644 --- a/compiler/rustc_trait_selection/src/solve/select.rs +++ b/compiler/rustc_trait_selection/src/solve/select.rs @@ -177,7 +177,8 @@ fn to_selection<'tcx>( | ProbeKind::UpcastProjectionCompatibility | ProbeKind::OpaqueTypeStorageLookup { result: _ } | ProbeKind::Root { result: _ } - | ProbeKind::ShadowedEnvProbing => { + | ProbeKind::ShadowedEnvProbing + | ProbeKind::RigidAlias { result: _ } => { span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind()) } }) diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index 099c66f6bdc8..138ba8bac887 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -135,4 +135,6 @@ pub enum ProbeKind { ShadowedEnvProbing, /// Try to unify an opaque type with an existing key in the storage. OpaqueTypeStorageLookup { result: QueryResult }, + /// Checking that a rigid alias is well-formed. + RigidAlias { result: QueryResult }, } diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index a0f7658212f4..f02c7a320719 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -130,6 +130,10 @@ pub enum GoalSource { ImplWhereBound, /// Instantiating a higher-ranked goal and re-proving it. InstantiateHigherRanked, + /// Predicate required for an alias projection to be well-formed. + /// This is used in two places: projecting to an opaque whose hidden type + /// is already registered in the opaque type storage, and for rigid projections. + AliasWellFormed, } #[derive_where(Clone; I: Interner, Goal: Clone)] diff --git a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr index 4523fc3e037e..010f51df15ad 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-1.next.stderr @@ -31,18 +31,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` - --> $DIR/defaults-unsound-62211-1.rs:24:96 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ types differ - | -note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:24:31 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` - error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-1.rs:24:96 | @@ -50,10 +38,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-1.rs:24:25 + --> $DIR/defaults-unsound-62211-1.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -75,7 +63,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr index 7a68f1ac8cc4..934789465707 100644 --- a/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr +++ b/tests/ui/associated-types/defaults-unsound-62211-2.next.stderr @@ -31,18 +31,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + AddAssign<&'static str> { | +++++++++++++++++++++++++ -error[E0271]: type mismatch resolving `::Target normalizes-to ::Target` - --> $DIR/defaults-unsound-62211-2.rs:24:96 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^ types differ - | -note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:24:31 - | -LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` - error[E0277]: the trait bound `Self: Deref` is not satisfied --> $DIR/defaults-unsound-62211-2.rs:24:96 | @@ -50,10 +38,10 @@ LL | type Output: Copy + Deref + AddAssign<&'static str> + Fro | ^^^^ the trait `Deref` is not implemented for `Self` | note: required by a bound in `UncheckedCopy::Output` - --> $DIR/defaults-unsound-62211-2.rs:24:25 + --> $DIR/defaults-unsound-62211-2.rs:24:31 | LL | type Output: Copy + Deref + AddAssign<&'static str> + From + Display = Self; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` + | ^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output` help: consider further restricting `Self` | LL | trait UncheckedCopy: Sized + Deref { @@ -75,7 +63,6 @@ help: consider further restricting `Self` LL | trait UncheckedCopy: Sized + Copy { | ++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-54108.next.stderr b/tests/ui/associated-types/issue-54108.next.stderr index 0866ed054514..5e2fa551afe3 100644 --- a/tests/ui/associated-types/issue-54108.next.stderr +++ b/tests/ui/associated-types/issue-54108.next.stderr @@ -1,15 +1,3 @@ -error[E0271]: type mismatch resolving `<::ActualSize as Add>::Output normalizes-to <::ActualSize as Add>::Output` - --> $DIR/issue-54108.rs:23:17 - | -LL | type Size = ::ActualSize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - | -note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:20 - | -LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` - error[E0277]: cannot add `::ActualSize` to `::ActualSize` --> $DIR/issue-54108.rs:23:17 | @@ -18,16 +6,15 @@ LL | type Size = ::ActualSize; | = help: the trait `Add` is not implemented for `::ActualSize` note: required by a bound in `Encoder::Size` - --> $DIR/issue-54108.rs:8:16 + --> $DIR/issue-54108.rs:8:20 | LL | type Size: Add; - | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` help: consider further restricting the associated type | LL | T: SubEncoder, ::ActualSize: Add | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 647dc84028c3..5c56e64a0172 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -4,12 +4,7 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } - //[current]~^ ERROR `dyn Iterator` is not an iterator - //[next]~^^ ERROR `dyn Iterator` is not an iterator - //[next]~| ERROR type ` as IntoIterator>::Item` cannot be dereferenced - - // FIXME(-Znext-solver): these error messages are horrible and have to be - // improved before we stabilize the new solver. + //~^ ERROR `dyn Iterator` is not an iterator } fn main() {} diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr index bc57874bf850..d624fb1e42b6 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + --> $DIR/ambig-hr-projection-issue-93340.rs:17:5 | LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` @@ -15,14 +15,16 @@ help: consider specifying the generic arguments LL | cmp_eq:: | +++++++++++ -error[E0271]: type mismatch resolving `build_expression::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(::RefType<'_>, ::RefType<'_>)` closure, found `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` --> $DIR/ambig-hr-projection-issue-93340.rs:14:1 | LL | / fn build_expression( LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { - | |_________________________________________________^ types differ + | |_________________________________________________^ expected an `Fn(::RefType<'_>, ::RefType<'_>)` closure, found `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` + | + = help: the trait `for<'a, 'b> Fn(::RefType<'a>, ::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::}` error: aborting due to 2 previous errors -Some errors have detailed explanations: E0271, E0283. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0283. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr index d913b2e91ca0..4a293d44e0e3 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr @@ -1,5 +1,5 @@ error[E0283]: type annotations needed - --> $DIR/ambig-hr-projection-issue-93340.rs:16:5 + --> $DIR/ambig-hr-projection-issue-93340.rs:17:5 | LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs index acfebad38db0..5f2e134109e2 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs @@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT fn build_expression( ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O { + //[next]~^^ expected a `Fn(::RefType<'_>, ::RefType<'_>)` closure cmp_eq //~^ ERROR type annotations needed } diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs index 5a6bf9bfaef2..351cdad4ee11 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs @@ -14,6 +14,8 @@ struct W(T); // `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still // encounter weak types in `assemble_alias_bound_candidates_recur`. fn hello(_: W>) {} -//~^ ERROR the size for values of type `A` cannot be known at compilation time +//~^ ERROR the trait bound `usize: Foo` is not satisfied +//~| ERROR the trait bound `usize: Foo` is not satisfied +//~| ERROR the trait bound `usize: Foo` is not satisfied fn main() {} diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr index cab6163803a4..79581066a3a3 100644 --- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr +++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr @@ -7,32 +7,42 @@ LL | #![feature(lazy_type_alias)] = note: see issue #112792 for more information = note: `#[warn(incomplete_features)]` on by default -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:13 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^ types differ + | ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` + | +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:10 | LL | fn hello(_: W>) {} - | ^ types differ - -error[E0271]: type mismatch resolving `A normalizes-to _` - --> $DIR/alias-bounds-when-not-wf.rs:16:10 + | ^ the trait `Foo` is not implemented for `usize` | -LL | fn hello(_: W>) {} - | ^ types differ +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +LL | trait Foo {} + | ^^^^^^^^^ -error[E0271]: type mismatch resolving `A normalizes-to _` +error[E0277]: the trait bound `usize: Foo` is not satisfied --> $DIR/alias-bounds-when-not-wf.rs:16:1 | LL | fn hello(_: W>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize` + | +help: this trait has no implementations, consider adding one + --> $DIR/alias-bounds-when-not-wf.rs:6:1 + | +LL | trait Foo {} + | ^^^^^^^^^ -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 5aa6931d371e..8eacfd3e44d4 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,15 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:13:9 + --> $DIR/method-resolution4.rs:14:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:13:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ types differ - error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time --> $DIR/method-resolution4.rs:11:20 | @@ -19,14 +13,8 @@ LL | fn foo(b: bool) -> impl Iterator { = help: the trait `Sized` is not implemented for `impl Iterator` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:16:5 - | -LL | std::iter::empty() - | ^^^^^^^^^^^^^^^^^^ types differ - error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:13:9 + --> $DIR/method-resolution4.rs:14:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -34,21 +22,7 @@ LL | foo(false).next().unwrap(); = help: the trait `Sized` is not implemented for `impl Iterator` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:13:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: aborting due to 3 previous errors -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/method-resolution4.rs:11:1 - | -LL | fn foo(b: bool) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - -error: aborting due to 7 previous errors - -Some errors have detailed explanations: E0271, E0277, E0282. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0282. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 91884eb59fd6..8eeedf04cbeb 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -9,12 +9,13 @@ //@[current] check-pass fn foo(b: bool) -> impl Iterator { + //[next]~^ ERROR the size for values of type `impl Iterator` cannot be known at compilation time if b { foo(false).next().unwrap(); //[next]~^ type annotations needed + //[next]~| ERROR the size for values of type `impl Iterator` cannot be known at compilation time } std::iter::empty() - //[next]~^ mismatched types } fn main() {} diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index 5feef0b44b53..b38850c9214e 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,9 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:15:23 + --> $DIR/recursive-coroutine-boxed.rs:16:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` -LL | +... LL | let mut r = gen.as_mut().resume(()); | ------ type must be known at this point | @@ -12,25 +12,6 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:14:18 - | -LL | #[coroutine] || { - | __________________^ -LL | | let mut gen = Box::pin(foo()); -LL | | -LL | | let mut r = gen.as_mut().resume(()); -... | -LL | | } -LL | | } - | |_____^ types differ - -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:15:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ types differ - error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time --> $DIR/recursive-coroutine-boxed.rs:9:13 | @@ -40,23 +21,8 @@ LL | fn foo() -> impl Coroutine { = help: the trait `Sized` is not implemented for `impl Coroutine` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:14:18 - | -LL | #[coroutine] || { - | __________________^ -LL | | let mut gen = Box::pin(foo()); -LL | | -LL | | let mut r = gen.as_mut().resume(()); -... | -LL | | } -LL | | } - | |_____^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:15:32 + --> $DIR/recursive-coroutine-boxed.rs:16:32 | LL | let mut gen = Box::pin(foo()); | ^^^^^ doesn't have a size known at compile-time @@ -64,21 +30,7 @@ LL | let mut gen = Box::pin(foo()); = help: the trait `Sized` is not implemented for `impl Coroutine` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:15:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: aborting due to 3 previous errors -error[E0271]: type mismatch resolving `foo::{opaque#0} normalizes-to _` - --> $DIR/recursive-coroutine-boxed.rs:9:1 - | -LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - -error: aborting due to 8 previous errors - -Some errors have detailed explanations: E0271, E0277, E0282. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0282. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 24a77d731141..8e670dd78ecb 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -7,13 +7,15 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { + //[next]~^ ERROR the size for values of type `impl Coroutine` cannot be known at compilation time + // FIXME(-Znext-solver): this fails with a mismatched types as the // hidden type of the opaque ends up as {type error}. We should not // emit errors for such goals. - - #[coroutine] || { //[next]~ ERROR mismatched types + #[coroutine] || { let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed + //[next]~| ERROR the size for values of type `impl Coroutine` cannot be known at compilation time let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/impl-trait/unsized_coercion.next.stderr b/tests/ui/impl-trait/unsized_coercion.next.stderr index f31a2a806674..4cebd26a5bee 100644 --- a/tests/ui/impl-trait/unsized_coercion.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion.next.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion.rs:14:17 +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time + --> $DIR/unsized_coercion.rs:15:17 | LL | let x = hello(); - | ^^^^^^^ types differ + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` error[E0308]: mismatched types - --> $DIR/unsized_coercion.rs:18:5 + --> $DIR/unsized_coercion.rs:19:5 | LL | fn hello() -> Box { | --------------- @@ -19,21 +21,15 @@ LL | Box::new(1u32) = note: expected struct `Box` found struct `Box` -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion.rs:14:17 - | -LL | let x = hello(); - | ^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time --> $DIR/unsized_coercion.rs:12:1 | LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0308. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion.rs b/tests/ui/impl-trait/unsized_coercion.rs index 46e040c1428a..b3791b38abc2 100644 --- a/tests/ui/impl-trait/unsized_coercion.rs +++ b/tests/ui/impl-trait/unsized_coercion.rs @@ -10,9 +10,10 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { + //[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time if true { let x = hello(); - //[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait` + //[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time let y: Box = x; } Box::new(1u32) //[next]~ ERROR: mismatched types diff --git a/tests/ui/impl-trait/unsized_coercion3.next.stderr b/tests/ui/impl-trait/unsized_coercion3.next.stderr index f5187a6256ef..d1e1809cf165 100644 --- a/tests/ui/impl-trait/unsized_coercion3.next.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.next.stderr @@ -1,11 +1,13 @@ -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion3.rs:13:17 +error[E0277]: the trait bound `dyn Send: Trait` is not satisfied + --> $DIR/unsized_coercion3.rs:14:17 | LL | let x = hello(); - | ^^^^^^^ types differ + | ^^^^^^^ the trait `Trait` is not implemented for `dyn Send` + | + = help: the trait `Trait` is implemented for `u32` error[E0308]: mismatched types - --> $DIR/unsized_coercion3.rs:18:5 + --> $DIR/unsized_coercion3.rs:19:5 | LL | fn hello() -> Box { | ------------------------ @@ -19,21 +21,15 @@ LL | Box::new(1u32) = note: expected struct `Box` found struct `Box` -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` - --> $DIR/unsized_coercion3.rs:13:17 - | -LL | let x = hello(); - | ^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0271]: type mismatch resolving `hello::{opaque#0} normalizes-to _` +error[E0277]: the trait bound `dyn Send: Trait` is not satisfied --> $DIR/unsized_coercion3.rs:11:1 | LL | fn hello() -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send` + | + = help: the trait `Trait` is implemented for `u32` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0271, E0308. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/unsized_coercion3.old.stderr b/tests/ui/impl-trait/unsized_coercion3.old.stderr index 52a72b84a8dd..3bb9f9c20951 100644 --- a/tests/ui/impl-trait/unsized_coercion3.old.stderr +++ b/tests/ui/impl-trait/unsized_coercion3.old.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time - --> $DIR/unsized_coercion3.rs:15:32 + --> $DIR/unsized_coercion3.rs:16:32 | LL | let y: Box = x; | ^ doesn't have a size known at compile-time diff --git a/tests/ui/impl-trait/unsized_coercion3.rs b/tests/ui/impl-trait/unsized_coercion3.rs index 7e862de2157d..c1dd5350e229 100644 --- a/tests/ui/impl-trait/unsized_coercion3.rs +++ b/tests/ui/impl-trait/unsized_coercion3.rs @@ -9,15 +9,15 @@ trait Trait {} impl Trait for u32 {} fn hello() -> Box { + //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied if true { let x = hello(); - //[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send` + //[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied let y: Box = x; //[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } Box::new(1u32) //[next]~^ ERROR: mismatched types - //[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know } fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 35757f2339db..70cc47bb0225 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -13,9 +13,17 @@ fn main() { } fn weird0() -> impl Sized + !Sized {} -//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()` +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird1() -> impl !Sized + Sized {} -//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()` +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird2() -> impl !Sized {} -//~^ ERROR type mismatch resolving `impl !Sized == ()` -//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time +//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277] +//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 561bf8eee228..366baf26dea9 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,14 +1,18 @@ -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 @@ -19,26 +23,32 @@ LL | fn weird0() -> impl Sized + !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized + Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird0::{opaque#0} normalizes-to _` +error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:36 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:36 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:17:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -46,26 +56,32 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait `Sized` is not implemented for `impl !Sized + Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird1::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:17:1 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:20:1 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ types differ + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:28 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:28 | LL | fn weird2() -> impl !Sized {} - | ^^ types differ + | ^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -73,11 +89,13 @@ LL | fn weird2() -> impl !Sized {} = help: the trait `Sized` is not implemented for `impl !Sized` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `weird2::{opaque#0} normalizes-to _` - --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 +error[E0277]: the size for values of type `()` cannot be known at compilation time + --> $DIR/opaque-type-unsatisfied-bound.rs:25:1 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 @@ -95,5 +113,4 @@ LL | fn consume(_: impl Trait) {} error: aborting due to 13 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 9951826a8466..3633e9f3f481 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -3,6 +3,9 @@ #![feature(negative_bounds, unboxed_closures)] fn produce() -> impl !Fn<(u32,)> {} -//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()` +//~^ ERROR expected a `Fn(u32)` closure, found `()` +//~| ERROR expected a `Fn(u32)` closure, found `()` +//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time +//~| ERROR expected a `Fn(u32)` closure, found `()` fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index a7a83cf1d69c..cdd89de0d888 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,14 +1,18 @@ -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^ types differ + | ^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 @@ -19,13 +23,14 @@ LL | fn produce() -> impl !Fn<(u32,)> {} = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` = note: the return type of a function must have a statically known size -error[E0271]: type mismatch resolving `produce::{opaque#0} normalizes-to _` +error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` + | + = help: the trait bound `(): !Fn(u32)` is not satisfied error: aborting due to 4 previous errors -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index b37dbc0e579e..8c263e8644bd 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -16,43 +16,6 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine` -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield` - --> $DIR/coroutine.rs:20:9 - | -LL | needs_coroutine( - | --------------- required by a bound introduced by this call -LL | #[coroutine] -LL | / || { -LL | | -LL | | yield (); -LL | | }, - | |_________^ types differ - | -note: required by a bound in `needs_coroutine` - --> $DIR/coroutine.rs:14:41 - | -LL | fn needs_coroutine(_: impl Coroutine) {} - | ^^^^^^^^^ required by this bound in `needs_coroutine` +error: aborting due to 1 previous error -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return normalizes-to <{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return` - --> $DIR/coroutine.rs:20:9 - | -LL | needs_coroutine( - | --------------- required by a bound introduced by this call -LL | #[coroutine] -LL | / || { -LL | | -LL | | yield (); -LL | | }, - | |_________^ types differ - | -note: required by a bound in `needs_coroutine` - --> $DIR/coroutine.rs:14:52 - | -LL | fn needs_coroutine(_: impl Coroutine) {} - | ^^^^^^^^^^ required by this bound in `needs_coroutine` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr index dbd2880943c9..cd8d8b3ffcd3 100644 --- a/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr +++ b/tests/ui/traits/next-solver/diagnostics/projection-trait-ref.stderr @@ -9,20 +9,6 @@ help: consider restricting type parameter `T` LL | fn test_poly() { | +++++++ -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:8:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^ types differ - -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:8:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - error[E0277]: the trait bound `i32: Trait` is not satisfied --> $DIR/projection-trait-ref.rs:13:12 | @@ -35,21 +21,6 @@ help: this trait has no implementations, consider adding one LL | trait Trait { | ^^^^^^^^^^^ -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:13:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^^^ types differ +error: aborting due to 2 previous errors -error[E0271]: type mismatch resolving `::Assoc normalizes-to ::Assoc` - --> $DIR/projection-trait-ref.rs:13:12 - | -LL | let x: ::Assoc = (); - | ^^^^^^^^^^^^^^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors - -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs index a347984daf6a..b53a6543c90a 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.rs +++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs @@ -13,6 +13,7 @@ pub fn copy_any(t: &T) -> T { //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup` //~| ERROR mismatched types //~| ERROR the trait bound `T: Copy` is not satisfied + //~| ERROR the size for values of type ` as Setup>::From` cannot be known at compilation time // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/fn-trait.stderr b/tests/ui/traits/next-solver/fn-trait.stderr index 0dee26d46727..00243fd90595 100644 --- a/tests/ui/traits/next-solver/fn-trait.stderr +++ b/tests/ui/traits/next-solver/fn-trait.stderr @@ -15,20 +15,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:20:16 - | -LL | require_fn(f as unsafe fn() -> i32); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32 {g}` --> $DIR/fn-trait.rs:22:16 | @@ -45,20 +31,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 {g} as FnOnce<()>>::Output normalizes-to i32 {g} as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:22:16 - | -LL | require_fn(g); - | ---------- ^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `extern "C" fn() -> i32` --> $DIR/fn-trait.rs:24:16 | @@ -75,20 +47,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 as FnOnce<()>>::Output normalizes-to i32 as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:24:16 - | -LL | require_fn(g as extern "C" fn() -> i32); - | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` - error[E0277]: expected a `Fn()` closure, found `unsafe fn() -> i32 {h}` --> $DIR/fn-trait.rs:26:16 | @@ -106,21 +64,6 @@ note: required by a bound in `require_fn` LL | fn require_fn(_: impl Fn() -> i32) {} | ^^^^^^^^^^^ required by this bound in `require_fn` -error[E0271]: type mismatch resolving ` i32 {h} as FnOnce<()>>::Output normalizes-to i32 {h} as FnOnce<()>>::Output` - --> $DIR/fn-trait.rs:26:16 - | -LL | require_fn(h); - | ---------- ^ types differ - | | - | required by a bound introduced by this call - | -note: required by a bound in `require_fn` - --> $DIR/fn-trait.rs:3:31 - | -LL | fn require_fn(_: impl Fn() -> i32) {} - | ^^^ required by this bound in `require_fn` +error: aborting due to 4 previous errors -error: aborting due to 8 previous errors - -Some errors have detailed explanations: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs index 9f6dea5d5bf8..e1bd234a275a 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.rs +++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs @@ -17,7 +17,7 @@ type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; impl Overlap for T {} impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} -//~^ ERROR conflicting implementations of trait `Overlap` for type `fn(_)` -//~| ERROR cannot find type `Missing` in this scope +//~^ ERROR cannot find type `Missing` in this scope +//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied fn main() {} 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 82ec9e3a22f7..f6545c6ebf9d 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -26,13 +26,19 @@ 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), .. } -error[E0271]: type mismatch resolving `Assoc<'a, T> normalizes-to _` +error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied --> $DIR/issue-118950-root-region.rs:19:17 | LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ types differ + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T` + | +help: this trait has no implementations, consider adding one + --> $DIR/issue-118950-root-region.rs:8:1 + | +LL | trait ToUnit<'a> { + | ^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors; 1 warning emitted -Some errors have detailed explanations: E0271, E0277, E0412. -For more information about an error, try `rustc --explain E0271`. +Some errors have detailed explanations: E0277, E0412. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs index 7bf3274f9c63..c4c2e695a1df 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-region-obligations.rs @@ -15,7 +15,7 @@ trait Mirror { type Assoc: ?Sized; } impl Mirror for T { type Assoc = T; } trait MirrorRegion<'a> { type Assoc: ?Sized; } -impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; } +impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; } impl Foo for T { #[cfg(normalize_param_env)] diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index f953111aef02..2617ce124c10 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -4,21 +4,6 @@ error[E0282]: type annotations needed LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type -error[E0271]: type mismatch resolving `Tait normalizes-to _` - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 - | -LL | self.bar.next().unwrap(); - | ^^^^^^^^ types differ +error: aborting due to 1 previous error -error[E0271]: type mismatch resolving `Tait normalizes-to _` - --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 - | -LL | self.bar.next().unwrap(); - | ^^^^^^^^ types differ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0271, E0282. -For more information about an error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index 5c9a3b7c2d29..b6adf08853f2 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -25,8 +25,6 @@ impl Foo { //[current]~^ ERROR: item does not constrain self.bar.next().unwrap(); //[next]~^ ERROR: type annotations needed - //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` - //[next]~| ERROR type mismatch resolving `Tait normalizes-to _` } } diff --git a/tests/ui/typeck/issue-103899.rs b/tests/ui/typeck/issue-103899.rs index 38882e9dc54d..81ab92a8994c 100644 --- a/tests/ui/typeck/issue-103899.rs +++ b/tests/ui/typeck/issue-103899.rs @@ -1,11 +1,9 @@ //@ revisions: current next -//@[next] compile-flags: -Znext-solver -//@[next] check-pass //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-fail -//@[current] failure-status: 101 -//@[current] dont-check-compiler-stderr -//@[current] known-bug: #103899 +//@ check-fail +//@ failure-status: 101 +//@ dont-check-compiler-stderr +//@ known-bug: #103899 trait BaseWithAssoc { type Assoc; From 0ead25c4a99242a526ef1076c52fa420c65b667a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 13:49:31 -0400 Subject: [PATCH 093/118] Register a dummy candidate for failed structural normalization during candiate assembly --- .../src/solve/assembly/mod.rs | 20 +++++++++ .../impl-trait/method-resolution4.next.stderr | 25 ++--------- tests/ui/impl-trait/method-resolution4.rs | 2 - .../recursive-coroutine-boxed.next.stderr | 27 ++---------- .../impl-trait/recursive-coroutine-boxed.rs | 3 -- .../opaque-type-unsatisfied-bound.rs | 3 -- .../opaque-type-unsatisfied-bound.stderr | 41 ++++--------------- .../opaque-type-unsatisfied-fn-bound.rs | 1 - .../opaque-type-unsatisfied-fn-bound.stderr | 11 +---- .../traits/next-solver/dyn-incompatibility.rs | 1 - .../next-solver/dyn-incompatibility.stderr | 15 +------ 11 files changed, 36 insertions(+), 113 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index cebeef76bfc0..c9c0d6391fc8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -6,6 +6,7 @@ use derive_where::derive_where; use rustc_type_ir::fold::TypeFoldable; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::inspect; use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate}; use tracing::{debug, instrument}; @@ -288,6 +289,25 @@ where let Ok(normalized_self_ty) = self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty()) else { + // FIXME: We register a fake candidate when normalization fails so that + // we can point at the reason for *why*. I'm tempted to say that this + // is the wrong way to do this, though. + let result = + self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| { + let normalized_ty = this.next_ty_infer(); + let alias_relate_goal = Goal::new( + this.cx(), + goal.param_env, + ty::PredicateKind::AliasRelate( + goal.predicate.self_ty().into(), + normalized_ty.into(), + ty::AliasRelationDirection::Equate, + ), + ); + this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal); + this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + }); + assert_eq!(result, Err(NoSolution)); return vec![]; }; diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 8eacfd3e44d4..0524f49f98e5 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,28 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:14:9 + --> $DIR/method-resolution4.rs:13:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type -error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:11:20 - | -LL | fn foo(b: bool) -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Iterator` - = note: the return type of a function must have a statically known size +error: aborting due to 1 previous error -error[E0277]: the size for values of type `impl Iterator` cannot be known at compilation time - --> $DIR/method-resolution4.rs:14:9 - | -LL | foo(false).next().unwrap(); - | ^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Iterator` - = note: the return type of a function must have a statically known size - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0282. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 8eeedf04cbeb..5c8813ed7922 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -9,11 +9,9 @@ //@[current] check-pass fn foo(b: bool) -> impl Iterator { - //[next]~^ ERROR the size for values of type `impl Iterator` cannot be known at compilation time if b { foo(false).next().unwrap(); //[next]~^ type annotations needed - //[next]~| ERROR the size for values of type `impl Iterator` cannot be known at compilation time } std::iter::empty() } diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index b38850c9214e..132f7de4ef23 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,9 +1,9 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:16:23 + --> $DIR/recursive-coroutine-boxed.rs:14:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` -... +LL | LL | let mut r = gen.as_mut().resume(()); | ------ type must be known at this point | @@ -12,25 +12,6 @@ help: consider specifying the generic argument LL | let mut gen = Box::::pin(foo()); | +++++ -error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:9:13 - | -LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Coroutine` - = note: the return type of a function must have a statically known size +error: aborting due to 1 previous error -error[E0277]: the size for values of type `impl Coroutine` cannot be known at compilation time - --> $DIR/recursive-coroutine-boxed.rs:16:32 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl Coroutine` - = note: the return type of a function must have a statically known size - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0282. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 8e670dd78ecb..8d38e6aed124 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -7,15 +7,12 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { - //[next]~^ ERROR the size for values of type `impl Coroutine` cannot be known at compilation time - // FIXME(-Znext-solver): this fails with a mismatched types as the // hidden type of the opaque ends up as {type error}. We should not // emit errors for such goals. #[coroutine] || { let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed - //[next]~| ERROR the size for values of type `impl Coroutine` cannot be known at compilation time let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 70cc47bb0225..25034b67e35b 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -15,15 +15,12 @@ fn main() { fn weird0() -> impl Sized + !Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird1() -> impl !Sized + Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized + Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] fn weird2() -> impl !Sized {} //~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time [E0277] //~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 366baf26dea9..3e803a1c24fa 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -14,15 +14,6 @@ LL | fn weird0() -> impl Sized + !Sized {} | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 - | -LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized + Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | @@ -32,7 +23,7 @@ LL | fn weird0() -> impl Sized + !Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -40,24 +31,15 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:36 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:36 | LL | fn weird1() -> impl !Sized + Sized {} | ^^ doesn't have a size known at compile-time | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized + Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:16 - | -LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized + Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:20:1 + --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 | LL | fn weird1() -> impl !Sized + Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -65,7 +47,7 @@ LL | fn weird1() -> impl !Sized + Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:16 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^ doesn't have a size known at compile-time @@ -73,24 +55,15 @@ LL | fn weird2() -> impl !Sized {} = help: the trait bound `(): !Sized` is not satisfied error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:28 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:28 | LL | fn weird2() -> impl !Sized {} | ^^ doesn't have a size known at compile-time | = help: the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:16 - | -LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Sized` - = note: the return type of a function must have a statically known size - error[E0277]: the size for values of type `()` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-bound.rs:25:1 + --> $DIR/opaque-type-unsatisfied-bound.rs:23:1 | LL | fn weird2() -> impl !Sized {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -111,6 +84,6 @@ note: required by a bound in `consume` LL | fn consume(_: impl Trait) {} | ^^^^^ required by this bound in `consume` -error: aborting due to 13 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 3633e9f3f481..7538e3c0d2bb 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -5,7 +5,6 @@ fn produce() -> impl !Fn<(u32,)> {} //~^ ERROR expected a `Fn(u32)` closure, found `()` //~| ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time //~| ERROR expected a `Fn(u32)` closure, found `()` fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index cdd89de0d888..57a423741b39 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -14,15 +14,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {} | = help: the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: the size for values of type `impl !Fn<(u32,)>` cannot be known at compilation time - --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 - | -LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `impl !Fn<(u32,)>` - = note: the return type of a function must have a statically known size - error[E0277]: expected a `Fn(u32)` closure, found `()` --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | @@ -31,6 +22,6 @@ LL | fn produce() -> impl !Fn<(u32,)> {} | = help: the trait bound `(): !Fn(u32)` is not satisfied -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.rs b/tests/ui/traits/next-solver/dyn-incompatibility.rs index b53a6543c90a..a347984daf6a 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.rs +++ b/tests/ui/traits/next-solver/dyn-incompatibility.rs @@ -13,7 +13,6 @@ pub fn copy_any(t: &T) -> T { //~^ ERROR the trait bound `T: Copy` is not satisfied in `dyn Setup` //~| ERROR mismatched types //~| ERROR the trait bound `T: Copy` is not satisfied - //~| ERROR the size for values of type ` as Setup>::From` cannot be known at compilation time // FIXME(-Znext-solver): These error messages are horrible and some of them // are even simple fallout from previous error. diff --git a/tests/ui/traits/next-solver/dyn-incompatibility.stderr b/tests/ui/traits/next-solver/dyn-incompatibility.stderr index adf46686e081..7f2c0646ef50 100644 --- a/tests/ui/traits/next-solver/dyn-incompatibility.stderr +++ b/tests/ui/traits/next-solver/dyn-incompatibility.stderr @@ -43,20 +43,7 @@ help: consider restricting type parameter `T` LL | pub fn copy_any(t: &T) -> T { | +++++++++++++++++++ -error[E0277]: the size for values of type ` as Setup>::From` cannot be known at compilation time - --> $DIR/dyn-incompatibility.rs:12:5 - | -LL | copy::>(t) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for ` as Setup>::From` - = note: the return type of a function must have a statically known size -help: consider further restricting the associated type - | -LL | pub fn copy_any(t: &T) -> T where as Setup>::From: Sized { - | +++++++++++++++++++++++++++++++++++++++++++++++++ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. From f956dc2e779ae5ca14c882998d308609648025e9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 20:38:43 -0400 Subject: [PATCH 094/118] Bless tests --- .../structually-relate-aliases.rs | 3 +- .../structually-relate-aliases.stderr | 32 ++++++----- .../opaque-type-unsatisfied-bound.rs | 18 +++---- .../opaque-type-unsatisfied-bound.stderr | 54 +++++++------------ .../opaque-type-unsatisfied-fn-bound.rs | 6 +-- .../opaque-type-unsatisfied-fn-bound.stderr | 18 +++---- 6 files changed, 58 insertions(+), 73 deletions(-) diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs index 698824509613..73c2cd23d86e 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.rs +++ b/tests/ui/higher-ranked/structually-relate-aliases.rs @@ -11,6 +11,7 @@ type Assoc<'a, T> = >::Unit; impl Overlap for T {} impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} -//~^ ERROR conflicting implementations of trait `Overlap fn(&'a (), _)>` +//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied +//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied fn main() {} diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr index 4ecd5829bc35..e9d91e45e217 100644 --- a/tests/ui/higher-ranked/structually-relate-aliases.stderr +++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr @@ -1,18 +1,26 @@ 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, '^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), .. } - 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), .. } -error[E0119]: conflicting implementations of trait `Overlap fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)` - --> $DIR/structually-relate-aliases.rs:13:1 +error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied + --> $DIR/structually-relate-aliases.rs:13:36 | -LL | impl Overlap for T {} - | ------------------------ first implementation here -LL | LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)` + | ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` | - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details +help: consider restricting type parameter `T` + | +LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ++++++++++++++++++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied + --> $DIR/structually-relate-aliases.rs:13:17 + | +LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {} + | ++++++++++++++++++++ -For more information about this error, try `rustc --explain E0119`. +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs index 25034b67e35b..1260cca51068 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.rs @@ -13,14 +13,14 @@ fn main() { } fn weird0() -> impl Sized + !Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird1() -> impl !Sized + Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied fn weird2() -> impl !Sized {} -//~^ ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] -//~| ERROR the size for values of type `()` cannot be known at compilation time [E0277] +//~^ ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied +//~| ERROR the trait bound `(): !Sized` is not satisfied diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr index 3e803a1c24fa..4ec578a3b7bc 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-bound.stderr @@ -1,74 +1,56 @@ -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:16 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:36 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:15:1 | LL | fn weird0() -> impl Sized + !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:16 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:36 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:19:1 | LL | fn weird1() -> impl !Sized + Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:16 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:28 | LL | fn weird2() -> impl !Sized {} - | ^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^ the trait bound `(): !Sized` is not satisfied -error[E0277]: the size for values of type `()` cannot be known at compilation time +error[E0277]: the trait bound `(): !Sized` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:23:1 | LL | fn weird2() -> impl !Sized {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait bound `(): !Sized` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied --> $DIR/opaque-type-unsatisfied-bound.rs:12:13 diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs index 7538e3c0d2bb..c6826578658f 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.rs @@ -3,8 +3,8 @@ #![feature(negative_bounds, unboxed_closures)] fn produce() -> impl !Fn<(u32,)> {} -//~^ ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR expected a `Fn(u32)` closure, found `()` -//~| ERROR expected a `Fn(u32)` closure, found `()` +//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied +//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied +//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied fn main() {} diff --git a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr index 57a423741b39..f81f0a23ac31 100644 --- a/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr +++ b/tests/ui/traits/negative-bounds/opaque-type-unsatisfied-fn-bound.stderr @@ -1,26 +1,20 @@ -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^ the trait bound `(): !Fn(u32)` is not satisfied -error[E0277]: expected a `Fn(u32)` closure, found `()` +error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied --> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1 | LL | fn produce() -> impl !Fn<(u32,)> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an `Fn(u32)` closure, found `()` - | - = help: the trait bound `(): !Fn(u32)` is not satisfied + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied error: aborting due to 3 previous errors From b4e9aad137800936b4fbc3c36da6ff2819b385b5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:20:41 -0400 Subject: [PATCH 095/118] Rename can_coerce to may_coerce --- compiler/rustc_hir_typeck/src/_match.rs | 4 +-- compiler/rustc_hir_typeck/src/cast.rs | 8 ++--- compiler/rustc_hir_typeck/src/coercion.rs | 17 ++++++---- compiler/rustc_hir_typeck/src/expr.rs | 10 +++--- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 10 +++--- .../src/fn_ctxt/suggestions.rs | 34 +++++++++---------- .../rustc_hir_typeck/src/method/suggest.rs | 4 +-- compiler/rustc_hir_typeck/src/pat.rs | 2 +- 8 files changed, 46 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 0d9d1910ae0c..e68caa3e2e35 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -235,8 +235,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(ret_coercion) => { let ret_ty = ret_coercion.borrow().expected_ty(); let ret_ty = self.infcx.shallow_resolve(ret_ty); - self.can_coerce(arm_ty, ret_ty) - && prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty)) + self.may_coerce(arm_ty, ret_ty) + && prior_arm.is_none_or(|(_, ty, _)| self.may_coerce(ty, ret_ty)) // The match arms need to unify for the case of `impl Trait`. && !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..)) } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 407191661a4b..8fa6ab8503d0 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let mut sugg_mutref = false; if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() { if let ty::RawPtr(expr_ty, _) = *self.expr_ty.kind() - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, expr_ty, mutbl), self.cast_ty, ) @@ -418,14 +418,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() && expr_mutbl == Mutability::Not && mutbl == Mutability::Mut - && fcx.can_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty) + && fcx.may_coerce(Ty::new_mut_ref(fcx.tcx, expr_reg, expr_ty), self.cast_ty) { sugg_mutref = true; } if !sugg_mutref && sugg == None - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, reg, self.expr_ty, mutbl), self.cast_ty, ) @@ -433,7 +433,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { sugg = Some((format!("&{}", mutbl.prefix_str()), false)); } } else if let ty::RawPtr(_, mutbl) = *self.cast_ty.kind() - && fcx.can_coerce( + && fcx.may_coerce( Ty::new_ref(fcx.tcx, fcx.tcx.lifetimes.re_erased, self.expr_ty, mutbl), self.cast_ty, ) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bd0b98702983..a6df9e45db50 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1083,21 +1083,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) } - /// Same as `coerce()`, but without side-effects. + /// Probe whether `expr_ty` can be coerced to `target_ty`. This has no side-effects, + /// and may return false positives if types are not yet fully constrained by inference. /// - /// Returns false if the coercion creates any obligations that result in - /// errors. - pub(crate) fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool { + /// Returns false if the coercion is not possible, or if the coercion creates any + /// sub-obligations that result in errors. + /// + /// This should only be used for diagnostics. + pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool { // FIXME(-Znext-solver): We need to structurally resolve both types here. let source = self.resolve_vars_with_obligations(expr_ty); - debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); + debug!("coercion::can_with_predicates({:?} -> {:?})", source, target_ty); let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); self.probe(|_| { - let Ok(ok) = coerce.coerce(source, target) else { + let Ok(ok) = coerce.coerce(source, target_ty) else { return false; }; let ocx = ObligationCtxt::new(self); @@ -1369,7 +1372,7 @@ pub fn can_coerce<'tcx>( ) -> bool { let root_ctxt = crate::typeck_root_ctxt::TypeckRootCtxt::new(tcx, body_id); let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, body_id); - fn_ctxt.can_coerce(ty, output_ty) + fn_ctxt.may_coerce(ty, output_ty) } /// CoerceMany encapsulates the pattern you should use when you have diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index b310398a0f1b..7bdd3c95ad18 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1330,9 +1330,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| { let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs()); let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs()); - self.can_coerce(rhs, lhs) + self.may_coerce(rhs, lhs) }; - let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) { + let (applicability, eq) = if self.may_coerce(rhs_ty, lhs_ty) { (Applicability::MachineApplicable, true) } else if refs_can_coerce(rhs_ty, lhs_ty) { // The lhs and rhs are likely missing some references in either side. Subsequent @@ -1349,7 +1349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let actual_lhs_ty = self.check_expr(rhs_expr); ( Applicability::MaybeIncorrect, - self.can_coerce(rhs_ty, actual_lhs_ty) + self.may_coerce(rhs_ty, actual_lhs_ty) || refs_can_coerce(rhs_ty, actual_lhs_ty), ) } else if let ExprKind::Binary( @@ -1363,7 +1363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let actual_rhs_ty = self.check_expr(lhs_expr); ( Applicability::MaybeIncorrect, - self.can_coerce(actual_rhs_ty, lhs_ty) + self.may_coerce(actual_rhs_ty, lhs_ty) || refs_can_coerce(actual_rhs_ty, lhs_ty), ) } else { @@ -1414,7 +1414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.param_env, ) .may_apply(); - if lhs_deref_ty_is_sized && self.can_coerce(rhs_ty, lhs_deref_ty) { + if lhs_deref_ty_is_sized && self.may_coerce(rhs_ty, lhs_deref_ty) { err.span_suggestion_verbose( lhs.span.shrink_to_lo(), "consider dereferencing here to assign to the mutably borrowed value", diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index fa471647d02d..660cbc29d4cd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -658,7 +658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && fn_sig.inputs()[1..] .iter() .zip(input_types.iter()) - .all(|(expected, found)| self.can_coerce(*expected, *found)) + .all(|(expected, found)| self.may_coerce(*expected, *found)) && fn_sig.inputs()[1..].len() == input_types.len() { err.span_suggestion_verbose( @@ -722,7 +722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expectation = Expectation::rvalue_hint(self, expected_input_ty); let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty); - let can_coerce = self.can_coerce(arg_ty, coerced_ty); + let can_coerce = self.may_coerce(arg_ty, coerced_ty); if !can_coerce { return Compatibility::Incompatible(Some(ty::error::TypeError::Sorts( ty::error::ExpectedFound::new(true, coerced_ty, arg_ty), @@ -802,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx + tys.len()), ), ) { - if !self.can_coerce(provided_ty, *expected_ty) { + if !self.may_coerce(provided_ty, *expected_ty) { satisfied = false; break; } @@ -1023,7 +1023,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { std::iter::zip(formal_and_expected_inputs.iter(), removed_arg_tys.iter()).all( |((expected_ty, _), (provided_ty, _))| { !provided_ty.references_error() - && self.can_coerce(*provided_ty, *expected_ty) + && self.may_coerce(*provided_ty, *expected_ty) }, ) }; @@ -2124,7 +2124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr_ty = self.typeck_results.borrow().expr_ty(expr); let return_ty = fn_sig.output(); if !matches!(expr.kind, hir::ExprKind::Ret(..)) - && self.can_coerce(expr_ty, return_ty) + && self.may_coerce(expr_ty, return_ty) { found_semi = true; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3e9e53261562..3f703c2fcf69 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -261,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let hir::ExprKind::MethodCall(hir::PathSegment { ident: method, .. }, recv_expr, &[], _) = expr.kind && let Some(recv_ty) = self.typeck_results.borrow().expr_ty_opt(recv_expr) - && self.can_coerce(recv_ty, expected) + && self.may_coerce(recv_ty, expected) && let name = method.name.as_str() && (name.starts_with("to_") || name.starts_with("as_") || name == "into") { @@ -349,7 +349,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return true; } - if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected)) + if self.suggest_fn_call(err, expr, found, |output| self.may_coerce(output, expected)) && let ty::FnDef(def_id, ..) = *found.kind() && let Some(sp) = self.tcx.hir().span_if_local(def_id) { @@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.hir().is_inside_const_context(hir_id) || !expected.is_box() || found.is_box() { return false; } - if self.can_coerce(Ty::new_box(self.tcx, found), expected) { + if self.may_coerce(Ty::new_box(self.tcx, found), expected) { let suggest_boxing = match found.kind() { ty::Tuple(tuple) if tuple.is_empty() => { errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span } @@ -663,7 +663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; match expected.kind() { ty::Adt(def, _) if Some(def.did()) == pin_did => { - if self.can_coerce(pin_box_found, expected) { + if self.may_coerce(pin_box_found, expected) { debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected); match found.kind() { ty::Adt(def, _) if def.is_box() => { @@ -689,7 +689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } true - } else if self.can_coerce(pin_found, expected) { + } else if self.may_coerce(pin_found, expected) { match found.kind() { ty::Adt(def, _) if def.is_box() => { err.help("use `Box::pin`"); @@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } } - ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => { + ty::Adt(def, _) if def.is_box() && self.may_coerce(box_found, expected) => { // Check if the parent expression is a call to Pin::new. If it // is and we were expecting a Box, ergo Pin>, we // can suggest Box::pin. @@ -884,7 +884,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = Binder::bind_with_vars(ty, bound_vars); let ty = self.normalize(hir_ty.span, ty); let ty = self.tcx.instantiate_bound_regions_with_erased(ty); - if self.can_coerce(expected, ty) { + if self.may_coerce(expected, ty) { err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected, @@ -1141,12 +1141,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Asyncness::No => ty, }; let ty = self.normalize(expr.span, ty); - self.can_coerce(found, ty) + self.may_coerce(found, ty) } hir::FnRetTy::DefaultReturn(_) if in_closure => { self.ret_coercion.as_ref().map_or(false, |ret| { let ret_ty = ret.borrow().expected_ty(); - self.can_coerce(found, ret_ty) + self.may_coerce(found, ret_ty) }) } _ => false, @@ -1510,7 +1510,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { provided_ty }; - if !self.can_coerce(expected_ty, dummy_ty) { + if !self.may_coerce(expected_ty, dummy_ty) { return; } let msg = format!("use `{adt_name}::map_or` to deref inner value of `{adt_name}`"); @@ -1534,7 +1534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty: Ty<'tcx>, ) { if let ty::Slice(elem_ty) | ty::Array(elem_ty, _) = expected_ty.kind() { - if self.can_coerce(blk_ty, *elem_ty) + if self.may_coerce(blk_ty, *elem_ty) && blk.stmts.is_empty() && blk.rules == hir::BlockCheckMode::DefaultBlock { @@ -1744,7 +1744,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if item_ty.has_param() { return false; } - if self.can_coerce(item_ty, expected_ty) { + if self.may_coerce(item_ty, expected_ty) { err.span_suggestion_verbose( segment.ident.span, format!("try referring to the associated const `{capitalized_name}` instead",), @@ -1804,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // diagnostic in cases where we have `(&&T).clone()` and we expect `T`). && !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..))) // Check that we're in fact trying to clone into the expected type - && self.can_coerce(*pointee_ty, expected_ty) + && self.may_coerce(*pointee_ty, expected_ty) && let trait_ref = ty::TraitRef::new(self.tcx, clone_trait_did, [expected_ty]) // And the expected type doesn't implement `Clone` && !self.predicate_must_hold_considering_regions(&traits::Obligation::new( @@ -2022,7 +2022,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { return false; }; - if is_ctor || !self.can_coerce(args.type_at(0), expected) { + if is_ctor || !self.may_coerce(args.type_at(0), expected) { return false; } @@ -2293,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .then(|| " (its field is private, but it's local to this crate and its privacy can be changed)".to_string()); let sole_field_ty = sole_field.ty(self.tcx, args); - if self.can_coerce(expr_ty, sole_field_ty) { + if self.may_coerce(expr_ty, sole_field_ty) { let variant_path = with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); // FIXME #56861: DRYer prelude filtering @@ -2401,7 +2401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let int_type = args.type_at(0); - if !self.can_coerce(expr_ty, int_type) { + if !self.may_coerce(expr_ty, int_type) { return false; } @@ -2585,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, checked_ty) } }; - if self.can_coerce(ref_ty, expected) { + if self.may_coerce(ref_ty, expected) { let mut sugg_sp = sp; if let hir::ExprKind::MethodCall(segment, receiver, args, _) = expr.kind { let clone_trait = diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 7f68e19a3139..9dd595411486 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1934,7 +1934,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && fn_sig.inputs()[1..] .iter() .zip(args.into_iter()) - .all(|(expected, found)| self.can_coerce(*expected, *found)) + .all(|(expected, found)| self.may_coerce(*expected, *found)) && fn_sig.inputs()[1..].len() == args.len() { err.span_suggestion_verbose( @@ -4148,7 +4148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; }; - if !self.can_coerce(output, expected) { + if !self.may_coerce(output, expected) { return false; } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index fb78da0a86c6..5ce9bae81c1c 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1767,7 +1767,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if inexistent_fields.len() == 1 { match pat_field.pat.kind { PatKind::Lit(expr) - if !self.can_coerce( + if !self.may_coerce( self.typeck_results.borrow().expr_ty(expr), self.field_ty(field.span, field_def, args), ) => {} From e3eba2d9204e9af2ac7a089f61996b25cfecf2d8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:26:56 -0400 Subject: [PATCH 096/118] Don't structurally resolve in may_coerce --- compiler/rustc_hir_typeck/src/coercion.rs | 6 +---- .../lazy_subtyping_of_opaques.stderr | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index a6df9e45db50..bb2f1f0493a7 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1091,16 +1091,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// This should only be used for diagnostics. pub(crate) fn may_coerce(&self, expr_ty: Ty<'tcx>, target_ty: Ty<'tcx>) -> bool { - // FIXME(-Znext-solver): We need to structurally resolve both types here. - let source = self.resolve_vars_with_obligations(expr_ty); - debug!("coercion::can_with_predicates({:?} -> {:?})", source, target_ty); - let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); self.probe(|_| { - let Ok(ok) = coerce.coerce(source, target_ty) else { + let Ok(ok) = coerce.coerce(expr_ty, target_ty) else { return false; }; let ocx = ObligationCtxt::new(self); diff --git a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr index 7bc2fa1b09ea..921667f577b4 100644 --- a/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr +++ b/tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.stderr @@ -1,3 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/lazy_subtyping_of_opaques.rs:11:5 + | +LL | fn reify_as_tait() -> Thunk { + | ----------- expected `Thunk<_>` because of return type +LL | +LL | Thunk::new(|cont| cont) + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` + | + = note: expected struct `Thunk<_>` + found unit type `()` + error[E0277]: expected a `FnOnce()` closure, found `()` --> $DIR/lazy_subtyping_of_opaques.rs:11:23 | @@ -12,19 +24,13 @@ error[E0277]: expected a `FnOnce()` closure, found `()` | LL | fn reify_as_tait() -> Thunk { | ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()` +LL | +LL | Thunk::new(|cont| cont) + | ----------------------- return type was inferred to be `{type error}` here | = help: the trait `FnOnce()` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` -error[E0308]: mismatched types - --> $DIR/lazy_subtyping_of_opaques.rs:11:5 - | -LL | Thunk::new(|cont| cont) - | ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()` - | - = note: expected struct `Thunk<_>` - found unit type `()` - error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308. From 9070abab4b6862e42a8ce25eeb4a810301b76dd7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 15 Oct 2024 13:47:43 -0400 Subject: [PATCH 097/118] Structurally resolve in may_coerce --- compiler/rustc_hir_typeck/src/coercion.rs | 23 +++++++++++++++++-- .../diagnostics/coerce-in-may-coerce.rs | 19 +++++++++++++++ .../diagnostics/coerce-in-may-coerce.stderr | 21 +++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs create mode 100644 tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index bb2f1f0493a7..fb9262a59b9c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1094,12 +1094,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion. // We also just always set `coerce_never` to true, since this is a heuristic. - let coerce = Coerce::new(self, cause, AllowTwoPhase::No, true); + let coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No, true); self.probe(|_| { + // Make sure to structurally resolve the types, since we use + // the `TyKind`s heavily in coercion. + let ocx = ObligationCtxt::new(self); + let structurally_resolve = |ty| { + let ty = self.shallow_resolve(ty); + if self.next_trait_solver() + && let ty::Alias(..) = ty.kind() + { + ocx.structurally_normalize(&cause, self.param_env, ty) + } else { + Ok(ty) + } + }; + let Ok(expr_ty) = structurally_resolve(expr_ty) else { + return false; + }; + let Ok(target_ty) = structurally_resolve(target_ty) else { + return false; + }; + let Ok(ok) = coerce.coerce(expr_ty, target_ty) else { return false; }; - let ocx = ObligationCtxt::new(self); ocx.register_obligations(ok.obligations); ocx.select_where_possible().is_empty() }) diff --git a/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs new file mode 100644 index 000000000000..bd3dccad1528 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Znext-solver + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +fn arg() -> &'static [i32; 1] { todo!() } + +fn arg_error(x: ::Assoc, y: ()) { todo!() } + +fn main() { + // Should suggest to reverse the args... + // but if we don't normalize the expected, then we don't. + arg_error((), || ()); + //~^ ERROR arguments to this function are incorrect +} diff --git a/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr new file mode 100644 index 000000000000..1938b3375a51 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/coerce-in-may-coerce.stderr @@ -0,0 +1,21 @@ +error[E0308]: arguments to this function are incorrect + --> $DIR/coerce-in-may-coerce.rs:17:5 + | +LL | arg_error((), || ()); + | ^^^^^^^^^ -- ----- expected `()`, found `{closure@$DIR/coerce-in-may-coerce.rs:17:19: 17:21}` + | | + | expected `::Assoc`, found `()` + | +note: function defined here + --> $DIR/coerce-in-may-coerce.rs:12:4 + | +LL | fn arg_error(x: ::Assoc, y: ()) { todo!() } + | ^^^^^^^^^ -------------------------- ----- +help: swap these arguments + | +LL | arg_error(|| (), ()); + | ~~~~~~~~~~~ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From c7730989de17b0cbdc1d48481062745d31d5c5a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 28 Sep 2024 13:21:39 -0400 Subject: [PATCH 098/118] Don't check unsize goal in MIR validation when opaques remain --- compiler/rustc_mir_transform/src/validate.rs | 11 +++++++++++ tests/crashes/130921.rs | 10 ---------- tests/ui/impl-trait/unsize-cast-validation-rpit.rs | 12 ++++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/130921.rs create mode 100644 tests/ui/impl-trait/unsize-cast-validation-rpit.rs diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index e353be6a105f..25e68f44456b 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -595,6 +595,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &self, pred: impl Upcast, ty::Predicate<'tcx>>, ) -> bool { + let pred: ty::Predicate<'tcx> = pred.upcast(self.tcx); + + // We sometimes have to use `defining_opaque_types` for predicates + // to succeed here and figuring out how exactly that should work + // is annoying. It is harmless enough to just not validate anything + // in that case. We still check this after analysis as all opaque + // types have been revealed at this point. + if pred.has_opaque_types() { + return true; + } + let infcx = self.tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( diff --git a/tests/crashes/130921.rs b/tests/crashes/130921.rs deleted file mode 100644 index b7cb1303937e..000000000000 --- a/tests/crashes/130921.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #130921 -//@ compile-flags: -Zvalidate-mir -Copt-level=0 --crate-type lib - -pub fn hello() -> [impl Sized; 2] { - if false { - let x = hello(); - let _: &[i32] = &x; - } - todo!() -} diff --git a/tests/ui/impl-trait/unsize-cast-validation-rpit.rs b/tests/ui/impl-trait/unsize-cast-validation-rpit.rs new file mode 100644 index 000000000000..cace30aca8a6 --- /dev/null +++ b/tests/ui/impl-trait/unsize-cast-validation-rpit.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ compile-flags: -Zvalidate-mir + +fn hello() -> &'static [impl Sized; 0] { + if false { + let x = hello(); + let _: &[i32] = x; + } + &[] +} + +fn main() {} From e9853961452b56997cc127b51308879b9cd09482 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 15 Oct 2024 20:56:20 +0000 Subject: [PATCH 099/118] llvm: Match aarch64 data layout to new LLVM layout LLVM has added 3 new address spaces to support special Windows use cases. These shouldn't trouble us for now, but LLVM requires matching data layouts. See llvm/llvm-project#111879 for details --- compiler/rustc_codegen_llvm/src/context.rs | 10 ++++++++++ .../src/spec/targets/aarch64_apple_darwin.rs | 3 ++- .../rustc_target/src/spec/targets/aarch64_apple_ios.rs | 3 ++- .../src/spec/targets/aarch64_apple_ios_macabi.rs | 3 ++- .../src/spec/targets/aarch64_apple_ios_sim.rs | 3 ++- .../src/spec/targets/aarch64_apple_tvos.rs | 3 ++- .../src/spec/targets/aarch64_apple_tvos_sim.rs | 3 ++- .../src/spec/targets/aarch64_apple_visionos.rs | 3 ++- .../src/spec/targets/aarch64_apple_visionos_sim.rs | 3 ++- .../src/spec/targets/aarch64_apple_watchos.rs | 3 ++- .../src/spec/targets/aarch64_apple_watchos_sim.rs | 3 ++- .../src/spec/targets/aarch64_kmc_solid_asp3.rs | 2 +- .../src/spec/targets/aarch64_linux_android.rs | 2 +- .../targets/aarch64_nintendo_switch_freestanding.rs | 2 +- .../src/spec/targets/aarch64_pc_windows_gnullvm.rs | 4 +++- .../src/spec/targets/aarch64_pc_windows_msvc.rs | 4 +++- .../src/spec/targets/aarch64_unknown_freebsd.rs | 2 +- .../src/spec/targets/aarch64_unknown_fuchsia.rs | 2 +- .../src/spec/targets/aarch64_unknown_hermit.rs | 2 +- .../src/spec/targets/aarch64_unknown_illumos.rs | 2 +- .../src/spec/targets/aarch64_unknown_linux_gnu.rs | 2 +- .../src/spec/targets/aarch64_unknown_linux_musl.rs | 2 +- .../src/spec/targets/aarch64_unknown_linux_ohos.rs | 2 +- .../src/spec/targets/aarch64_unknown_netbsd.rs | 2 +- .../src/spec/targets/aarch64_unknown_none.rs | 2 +- .../src/spec/targets/aarch64_unknown_none_softfloat.rs | 2 +- .../src/spec/targets/aarch64_unknown_nto_qnx700.rs | 2 +- .../src/spec/targets/aarch64_unknown_openbsd.rs | 2 +- .../src/spec/targets/aarch64_unknown_redox.rs | 2 +- .../src/spec/targets/aarch64_unknown_teeos.rs | 2 +- .../src/spec/targets/aarch64_unknown_trusty.rs | 2 +- .../src/spec/targets/aarch64_unknown_uefi.rs | 4 +++- .../src/spec/targets/aarch64_uwp_windows_msvc.rs | 4 +++- .../src/spec/targets/aarch64_wrs_vxworks.rs | 2 +- .../src/spec/targets/arm64_32_apple_watchos.rs | 3 ++- .../src/spec/targets/arm64e_apple_darwin.rs | 3 ++- .../rustc_target/src/spec/targets/arm64e_apple_ios.rs | 3 ++- .../rustc_target/src/spec/targets/arm64e_apple_tvos.rs | 3 ++- .../src/spec/targets/arm64ec_pc_windows_msvc.rs | 4 +++- 39 files changed, 72 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index c836dd5473f3..2f830d6f941e 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -138,6 +138,16 @@ pub(crate) unsafe fn create_module<'ll>( } } + if llvm_version < (20, 0, 0) { + if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") { + // LLVM 20 defines three additional address spaces for alternate + // pointer kinds used in Windows. + // See https://github.com/llvm/llvm-project/pull/111879 + target_data_layout = + target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", ""); + } + } + // Ensure the data-layout values hardcoded remain the defaults. { let tm = crate::back::write::create_informational_target_machine(tcx.sess, false); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index e6ce50a005f7..adee6f5fe994 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { mcount: "\u{1}mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index 78441ede3337..efc42b909e4e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs index 857abd21faf6..be503d18bf15 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index cbc8b7cd95e4..04bbee45cd32 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index f5176d35f809..fa0bc130e1c7 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs index d67385141456..428045da4930 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs index dc5dac4fd8f2..62d6ffbd34f0 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a16".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs index e9fe786f65ec..a66c4f6e96bd 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a16".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs index 4f5ce2f12e73..abd924b5934a 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+v8a,+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs index 952c98c324fa..ba85647fddcc 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs index 97ce53b2d8fd..58fc703946e5 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_kmc_solid_asp3.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { linker: Some("aarch64-kmc-elf-gcc".into()), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs index a8ef5544a243..a021d317cc83 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_linux_android.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs index 1f1cd9663267..6ac69e0f57f3 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_nintendo_switch_freestanding.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index 7a56809dcfc7..8b96f589c74d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -15,7 +15,9 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs index e1133a4ce051..14ce5edd2f3c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs @@ -14,7 +14,9 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs index 2ca2f403e177..dd90161f4408 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_freebsd.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs index 26a736a27126..df13d52a2236 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs index 3989cc13fba5..459e888eb943 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_hermit.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { }, pointer_width: 64, arch: "aarch64".into(), - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), options: TargetOptions { features: "+v8a,+strict-align,+neon,+fp-armv8".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs index b76f10b8efdf..699376a7928b 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs index 96c25af0a7fc..18711cb399d7 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_gnu.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a,+outline-atomics".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs index 197ff2d74e5e..bb65048a56d6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs @@ -21,7 +21,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { mcount: "\u{1}_mcount".into(), ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs index 9d5bce053500..22b3a5f88426 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_ohos.rs @@ -13,7 +13,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+reserve-x18".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs index d1769d1476cc..0ec76e4b42fd 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_netbsd.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs index d124f8a3d297..05fe32734a7e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none.rs @@ -37,7 +37,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: opts, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs index 7933041b584e..d6b77ffd091a 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_none_softfloat.rs @@ -32,7 +32,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: opts, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs index 6c061112b166..441ed7cf1535 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs @@ -22,7 +22,7 @@ pub(crate) fn target() -> Target { // i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128 // n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently. // S128 = 128 bits are the natural alignment of the stack in bits. - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs index 31c8daa98b06..0fcf5c34bb0e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_openbsd.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs index 6bd8c306abb4..7ff99c574ad8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_redox.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs index 4bffef4758d1..fb8b59f77291 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs index 69ab992e12ca..cebd8ff2f684 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_trusty.rs @@ -12,7 +12,7 @@ pub(crate) fn target() -> Target { std: Some(false), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+neon,+fp-armv8,+reserve-x18".into(), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs index bde1ce95b3f9..9656024ddaa1 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs @@ -19,7 +19,9 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs index c916aa6b23cf..3d7c02698080 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_uwp_windows_msvc.rs @@ -14,7 +14,9 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch: "aarch64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs index dd5298944e0d..d5e78d030760 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_wrs_vxworks.rs @@ -10,7 +10,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(), arch: "aarch64".into(), options: TargetOptions { features: "+v8a".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs index 4f7a1857e76a..a5a6f772ac84 100644 --- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32".into(), arch, options: TargetOptions { features: "+v8a,+neon,+fp-armv8,+apple-a7".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs index 04906fb04609..744d95445b8e 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { mcount: "\u{1}mcount".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs index 3264669c169f..dace11dae24d 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs index 4c231cb519c0..2ccdc76c52e6 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs @@ -12,7 +12,8 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch, options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(), diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index a6744b95a3eb..03c96fbfdb0c 100644 --- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -18,7 +18,9 @@ pub(crate) fn target() -> Target { std: None, // ? }, pointer_width: 64, - data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32".into(), + data_layout: + "e-m:w-p270:32:32-p271:32:32-p272:64:64-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32" + .into(), arch: "arm64ec".into(), options: base, } From 4cf0475eeb6fb3aca3b67cd16127d825709a0bb4 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 16 Oct 2024 12:16:17 +1100 Subject: [PATCH 100/118] Fix unnecessary nesting in run-make test output directories --- src/tools/compiletest/src/runtest/run_make.rs | 6 +++++- tests/run-make/README.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 75fe6a6baafa..f8ffd0fbe3f7 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -22,6 +22,10 @@ impl TestCx<'_> { let src_root = self.config.src_base.parent().unwrap().parent().unwrap(); let src_root = cwd.join(&src_root); + // FIXME(Zalathar): This should probably be `output_base_dir` to avoid + // an unnecessary extra subdirectory, but since legacy Makefile tests + // are hopefully going away, it seems safer to leave this perilous code + // as-is until it can all be deleted. let tmpdir = cwd.join(self.output_base_name()); if tmpdir.exists() { self.aggressive_rm_rf(&tmpdir).unwrap(); @@ -213,7 +217,7 @@ impl TestCx<'_> { // `rmake_out/` directory. // // This setup intentionally diverges from legacy Makefile run-make tests. - let base_dir = self.output_base_name(); + let base_dir = self.output_base_dir(); if base_dir.exists() { self.aggressive_rm_rf(&base_dir).unwrap(); } diff --git a/tests/run-make/README.md b/tests/run-make/README.md index 9e1eaa881c94..403599034738 100644 --- a/tests/run-make/README.md +++ b/tests/run-make/README.md @@ -29,7 +29,7 @@ The setup for the `rmake.rs` version is a 3-stage process: structure within `build//test/run-make/` ``` - // + / rmake.exe # recipe binary rmake_out/ # sources from test sources copied over ``` From 69faeafd0cac0f503f75a994f68f3e42af568046 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?= <39484203+jieyouxu@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:40:29 +0800 Subject: [PATCH 101/118] mailmap: add entry for my dev-desktop setup --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index dc5bfe6d5fc7..bdc34c52aa76 100644 --- a/.mailmap +++ b/.mailmap @@ -280,6 +280,7 @@ Jerry Hardee Jesús Rubio Jethro Beekman Jian Zeng +Jieyou Xu <39484203+jieyouxu@users.noreply.github.com> Jihyun Yu Jihyun Yu jihyun Jihyun Yu Jihyun Yu From f204e2c23b20f3052acaec7e0e231deb4ee23e50 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 14 Oct 2024 10:22:50 -0700 Subject: [PATCH 102/118] replace placeholder version (cherry picked from commit 567fd9610cbfd220844443487059335d7e1ff021) --- compiler/rustc_feature/src/accepted.rs | 10 ++++---- compiler/rustc_feature/src/removed.rs | 4 ++-- compiler/rustc_feature/src/unstable.rs | 14 +++++------ library/core/src/array/mod.rs | 2 +- library/core/src/cell.rs | 8 +++---- library/core/src/cell/once.rs | 2 +- library/core/src/char/methods.rs | 6 ++--- library/core/src/fmt/builders.rs | 8 +++---- library/core/src/intrinsics.rs | 20 ++++++++-------- library/core/src/mem/maybe_uninit.rs | 5 +--- library/core/src/mem/mod.rs | 2 +- library/core/src/num/f32.rs | 32 ++++++++++++------------- library/core/src/num/f64.rs | 32 ++++++++++++------------- library/core/src/ops/control_flow.rs | 8 +++---- library/core/src/option.rs | 22 ++++++++--------- library/core/src/ptr/const_ptr.rs | 6 ++--- library/core/src/ptr/metadata.rs | 6 ++--- library/core/src/ptr/mod.rs | 8 +++---- library/core/src/ptr/mut_ptr.rs | 16 ++++++------- library/core/src/ptr/non_null.rs | 21 +++++++--------- library/core/src/result.rs | 8 +++---- library/core/src/slice/mod.rs | 22 ++++++++--------- library/core/src/slice/raw.rs | 4 ++-- library/core/src/str/converts.rs | 5 +--- library/core/src/str/mod.rs | 4 ++-- library/core/src/task/wake.rs | 8 +++---- library/core/src/time.rs | 8 +++---- library/std/src/collections/hash/map.rs | 20 ++++++++-------- library/std/src/collections/hash/set.rs | 4 ++-- library/std/src/io/error.rs | 32 ++++++++++++------------- library/std/src/io/mod.rs | 2 +- 31 files changed, 170 insertions(+), 179 deletions(-) diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index a850eb956207..0c5fe6e8d8b7 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -116,7 +116,7 @@ declare_features! ( /// Allows calling constructor functions in `const fn`. (accepted, const_constructor, "1.40.0", Some(61456)), /// Allows the definition of `const extern fn` and `const unsafe extern fn`. - (accepted, const_extern_fn, "CURRENT_RUSTC_VERSION", Some(64926)), + (accepted, const_extern_fn, "1.83.0", Some(64926)), /// Allows basic arithmetic on floating point types in a `const fn`. (accepted, const_fn_floating_point_arithmetic, "1.82.0", Some(57241)), /// Allows using and casting function pointers in a `const fn`. @@ -144,15 +144,15 @@ declare_features! ( /// Allows the use of `loop` and `while` in constants. (accepted, const_loop, "1.46.0", Some(52000)), /// Allows using `&mut` in constant functions. - (accepted, const_mut_refs, "CURRENT_RUSTC_VERSION", Some(57349)), + (accepted, const_mut_refs, "1.83.0", Some(57349)), /// Allows panicking during const eval (producing compile-time errors). (accepted, const_panic, "1.57.0", Some(51999)), /// Allows dereferencing raw pointers during const eval. (accepted, const_raw_ptr_deref, "1.58.0", Some(51911)), /// Allows references to types with interior mutability within constants - (accepted, const_refs_to_cell, "CURRENT_RUSTC_VERSION", Some(80384)), + (accepted, const_refs_to_cell, "1.83.0", Some(80384)), /// Allows creating pointers and references to `static` items in constants. - (accepted, const_refs_to_static, "CURRENT_RUSTC_VERSION", Some(119618)), + (accepted, const_refs_to_static, "1.83.0", Some(119618)), /// Allows implementing `Copy` for closures where possible (RFC 2132). (accepted, copy_closures, "1.26.0", Some(44490)), /// Allows `crate` in paths. @@ -190,7 +190,7 @@ declare_features! ( /// Allows explicit generic arguments specification with `impl Trait` present. (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701)), /// Uses 2024 rules for matching `expr` fragments in macros. Also enables `expr_2021` fragment. - (accepted, expr_fragment_specifier_2024, "CURRENT_RUSTC_VERSION", Some(123742)), + (accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)), /// Allows arbitrary expressions in key-value attributes at parse time. (accepted, extended_key_value_attributes, "1.54.0", Some(78835)), /// Allows resolving absolute paths as paths from other crates. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index cba4535156b8..d797fee000dd 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -156,7 +156,7 @@ declare_features! ( (removed, no_stack_check, "1.0.0", None, None), /// Allows making `dyn Trait` well-formed even if `Trait` is not dyn-compatible (object safe). /// Renamed to `dyn_compatible_for_dispatch`. - (removed, object_safe_for_dispatch, "CURRENT_RUSTC_VERSION", Some(43561), + (removed, object_safe_for_dispatch, "1.83.0", Some(43561), Some("renamed to `dyn_compatible_for_dispatch`")), /// Allows using `#[on_unimplemented(..)]` on traits. /// (Moved to `rustc_attrs`.) @@ -221,7 +221,7 @@ declare_features! ( /// Allows using items which are missing stability attributes (removed, unmarked_api, "1.0.0", None, None), /// Allows unnamed fields of struct and union type - (removed, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), Some("feature needs redesign")), + (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")), (removed, unsafe_no_drop_flag, "1.0.0", None, None), /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue. (removed, untagged_unions, "1.13.0", Some(55149), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index c0398db9c101..1067156958dc 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -228,7 +228,7 @@ declare_features! ( /// Added for testing unstable lints; perma-unstable. (internal, test_unstable_lint, "1.60.0", None), /// Helps with formatting for `group_imports = "StdExternalCrate"`. - (unstable, unqualified_local_imports, "CURRENT_RUSTC_VERSION", None), + (unstable, unqualified_local_imports, "1.83.0", None), /// Use for stable + negative coherence and strict coherence depending on trait's /// rustc_strict_coherence value. (unstable, with_negative_coherence, "1.60.0", None), @@ -266,7 +266,7 @@ declare_features! ( /// Renamed from `object_safe_for_dispatch`. /// /// [^1]: Formerly known as "object safe". - (unstable, dyn_compatible_for_dispatch, "CURRENT_RUSTC_VERSION", Some(43561)), + (unstable, dyn_compatible_for_dispatch, "1.83.0", Some(43561)), /// Allows using the `#[fundamental]` attribute. (unstable, fundamental, "1.0.0", Some(29635)), /// Allows using `#[link_name="llvm.*"]`. @@ -360,7 +360,7 @@ declare_features! ( /// Allows inherent and trait methods with arbitrary self types. (unstable, arbitrary_self_types, "1.23.0", Some(44874)), /// Allows inherent and trait methods with arbitrary self types that are raw pointers. - (unstable, arbitrary_self_types_pointers, "CURRENT_RUSTC_VERSION", Some(44874)), + (unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)), /// Enables experimental inline assembly support for additional architectures. (unstable, asm_experimental_arch, "1.58.0", Some(93335)), /// Allows using `label` operands in inline assembly. @@ -380,7 +380,7 @@ declare_features! ( /// Allows using C-variadics. (unstable, c_variadic, "1.34.0", Some(44930)), /// Allows the use of `#[cfg()]`. - (unstable, cfg_boolean_literals, "CURRENT_RUSTC_VERSION", Some(131204)), + (unstable, cfg_boolean_literals, "1.83.0", Some(131204)), /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. (unstable, cfg_overflow_checks, "1.71.0", Some(111466)), /// Provides the relocation model information as cfg entry @@ -498,7 +498,7 @@ declare_features! ( /// Allows `if let` guard in match arms. (unstable, if_let_guard, "1.47.0", Some(51114)), /// Rescoping temporaries in `if let` to align with Rust 2024. - (unstable, if_let_rescope, "CURRENT_RUSTC_VERSION", Some(124085)), + (unstable, if_let_rescope, "1.83.0", Some(124085)), /// Allows `impl Trait` to be used inside associated types (RFC 2515). (unstable, impl_trait_in_assoc_type, "1.70.0", Some(63063)), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. @@ -563,11 +563,11 @@ declare_features! ( /// Allows specifying nop padding on functions for dynamic patching. (unstable, patchable_function_entry, "1.81.0", Some(123115)), /// Experimental features that make `Pin` more ergonomic. - (incomplete, pin_ergonomics, "CURRENT_RUSTC_VERSION", Some(130494)), + (incomplete, pin_ergonomics, "1.83.0", Some(130494)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<..>` precise capturign on impl Trait in traits. - (unstable, precise_capturing_in_traits, "CURRENT_RUSTC_VERSION", Some(130044)), + (unstable, precise_capturing_in_traits, "1.83.0", Some(130044)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index a95046162d28..72f488789048 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -146,7 +146,7 @@ pub const fn from_ref(s: &T) -> &[T; 1] { /// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying). #[stable(feature = "array_from_ref", since = "1.53.0")] -#[rustc_const_stable(feature = "const_array_from_ref", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_array_from_ref", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn from_mut(s: &mut T) -> &mut [T; 1] { // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound. diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 513b9cbcefca..0945845021ee 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -515,7 +515,7 @@ impl Cell { /// assert_eq!(five, 5); /// ``` #[stable(feature = "move_cell", since = "1.17.0")] - #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_cell_into_inner", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn into_inner(self) -> T { self.value.into_inner() @@ -864,7 +864,7 @@ impl RefCell { /// let five = c.into_inner(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_cell_into_inner", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] #[inline] pub const fn into_inner(self) -> T { @@ -2108,7 +2108,7 @@ impl UnsafeCell { /// ``` #[inline(always)] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_cell_into_inner", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn into_inner(self) -> T { self.value @@ -2182,7 +2182,7 @@ impl UnsafeCell { #[inline(always)] #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_unsafecell_get_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_unsafecell_get_mut", since = "1.83.0")] pub const fn get_mut(&mut self) -> &mut T { &mut self.value } diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 14c587e0c482..c14afe0f4761 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -309,7 +309,7 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] - #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_cell_into_inner", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn into_inner(self) -> Option { // Because `into_inner` takes `self` by value, the compiler statically verifies diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 04698193bba1..1abfaa46ec66 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -36,7 +36,7 @@ impl char { /// let value_at_min = u32::from(char::MIN); /// assert_eq!(char::from_u32(value_at_min), Some('\0')); /// ``` - #[stable(feature = "char_min", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "char_min", since = "1.83.0")] pub const MIN: char = '\0'; /// The highest valid code point a `char` can have, `'\u{10FFFF}'`. @@ -674,7 +674,7 @@ impl char { /// 'ß'.encode_utf8(&mut b); /// ``` #[stable(feature = "unicode_encode_char", since = "1.15.0")] - #[rustc_const_stable(feature = "const_char_encode_utf8", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0")] #[inline] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str { @@ -1773,7 +1773,7 @@ const fn len_utf16(code: u32) -> usize { /// Panics if the buffer is not large enough. /// A buffer of length four is large enough to encode any `char`. #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")] -#[rustc_const_stable(feature = "const_char_encode_utf8", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0")] #[doc(hidden)] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 3d0c9f7c9641..1862be0e86c5 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -383,7 +383,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { /// "Foo(10, ..)", /// ); /// ``` - #[stable(feature = "debug_more_non_exhaustive", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")] pub fn finish_non_exhaustive(&mut self) -> fmt::Result { self.result = self.result.and_then(|_| { if self.fields > 0 { @@ -626,7 +626,7 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// "{1, 2, ..}", /// ); /// ``` - #[stable(feature = "debug_more_non_exhaustive", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")] pub fn finish_non_exhaustive(&mut self) -> fmt::Result { self.inner.result = self.inner.result.and_then(|_| { if self.inner.has_fields { @@ -818,7 +818,7 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { /// "[1, 2, ..]", /// ); /// ``` - #[stable(feature = "debug_more_non_exhaustive", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")] pub fn finish_non_exhaustive(&mut self) -> fmt::Result { self.inner.result.and_then(|_| { if self.inner.has_fields { @@ -1146,7 +1146,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// r#"{"A": 10, "B": 11, ..}"#, /// ); /// ``` - #[stable(feature = "debug_more_non_exhaustive", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")] pub fn finish_non_exhaustive(&mut self) -> fmt::Result { self.result = self.result.and_then(|_| { assert!(!self.has_key, "attempted to finish a map with a partial entry"); diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index e8f5af863c1d..ca5b9fc98b93 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1085,7 +1085,7 @@ extern "rust-intrinsic" { /// it does not require an `unsafe` block. /// Therefore, implementations must not require the user to uphold /// any safety invariants. - #[rustc_const_stable(feature = "const_intrinsic_forget", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_forget", since = "1.83.0")] #[rustc_safe_intrinsic] #[rustc_nounwind] pub fn forget(_: T); @@ -2541,7 +2541,7 @@ extern "rust-intrinsic" { /// This intrinsic can *only* be called where the pointer is a local without /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so /// that it trivially obeys runtime-MIR rules about derefs in operands. - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_nounwind] pub fn write_via_move(ptr: *mut T, value: T); @@ -3070,7 +3070,7 @@ pub const fn type_id() -> u128 { /// change the possible layouts of pointers. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn aggregate_raw_ptr, D, M>(_data: D, _meta: M) -> P { @@ -3095,7 +3095,7 @@ impl AggregateRawPtr<*mut T> for *mut P { /// This is used to implement functions like `ptr::metadata`. #[rustc_nounwind] #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[rustc_intrinsic] #[rustc_intrinsic_must_be_overridden] pub const fn ptr_metadata + ?Sized, M>(_ptr: *const P) -> M { @@ -3196,13 +3196,13 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons #[doc(alias = "memcpy")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_allowed_through_unstable_modules] -#[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"] pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[rustc_nounwind] pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); } @@ -3300,13 +3300,13 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[doc(alias = "memmove")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_allowed_through_unstable_modules] -#[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_copy"] pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[rustc_nounwind] fn copy(src: *const T, dst: *mut T, count: usize); } @@ -3381,13 +3381,13 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[doc(alias = "memset")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_allowed_through_unstable_modules] -#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_write_bytes"] pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { extern "rust-intrinsic" { - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_nounwind] fn write_bytes(dst: *mut T, val: u8, count: usize); } diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index f992785c43bb..bb01d4e642cf 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -569,10 +569,7 @@ impl MaybeUninit { /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] - #[rustc_const_stable( - feature = "const_maybe_uninit_as_mut_ptr", - since = "CURRENT_RUSTC_VERSION" - )] + #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut T { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 9bf2aa594c04..ada804633065 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -858,7 +858,7 @@ pub fn take(dest: &mut T) -> T { #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] -#[rustc_const_stable(feature = "const_replace", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] pub const fn replace(dest: &mut T, src: T) -> T { // It may be tempting to use `swap` to avoid `unsafe` here. Don't! diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 05f5a08ad0ac..a01761ee5d4a 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -517,7 +517,7 @@ impl f32 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] #[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :) pub const fn is_nan(self) -> bool { @@ -550,7 +550,7 @@ impl f32 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_infinite(self) -> bool { // Getting clever with transmutation can result in incorrect answers on some FPUs @@ -575,7 +575,7 @@ impl f32 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, @@ -603,7 +603,7 @@ impl f32 { /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[must_use] #[stable(feature = "is_subnormal", since = "1.53.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_subnormal(self) -> bool { matches!(self.classify(), FpCategory::Subnormal) @@ -630,7 +630,7 @@ impl f32 { /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_normal(self) -> bool { matches!(self.classify(), FpCategory::Normal) @@ -650,7 +650,7 @@ impl f32 { /// assert_eq!(inf.classify(), FpCategory::Infinite); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] pub const fn classify(self) -> FpCategory { // We used to have complicated logic here that avoids the simple bit-based tests to work // around buggy codegen for x87 targets (see @@ -686,7 +686,7 @@ impl f32 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() @@ -711,7 +711,7 @@ impl f32 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus @@ -1093,7 +1093,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_bits(self) -> u32 { // SAFETY: `u32` is a plain old datatype so we can always transmute to it. @@ -1137,7 +1137,7 @@ impl f32 { /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_bits(v: u32) -> Self { @@ -1161,7 +1161,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_be_bytes(self) -> [u8; 4] { self.to_bits().to_be_bytes() @@ -1182,7 +1182,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_le_bytes(self) -> [u8; 4] { self.to_bits().to_le_bytes() @@ -1216,7 +1216,7 @@ impl f32 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_ne_bytes(self) -> [u8; 4] { self.to_bits().to_ne_bytes() @@ -1234,7 +1234,7 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_be_bytes(bytes: [u8; 4]) -> Self { @@ -1253,7 +1253,7 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_le_bytes(bytes: [u8; 4]) -> Self { @@ -1283,7 +1283,7 @@ impl f32 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self { diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 89c6726d985e..2995e41cd6ea 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -516,7 +516,7 @@ impl f64 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] #[allow(clippy::eq_op)] // > if you intended to check if the operand is NaN, use `.is_nan()` instead :) pub const fn is_nan(self) -> bool { @@ -549,7 +549,7 @@ impl f64 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_infinite(self) -> bool { // Getting clever with transmutation can result in incorrect answers on some FPUs @@ -574,7 +574,7 @@ impl f64 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, @@ -602,7 +602,7 @@ impl f64 { /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[must_use] #[stable(feature = "is_subnormal", since = "1.53.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_subnormal(self) -> bool { matches!(self.classify(), FpCategory::Subnormal) @@ -629,7 +629,7 @@ impl f64 { /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_normal(self) -> bool { matches!(self.classify(), FpCategory::Normal) @@ -649,7 +649,7 @@ impl f64 { /// assert_eq!(inf.classify(), FpCategory::Infinite); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] pub const fn classify(self) -> FpCategory { // We used to have complicated logic here that avoids the simple bit-based tests to work // around buggy codegen for x87 targets (see @@ -685,7 +685,7 @@ impl f64 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_sign_positive(self) -> bool { !self.is_sign_negative() @@ -719,7 +719,7 @@ impl f64 { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_float_classify", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus @@ -1093,7 +1093,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_bits(self) -> u64 { // SAFETY: `u64` is a plain old datatype so we can always transmute to it. @@ -1137,7 +1137,7 @@ impl f64 { /// assert_eq!(v, 12.5); /// ``` #[stable(feature = "float_bits_conv", since = "1.20.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_bits(v: u64) -> Self { @@ -1161,7 +1161,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_be_bytes(self) -> [u8; 8] { self.to_bits().to_be_bytes() @@ -1182,7 +1182,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_le_bytes(self) -> [u8; 8] { self.to_bits().to_le_bytes() @@ -1216,7 +1216,7 @@ impl f64 { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] pub const fn to_ne_bytes(self) -> [u8; 8] { self.to_bits().to_ne_bytes() @@ -1234,7 +1234,7 @@ impl f64 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_be_bytes(bytes: [u8; 8]) -> Self { @@ -1253,7 +1253,7 @@ impl f64 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_le_bytes(bytes: [u8; 8]) -> Self { @@ -1283,7 +1283,7 @@ impl f64 { /// assert_eq!(value, 12.5); /// ``` #[stable(feature = "float_to_from_bytes", since = "1.40.0")] - #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self { diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 7a8158b82318..55deabbee8fb 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -177,7 +177,7 @@ impl ControlFlow { /// assert_eq!(ControlFlow::::Continue(3).break_value(), None); /// ``` #[inline] - #[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "control_flow_enum", since = "1.83.0")] pub fn break_value(self) -> Option { match self { ControlFlow::Continue(..) => None, @@ -188,7 +188,7 @@ impl ControlFlow { /// Maps `ControlFlow` to `ControlFlow` by applying a function /// to the break value in case it exists. #[inline] - #[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "control_flow_enum", since = "1.83.0")] pub fn map_break(self, f: impl FnOnce(B) -> T) -> ControlFlow { match self { ControlFlow::Continue(x) => ControlFlow::Continue(x), @@ -208,7 +208,7 @@ impl ControlFlow { /// assert_eq!(ControlFlow::::Continue(3).continue_value(), Some(3)); /// ``` #[inline] - #[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "control_flow_enum", since = "1.83.0")] pub fn continue_value(self) -> Option { match self { ControlFlow::Continue(x) => Some(x), @@ -219,7 +219,7 @@ impl ControlFlow { /// Maps `ControlFlow` to `ControlFlow` by applying a function /// to the continue value in case it exists. #[inline] - #[stable(feature = "control_flow_enum", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "control_flow_enum", since = "1.83.0")] pub fn map_continue(self, f: impl FnOnce(C) -> T) -> ControlFlow { match self { ControlFlow::Continue(x) => ControlFlow::Continue(f(x)), diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 84ccb7a1f668..661176ce9fcf 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -724,7 +724,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn as_mut(&mut self) -> Option<&mut T> { match *self { Some(ref mut x) => Some(x), @@ -926,7 +926,7 @@ impl Option { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn expect(self, msg: &str) -> T { match self { Some(val) => val, @@ -965,7 +965,7 @@ impl Option { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn unwrap(self) -> T { match self { Some(val) => val, @@ -1073,7 +1073,7 @@ impl Option { #[track_caller] #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const unsafe fn unwrap_unchecked(self) -> T { match self { Some(val) => val, @@ -1655,7 +1655,7 @@ impl Option { /// assert_eq!(x, Some(7)); /// ``` #[inline] - #[stable(feature = "option_get_or_insert_default", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "option_get_or_insert_default", since = "1.83.0")] pub fn get_or_insert_default(&mut self) -> &mut T where T: Default, @@ -1717,7 +1717,7 @@ impl Option { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn take(&mut self) -> Option { // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready mem::replace(self, None) @@ -1776,7 +1776,7 @@ impl Option { #[inline] #[stable(feature = "option_replace", since = "1.31.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) } @@ -1884,7 +1884,7 @@ impl Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn copied(self) -> Option where T: Copy, @@ -1938,7 +1938,7 @@ impl Option<&mut T> { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn copied(self) -> Option where T: Copy, @@ -1994,7 +1994,7 @@ impl Option> { #[inline] #[stable(feature = "transpose_result", since = "1.33.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn transpose(self) -> Result, E> { match self { Some(Ok(x)) => Ok(Some(x)), @@ -2542,7 +2542,7 @@ impl Option> { #[inline] #[stable(feature = "option_flattening", since = "1.40.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] - #[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn flatten(self) -> Option { // FIXME(const-hack): could be written with `and_then` match self { diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 0b0449d61749..72f4bc2c9dae 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -113,7 +113,7 @@ impl *const T { /// println!("{:?}", unsafe { &*bad }); /// ``` #[unstable(feature = "set_ptr_value", issue = "75091")] - #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *const U @@ -1299,7 +1299,7 @@ impl *const T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1319,7 +1319,7 @@ impl *const T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index feeaf78d3e72..09c4002dbc76 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -92,7 +92,7 @@ pub trait Thin = Pointee; /// /// assert_eq!(std::ptr::metadata("foo"), 3_usize); /// ``` -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[inline] pub const fn metadata(ptr: *const T) -> ::Metadata { ptr_metadata(ptr) @@ -106,7 +106,7 @@ pub const fn metadata(ptr: *const T) -> ::Metadata { /// /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts #[unstable(feature = "ptr_metadata", issue = "81513")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[inline] pub const fn from_raw_parts( data_pointer: *const impl Thin, @@ -120,7 +120,7 @@ pub const fn from_raw_parts( /// /// See the documentation of [`from_raw_parts`] for more details. #[unstable(feature = "ptr_metadata", issue = "81513")] -#[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[inline] pub const fn from_raw_parts_mut( data_pointer: *mut impl Thin, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index dd93f919c92c..61b48e312cfe 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -992,7 +992,7 @@ pub const fn slice_from_raw_parts(data: *const T, len: usize) -> *const [T] { /// ``` #[inline] #[stable(feature = "slice_from_raw_parts", since = "1.42.0")] -#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"] pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { from_raw_parts_mut(data, len) @@ -1266,7 +1266,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped(x: *mut T, y: *mut T, coun #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] -#[rustc_const_stable(feature = "const_replace", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_replace"] pub const unsafe fn replace(dst: *mut T, src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be @@ -1616,7 +1616,7 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write(dst: *mut T, src: T) { @@ -1726,7 +1726,7 @@ pub const unsafe fn write(dst: *mut T, src: T) { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_refs_to_cell))] -#[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write_unaligned"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write_unaligned(dst: *mut T, src: T) { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 8b61da74d02e..d7ce197848b2 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -94,7 +94,7 @@ impl *mut T { /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`. /// println!("{:?}", unsafe { &*bad }); #[unstable(feature = "set_ptr_value", issue = "75091")] - #[rustc_const_stable(feature = "ptr_metadata_const", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_metadata_const", since = "1.83.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[inline] pub const fn with_metadata_of(self, meta: *const U) -> *mut U @@ -1378,7 +1378,7 @@ impl *mut T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1398,7 +1398,7 @@ impl *mut T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1418,7 +1418,7 @@ impl *mut T { /// See [`ptr::copy`] for safety concerns and examples. /// /// [`ptr::copy`]: crate::ptr::copy() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1438,7 +1438,7 @@ impl *mut T { /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping() - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1469,7 +1469,7 @@ impl *mut T { /// /// [`ptr::write`]: crate::ptr::write() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write(self, val: T) @@ -1488,7 +1488,7 @@ impl *mut T { /// [`ptr::write_bytes`]: crate::ptr::write_bytes() #[doc(alias = "memset")] #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write_bytes(self, val: u8, count: usize) @@ -1529,7 +1529,7 @@ impl *mut T { /// /// [`ptr::write_unaligned`]: crate::ptr::write_unaligned() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn write_unaligned(self, val: T) diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 980d4a3cf6ce..c68391363485 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -395,7 +395,7 @@ impl NonNull { /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_ptr_as_ref", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_as_ref", since = "1.83.0")] #[must_use] #[inline(always)] pub const unsafe fn as_mut<'a>(&mut self) -> &'a mut T { @@ -923,7 +923,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] pub const unsafe fn copy_to(self, dest: NonNull, count: usize) where T: Sized, @@ -943,7 +943,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] pub const unsafe fn copy_to_nonoverlapping(self, dest: NonNull, count: usize) where T: Sized, @@ -963,7 +963,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] pub const unsafe fn copy_from(self, src: NonNull, count: usize) where T: Sized, @@ -983,7 +983,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_intrinsic_copy", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] pub const unsafe fn copy_from_nonoverlapping(self, src: NonNull, count: usize) where T: Sized, @@ -1013,7 +1013,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] pub const unsafe fn write(self, val: T) where T: Sized, @@ -1032,7 +1032,7 @@ impl NonNull { #[doc(alias = "memset")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] pub const unsafe fn write_bytes(self, val: u8, count: usize) where T: Sized, @@ -1073,7 +1073,7 @@ impl NonNull { #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_stable(feature = "const_ptr_write", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] pub const unsafe fn write_unaligned(self, val: T) where T: Sized, @@ -1432,10 +1432,7 @@ impl NonNull<[T]> { /// (Note that this example artificially demonstrates a use of this method, /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) #[stable(feature = "nonnull_slice_from_raw_parts", since = "1.70.0")] - #[rustc_const_stable( - feature = "const_slice_from_raw_parts_mut", - since = "CURRENT_RUSTC_VERSION" - )] + #[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] #[must_use] #[inline] pub const fn slice_from_raw_parts(data: NonNull, len: usize) -> Self { diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 95faacbf96db..e84c4e3a2398 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -734,7 +734,7 @@ impl Result { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_stable(feature = "const_result", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_result", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { @@ -1537,7 +1537,7 @@ impl Result<&T, E> { /// ``` #[inline] #[stable(feature = "result_copied", since = "1.59.0")] - #[rustc_const_stable(feature = "const_result", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_result", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn copied(self) -> Result where @@ -1588,7 +1588,7 @@ impl Result<&mut T, E> { /// ``` #[inline] #[stable(feature = "result_copied", since = "1.59.0")] - #[rustc_const_stable(feature = "const_result", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_result", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn copied(self) -> Result @@ -1643,7 +1643,7 @@ impl Result, E> { /// ``` #[inline] #[stable(feature = "transpose_result", since = "1.33.0")] - #[rustc_const_stable(feature = "const_result", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_result", since = "1.83.0")] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn transpose(self) -> Option> { match self { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 90ddc9c1d85d..9fdcea1f7b73 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -172,7 +172,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_slice_first_last", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] pub const fn first_mut(&mut self) -> Option<&mut T> { @@ -215,7 +215,7 @@ impl [T] { /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_slice_first_last", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> { @@ -258,7 +258,7 @@ impl [T] { /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_slice_first_last", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> { @@ -301,7 +301,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_slice_first_last", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] pub const fn last_mut(&mut self) -> Option<&mut T> { @@ -356,7 +356,7 @@ impl [T] { /// ``` #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] - #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn first_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { @@ -422,7 +422,7 @@ impl [T] { /// ``` #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] - #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_first_chunk_mut( &mut self, @@ -493,7 +493,7 @@ impl [T] { /// ``` #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] - #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_last_chunk_mut( &mut self, @@ -563,7 +563,7 @@ impl [T] { /// ``` #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] - #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn last_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { @@ -1907,7 +1907,7 @@ impl [T] { #[inline] #[track_caller] #[must_use] - #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { match self.split_at_mut_checked(mid) { @@ -2010,7 +2010,7 @@ impl [T] { /// assert_eq!(v, [1, 2, 3, 4, 5, 6]); /// ``` #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")] - #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] @@ -2111,7 +2111,7 @@ impl [T] { /// assert_eq!(None, v.split_at_mut_checked(7)); /// ``` #[stable(feature = "split_at_checked", since = "1.80.0")] - #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 20c5e026946e..976749cc148c 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -171,7 +171,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] #[rustc_diagnostic_item = "slice_from_raw_parts_mut"] @@ -204,7 +204,7 @@ pub const fn from_ref(s: &T) -> &[T] { /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] -#[rustc_const_stable(feature = "const_slice_from_ref", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_stable(feature = "const_slice_from_ref", since = "1.83.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] pub const fn from_mut(s: &mut T) -> &mut [T] { diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index 194db56fdafd..b61ed454cd9e 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -196,10 +196,7 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[must_use] #[stable(feature = "str_mut_extras", since = "1.20.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] -#[rustc_const_stable( - feature = "const_str_from_utf8_unchecked_mut", - since = "CURRENT_RUSTC_VERSION" -)] +#[rustc_const_stable(feature = "const_str_from_utf8_unchecked_mut", since = "1.83.0")] #[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"] pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { // SAFETY: the caller must guarantee that the bytes `v` diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 1d10015d75a2..09938dda262c 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -340,7 +340,7 @@ impl str { /// ``` #[stable(feature = "str_mut_extras", since = "1.20.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_str_as_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[must_use] #[inline(always)] pub const unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { @@ -387,7 +387,7 @@ impl str { /// modified in a way that it remains valid UTF-8. #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] - #[rustc_const_stable(feature = "const_str_as_mut", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[rustc_never_returns_null_ptr] #[must_use] #[inline(always)] diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index fc549abd4336..3e795e7b5e3f 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -519,8 +519,8 @@ impl Waker { /// [`Wake`]: ../../alloc/task/trait.Wake.html #[inline] #[must_use] - #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] - #[rustc_const_stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "waker_getters", since = "1.83.0")] + #[rustc_const_stable(feature = "waker_getters", since = "1.83.0")] pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self { Waker { waker: RawWaker { data, vtable } } } @@ -584,7 +584,7 @@ impl Waker { /// Gets the `data` pointer used to create this `Waker`. #[inline] #[must_use] - #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "waker_getters", since = "1.83.0")] pub fn data(&self) -> *const () { self.waker.data } @@ -592,7 +592,7 @@ impl Waker { /// Gets the `vtable` pointer used to create this `Waker`. #[inline] #[must_use] - #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "waker_getters", since = "1.83.0")] pub fn vtable(&self) -> &'static RawWakerVTable { self.waker.vtable } diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 51005ff795c6..5081e777af46 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -844,7 +844,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_stable(feature = "duration_consts_float", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64) } @@ -863,7 +863,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_stable(feature = "duration_consts_float", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn as_secs_f32(&self) -> f32 { (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32) } @@ -1084,7 +1084,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_stable(feature = "duration_consts_float", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn div_duration_f64(self, rhs: Duration) -> f64 { let self_nanos = (self.secs as f64) * (NANOS_PER_SEC as f64) + (self.nanos.0 as f64); let rhs_nanos = (rhs.secs as f64) * (NANOS_PER_SEC as f64) + (rhs.nanos.0 as f64); @@ -1105,7 +1105,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_stable(feature = "duration_consts_float", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "duration_consts_float", since = "1.83.0")] pub const fn div_duration_f32(self, rhs: Duration) -> f32 { let self_nanos = (self.secs as f32) * (NANOS_PER_SEC as f32) + (self.nanos.0 as f32); let rhs_nanos = (rhs.secs as f32) * (NANOS_PER_SEC as f32) + (rhs.nanos.0 as f32); diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index f2e523dca779..ded4f404d781 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1438,7 +1438,7 @@ impl Clone for Iter<'_, K, V> { } } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for Iter<'_, K, V> { #[inline] fn default() -> Self { @@ -1484,7 +1484,7 @@ impl<'a, K, V> IterMut<'a, K, V> { } } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for IterMut<'_, K, V> { #[inline] fn default() -> Self { @@ -1522,7 +1522,7 @@ impl IntoIter { } } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for IntoIter { #[inline] fn default() -> Self { @@ -1562,7 +1562,7 @@ impl Clone for Keys<'_, K, V> { } } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for Keys<'_, K, V> { #[inline] fn default() -> Self { @@ -1609,7 +1609,7 @@ impl Clone for Values<'_, K, V> { } } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for Values<'_, K, V> { #[inline] fn default() -> Self { @@ -1705,7 +1705,7 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> { inner: IterMut<'a, K, V>, } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for ValuesMut<'_, K, V> { #[inline] fn default() -> Self { @@ -1735,7 +1735,7 @@ pub struct IntoKeys { inner: IntoIter, } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for IntoKeys { #[inline] fn default() -> Self { @@ -1765,7 +1765,7 @@ pub struct IntoValues { inner: IntoIter, } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for IntoValues { #[inline] fn default() -> Self { @@ -2865,7 +2865,7 @@ impl<'a, K, V> Entry<'a, K, V> { /// assert_eq!(entry.key(), &"poneyland"); /// ``` #[inline] - #[stable(feature = "entry_insert", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "entry_insert", since = "1.83.0")] pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { match self { Occupied(mut entry) => { @@ -3152,7 +3152,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { /// assert_eq!(map["poneyland"], 37); /// ``` #[inline] - #[stable(feature = "entry_insert", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "entry_insert", since = "1.83.0")] pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { let base = self.base.insert_entry(value); OccupiedEntry { base } diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 210f57152250..e1e0eb36d23f 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1244,7 +1244,7 @@ pub struct Iter<'a, K: 'a> { base: base::Iter<'a, K>, } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for Iter<'_, K> { #[inline] fn default() -> Self { @@ -1273,7 +1273,7 @@ pub struct IntoIter { base: base::IntoIter, } -#[stable(feature = "default_iters_hash", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "default_iters_hash", since = "1.83.0")] impl Default for IntoIter { #[inline] fn default() -> Self { diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index f20814dd95cc..adf103e9430b 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -223,10 +223,10 @@ pub enum ErrorKind { #[stable(feature = "rust1", since = "1.0.0")] ConnectionReset, /// The remote host is not reachable. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] HostUnreachable, /// The network containing the remote host is not reachable. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NetworkUnreachable, /// The connection was aborted (terminated) by the remote server. #[stable(feature = "rust1", since = "1.0.0")] @@ -243,7 +243,7 @@ pub enum ErrorKind { #[stable(feature = "rust1", since = "1.0.0")] AddrNotAvailable, /// The system's networking is down. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NetworkDown, /// The operation failed because a pipe was closed. #[stable(feature = "rust1", since = "1.0.0")] @@ -259,18 +259,18 @@ pub enum ErrorKind { /// /// For example, a filesystem path was specified where one of the intermediate directory /// components was, in fact, a plain file. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NotADirectory, /// The filesystem object is, unexpectedly, a directory. /// /// A directory was specified when a non-directory was expected. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] IsADirectory, /// A non-empty directory was specified where an empty directory was expected. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] DirectoryNotEmpty, /// The filesystem or storage medium is read-only, but a write operation was attempted. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] ReadOnlyFilesystem, /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links. /// @@ -285,7 +285,7 @@ pub enum ErrorKind { /// /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated /// by problems with the network or server. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] StaleNetworkFileHandle, /// A parameter was incorrect. #[stable(feature = "rust1", since = "1.0.0")] @@ -319,13 +319,13 @@ pub enum ErrorKind { /// The underlying storage (typically, a filesystem) is full. /// /// This does not include out of quota errors. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] StorageFull, /// Seek on unseekable file. /// /// Seeking was attempted on an open file handle which is not suitable for seeking - for /// example, on Unix, a named pipe opened with `File::open`. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] NotSeekable, /// Filesystem quota was exceeded. #[unstable(feature = "io_error_more", issue = "86442")] @@ -335,22 +335,22 @@ pub enum ErrorKind { /// This might arise from a hard limit of the underlying filesystem or file access API, or from /// an administratively imposed resource limitation. Simple disk full, and out of quota, have /// their own errors. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] FileTooLarge, /// Resource is busy. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] ResourceBusy, /// Executable file is busy. /// /// An attempt was made to write to a file which is also in use as a running program. (Not all /// operating systems detect this situation.) - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] ExecutableFileBusy, /// Deadlock (avoided). /// /// A file locking operation would result in deadlock. This situation is typically detected, if /// at all, on a best-effort basis. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] Deadlock, /// Cross-device or cross-filesystem (hard) link or rename. #[unstable(feature = "io_error_more", issue = "86442")] @@ -358,7 +358,7 @@ pub enum ErrorKind { /// Too many (hard) links to the same filesystem object. /// /// The filesystem does not support making so many hardlinks to the same file. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] TooManyLinks, /// A filename was invalid. /// @@ -369,7 +369,7 @@ pub enum ErrorKind { /// /// When trying to run an external program, a system or process limit on the size of the /// arguments would have been exceeded. - #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_a_bit_more", since = "1.83.0")] ArgumentListTooLong, /// This operation was interrupted. /// diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 8fedcb241d09..71dfd0676c94 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -2405,7 +2405,7 @@ pub trait BufRead: Read { /// assert_eq!(num_bytes, 11); /// assert_eq!(animal, b"Crustacean\0"); /// ``` - #[stable(feature = "bufread_skip_until", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "bufread_skip_until", since = "1.83.0")] fn skip_until(&mut self, byte: u8) -> Result { skip_until(self, byte) } From 6134f9f636422abeda9fbc1563f6aa9a5b0b3fdf Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 15 Oct 2024 20:13:29 -0700 Subject: [PATCH 103/118] bump stage0 to 1.83.0-beta.1 --- src/stage0 | 900 ++++++++++++++++++++++++++--------------------------- 1 file changed, 450 insertions(+), 450 deletions(-) diff --git a/src/stage0 b/src/stage0 index 0d6542d2dd70..57a01edb6fdc 100644 --- a/src/stage0 +++ b/src/stage0 @@ -14,456 +14,456 @@ nightly_branch=master # All changes below this comment will be overridden the next time the # tool is executed. -compiler_date=2024-09-22 +compiler_date=2024-10-16 compiler_version=beta -rustfmt_date=2024-09-22 +rustfmt_date=2024-10-16 rustfmt_version=nightly -dist/2024-09-22/rustc-beta-aarch64-apple-darwin.tar.gz=59b70ccc04680e74bbd1e13368bbf5639679fb8e1e7ba39ae4a235f9a96522f6 -dist/2024-09-22/rustc-beta-aarch64-apple-darwin.tar.xz=d4b18e0a269e7b66dbbdf03d7da6b478c6cff9cd52ef34f110b68a9ff0111d0f -dist/2024-09-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz=7cc2e8511801c27360e17cc0380e30e5eb6cc185224aba94bf9ed852e5ff2ce0 -dist/2024-09-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz=a9f8f8e691b9a307ddc4468cc34964063253292f18869d21dc91ca437bbc08fd -dist/2024-09-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=5940e8c99d329fae3cc4b1d5709e9481e8f2b1dc799363ae0a1429ea4df4ad41 -dist/2024-09-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=c7c36aada972ea10e50e0904530d06b2df074f9981dec4dcc66efeaa16499c1b -dist/2024-09-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz=2ae2b1e2d90c130be5274806db1e4dcdfe0b588fe72f967e58b128aa1d28a7eb -dist/2024-09-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz=d8297b214d4ef841bb5963e71353ce08a4d3aead47a2cdf234e0846ad0b1ccbb -dist/2024-09-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=256b62cd5f1bc17c081277752a49d38104ce438e83342e6bbb467442e9250563 -dist/2024-09-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=457ea31587b8ff8c9fcc7a9ed4bf958625c7b9e55d640329ccdf432309a6583f -dist/2024-09-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=4cc8f851eff833100fe4d7c421c25e65d4779d8cdbb9b5e2cb3c8f5ebf9f8e98 -dist/2024-09-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=6ab386aaab687a253b3d28b12307ad5c8df2ea1a0af281a8fab6fe6d24ee6130 -dist/2024-09-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=0b548c45c2ec840942b29a68ad38debd8a2ec7c920d3be7cda91365e0a8fce80 -dist/2024-09-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=bc1ce3524199c62230fc08b9dab1282d2f31d3cd1a892cbc8bfab0257e0ff5dc -dist/2024-09-22/rustc-beta-i686-pc-windows-gnu.tar.gz=a407a4dda4c24e8e9d510843aa9e8f06291622d240538a14c1d924d8b7d84e33 -dist/2024-09-22/rustc-beta-i686-pc-windows-gnu.tar.xz=fe3b235ed043d14856f47babf433ae214d9b64480b1824053fee8b99ca69cc69 -dist/2024-09-22/rustc-beta-i686-pc-windows-msvc.tar.gz=a156aa0fb17b5edf476f97b8e839f9fe550ed3edd63a2fe2936a7fe0f388ece4 -dist/2024-09-22/rustc-beta-i686-pc-windows-msvc.tar.xz=0e46e75722b10bbbd2631c2676089665f92ce092408ed63aa14c99b1fc385369 -dist/2024-09-22/rustc-beta-i686-unknown-linux-gnu.tar.gz=5523e67362db0840d6f0ab6a1deec99c1b64c32fae94362792b0aa031bfd39d6 -dist/2024-09-22/rustc-beta-i686-unknown-linux-gnu.tar.xz=45a820f2ebd182ec3237436a567960d2bd0f92e9e603aa394b1a6eafbd9ba0fa -dist/2024-09-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=bdbe165ffd50974b32f4b570da7908c125739c0321f700d12cc481f32ab76eaa -dist/2024-09-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=997a8387989676848355e30dea1b131fa96945e62cef8f011025c52351db1269 -dist/2024-09-22/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=a49f46df49a9aa974ff10361ae29267d2c86c10486399803a5a6879e638212f2 -dist/2024-09-22/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=ee236f4dab4a06d23b6040a47afdf73496bc9093b3b29fae896f5f5bbe87c222 -dist/2024-09-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=e83c1253643c4ff70301bab198db731ac65c6d3b0ec847d7aa68bd6afef6ee93 -dist/2024-09-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=f7f09a5028ca3f45475cedec7518ead06b2e305554292462d82b2032e5d83f73 -dist/2024-09-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=9ef2829f5b2bc9666bba319875eecbda37840d204f7c1493dce2a4f2f45d45c5 -dist/2024-09-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=140489beedcf46e02931ce8f69e9008ea4c7e3c332d0a3482d4495d7fff21b81 -dist/2024-09-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=63a34f34425d6c11d62768a3cdfc4602d96ae0f11d82344412a69a3b1ec550b9 -dist/2024-09-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=108d429397a5cef93151439646b684109d1b619c1a6f11544062e407258f4897 -dist/2024-09-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=77cb4dea8b55779e0f3de1f48e74de966d3a2dc27946228b42b0eae654d53e5a -dist/2024-09-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=93b7dc39c3da7560cbabef5a35dddec111a4d9c0ec0e2b0648925975c5042b31 -dist/2024-09-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz=58b1eed6046552703f8993b36d2a571d12db806ca9665d276c338fc89f79b980 -dist/2024-09-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz=39ad5c20dd703e5949f008ed21e671b1438a1160b4aece5ba434ae03f32004cf -dist/2024-09-22/rustc-beta-x86_64-apple-darwin.tar.gz=c5082f7773f1573a1f60148ed744f148169b3c58ca38539e72688cb31221003e -dist/2024-09-22/rustc-beta-x86_64-apple-darwin.tar.xz=a797564192dc84184d5af88ecb4d295ab266cde4a1c4407b06c56f656800e336 -dist/2024-09-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz=0f29dc08756a36f42e9937cf9e2f8c5cc7771fab5b791b58dd7b038dcb20e2ca -dist/2024-09-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz=9a9f6178208f01487a132ab91ffb1251722df3f6e3ccc7f4b3e79dc389b7217a -dist/2024-09-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz=2f2b828b46dea57c9896149a5ffc5cc6db368d90067c498f554b9ea75de0990f -dist/2024-09-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz=42c64410633bf748134ba004ef397f2319556e44fc2862a4f3a5e847e334fdbf -dist/2024-09-22/rustc-beta-x86_64-unknown-freebsd.tar.gz=9ba0fdecbd343606bbdf2d4b401d64ed5de82e4bd508c0e6b6bcc21365c4b840 -dist/2024-09-22/rustc-beta-x86_64-unknown-freebsd.tar.xz=aeabedce922b315fb872127a6102a76e9fe5e1932b14a7210f31191f9a85488b -dist/2024-09-22/rustc-beta-x86_64-unknown-illumos.tar.gz=4d5348b0ef100a1691f655acee54447866d76b46f88e23ee641eb5e4b4318b4c -dist/2024-09-22/rustc-beta-x86_64-unknown-illumos.tar.xz=046b8d0139b97d78a741251ef7094629394f67cbb817a7239de704b4ff3a8963 -dist/2024-09-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=81ba8a28534746a9c33c98a98aeeea89f6c057333827d919b2f404991e0ded45 -dist/2024-09-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=358bbda124aa68416d55d8ed6c9a184f8ea7ae166f3f0427e8c9ac40900bd4b6 -dist/2024-09-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz=8594ed15236342879b4c486e4d5e2440891e9dec52302e1bb6393008eaf876e7 -dist/2024-09-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz=e45cdb771899998e42bf3f9e965a4b4557199b1632843c0472731d48ea664834 -dist/2024-09-22/rustc-beta-x86_64-unknown-netbsd.tar.gz=ba1d8b89c65441cfe6fa1341c6a7e21dc596df13cef8e8038d8d7ac376bd91fc -dist/2024-09-22/rustc-beta-x86_64-unknown-netbsd.tar.xz=95fb21a9730eaf815ba6da5f42b997accca0b578870207912a2ea359b588421e -dist/2024-09-22/rust-std-beta-aarch64-apple-darwin.tar.gz=60127b21a176a56664e537a8e6d81c18c5406706f12e3a406ebad8c86f5fc442 -dist/2024-09-22/rust-std-beta-aarch64-apple-darwin.tar.xz=04d163b5bb40aa4ed7e712006155549eb5ca094e71b89b4a3e5142c40d0b2102 -dist/2024-09-22/rust-std-beta-aarch64-apple-ios.tar.gz=1463a6f3a55b1c7795c0417040423f2dc1d9a3df343ee4bd2d9c96b2de5c84e8 -dist/2024-09-22/rust-std-beta-aarch64-apple-ios.tar.xz=74a06570dd6bd8b501ccdcdf25b9b5ccac25936b883b37be6a0296d5e59394b6 -dist/2024-09-22/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=ccdf0df40f435ca4c5f8d6b67cf06b48c1792d5b1592cb129e7e40e7690c3c5b -dist/2024-09-22/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=4388b9b3ab0e048b6c8349a3ceae6afc078bdc217172d7ef0271afb5e181fb6f -dist/2024-09-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz=4428d02fe8e43b5d082149991e88a4c9d342157fa1c2cd91903812240fb5bb08 -dist/2024-09-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz=21f9c521dc8203584ce0c56536818431ec19f259f86b8d8cab5a33f7e44165cf -dist/2024-09-22/rust-std-beta-aarch64-linux-android.tar.gz=d9d238db60d1e54366cfb4f20e2a6c6b8bc055f83716837970261b074cc93218 -dist/2024-09-22/rust-std-beta-aarch64-linux-android.tar.xz=aab44af6a7f1dc483c943be9fd0b2ade0c938a844acc8deab76843e3dc514355 -dist/2024-09-22/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=fccf8f5199da8c0fe2d1dec6ee384c9761f2e6334e5dce28add413f29207e902 -dist/2024-09-22/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=d6373d38a862120c08afa569ea9941945b43ce1676f45ca995fb3b30c34500ec -dist/2024-09-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=e0b31c36068626fbf2133a352002cbd8f4c2b6a1b5379a0ab0fd3bc640576e9d -dist/2024-09-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=d10defe0175f8872ebb68d2dd331fa9bbbeb1fa892188371665547567f7f2738 -dist/2024-09-22/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=dda6f7b74035c963dd89a2e003d6c7baca2e2db9bfdd3007f95743e44bd08cb0 -dist/2024-09-22/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=23944ba7752e89e860f19f3c18d2951bb5c7c6b707bd6e06914f7d48aafee40c -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=b00fa5fea66b2af7d173d6405a59c529a1dd0b793d735c2d97fcab7775693ed4 -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=34bd748cc5bc0a6b6d8e6d8ea23693d7628bed11ebcd886860cd5c0b31ac3c0d -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=ecb1b709c48556fabc527d976e6cc69b8b69384cb4c45e691195a12b9cdba383 -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=2c90df930935dcf9f9725588ed6579100fdf676267305f715f03e413a04c3032 -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=56782db097cca16a0d6e8466b83b35bfd7334d5f48b9ac5c500767eeba30c122 -dist/2024-09-22/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=9b41b551b5f88dfa3fdcc1d22102f102627c5c88e42353edaceda6da3b76d97b -dist/2024-09-22/rust-std-beta-aarch64-unknown-none.tar.gz=087fccd0b40fe73a545885a58758eafb86e9bb7b9588d047c9536e5bd8c201b6 -dist/2024-09-22/rust-std-beta-aarch64-unknown-none.tar.xz=60039451dc07ada83944606e67363ca32b22879293bc41a6d66f6545e7e3f1aa -dist/2024-09-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=0e1f73720beaecff935d0a90272448f5dfb0c912b2e366239c46c6ab3b854cfc -dist/2024-09-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=c2670b262833415d43b22485c2734d87d8748315e6471a2a384249b2cba6e581 -dist/2024-09-22/rust-std-beta-aarch64-unknown-uefi.tar.gz=edfd391f36b6aa6758649ca6f9706d671956f078e572ea9ce5f9423a1310e817 -dist/2024-09-22/rust-std-beta-aarch64-unknown-uefi.tar.xz=59b09f6cef1d97b273262d3ccdd95d9c46766b82e935cb46538514292cd04a39 -dist/2024-09-22/rust-std-beta-arm-linux-androideabi.tar.gz=f84267d71217b79a5e622a281ce926c1a54ee9122e19b2647d1aa85afa9132be -dist/2024-09-22/rust-std-beta-arm-linux-androideabi.tar.xz=57e80fea8463416012339fc6f74e9ae4da7d92042d05311bc8a9620fec3541b2 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=556ff5b6947ed37f5215953fbcbe3e82313e7deb9d32d5b86feabe46c8328e56 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=3f0721bc56fa232ca4203dcb43f1ef8f453373d9a0fa4720d89c51b827407a91 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=57b81555f7d7695e985e1538795c97b9f0573cd84d6fda25a09d49ac54bd1a24 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=66d5af25be1dfc99fbeb1aa0c7eee30dc2d3e5766affb73e6e7c0e7b9a78abff -dist/2024-09-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=23cfcb1cde1e95f55442ebb8ba155a0e13ec932cd7a8ab20a2ad09596a79b3a4 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=660d3f7b05da3d5b01775989546a687fe40090d193289c3ad24317c07c5eb445 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=ee453c78eacca64fd0a6f1c066a6728ddca0ecbd6e184b63a4b4455f77183f07 -dist/2024-09-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=b003790997ebe0bfa095b0fe38db67db179a2f9e93f4b49852f5ec04828337f4 -dist/2024-09-22/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=60f03912a464169464800a603606e2cb8a302c998bd59f582cdd3b9bf39ecc82 -dist/2024-09-22/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=6d1858acf2f2cfb3daac89ae21cfc7a7df3e1f57dac0aaa3ee70057b1974c0f2 -dist/2024-09-22/rust-std-beta-armebv7r-none-eabi.tar.gz=b23fd4380d20e289e58b86afaad1df0636004c74a03d7f3ff861f26c6ca308f8 -dist/2024-09-22/rust-std-beta-armebv7r-none-eabi.tar.xz=beac209cec83a56315c109fc3a0e3b6b16f8044de270e23cdd9dc3e2b5db3af3 -dist/2024-09-22/rust-std-beta-armebv7r-none-eabihf.tar.gz=731064c4b9b35d420f740ff5fbc4f6dd1f038e3225db19ca861af6db5f283ea7 -dist/2024-09-22/rust-std-beta-armebv7r-none-eabihf.tar.xz=04b406b44da8aee6a077f9f971b5ba62bc98fb09413fe47fd892c67798381d5b -dist/2024-09-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=26dc6030f28453478e790879547f22a63ae810572cac790d4ed944eb68c96d87 -dist/2024-09-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=2aa9589c9512388e75c3c93e53b6a90ce5c973d98830a64388b0ec22618504c5 -dist/2024-09-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=0020c2142cef0ab6bd62c4212f01dce2675104e0da5e701cbf03ee7c45a0fb2c -dist/2024-09-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=b891ccdcbd8abf7d56d31b84800a17cbe1f6d4242584598433e38eff5a9a16c0 -dist/2024-09-22/rust-std-beta-armv7-linux-androideabi.tar.gz=128b86795a07b47088fbc51a251f6b112379454940878150547b54ffb95890e9 -dist/2024-09-22/rust-std-beta-armv7-linux-androideabi.tar.xz=26497ef07fb7f42198b4fc02b122497fc09bd215eb7e3e01c789b481bd2d86ae -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=933f22ab901b9de042b17548e0218de699275a8553b8056d2d85430858f4e1bc -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=495f8186e0c589882d1e1f1cf21ab28ea5531bad327b6d5ae1ca83d26c77944e -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=53c87859857618a011e94c14c5641927503c5543831acd16498d7fb244eb00b8 -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=7ee039186087e320396e56cdd9e5a6b7993c44783e3a80fd86e74e41be646a57 -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=fa9f256a201c4fe5cd95363c2cb02d87565a321e27554e83d63f1d61ed55dfda -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=fd3eced91b52924bb6d4acb3cc6c3bd7b45a1879e353f22442cb1e76ed5a7f28 -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=b683d929fd6a6b60a786ec154970338158cc2b7bce28601b70966b898017b131 -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=518fa28ee0292b95322bea4c0b714146a1b94c730e49bb6a84038520c91a668b -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=d0f8659cddfc6da0b0dd815794f86ec1ffa0a243020dc9190c4358c6cdc03fdf -dist/2024-09-22/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=89f39595aa42f23efa2b3853c466cddd6a932043bae3373193c25b788c15efd6 -dist/2024-09-22/rust-std-beta-armv7a-none-eabi.tar.gz=c1fc1973cc683c313e50542f1a6b69f1b5a5b4ac558b45954f79ef4dff9d5f75 -dist/2024-09-22/rust-std-beta-armv7a-none-eabi.tar.xz=00c45dfc370ea40d8993519bdb5cce8f5167401434f0b7553b6fdf7c5b49da87 -dist/2024-09-22/rust-std-beta-armv7r-none-eabi.tar.gz=ef54f8762f1d190b822e58b845889ac9c2dba4250cf0d693a3b1cbf64e2cf8a2 -dist/2024-09-22/rust-std-beta-armv7r-none-eabi.tar.xz=9375a15e96f7b3da4394bcda8ce34c452417f4278f07926830d5b00b155cb338 -dist/2024-09-22/rust-std-beta-armv7r-none-eabihf.tar.gz=85a5ae26f11c47872649699eaf01557aac746831b4c30de7b892438cc736b679 -dist/2024-09-22/rust-std-beta-armv7r-none-eabihf.tar.xz=e9dde209b4e0de6ae76b316c5e3aa2923f208bd9aa7858fef5177ba2e3b06119 -dist/2024-09-22/rust-std-beta-i586-pc-windows-msvc.tar.gz=652bc4cbf176d0780a81cff637684fd8f1cdc99c7a58d68325f54564942d46dc -dist/2024-09-22/rust-std-beta-i586-pc-windows-msvc.tar.xz=367eca53e9c4be297454751d2d8b7f5503caf669962a44ea92290b0772969fb6 -dist/2024-09-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz=7c48fb48b02628358ae3572c92d5cc112734e99606c78d04b29e665ee03f36ec -dist/2024-09-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz=4ac829df3b8b5e7864b883713a90ed18a9b08f45a3da2af2c6b3f700c8d7c27c -dist/2024-09-22/rust-std-beta-i586-unknown-linux-musl.tar.gz=7786d5b5e0cb8489df5456854cbbdfefbb8b4a3755f61e62747abc224e48dfc6 -dist/2024-09-22/rust-std-beta-i586-unknown-linux-musl.tar.xz=e2ec9458a99a159480a45b8107041b3b4054316ba15adaf802690d2bf66b2f22 -dist/2024-09-22/rust-std-beta-i686-linux-android.tar.gz=54edc2ca229e1a5aad5077800c492cf5038da341555eda11fc4b77d1a3896def -dist/2024-09-22/rust-std-beta-i686-linux-android.tar.xz=a75135f1e04b716855fce5b830797ea87bd428d54c06190cc8067ba5952d7215 -dist/2024-09-22/rust-std-beta-i686-pc-windows-gnu.tar.gz=4c5b54eecd6efbb03a3a01f57c265d47c49df49dd584e67b493205fcec92a59b -dist/2024-09-22/rust-std-beta-i686-pc-windows-gnu.tar.xz=7ec6292ac497b450277c17cca3ca87321d5b6bd545bd479b37698ceebdcbf719 -dist/2024-09-22/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=0deb2de1b9830099bb6de1bb99e4658c8e4e3438e555f239c85309b771293e6b -dist/2024-09-22/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=f35566df72b302dd446d449ffc8a775015b30970911c5284a3d4c1866e004a6b -dist/2024-09-22/rust-std-beta-i686-pc-windows-msvc.tar.gz=17e505c8ece5c89988896b1c14400b203e2588bc7777189bef89335cc868fb1d -dist/2024-09-22/rust-std-beta-i686-pc-windows-msvc.tar.xz=197fe430d6fce984ca397ba664beb25d4a0216180cd8fc2797710a8c541573a8 -dist/2024-09-22/rust-std-beta-i686-unknown-freebsd.tar.gz=9d7ff528d75e80ebb8255c9b6ef3f5ec6db579524e03dc3aad540690401fb7b8 -dist/2024-09-22/rust-std-beta-i686-unknown-freebsd.tar.xz=81152e616efe27a4ae80d2ffc86b79211c31ab324faa7847606f6ed839a3d470 -dist/2024-09-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz=b1913a26f2258531596e1ef31fc42d720f807f04b068802ea3a0164d877d694c -dist/2024-09-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz=3be89fd0c0f0a5b6d5cea23feffd32573be29ec1ce6c96b88ac35e04cf1eaa46 -dist/2024-09-22/rust-std-beta-i686-unknown-linux-musl.tar.gz=e446e4cbb904f89fbaf7bd48be6975671db2cc2ad018fc03e967dff2bbce0e3d -dist/2024-09-22/rust-std-beta-i686-unknown-linux-musl.tar.xz=453d6a6b1872e884aeae40936e950b7c2d0ce291c9f5882fc9c15a6b3e9c86fe -dist/2024-09-22/rust-std-beta-i686-unknown-uefi.tar.gz=a330462d4b0ade7028d2c2bd8764b1225cc9eac90b014c8899f971fadf002cba -dist/2024-09-22/rust-std-beta-i686-unknown-uefi.tar.xz=8fdb9e12d0cf92e0c4fcbcdc57daceb2cf17b21786e1252904ec0faba4b90a9d -dist/2024-09-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=82859d2feb163fa7ac068db184e8c76261771dc47838bd952301ffd8037d885a -dist/2024-09-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=1fa1ae996cd7010b4ab9006bfcb69098fcadbfc7a8f6988bdd34c62d2d6309f3 -dist/2024-09-22/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=e4200a2c1eb5a1420071fde891266849da5d46aaf46031129ae329175a3708f8 -dist/2024-09-22/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=15fc279f0c1370d05543af48c493d91687e3de2dc25123a1b657919494a0653c -dist/2024-09-22/rust-std-beta-loongarch64-unknown-none.tar.gz=4cc49f8231bca8c19e4d449cf3b3cd84d5db9e4665394ebada29ea626cee4dc4 -dist/2024-09-22/rust-std-beta-loongarch64-unknown-none.tar.xz=b3b7959a696c75575edb3676520f64178151df1d523128c6ed6e28cd0c8051b9 -dist/2024-09-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=7b15fd753967116653b4372e10796ae2ea35910872f517a2d1c6dd3539717915 -dist/2024-09-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=87f88922e5c3a17af392bade5af1ce94f03aac275e6ed3dbadc9d6c720223c7f -dist/2024-09-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=f1d4f6887d12f1316bcf515bd07f9474bb9e036dfe78171720d72e98de580791 -dist/2024-09-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=2dcaa78854d5b619e9609db70fa805cdf1e5baf2fac35f3eefb66ae854e78891 -dist/2024-09-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=c4ae30e180d94550da74b09f6005a6224136d8b5d752e9cdb1b44081a95b8c9f -dist/2024-09-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=c6438a341e8008b3c475e3250d52df2cb0a505862a14ed70e89884086a56e54f -dist/2024-09-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=8ff723f008f1ff81541f2f14d68ad1e77a2842577dcbe4f5109f6c54fdc42726 -dist/2024-09-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=c5704ef9d690721790d127ca341e4747d572bd34f636894fe897d23660a11467 -dist/2024-09-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=13d46982612f710d7aacf1a9636502418fdc673dde21641e1c52d2c55c8c35a1 -dist/2024-09-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=9e33e5c0ffd8511705258a741b448e167fdb13229d1d8bb36ef0b41a1f9c49ec -dist/2024-09-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=f7e0cc15730cfcd05ac904a3fb6012a99310c15402db19e915860fc4bc1f55ce -dist/2024-09-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=af179ee477d53727d01feeb704776370482f8aa6f6bd51d7dcbcf90010d36b74 -dist/2024-09-22/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=9673565000aebce56cddf905d27ec651d2c2845e9a2768ec38d10e18443924d8 -dist/2024-09-22/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=38a5d0812838d5596a7a4804ee46e97bc5f4814056f93ad0988b7f2f34a90325 -dist/2024-09-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=cb397f91bf2c66a0f7d704c320964885aaeacec90a0f562358e8678e749c1e64 -dist/2024-09-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=ff95fa7f5598ed1f25e2aa0be9fb89ef0a7b145ffa9bcba7479bb3c0d83808b5 -dist/2024-09-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=9049a87a4bea3319c7bf8162d5289ce252897e3ee637a0b6bca841c3507b98c4 -dist/2024-09-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=e24970b400b30728a9ee5202b0fdb9734c115e015178817629220390badb7e50 -dist/2024-09-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=aa06101ff7386aac69a1dafeb39645344fae3c0ca02537078029c4ba073aa1af -dist/2024-09-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=13e358d57a5bfe3e4ca2c8ca5e6c8d026cfac417b3c050ebd9bcd5d24f3a5f6c -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=5d880502cba47ed72006ef6e60fe004885c0f215d589a20456d41dcec8238503 -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=a242f39d05716b72aeebdf83357835bae0d2386feca6759f343721148b7a0d4d -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=117ec2433159f057fcd7fbae9d85042979340ab00f8d1b940c3adc5d3c791803 -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=be0f262d8ed5122fee6b67abd4b78e419839e4005cfff1db9813ae655fbea23f -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=78e28d3d341cedd0fe5ef0036b3b3c246b9f86e5e61d3bfd7e03e95d03920985 -dist/2024-09-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=43bb14df9b4947f111c1e4ba9c4092b73a895c9431a299e4b076d387477f5687 -dist/2024-09-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=e325c2ad8623b87456c12e17b29aa7f52ad243971002b4763677052f9b305eff -dist/2024-09-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=ca02e01254defcfbf0a48ab574dc4b5aecd6a6be2ddc835704986284916019d8 -dist/2024-09-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=79044a23a910bfd8488c382a3d2eab0c6a7ba9677165878b02f28a6c75d3a0b5 -dist/2024-09-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=6a1196d2b2f30e22497a739e3b1ee302339ed442e0b807c707d1c4eb7c53ff3b -dist/2024-09-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=fa3ad826bcf924094ad5cf19779fbfa70f656c1d2e66f4aee5dcf51792af74f4 -dist/2024-09-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=d5f701446546c6cb64b413be37f3c4a0739010f25616b6a295adfcefb16e8642 -dist/2024-09-22/rust-std-beta-sparcv9-sun-solaris.tar.gz=1ac5c327d5a0d0256d16968aab3bf35828c995c818ba73788421da56404f165e -dist/2024-09-22/rust-std-beta-sparcv9-sun-solaris.tar.xz=fd6c7f163d2d6006eb85cc68e2794850f82dfe09f9173390cd0c167d90622d8d -dist/2024-09-22/rust-std-beta-thumbv6m-none-eabi.tar.gz=8f082a38dfe968d8f987bfec0822e221d0ab8ab73dfd451b63de7644ccaeb239 -dist/2024-09-22/rust-std-beta-thumbv6m-none-eabi.tar.xz=044bca675ac6b621ced7f2bc9a9909814c0b0818505ca1bfcd765c1859a9ed7f -dist/2024-09-22/rust-std-beta-thumbv7em-none-eabi.tar.gz=f3e1789a409b58b9769db8587ddbd21352e6634ff5a508b6ad82237cc85409be -dist/2024-09-22/rust-std-beta-thumbv7em-none-eabi.tar.xz=5f36d0504401bf6cbd2eed78e4575a190300ae26c581ee8599ab8d6e32dfafaf -dist/2024-09-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz=a0ed6b4c71570e900e1605302ef865f7df9405e19245ed45ff5f7654eb3cbea7 -dist/2024-09-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz=6fd7fac23460b49ca5246a6471de4f39d92764231ef2eac5f51d177c9d14ce2a -dist/2024-09-22/rust-std-beta-thumbv7m-none-eabi.tar.gz=21e1983e3f9c481677db7c839d5b2b301bae748ef52e1d0b5c3fbf9347732c66 -dist/2024-09-22/rust-std-beta-thumbv7m-none-eabi.tar.xz=ade8b1a2c128c298ba1d20ea7c7585af2a2b3a17b55a8dc6d39f0eebf0f01e66 -dist/2024-09-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=29c7c493c9fee6afa8aea0f337da66118216ee21b373303432ccfb6375cd8428 -dist/2024-09-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=d63e1c8cf97c0834a3825d9a552ed0ce744b2471028f49cbad6f7df1f7bfad7c -dist/2024-09-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=0cec39208ae369c146d49dbc98984edb993c318a5dcbff205d3fa6b651400bc0 -dist/2024-09-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=158f249f6446503ad5c558dba966ca69f57161aa90fa995a9e9b68fb3e38e732 -dist/2024-09-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=8df09685f21eb9285adff2493ea6a9b3a04ce2e24b0761a47b44f0257b3485ff -dist/2024-09-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=0a119d100a6bddf66047e98d453b8c54ab0952712c38b1e396bbef81114d4423 -dist/2024-09-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=e7e234a7a8f687f0649654f562b12e09d332229dfd9e8d81a780afd9d8eac8ea -dist/2024-09-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=a3c6c68ad6c24d080af8034168b36bbb24edc30e1fce2ac91bc3fa09ac34a678 -dist/2024-09-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=1662be2b7ec3db6331ef545ac59c844733c3d1cdc728aef78049fecf37a416c5 -dist/2024-09-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=b19dd77e7582da1785f78e85e39a9d966c7a747641e6772dd18cbd489b4940b8 -dist/2024-09-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz=a7ae18e142b5b7a3fbab372bbf4e829626b52a67a10496f2cdecc89aab029310 -dist/2024-09-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz=75a9a2dae5117b714a08024588cb4f5e5a6f07f28af55013f49fbe7cc8e2a690 -dist/2024-09-22/rust-std-beta-wasm32-unknown-unknown.tar.gz=25bf0342788e03ad52ee4835f280f3d92bf2324db3acfcf2654c5f5d37d43431 -dist/2024-09-22/rust-std-beta-wasm32-unknown-unknown.tar.xz=21798a2663b6d0e7347404666d5341b51c5d5de108cd68efbd1466b7c4002a62 -dist/2024-09-22/rust-std-beta-wasm32-wasi.tar.gz=02c1fcc01d28005432f6e53b6f8cecda2b555d482f713ec70ac92b1507121ec7 -dist/2024-09-22/rust-std-beta-wasm32-wasi.tar.xz=f2b4ae22141d39202bddd45e3373a8520684dd71460ceb3cdc9bc7d09aedd774 -dist/2024-09-22/rust-std-beta-wasm32-wasip1.tar.gz=f59a67c3acc927e72278f66553cd10bb3d81e16045c76671d38d09c8a462c78f -dist/2024-09-22/rust-std-beta-wasm32-wasip1.tar.xz=0f4eea80dcd13008f55d7120f2239aed87a6dcf693f70983caffc36a4be72ffb -dist/2024-09-22/rust-std-beta-wasm32-wasip1-threads.tar.gz=2581846fe64f1d9547ec293875be715251174c5b163a7c533dcae81fd55ea6d6 -dist/2024-09-22/rust-std-beta-wasm32-wasip1-threads.tar.xz=ad6d869148eea87192f786fca0302983094b25a1afec2813012ba3133e8994c8 -dist/2024-09-22/rust-std-beta-wasm32-wasip2.tar.gz=091057da389eb1d464353acca41e158130f969ad20f90827a4dc38bd363a68fa -dist/2024-09-22/rust-std-beta-wasm32-wasip2.tar.xz=c91b4440326443a4987758ac161b79f5aa30d23662a5c99a3c0adfedc0eb8e51 -dist/2024-09-22/rust-std-beta-x86_64-apple-darwin.tar.gz=180a9b1d5fb71ec3e88dd4e3a88f6f1da433a191125ecdf98c0169bd7b0511b3 -dist/2024-09-22/rust-std-beta-x86_64-apple-darwin.tar.xz=7d066c7b394c5b15027472fa388b9379ae8a7d4a990e02c0785f63a6f1b7f0c7 -dist/2024-09-22/rust-std-beta-x86_64-apple-ios.tar.gz=4ebdf9f16075859830e76e40547d1d56230ed8715e57f254c82d467634aa63e5 -dist/2024-09-22/rust-std-beta-x86_64-apple-ios.tar.xz=0bdcf11914a169b86b945df232a30c69f991393e3871956b55ca88a0ad65bf79 -dist/2024-09-22/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=45ea8961f12b31e8404ebd178586711f7e4d4729d96ee298623240d8163766aa -dist/2024-09-22/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=a36a3ed36c0224edaa5161b1c2cb7acb2736d0c2845d56064bde1c94af4e2db1 -dist/2024-09-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=8d217487118140549fdc2223954d38a7932a2e9004a07924f853139395f8d88d -dist/2024-09-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=66d7b8cc0b92af4f0458eab631faee6069c3bdf8e35200fa3d573177b1b354c8 -dist/2024-09-22/rust-std-beta-x86_64-linux-android.tar.gz=7efbe112fdf33d55ada19f3803b2552796d1027281b6c652a19465e4902a22bf -dist/2024-09-22/rust-std-beta-x86_64-linux-android.tar.xz=cacbf59cc9bad0a212d9fb86c81434350fb0b4842918bf7dc51fe978d21402b6 -dist/2024-09-22/rust-std-beta-x86_64-pc-solaris.tar.gz=073833d7b60d396be6890552f7068e885dc0fd4536e5049e88d97c71df31f126 -dist/2024-09-22/rust-std-beta-x86_64-pc-solaris.tar.xz=c6cbc8c41eb2e071cad032ae7587c5ae2e841f1d074c328229e3b7f271fe9330 -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=0b5c7c007faa77fb28fe7cf275846f23adf0aa3fa1338dc93f86c05f7c605ded -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=c1ec0ad342ec630f2ed909c54b0ca7f9073a85977da3a86eb5ef68d5c13ad4b9 -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=5cf9a1daad4b60f7946adbdc9bde0d0d3ce438902f0a158f5f4f423f10960886 -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=d8cfeec61cbbf6bb1b4234bd53a777ad2157def8dc232ba4b5f16bc81f4f1524 -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=795ac3edcb9f0f10f36a19be14641918b5b0d647d5cc38e8652040437e409538 -dist/2024-09-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=dacb5baf49d2b3dd8727a159f8fd348967f987a95162e587c8e5add57dd6d31e -dist/2024-09-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz=089f99e1cbeab86b5d7ba9d582c5771c8d229ece1f81ad110716618823692deb -dist/2024-09-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz=8749c2ae47644c16f62a310500ab91e5403a25c3e023a2c6e25cfa16217c98e9 -dist/2024-09-22/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=becef9619e8ad1d4de66796c5877fd9798e5c943fb93a893aacd7819465f8a15 -dist/2024-09-22/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=3801cc566789ae0313a5d10159cd0c94cbbcd8636409ba69ace73fae972ce2eb -dist/2024-09-22/rust-std-beta-x86_64-unknown-illumos.tar.gz=ba74cfa20f8c53865d96d26b9aaaa7abebf2269d1c3fe2bcd70e3cd7bd4e78d1 -dist/2024-09-22/rust-std-beta-x86_64-unknown-illumos.tar.xz=8f0a00cb53e21c90d60eb02853412d4cf671a1667bbbf7fe9a64183d966a9e48 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=1188997812bfef02c93a13a7d31a9df560383a875bb6a3cbdbb03eaf5fa0d649 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=12583cfd10835abf0f340fe8e141683cdce3e4df5a00998a04361b59203321e6 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=854f01a511c01b003facf4beb89a511395f0efcdc2284ad279b92837349eaa95 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=b016d4584a44064feee64de50963ccfbfaaecb792c88c97a079f279a0c1df955 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=912eea9c27b6fd251c5b92ae24d6321d5effe9586dbbd473e16a8dee2b758291 -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=96bf10ef8fee6f8571b6601ab89e65562a91312502630c139d986b6e1ec9fbac -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=09e42b412f0891d608a9d4030203fe09645fc763ecad4be5ae790122a5d01f4a -dist/2024-09-22/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=dd84077f22ac4abea1c143d5d293425a85fad62ac65a4b31f18b9100c4e1076e -dist/2024-09-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz=9aa5fa7bf57fbb95c3a6f718c0a2b62f32c6d1c9ccf93b392d4e166d311e0833 -dist/2024-09-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz=765cf1a81b03ce210a88e87404a64d5b378f6615e428c385fac7a33b646f1276 -dist/2024-09-22/rust-std-beta-x86_64-unknown-none.tar.gz=e00c50362ffc95a1704912ea35c7b1792ead7906d98937fd73b9fa9fe31a520c -dist/2024-09-22/rust-std-beta-x86_64-unknown-none.tar.xz=280cf203356db9c32898197a3b5954901897a5b3059547f67c59cf5780c46386 -dist/2024-09-22/rust-std-beta-x86_64-unknown-redox.tar.gz=77069fcc33bc481ac8e18697884c1f3e3004a5fe5b265acb419b5f60c03fd2c9 -dist/2024-09-22/rust-std-beta-x86_64-unknown-redox.tar.xz=254dba227a76cb476fbc2a897169713969bf00f691ef77e03d303473db130523 -dist/2024-09-22/rust-std-beta-x86_64-unknown-uefi.tar.gz=4f1fb25ef423ab3cd5577f3e081771494978998acb8c04dda9de8a7d56cce985 -dist/2024-09-22/rust-std-beta-x86_64-unknown-uefi.tar.xz=fc21de2770ff0d0eb44d0939db5b274b0f408eb1a904c9eaf4db4c9463b5ff8d -dist/2024-09-22/cargo-beta-aarch64-apple-darwin.tar.gz=489c1b6aef3a7275e2e7a644677dde933a738534966089fe28c52c61dff04f2c -dist/2024-09-22/cargo-beta-aarch64-apple-darwin.tar.xz=5fe4d6a15e4f51f0575f2aee12eb644a95e548a4f03a80835296c44b1daf18a6 -dist/2024-09-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz=5c5c408b026e0332c4e5d816c7a6a961ae5af0174f02b793edd613e56c672494 -dist/2024-09-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz=4e060bccd78dc8abba7c7006585103b6bfa473a0f1cdd9e2c6b10d4fb8294f8c -dist/2024-09-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=45cee09ecd3655b3a822b9c85e3f61f8e40b3fb510728503a3691f56ce415274 -dist/2024-09-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=d8902eb0c3a725ef6345d325907ac10a7eb81e274c59aa589bf05aedea5958cb -dist/2024-09-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz=67e6658e39c0381554ac025c26564888804eb9d8a3e1178726652fff03bc21b4 -dist/2024-09-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz=427e7a4781dcdd2e316eb0c2751257597b4af58da8a5fd8407a8402814b65148 -dist/2024-09-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=735d1b824d3a375a6b9c5a5d22fb5e607d3ad06ff70cebe81b84007967c6a5c7 -dist/2024-09-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=749c017f8c25d0df23a160e02a765bb5e967f7657fdf3105d0d7ce64afe83524 -dist/2024-09-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=050ae56d0398150212a75493562e6654cc14b7a1ebd6051bde146b5d408d24c8 -dist/2024-09-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=1088b61e20981dabe406ff52965f48ab1542dd84d9673f7d56b21145d0b604b3 -dist/2024-09-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=43dfb8491dcb64b91e6786366300a0ee3fd00f1815cd84f3bb4247e6b723a6d6 -dist/2024-09-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=90266fcba10bd88e1f8f5d8420ee6835fe3e337dad1cc43ab7ef79edbe1a1b98 -dist/2024-09-22/cargo-beta-i686-pc-windows-gnu.tar.gz=6dca2e273600ee0f92a416901a7713ffd6db420b953e62d51d95bc85c1dbe27b -dist/2024-09-22/cargo-beta-i686-pc-windows-gnu.tar.xz=36fa46c7edcfc881568435f366e76f1989479356d93b8982981658fd44b80f4d -dist/2024-09-22/cargo-beta-i686-pc-windows-msvc.tar.gz=bd99a9cf662fbe90b79711776f972d2d574fcd6f0053bb672e4cdb35fc67ddf3 -dist/2024-09-22/cargo-beta-i686-pc-windows-msvc.tar.xz=8a995e56a96217cd999e786b16a69de1ec6e9db6412cd2c9c6ce090ed21a84bf -dist/2024-09-22/cargo-beta-i686-unknown-linux-gnu.tar.gz=ae115caa9516a96f144db9751b185503e1c648ea9b7e8b0a6aa10200315e6458 -dist/2024-09-22/cargo-beta-i686-unknown-linux-gnu.tar.xz=54b125ce0c00afa7bdebf5cb592249c37ac21d78479129a46d0b70d86fe6bf17 -dist/2024-09-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=21d2ca9f6d715e44fae058b7c26abc873930ac2823e72c9f8c983f7d089bd91a -dist/2024-09-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=b9b395041d328a09643b7e727705aa7705bf67c08edb3d26b78405ce454c6798 -dist/2024-09-22/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=da7853da9096b6ddebc3b3da948b90ac448663dc9a5d2940cad420360d5934a2 -dist/2024-09-22/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=9997e251abe606e390e3d2c280233f435f8ab46a6a3d24ce95d7a700ec049664 -dist/2024-09-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=1715eabf3860f2fa7e1e27f2163a5243c8000b6216c0e7ac8dec993061ff479b -dist/2024-09-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=f4e0f364c4ca68dc7b40b40bf13e28284a9bf6e6075b10504b9e6979d4a1a375 -dist/2024-09-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=70cb2337910933f0ce22ef57e8dec4ab5732855d0657e56ed237e3e483aa07d2 -dist/2024-09-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=1e9e383a093b54b8f7bff8dbf2f38590c148d0c9e18399bc128a09a6c67565bd -dist/2024-09-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=6e01a5a6cf68b8385d2a2eaa07984ba62ef4df6811be2ade5dd7b22ba7d4bd69 -dist/2024-09-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=70d0e45fba27db3322c3e4d802cdcd37503d2a848b9c0c2b9b759d48611c19ab -dist/2024-09-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=baabb56c3670a0dab62fc7c0e5cb07474de795e81a6be42c57a91c2249e9b960 -dist/2024-09-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=fd87e580bd0d4b47340b797fb52aeda83854556328869ebd1ce7136bcf8ead78 -dist/2024-09-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz=dbf01fb97c1aa9db57b68fa863dca5df81e1f83c1686bdbc01c702b0148bba7a -dist/2024-09-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz=f2eaf49ad1a05b5acf3050159aeb7351544c5aa14a46b381b0e2659eb857bce8 -dist/2024-09-22/cargo-beta-x86_64-apple-darwin.tar.gz=cdd90fe77bff57d0acae21499c0188fac2ddf7aa24dba07dcbf900444ceb1295 -dist/2024-09-22/cargo-beta-x86_64-apple-darwin.tar.xz=2c8acbf6eb4076ad876993f09714a2b1664031a41a12ff395c1f9c4bd0283640 -dist/2024-09-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz=f16189ad7a0d311b17b6bb6ced913cde0115ac07e9a950b85d4336c488456c6c -dist/2024-09-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz=1d4bf171c84def4110ee3f4e4798ab3ee52d0323bc2fc4abd564f229a23846da -dist/2024-09-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz=c3e27d6a38eb46fca153ef17cea76b11664e8171e0aa76af594e67ed9dffbef5 -dist/2024-09-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz=b64792d6ec70ee083dac929343ab45f4a52039c7fbc6cb223b02663591c8f544 -dist/2024-09-22/cargo-beta-x86_64-unknown-freebsd.tar.gz=40bf96a087dc1d57ba495733975ff34a4e75e51d7ddffc025561f0951adb57ca -dist/2024-09-22/cargo-beta-x86_64-unknown-freebsd.tar.xz=7912a49f7a181145b71a197014e3de6594b216959cd7c95a003fcd13854cb056 -dist/2024-09-22/cargo-beta-x86_64-unknown-illumos.tar.gz=1c3dfd5dcb8e7c8ba947b67f5bc466bae26ca1518a74798cfe5a21997bfcf71d -dist/2024-09-22/cargo-beta-x86_64-unknown-illumos.tar.xz=6f620a91c2bc145f894f5736a9818f7b54583a93e7eb2d0ac202f46a38040b99 -dist/2024-09-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=c6c20977054f56fc279e666cf02da65acb376c1b08bbbc998cf34d0cc2b5bb7b -dist/2024-09-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=9cca7e46ad35f0f69d8fe628a95e44388ed5cb62c1b77f2bab03dab28a05a650 -dist/2024-09-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz=74005a4511ca2087ebb92db7e19a2e31e3ddcdef93e27da544bbc444df01dc32 -dist/2024-09-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz=94215716623cadc8bf4a119612ad7482661905748d4e43ddff1855d4746f3972 -dist/2024-09-22/cargo-beta-x86_64-unknown-netbsd.tar.gz=fd9b2dd77b76b2ac44dbeb80e46371669223fe8ca57e4d480deeb162168c38d5 -dist/2024-09-22/cargo-beta-x86_64-unknown-netbsd.tar.xz=d419dbb9d1c905eb841c6870ddc8afe946b7618d3a0c6f39f8feeba6ecc74f0d -dist/2024-09-22/clippy-beta-aarch64-apple-darwin.tar.gz=60aba239287116d7e0f58fc71e510fdb7582003efdb3011765f732b1e494c7e1 -dist/2024-09-22/clippy-beta-aarch64-apple-darwin.tar.xz=00ef2da71c8e3f5be8401128509ff99130eebd5c0b90b5b5c16dc0465c2a18f8 -dist/2024-09-22/clippy-beta-aarch64-pc-windows-msvc.tar.gz=7ff2952e057849ec69a7d1147920c2b6ecb99fe7984afe627c5514c8c6a8811c -dist/2024-09-22/clippy-beta-aarch64-pc-windows-msvc.tar.xz=cc3e145daaf3674c1436d4380171ce5e26b075975121dac5c1d5c5d6cfa1a6e6 -dist/2024-09-22/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=430c6d5ded52d04bfe93fce17f8fef57ce3ab05715767b85d6c9b59e521671b2 -dist/2024-09-22/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=df4b9444dd435133bcfe386955b1d4b63c13e4acd766dc3bb9742c21431926d4 -dist/2024-09-22/clippy-beta-aarch64-unknown-linux-musl.tar.gz=7064208f59db897b1107072a3cc1a516d53888ea1c549bdf3cfd8479c65ec0c3 -dist/2024-09-22/clippy-beta-aarch64-unknown-linux-musl.tar.xz=1d33c3e2b4daa1ba7f1a6399790d1b76fdfe1ac9d293859983412d5e1e3663a1 -dist/2024-09-22/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=b851cb5bcb31a2105039b55a613d937113fd45f5c1fbd4e3d24eecbed85a0bb0 -dist/2024-09-22/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=a17f46c82fa28bfa9e3c9ff99cd25a888b6ff0c08a887ef4056b8ae29437a67a -dist/2024-09-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=784a1a0134d54cff72c9bf59ee1e750d0493fef5bde06bf778bc98321d833031 -dist/2024-09-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=c11461066103bf92f21298e5cb3b009cf4ac07bde5d99ce9ab97c1cbdf7c73f5 -dist/2024-09-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=98c74f6a0692482355045bb4b0977887b419a8aa3c4654b9b59cd0d867f261ac -dist/2024-09-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=20c82e6bbefdbaca22911a63a41d0aa05ed0ffad4571090c053cb354b49acd23 -dist/2024-09-22/clippy-beta-i686-pc-windows-gnu.tar.gz=3da558108df227ceb0ff7a2837d1bd2f5a75a0c7167f0b3c380d1aa5b2fa3e77 -dist/2024-09-22/clippy-beta-i686-pc-windows-gnu.tar.xz=f657f1cdc9f91243112834afbe5fe60f8b43e914504c8aed1994a13ac98bc575 -dist/2024-09-22/clippy-beta-i686-pc-windows-msvc.tar.gz=cf27f06843f5e0706aace4be4b9973fd164b57697b44d00852a9545d336c6fd2 -dist/2024-09-22/clippy-beta-i686-pc-windows-msvc.tar.xz=74dd229cdf65ce19ded1ed27cf5fb31c20f6a45879b277ad43aedc818eed514c -dist/2024-09-22/clippy-beta-i686-unknown-linux-gnu.tar.gz=4d22b439675ec118d021a85dc75540d7a3331364395e21bc1a2d76c26aabe9d3 -dist/2024-09-22/clippy-beta-i686-unknown-linux-gnu.tar.xz=bfc60e9fe1dbed050904efc71e8d0e5c90dae7f949fc7c81312de0c129f4d058 -dist/2024-09-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=25df67e21543e3a3b71500f55da1abe6182a24aabe1f5bb1e57fe99821a22d97 -dist/2024-09-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=7b56b6f7704742821f42396f5c517adda129b68f05da258d371cc8a3bc7356f3 -dist/2024-09-22/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=f7305d23b8b850b4169a2ae6816c9db721a989ffbb642a4645ed95068a6553fe -dist/2024-09-22/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=9576586590c11c86e8b029c32f17916ebd13d27d8750e30a927a4a986dd47aea -dist/2024-09-22/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=1eb483594b3ca3ab8e0eac99e7699be151791fcdf0349714b0da923ea33b92bc -dist/2024-09-22/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=42b9373a18ebf76394513cb75f8072ca094efbdfd8c60cc2249b04fad344f677 -dist/2024-09-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=fa6438d40613bb99062118bfb293f6f252a21c927d222c7cdfe4cee865d30d16 -dist/2024-09-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=7cfba858f149b327cbd9bf292080a2ae20404018228ab556eeefc3776f429785 -dist/2024-09-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=5f6d94333400f99bbb0762be18fa9390885c13f4fe0ad7ea05b57808b26653e4 -dist/2024-09-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=38042ee6161d8e8b04faf58a4bca98cf7940ece6ec42eb44ce29bdb9aedb6c89 -dist/2024-09-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=b5056a3d8a8b3bbd888647117b316404b2701803bff09737cca18e16611ed3cd -dist/2024-09-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=9322024609e563bb0d1f342bae2deab1d0c0ae951c2e94fe74ddc22fe2c7d3f2 -dist/2024-09-22/clippy-beta-s390x-unknown-linux-gnu.tar.gz=8b52721fc1df5cd158e12ae80a2936929f64a7b2506c55793b4a7d28522f0e3e -dist/2024-09-22/clippy-beta-s390x-unknown-linux-gnu.tar.xz=66dedbc154a11588a03616b92823c63502276123e66e9ff110c2e63cc7ed3529 -dist/2024-09-22/clippy-beta-x86_64-apple-darwin.tar.gz=66ba82b5e5097a2e35053fcb5db9ca44a152c1172f75d689688454561c8b3712 -dist/2024-09-22/clippy-beta-x86_64-apple-darwin.tar.xz=cfaa2e71b847103660336ad58025fff26f2928a4d7bcc5907fef91e70b63e1fc -dist/2024-09-22/clippy-beta-x86_64-pc-windows-gnu.tar.gz=fef4e4f2c68294908e170c78efb657c02166fbfbc45b6ce65fbfb5c76ce6d20c -dist/2024-09-22/clippy-beta-x86_64-pc-windows-gnu.tar.xz=0eec7155f78dfd0cc2e6ac996053492d7ba8a4fa5203f779a92b04ad42e8f651 -dist/2024-09-22/clippy-beta-x86_64-pc-windows-msvc.tar.gz=4dc7b6c972ed13417fa831ee20b9e4cc0a3895c39d4f059d1a14ebe51f7430e3 -dist/2024-09-22/clippy-beta-x86_64-pc-windows-msvc.tar.xz=c9f3fb89a31cbba2b575cbb7fc74c09c087940b138b34015239c8938ed6d6f14 -dist/2024-09-22/clippy-beta-x86_64-unknown-freebsd.tar.gz=cd7e5a9ee6be58a627b13d2e85c05aebd64414f854229aca917f3334acbe2352 -dist/2024-09-22/clippy-beta-x86_64-unknown-freebsd.tar.xz=7d81d8fd02506935f289e22c6a8f3433bc2c78ea02bbfa4950a31f49eb95344b -dist/2024-09-22/clippy-beta-x86_64-unknown-illumos.tar.gz=d38eda29de151d13b0fb1f58b090b63e049e095a326e26b76055383ba13285a0 -dist/2024-09-22/clippy-beta-x86_64-unknown-illumos.tar.xz=3100a9e357e6ded30499d4a60a6ff64f26d99e1cbd1eea11ca7fcf92a9c1f293 -dist/2024-09-22/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=c09c9e00e653ffdb51c4edca6aa1e23572092c45a1cb81235f05bc75331d68c3 -dist/2024-09-22/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=1e2fa4de890d7bc6c2828df95a729a55cb2b255a25d96194ccca0c3e06a580ba -dist/2024-09-22/clippy-beta-x86_64-unknown-linux-musl.tar.gz=ac80d0b1b7f3e451c3bd00fd882b547a9b87e95c3fc0d332050859ff827782a9 -dist/2024-09-22/clippy-beta-x86_64-unknown-linux-musl.tar.xz=1178ff5a580bd131ecb9a7b0ad2894c09f2882bcfc483ca14e1fd780925e97ed -dist/2024-09-22/clippy-beta-x86_64-unknown-netbsd.tar.gz=b69d92c035e456d4d1dd8a09032a92f8226c9f39579966e86c2e202ac9995d29 -dist/2024-09-22/clippy-beta-x86_64-unknown-netbsd.tar.xz=a0e827a24ffe8d2b38efff5da0972eee15e098f790b49035b21a72ebf1cb17ef -dist/2024-09-22/rustfmt-nightly-aarch64-apple-darwin.tar.gz=4e632df4953f955b24414d929c352ce1f6e196c50cedde3da4d8663f5f1dd77e -dist/2024-09-22/rustfmt-nightly-aarch64-apple-darwin.tar.xz=d7f8d8442b25053e767ec85e50aa2a6f9bb01e45a2ec3fdec56ef1c305a91ba2 -dist/2024-09-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=eaee820d549347d15f1b96e3c85517a65e2a5655b86e27927eb6646a7c1d7b67 -dist/2024-09-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=5fb16519d2acb68df963800c9a5036f1ee38b6ea02a115c40b6622338cf7052c -dist/2024-09-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=037999e2fed25ae76b70960133a811a29707712d2141fc74a1db312cfe6020e1 -dist/2024-09-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=b10d1947baafc6160ce8d5902936c2b3469a1558b71263671e581ac5b1c14f0e -dist/2024-09-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=eb33ec39c232a6ddeab1b8038222f96407b9671052f995e0a60ada332a1ccb3f -dist/2024-09-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=396775133e37dac5de8e71e5d8fea26c19dbfc7841244a35c3529f5dfec93163 -dist/2024-09-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=4885a99dbab8f33288501532b287c20f981bdcd10ea4d9ccffe585d5338c43d3 -dist/2024-09-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=af165d8090fd3c32efc7e5f58dd57d4a2c228cc6a9939c40024d896c35119bf6 -dist/2024-09-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=150086cbd94e084b30faaebabc809cff11eca87a4aa4ff2b2b89286e0af6760e -dist/2024-09-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=49ab34e495e893037431851e65a35ea7e9d0b46ba651f7d73591bd659c031bd7 -dist/2024-09-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c61c6bb8a96c19a848155a38560e0a6dac91ec5f1ee2c602a060cd6039324839 -dist/2024-09-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=81b7ae3c5e27830fa10a17e062c56bcfe66413b994b27951b63f67faabd296d4 -dist/2024-09-22/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=585896ee3c2b1644ebcba6a81b2f2dabc47da151f6100b5660e208c3a2967952 -dist/2024-09-22/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ca875f395d33249cbfd657cfab1b4c596de1453c4451c7bb4466ebec639ad016 -dist/2024-09-22/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=4dbce4c329cac38785408eb1a8b2ff5358fd18b59276435695324a03a7018fa9 -dist/2024-09-22/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=10aea1e2abaae9d098afff8d080cc9d84bfb3f77e2e72ec0a639d61dc5900fd8 -dist/2024-09-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=140897d538c0f7df473c3f704ec7e9198c9e903b5882688f0494166647dbd91e -dist/2024-09-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=06e85fa8391eb7d82902ef55af8ee89a16f07b32e4839a848ac09b506f4227e3 -dist/2024-09-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=4103e5daf242f72c0c7875044ea2ee5f2c88bc5c87ba1e685eee526038663e7d -dist/2024-09-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=fe424f1c13eb8257036db3e843d4c6b7b0e3bbf310f1d42719046f86dd635c95 -dist/2024-09-22/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=86304bb8673decae3d6e8b923765b410948277ea00d0cc5b14bb448da149aa8d -dist/2024-09-22/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=743abf4d3ea8b3e1e8dbed6d9f75ee84680b0636e8e7c536b13bd69a41c8a0d9 -dist/2024-09-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=db68cf7bfaa00b8f6c544b615eabdea998540ae70ec23af6b7370153a6706a64 -dist/2024-09-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=fe1abd02ed36a3720c41c46c77136c89c5addc2c8e5e2cbe25331a34082f4b7a -dist/2024-09-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=c6bb214d68fe7d631398a8684df49f4d1faeb42f9d422c247328e508bdaee830 -dist/2024-09-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=230e19228f80fa4da3036d4eac5b9f9dde02b47d32c43278190da4d322461fd1 -dist/2024-09-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=b21b569a1831a2ea621c35e19a1820f236fdfc54d38a387789b7750b1af26043 -dist/2024-09-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=28f8c4aa4cf00561d6c9dfddc13fdf5fba7b936f9f510b9ecc84160385d590d0 -dist/2024-09-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=5cd81cb8c792abb3c31da225424ef5d1f6006163d3ddee06a95bb4286a29123e -dist/2024-09-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=58eedfc8cda153ea5ee92278bf08a0625d129d3e208b3e0244e2b90819c7cc2e -dist/2024-09-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=17a0c073de3c6e3769a86d0438b1132762456153f3739c6652f94fca270e3a4b -dist/2024-09-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=d7001fc75844be6859a57d2263075ff1b7ac2d88c62452bd42fef97b0afe03d7 -dist/2024-09-22/rustfmt-nightly-x86_64-apple-darwin.tar.gz=7bc303ca8b36c782f2034441cbb6d3dc3ea891114895d2027cce9d8cd25ce348 -dist/2024-09-22/rustfmt-nightly-x86_64-apple-darwin.tar.xz=119dcbdeda0fc6cb80d18e6e908646cbaedd615f5a501922344c795ffd1dc7d8 -dist/2024-09-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=b14962a790a48b609eda7e1a847c85759cd7dc7f9d0ac9914f126f458b4ae268 -dist/2024-09-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=3a710fdf3d35c0a42f5c43341aa00390644d82e76c52aa59f4d652a6ab980b3d -dist/2024-09-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=946233868c179df3c133fa04bde2c863028a69776c7416aa4a33adb102d63783 -dist/2024-09-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=1db1094ee7c9cad7a16b227de6763b835bc33c0650ba2eb9b380c430a766b81c -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=68bc0322c947af0d98f63fc3e41322c12ce8be2bd185091b14407792d407f59b -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=66e380f40e18c8a1ce91a9eaf7f662cacd580fc2b276cc854c03d795a5b9d547 -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=5048bd14d07ed54f5120b0488925f69ff92d2fe00f1e19ae3a8a39a56201c09b -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=d2f903f996c265b4d70bb88d47e85dd7382b3298f9ff02ad4502f32d6f9919dd -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=f0c150cb2fcbb7cfc4982426be6760093aa6cf854d84ed3c793f766fba6a0cc8 -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=5d5cc741435c63b162417f425f7cf9445a13c109687cc85f28424fc51192e333 -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=a3252a997f60b086ea8c9c32665277f33cf574fdefee859ee448dc0b7eed5be9 -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=b888f58dce3689e75ea6c23904481f7fec110f0aea45b75a9390d2160e0d3151 -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=4663adcc009bd376b0787760854fb694eaa0edff88f72b4cf486f7180f6a1c2b -dist/2024-09-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=bfc83277d2217b3a908c3f9153db1336b63270c70c6cd83a2628cf18c41db47f -dist/2024-09-22/rustc-nightly-aarch64-apple-darwin.tar.gz=ade996e00dd338a86cdcb25961d07c936edec1392526d78dd5de156ba012fe55 -dist/2024-09-22/rustc-nightly-aarch64-apple-darwin.tar.xz=147d0cfe57be988564d30fcba7fc0c69979b5fbdd91e4a08ac8e580be8a1cc6f -dist/2024-09-22/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=e6a59a0303abbabb3b373fda7fb697ad2cfd31011f231fbdfd45c1cbd64e8bd7 -dist/2024-09-22/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=9ee27bc608470ef29a51272656d0ed5e03946dcc3411412ef8b05cc70f97f8b9 -dist/2024-09-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=3ec6f8cee20883195c102bdcffee31d695698bb6eaf45502720edbc16b02f471 -dist/2024-09-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=7f8fabd6433acb752131071c5bee76752fcc88e08ffff4684a7badb9ed4bc50e -dist/2024-09-22/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=7a8756afcd643b78aa6834497935d7bc0ede1ae74150fa83fff85243deb5e554 -dist/2024-09-22/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=de39081dbeeb0715d433e0cd56e62db45c3bb5bf04d1e7dc3fa097e7b3ca97dc -dist/2024-09-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=ea6bd6b337d24a7c9995fa95d8884e66755d016fb1d50fea063129a410bec22a -dist/2024-09-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=fa195b2588675831274ca21c0d2420e5729d1c21c4c245f2fd1d2c044d7ede1c -dist/2024-09-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=6f0719613ec54221e978e7136baa00eb25b8b3d627e5de5ee3488c9d9e869b97 -dist/2024-09-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=9e0bbd283a0377f881f1c048660c54700561762e220ff2713566d3fb6eb56cce -dist/2024-09-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=c8f88bb948119a9ff218571eb3ff0144915b2ce4a404d445db9f8f9c25044aa3 -dist/2024-09-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=1c41588099d929a7e9dd56cba22782f5202fac2829b924b1aa7dab3e03c52960 -dist/2024-09-22/rustc-nightly-i686-pc-windows-gnu.tar.gz=af2d30b4925e786ace64d4a11bb05ac6f7df1636989a3656d1aa9fe56cdc330f -dist/2024-09-22/rustc-nightly-i686-pc-windows-gnu.tar.xz=4bfe618c3702ea805b63beac19cbf0561d262e67d87765a4e10ea9defded53c4 -dist/2024-09-22/rustc-nightly-i686-pc-windows-msvc.tar.gz=c4e57fe6fec40d874c8fb54227b310072dc98f35f99b8cc741e6818a67941f6d -dist/2024-09-22/rustc-nightly-i686-pc-windows-msvc.tar.xz=ed10535a830e2e1ab22767a24b82b3314b7ef4ac3c318954ee8f2384b287d8e7 -dist/2024-09-22/rustc-nightly-i686-unknown-linux-gnu.tar.gz=da5e36f6bb3d9f00b8e5db5aceefcf8ad38552b85a1a4f60f7b700148cd49152 -dist/2024-09-22/rustc-nightly-i686-unknown-linux-gnu.tar.xz=5831b0209eb64a44b6bfc8aa4b092faaae85101f58f79c4e869bffec22361f1b -dist/2024-09-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=f31871890aa6249528b43119d0f050d27c5f404b560d48660cd4c9e7a3a80b76 -dist/2024-09-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=19dc59393d25edef8a341bb137ad1f4ca20741038b0111dc81d6e61c0a7a1975 -dist/2024-09-22/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=8ebea352863ef014e4dafbafe5a28ddfff6a26f3e4cf728fb4099ecd3444a3ec -dist/2024-09-22/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=97196b586f44022d2c24b7378830f716abceb451244035f74c40b6c1587f6c50 -dist/2024-09-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=6f4d2428ec7a4d5e1540b53e35904b9f9ff5b8fcd05cf3311b005dbfd426d65b -dist/2024-09-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=c2bc66d7d763c1d4c5752b60ab563fe5b870dd35533712046acd40f258f7a337 -dist/2024-09-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=d0e6f42aafc8d8b289b55c1ba4a34039c747a7445b347f05017606801a7d81a4 -dist/2024-09-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=9612777e56955ab5446e3ef20e0d579fbeceedc3bdc4d0053367be2191551fd7 -dist/2024-09-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=811099c8b6adc017678c4e43c8f7b02b2bde267eac1bbc023b1f22c184894231 -dist/2024-09-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f766dab0fa46122c26e5a7736da65e8a2df9c2c6578093b6532dbd88a162d1a5 -dist/2024-09-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=21e9896e5184d797445a19ce5788d8dabe86302d5f63bf8c07105b52a237c13b -dist/2024-09-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=002da974c9606726cc7e6f68cda012ef305e420cf6f7a0de84bf791c007fecd6 -dist/2024-09-22/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=adfa4248f4ad883a04d67f923325c28b7400853063f2d8017cca8f4100ec1125 -dist/2024-09-22/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=8334aa8a99d2a8034267394d44b0e5036d053c247812dbd5bc90bdb2344e4713 -dist/2024-09-22/rustc-nightly-x86_64-apple-darwin.tar.gz=385aa935fb1762423d1a11c0928597e502adbab9809a86c17d98096c31f65775 -dist/2024-09-22/rustc-nightly-x86_64-apple-darwin.tar.xz=f2bb16e1618dbcc7dda85e0ff4460ee270a99871477380a6412f575bd02f4cf5 -dist/2024-09-22/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=6e3894c7651bfb48c741aba516ee99690616431643db82cd186fe408675d07b4 -dist/2024-09-22/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=5661b5ba3a496106f4b0019d4ce81dbcb4b4a0db68a90bac64a95a0bd9201514 -dist/2024-09-22/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=564f7a0582f3b900201cda4fe502e191b651a845210d21a40a119b94e2e51133 -dist/2024-09-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=1804ebc7ade5c49ec4b82cac2261cf159b8c852a7e06f3faafbf990214936d2b -dist/2024-09-22/rustc-nightly-x86_64-unknown-freebsd.tar.gz=7455de95ddb8e565ddeaf2da7d80d890c60bc653f52afcab5244476d35305e0b -dist/2024-09-22/rustc-nightly-x86_64-unknown-freebsd.tar.xz=36a7cf6e8245c3879c08d5e3acfb0155ebcdc6c5b06edc51d43376c44d9ed0b4 -dist/2024-09-22/rustc-nightly-x86_64-unknown-illumos.tar.gz=143f5ce723a8f5e54af64a3b31d83243a808355705b1402be5de821759187066 -dist/2024-09-22/rustc-nightly-x86_64-unknown-illumos.tar.xz=c88c8d2ae8f221fe1db978802c98368472381b443bed9501371c03617865785d -dist/2024-09-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=0ea098f78927d9fdf4ec075a04e989b6ac83bc1f1225aca5960281cd65046a3b -dist/2024-09-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=33e5e1e0b758de383281ae704d3dd1ee337d8e28515d6b4584dd2691587c7f0e -dist/2024-09-22/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=723f5eaceef968b05286a17b7868c7e0cf222ac33d23a9ac3f761fc274b87c38 -dist/2024-09-22/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=1b00b14a57b6f3b7edbf9adc05d3ed28ed1e2b8ced921a444d13dd1ef577e715 -dist/2024-09-22/rustc-nightly-x86_64-unknown-netbsd.tar.gz=6cd2651e4e8aedd8aef8d325a72cf18694ee7a14077c7331d96e2e7c03b9c57a -dist/2024-09-22/rustc-nightly-x86_64-unknown-netbsd.tar.xz=0c6144559f040a209183d6f02f61caf485f0174190e643870d1d6c9744bfede3 \ No newline at end of file +dist/2024-10-16/rustc-beta-aarch64-apple-darwin.tar.gz=24719797bf50fb494c61cf4711d6bb238ea9e789a1b10d957abb23f9849a06cd +dist/2024-10-16/rustc-beta-aarch64-apple-darwin.tar.xz=5eed456f0034e2b31ed4f6089163dd5e86ecb04630371e408aca741c32d845c5 +dist/2024-10-16/rustc-beta-aarch64-pc-windows-msvc.tar.gz=f337d992f4a730d39ae571d602f15d2c66ed0b6abf1b2c63112b570e855ac409 +dist/2024-10-16/rustc-beta-aarch64-pc-windows-msvc.tar.xz=d22b4f26ba8b82e32114311c1f0386d0126eecffa2accab8ca9ecd6a7aa38400 +dist/2024-10-16/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=047735b5c90fca9f26e5eca2a1d24dcac6fdddfddcb89c9d1e2f6d0af0199946 +dist/2024-10-16/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=c70bce1fa2a6e98577683d94473ca7046e8add65b85792e9887fee4edb8bdcb7 +dist/2024-10-16/rustc-beta-aarch64-unknown-linux-musl.tar.gz=4c75417b640557b35172ea384fa34a3e8da1960efdf4a40cf8d1fdbdd50ee997 +dist/2024-10-16/rustc-beta-aarch64-unknown-linux-musl.tar.xz=f7f5e67b831af5fdb28266fadd7cfd9f092c066f7e7322b058d6fb2bc7f6ff77 +dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=5d94f4e51767b02ddcdafdcaba3404a3133d308fe98c7bf5145a41bde8146319 +dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=49166b4eb2e18e009ebde1e4c133adcacc3d5257fbd63b07418642d5c841957a +dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=9e51ecc782cf9738adafd70c055ed793ab895c9616619c525cb52d7412cdf884 +dist/2024-10-16/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=d60502f25273c2552997de281727b0f5914a2a97f32310f921ea714c5a1080d7 +dist/2024-10-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=5796a33eda8d7b47c8982d3a2e425728cf681043151a291fea107b3aca9ff1a7 +dist/2024-10-16/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=71fb2132822aa284cae878a76f9996092316942f84dc5a674fb8be17eb391cb0 +dist/2024-10-16/rustc-beta-i686-pc-windows-gnu.tar.gz=d089cdb87961d00e7dc51c767993342a2fa704756a94c421be7f195dfa6c5293 +dist/2024-10-16/rustc-beta-i686-pc-windows-gnu.tar.xz=42865105f308f7e0cf9af250b54086eaa20da8ef13e9cbf82380340a9db4ce90 +dist/2024-10-16/rustc-beta-i686-pc-windows-msvc.tar.gz=5753e00d74de3ceb1af0dc533496d7db6295d673eb05aea779734a519b5f789f +dist/2024-10-16/rustc-beta-i686-pc-windows-msvc.tar.xz=dff93d0c39e8653f01248f0db05123018c63c92a1d3861935b12ad1818b00864 +dist/2024-10-16/rustc-beta-i686-unknown-linux-gnu.tar.gz=4e2e06e503be7d15211dad18911ce951491d2596cef466ae8282af840184427c +dist/2024-10-16/rustc-beta-i686-unknown-linux-gnu.tar.xz=77d0d69f3e0c2b32bd1ccb73f12b5b770a1a720e7928859d454f42e611f77d67 +dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=5faa3516ecfe77f8fb21ba80e78c21a1b039f5fffae508cceffd04c8c329f152 +dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=8f086e53b3abffd7c947f5b0784f9977ed4559e654805bc3877ada99072d38e4 +dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-musl.tar.gz=2147f76d151c513aaef63cb2365bb2c9a8d0eb21a6b1c7c2ff535dab0882c46a +dist/2024-10-16/rustc-beta-loongarch64-unknown-linux-musl.tar.xz=db2c17f1f3e0af9ad56982e1396a031df07939aa04c73795f541b16161fc3bdf +dist/2024-10-16/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=e5d3fabc7902695ccf85171dd16cfe772a480dce203004da0853170450e57b1c +dist/2024-10-16/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=db2f03a41470e60a0070b4d96590ae049c23d2c0f8c07a5778023a4ecf3e52eb +dist/2024-10-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=49610d2df0b6ece6b2afc583db707eed0a6a12ef99a8ba0a82f9acb7c1e15fca +dist/2024-10-16/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=801a92eebf0c068c88a48129b054c4ecea143f38468ff5d53e28fd00a0fad6de +dist/2024-10-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=db8a9c4bc9313627d5ad2ed2ebe91b6129958254a32862aec67edee10cdf9bca +dist/2024-10-16/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=fb2f2f2acb7516d98a6abf17e84e8b36beb7179c69776d69465f1c981466321d +dist/2024-10-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=87effe21c4b4333769fa7b4b0fc4bd43edaabc1c8ba33e75480cb4da0d59dae9 +dist/2024-10-16/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=71701db843d0974b4fc09afb65e3872faaaf66bfda258c9627576efe8f998f96 +dist/2024-10-16/rustc-beta-s390x-unknown-linux-gnu.tar.gz=6485ed4c99deffdde4eee34e46b8be2eeb65a3f8f4b4eb032a4ccd9c6f4e29e7 +dist/2024-10-16/rustc-beta-s390x-unknown-linux-gnu.tar.xz=e8ee8b61386d490c8e59e0c2ccb30fb7758ea0ff0b1448d5f946d9fc58496a11 +dist/2024-10-16/rustc-beta-x86_64-apple-darwin.tar.gz=23e36a4892e948a6dc231d15913562f1f95f798a62a38315a6b19244aaf78385 +dist/2024-10-16/rustc-beta-x86_64-apple-darwin.tar.xz=2db43b3b599eab832a13c784d3a1bc60c3222f5bfce8e112688e1478837b8c25 +dist/2024-10-16/rustc-beta-x86_64-pc-windows-gnu.tar.gz=099c529cc84219ae3ed9a33dbc5265c46a01c8cffb8989e66e367078bc981eec +dist/2024-10-16/rustc-beta-x86_64-pc-windows-gnu.tar.xz=efef4dd4a40d4f96d151293031783688c84b088a5f2cdde84d931bd44aee923a +dist/2024-10-16/rustc-beta-x86_64-pc-windows-msvc.tar.gz=28633202a502121e9369e93a8cc66bcb52b2cc959d7598f9bbb8e4c840381baa +dist/2024-10-16/rustc-beta-x86_64-pc-windows-msvc.tar.xz=c7b879d2e7d7c21eafc7b8e9f18f009d2d38f91a2eafa51d25d38e3b51e17ef3 +dist/2024-10-16/rustc-beta-x86_64-unknown-freebsd.tar.gz=69bdb56ac4f47fa614fa9e8be5218a492d31a423454c192ed5850f49357687e5 +dist/2024-10-16/rustc-beta-x86_64-unknown-freebsd.tar.xz=36c995c1dd55ab4501f250a77f27cce34330daa2a3e74129ce389aa23b4e3a05 +dist/2024-10-16/rustc-beta-x86_64-unknown-illumos.tar.gz=84bb641a5576ef0e93c7b5bae7417eae344f32271a0ebc31bb987d15316815a3 +dist/2024-10-16/rustc-beta-x86_64-unknown-illumos.tar.xz=a7311a345dddc9f8cf1eab6b3e82658fadb485bd755a115d4d6ffdfb42a5625e +dist/2024-10-16/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=9def7618829111d1014e21fb0bc10abc26459e59ce61fdac5fb3b63583f472c6 +dist/2024-10-16/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=97d124a65a7d7e5610901521b565ff031313685cc37a1caf89de58d952065c3c +dist/2024-10-16/rustc-beta-x86_64-unknown-linux-musl.tar.gz=101a440c383011cb4621825481582a81bfbad0ac03439542bd8d05ccb5aaf2c4 +dist/2024-10-16/rustc-beta-x86_64-unknown-linux-musl.tar.xz=4148b4311ce8e1cc5dae86d5f27e207496b85e5c23a53c7bc5b05ba18918f717 +dist/2024-10-16/rustc-beta-x86_64-unknown-netbsd.tar.gz=25c5c35f2acd37a7c72eb8dc546cb6e9f62b3e76e1569d188bbe2aa9b31ea3e1 +dist/2024-10-16/rustc-beta-x86_64-unknown-netbsd.tar.xz=9b84ce176d4015ed8f6946ef2d42f2f601cf419d1a6477f44bd6b7c7d27c95fc +dist/2024-10-16/rust-std-beta-aarch64-apple-darwin.tar.gz=ebdf49b8d4fab00c7fb4d396c54caf5cb234389b7353856734b960f908c3cff9 +dist/2024-10-16/rust-std-beta-aarch64-apple-darwin.tar.xz=4d0d5fbc235d8cc78e9997302c45916008e203ba7f02edcd061290fb9639ee8f +dist/2024-10-16/rust-std-beta-aarch64-apple-ios.tar.gz=6693f5a06df0ea5929df18b633ad6373d098db4454d0e1d35e4c19b6dd7fa4ed +dist/2024-10-16/rust-std-beta-aarch64-apple-ios.tar.xz=351a1a2a13316161edcf97238d868cf4b1b5216bdf28ca0aff5a1dba2a1258f4 +dist/2024-10-16/rust-std-beta-aarch64-apple-ios-macabi.tar.gz=f0e13e1700a1cbc1489c0a5728ce6c0f5ba1432a75ca2c0c0573b9fcf130ae9b +dist/2024-10-16/rust-std-beta-aarch64-apple-ios-macabi.tar.xz=825550e3a2afbe15130dcf7b702ea62b3b90f8a1e0b850cd6e9a5b5dd180e72d +dist/2024-10-16/rust-std-beta-aarch64-apple-ios-sim.tar.gz=f77a6c24301c5c7165de3bf51b5b6d45e7d37a82d00446d1abbe5a5c591ca616 +dist/2024-10-16/rust-std-beta-aarch64-apple-ios-sim.tar.xz=5a9507e0c06b252196203b01319355e4d246eddead60993262bd680b6a1d2315 +dist/2024-10-16/rust-std-beta-aarch64-linux-android.tar.gz=eca36ae4253e5f1b51c065631a650135b71797b452a7fbf6dfa17c49a01f71d9 +dist/2024-10-16/rust-std-beta-aarch64-linux-android.tar.xz=1da17cca8397bedda8b5403ddcc9f7686d7ad207daa7389a6cf80f922bac8140 +dist/2024-10-16/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=1a4eea434371a7d95b473410a42d8409995119c85954f94a75b8b0a69aa3095b +dist/2024-10-16/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=cea3d7d9568d2ed86ab11d28f5a02cf36210971b798c4d61e133357c24108f6f +dist/2024-10-16/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=355fa0988a68a1a331a2794a573cd065e6fbbe8b312e187dfff59f4f4245cc5f +dist/2024-10-16/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=c93347602b0133e0da072243ba9419c95179f9f548b6284612967d7b80a42144 +dist/2024-10-16/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c4305667ed2a77764c729fe236491b239cea7c2605039c2bc28a926d21f343cc +dist/2024-10-16/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=02b6b621a1b3b91e25482400680cd38be806d7de541cf364d0ed181a92fdcbf5 +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=830e1b90ea156eee05b0c5fab514d82558e2473eb5f6bddfeafa51e7417315c2 +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=c5910437177f607439a6b18bd05b93c3965f915a0d372fb540deecf044b21880 +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=7a0f343b5fa50168a3edd0770dee148c82e43e7b2b82e2149ca22badeade3218 +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=dc4d7b3cb830451044726e72b848e529e92ec0330e610f06b07f8ed37415c3cd +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=8a9e341e6f208d5036e4c774f68b75802c64c53c4a9381ffd5a62e9b3c486cdd +dist/2024-10-16/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=fd24b56cc9891d9a1246e62eb33f6de8385acb265ca875af79f2593ff4bd323d +dist/2024-10-16/rust-std-beta-aarch64-unknown-none.tar.gz=51a58a9f663de787ca58da8e4ed705a1099bfeca945eaab3bbce01edd45aff4b +dist/2024-10-16/rust-std-beta-aarch64-unknown-none.tar.xz=47fcf0fcdabaddde929e4828c1de1db3986af1d32a752c057ec69aee9c8f6162 +dist/2024-10-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=207281137a1b6ec8c1df21c581c23a6db7bfdd11c550749203bbe24b9ae80019 +dist/2024-10-16/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=217625e68479d09d8e63f931983e030ea9f0829cdd559ba88bf657e711c96aa6 +dist/2024-10-16/rust-std-beta-aarch64-unknown-uefi.tar.gz=4c5fa8fc4e18723c4522a1e93e9e343e35f02e74fc82e6fc44951bf7e1849371 +dist/2024-10-16/rust-std-beta-aarch64-unknown-uefi.tar.xz=f4440f97ebab6a79d50683169994cef569a427cb1811b85ee196432d4e2d0b38 +dist/2024-10-16/rust-std-beta-arm-linux-androideabi.tar.gz=ab7dfa2b8aff6bb7514798d11970e4c09c8a4844d7408e295c547f1a87c23ea0 +dist/2024-10-16/rust-std-beta-arm-linux-androideabi.tar.xz=fb9ce70893a8c89bc3e66dd6ded2e0c4813c96bd0781b6c3b420a278c53ba4cd +dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=4650f832189a221337fc172c2ffa113ff209774949ae12e7ef159117a02e984e +dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=f6bb5528b914311802fdb9816260e8a57531fedc5f68bef2dc6ba83d59d5ce4c +dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=2fff203abd959498321680582bb969de89c9de4718b38e06cc91a789d7fd415e +dist/2024-10-16/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=df5cadfd5895ee1552bbcfebc40b34826481932bdde309ecb2c13f55541ca2c0 +dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e29900d97e62c7568395191e1230fa6f98f971c1593303810f05d4db5c68592e +dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=4455ff5a1de11281aca0df4f3f6d33d245314ce4276bda9d161bf850eda24ad6 +dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=26fcafd19aee4fcba45875d0f35aeceed7cb0a0fa070e6a2447b3d9b86170c8a +dist/2024-10-16/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=cc43780fa58e7fa1d23a3b5e2695dfd3f4ac3c02398756516c395f4546e2042d +dist/2024-10-16/rust-std-beta-arm64ec-pc-windows-msvc.tar.gz=a67a25cdaa3fabdd2b619434e3b98f05acc13f25cc7ebf8f936e7f3d1761e272 +dist/2024-10-16/rust-std-beta-arm64ec-pc-windows-msvc.tar.xz=e8ee762127e02a73614e636b77d34d927f34e967cadd79158ca6ea27687c679a +dist/2024-10-16/rust-std-beta-armebv7r-none-eabi.tar.gz=7343489518ad6d354f9bfcbbc884d1c0e4fc88c4650cc68d9b9b84ee12b750b2 +dist/2024-10-16/rust-std-beta-armebv7r-none-eabi.tar.xz=eef35d9c016fdb67b9825104558ca0fc1aec3af8a738636a0f24797ad270b8e6 +dist/2024-10-16/rust-std-beta-armebv7r-none-eabihf.tar.gz=ed36702bbf1d45c263b8b52a06f2b4a9783c6ec78db28e00d317acd09a549977 +dist/2024-10-16/rust-std-beta-armebv7r-none-eabihf.tar.xz=e4fbf4007af9858e1bebffef6bdb4c66f419b035c8fb385dc70d46ce2e312e2e +dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=1eebca6a4ed9b04a1cd3fc57f8f75bda14cc03c8909385586c8a084e46aa96fd +dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=0bf68ccaa22a4782f23a34b8a52ca250b183e265f12bffde7cda9ddac515040c +dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=6f7b932bb0176fefbcc1de700a36da7c60dac609ec91e6bf351e4c42ea6fb119 +dist/2024-10-16/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=a0d9397caf812fa479da6b389b653fcff451f8d54fa0545e5c908e73391b6dee +dist/2024-10-16/rust-std-beta-armv7-linux-androideabi.tar.gz=5be2ca5bd0340fa2e7ffe435081d1848ab883e46a9c0f07eee69f7dd9d08e0f6 +dist/2024-10-16/rust-std-beta-armv7-linux-androideabi.tar.xz=ed563b78d4201ce29ba79cf6ebf5a3b7d8020611309e39b8790c59edcdd05b29 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=53f7928406a1a14dfc6774fb2704bfa9c68091b135b750c5e46e3610e00e8c72 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=d71cf98a8b6dfa2cc1682819d1bc5bbfe0eae819f63bb91d64e4f52bbee4158f +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=f65eccc2a47e34d96faa94954c738813d9b5acae351936b07df6ee2ee8592296 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=4f44230338a6b6bc17a8a2a80125ba18a9dedb6f9347c6e93b7f7b88c87e4468 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=80eae216bc5c3f77817d244f0d81cc13704894c1c7bde30c89b4f58b6049767f +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=b8036aee8615786593f83c3e7808eac2a59ad44ae9f5959b9719fd475b3197b0 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=95ca16bf6931261a62f4a3637495c02450d34fd0a0ee8abe350881b9aa0bc773 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=df92b9f5ec3ea09c2cc48e4c91d41ecb1fa82db87180458b1e051bbceeb4efc2 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=26a4426464874411bf51cf0148569c9a110681632d228dc9c9d57fbe24292e93 +dist/2024-10-16/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=70ee4948185aec3b556c963ba030abbb6424e09190e31afb11d063bc2ba21664 +dist/2024-10-16/rust-std-beta-armv7a-none-eabi.tar.gz=50c5b3d721cb5d83ab5f277c24eecbdbde32bdbc208bc0597830329fd19bf786 +dist/2024-10-16/rust-std-beta-armv7a-none-eabi.tar.xz=9add40fc1a971f135796a8020e3ecbc6ccfa657714cee2535866f2af38fcde97 +dist/2024-10-16/rust-std-beta-armv7r-none-eabi.tar.gz=d9e4695576a9f34e67804a636de6164fa7d381ac2193095cd2daa74fe148b748 +dist/2024-10-16/rust-std-beta-armv7r-none-eabi.tar.xz=6592a61388b53c3d3040245b8634715026f1e2a020a118edaf43f98839537aa3 +dist/2024-10-16/rust-std-beta-armv7r-none-eabihf.tar.gz=da24db2c8642e8273ef7d0e74fd32a1045ec99f5201b35d0116ba1818ab330d3 +dist/2024-10-16/rust-std-beta-armv7r-none-eabihf.tar.xz=75574d203e5e15973ce1e6e12a43d6b26825844382ef76b05c4dd568912fd16b +dist/2024-10-16/rust-std-beta-i586-pc-windows-msvc.tar.gz=2e4bab4042bac836ac40e07c36c6057273d6bffaf97b1b22a64cd0876d48895d +dist/2024-10-16/rust-std-beta-i586-pc-windows-msvc.tar.xz=f335988ba2ae2853c4c8928562fa6ed81a2bbd2bd5d09dbcebd7e64cbc7d458e +dist/2024-10-16/rust-std-beta-i586-unknown-linux-gnu.tar.gz=e96921c51d49ae28871286147d589bb59eec596826d1e0eeddd928f57ed4499f +dist/2024-10-16/rust-std-beta-i586-unknown-linux-gnu.tar.xz=c17d7cbbc6bb30899a1a94f74f380bb54878b927ebe58b31592f7adb64d7b5fb +dist/2024-10-16/rust-std-beta-i586-unknown-linux-musl.tar.gz=f9030f5b2ae0411349f1f4fabd00efa3e1117ca5dc5ba60fe87f33f94e51787b +dist/2024-10-16/rust-std-beta-i586-unknown-linux-musl.tar.xz=d45b9c7c6f8de53f99b550a6d673bf8ff29e507c60ef63271d7d5ac73c765e07 +dist/2024-10-16/rust-std-beta-i686-linux-android.tar.gz=2a6b9c893d2d8bbdb5900c4105fe54a988101c7d69f504e4d2983ba7aaadbbd4 +dist/2024-10-16/rust-std-beta-i686-linux-android.tar.xz=94c884a0cd03fe092bdfb6fe718fd335921a82c9c2887e0e68a13fe6a183a877 +dist/2024-10-16/rust-std-beta-i686-pc-windows-gnu.tar.gz=2d4a8b299987ab046536db276f3c4ea97413be5915189b9af085e4a4ba7b28ab +dist/2024-10-16/rust-std-beta-i686-pc-windows-gnu.tar.xz=eb60bf4d73fa45fe61730427287585939ff1a14efa8910877546818167b343cc +dist/2024-10-16/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=ec0f11f5cce47e6ad288393dafaa69b27fc5207194e886f0a00b4e6c3a006164 +dist/2024-10-16/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=10a5c127538bc9b951c62692ca4d626cd669919d5bb2236ef6112da28db028a5 +dist/2024-10-16/rust-std-beta-i686-pc-windows-msvc.tar.gz=7c9afcae592f5494ffd2baa95947b4fa5483c795e516852b463170e4797984cc +dist/2024-10-16/rust-std-beta-i686-pc-windows-msvc.tar.xz=ad9381999c1846c188d7264992c79faf413d675fdd70f22f25afcf84ed6e3b22 +dist/2024-10-16/rust-std-beta-i686-unknown-freebsd.tar.gz=9b4ea3de244aaf14b6759807444bb983ec5732b119faad1c9437eb2c02d407ed +dist/2024-10-16/rust-std-beta-i686-unknown-freebsd.tar.xz=88f975eff5146af6ae548e2d7be8d402ca3d6f470b6760b75e27dedcac9f70fb +dist/2024-10-16/rust-std-beta-i686-unknown-linux-gnu.tar.gz=8a8a255695d36a86ab32abe9f37f9f6f3e9b75eee75953486d82f186d8342180 +dist/2024-10-16/rust-std-beta-i686-unknown-linux-gnu.tar.xz=00a55b220767f3b692286bea728208bf665ea9a54869f82b31805b40ff56f763 +dist/2024-10-16/rust-std-beta-i686-unknown-linux-musl.tar.gz=96e838064bfdace0fcd5596c50714585a221a5116e2825aba448cc1f188d0edf +dist/2024-10-16/rust-std-beta-i686-unknown-linux-musl.tar.xz=78c5be28afda04d536a634a049c175b38d46309eb4b02126ba2cda3102b92d45 +dist/2024-10-16/rust-std-beta-i686-unknown-uefi.tar.gz=41a11092091b1f3b508f606978c0ac026e94614fe4b2207522b4f5f3d6c3262b +dist/2024-10-16/rust-std-beta-i686-unknown-uefi.tar.xz=a2250a5bb179549426ead55edaf3eba7626ee57a5e2c578057c3166348a47523 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=782998317c6c9cca107e84538ee166a37490b287efb437e5da9bf799178084b1 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=75b15b6d6db6f801a74419aa294b9537aa6e92b4d9d4c482e66aa6e319accee5 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-musl.tar.gz=003a9949067435194f6a9bc6ea742876d5894ade67b5831c111826aa8ba5c2d5 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-linux-musl.tar.xz=5f1a4b6acfc1c82049c13ee2553ac20df016062feb368a54e44aead601105987 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-none.tar.gz=f5e851d27f7017832de64c134727b7cd045495ed93fece21101c1e32b4c4c5e2 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-none.tar.xz=289a56a0ee6087fbebed28a8d2110961c08889724d1a776a41094d5589cd112d +dist/2024-10-16/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=86cc3aa69dd4b18fc8435b6f6c1c73a24dc0b031cd79f942f6bc20a11f093f67 +dist/2024-10-16/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=3e29c510424862fbd96cf61e89b6f9d64cef3c0274dea125f4af2c2a84816f5d +dist/2024-10-16/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=7506febb3ffaf1e763084d06a8dc9da096155c6a609a5c4c26feb993688f45f4 +dist/2024-10-16/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=9c7e50509abfe5f0faa41eb526effa915e0799f59e5404e5a667c5f674a1ed18 +dist/2024-10-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=6070daa8b4fc8bfb6c392767ac669a80067520c0fa85c923cb435c03a5ba6b9b +dist/2024-10-16/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=32e4064ed11bc521f26e222897ca651704e41bd42df214eb618b6fffcb909b56 +dist/2024-10-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=51a092e812baf52f5eb7100e433fc1d5ac7cd984f8062b7d960711b9b88f1431 +dist/2024-10-16/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=444bcbf145d1aff19d8e2474191ee4ff0be738c7c3b1ded12e1a9bb35d700c2f +dist/2024-10-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=9a4968669cb034ebdd0623f57f86a674df513abf6c01cbffce0d104447f0aacf +dist/2024-10-16/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=11e478ed0cf115eaed256e9f0f64ab9f879ea0fb26b2f520a6388d3efe705422 +dist/2024-10-16/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0476e97436699b50ce459b3c38b55425b81864162639997bc14bce33fd7ea429 +dist/2024-10-16/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=f76163c6963a7f1e29cc6a348b68e3c0659b739383273029eefac4d292280a3f +dist/2024-10-16/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=f922ff15e927c047bed29d64534218d392bb584e12abdba09d9d9243613de3b4 +dist/2024-10-16/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=0131845949fe27479123189bca11f2ff13aa14e0349c0901407cf65723271fad +dist/2024-10-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=a7898b83bf49203172e6191cc720b6b184aca6cdbe44386278fab0e6c8ca4bca +dist/2024-10-16/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=d5a4a03dfa52f732af211ae3ed3220fd76c5a2a6babada0bf94de3817e71cca9 +dist/2024-10-16/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=c074043d065a85860d2f99b657035b87a1ee7fdcea53c557035a8da6fbba96ad +dist/2024-10-16/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=9a02c6c4c5cf7c57942a89da30869d7bbe2b0f5bf7374b7dec868bb5f84e00f6 +dist/2024-10-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=1c016db6ffad0ecc552025777b2d2df5a54d6ec3a215eb2b4af0f1ccc6e45f14 +dist/2024-10-16/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=399d56e3525aeb354a0c9250f070a43a7426e185960db6d8b57484f47ad11a4d +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=64f01a83583f4d025c95b3b2c09b86c4bae123c72a66a6a0995994d4226d34fa +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=794cb971242dedc2926a6b56badeffd1b4aa4f1753a22a1228eda8f336c2a5c5 +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-musl.tar.gz=1eaa20562af0921066ae04c8e1d9191ecfc4f9816a721ad2797c47b58a343084 +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-linux-musl.tar.xz=423b35248c797ea494e6462b4a9c16e49649f0105b06b16c6137799a82f0a401 +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=38a31b095b74cb4b678ecd797ed768f4f9f967a201b79f21b059ef8a39fbd4f9 +dist/2024-10-16/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=d7a53419a2f604102bda0d0b8ee9aba790082ccb0d63c31ff28be15f37ee87d6 +dist/2024-10-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0cbccec64f57ca0951fe678299cf17a7aec8bb2a8d71aa7fea1a26cd720b38ca +dist/2024-10-16/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=aed7bcbb60aa5444ed8a8e1ccc7b74cc978b7e1646eb618a1899ebe61adf2c34 +dist/2024-10-16/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=0cd68dad85a5cc084d8a0cddc275cd5e932e50cea18d3d622d03ecca068008e4 +dist/2024-10-16/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=0873ae093594ae2d93f19003ded34d1d6d4884757e0a5a790d4766be4bd7622a +dist/2024-10-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=ae70c9e9edd7d83776cdd0013e081d3b16dadb2a2504037b245acc82f104112f +dist/2024-10-16/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=810c1346632064535769e8fb15ac207de45f06700e8cc9875b3971c44725a3df +dist/2024-10-16/rust-std-beta-sparcv9-sun-solaris.tar.gz=0538ccf4739439c52d6c7d99b573e7d8163a834a6163720829816d291e067217 +dist/2024-10-16/rust-std-beta-sparcv9-sun-solaris.tar.xz=8064bfdddb99ba6ff202ab92e3492bd2191ea11387b930a35fcde5ac7e341c29 +dist/2024-10-16/rust-std-beta-thumbv6m-none-eabi.tar.gz=a988938091594f39015783e78a334d72d41f5a3646a3da09fe7a7a0db7ec2662 +dist/2024-10-16/rust-std-beta-thumbv6m-none-eabi.tar.xz=0dbf287df801225c52d4dcbfd7afdfd5c1bb8410d9342885c092a4982a0d038b +dist/2024-10-16/rust-std-beta-thumbv7em-none-eabi.tar.gz=d5b46640810193ee163ef6cf3bb8d506b6844104c3d00c033d436d79ee790dcf +dist/2024-10-16/rust-std-beta-thumbv7em-none-eabi.tar.xz=f4e7ee83d5392e2496b9d3fc1e42b45d73be3b67e723a2e62f931c11a61480af +dist/2024-10-16/rust-std-beta-thumbv7em-none-eabihf.tar.gz=0fa0ba0ca7c4e73f8b9ff2800919484cad7d902cc5e704e5aa3adb742cf6a6a0 +dist/2024-10-16/rust-std-beta-thumbv7em-none-eabihf.tar.xz=ce3f3f3bc51cf79449df550b8c3fbcac588444b3234f379b93076034be6a40e7 +dist/2024-10-16/rust-std-beta-thumbv7m-none-eabi.tar.gz=3b2aee46d16f38cf43cdd3f3fab78df181bab6438cb012c2caa56fa097ad1402 +dist/2024-10-16/rust-std-beta-thumbv7m-none-eabi.tar.xz=3ee398b8497b7920f5d3cb18be2334ce440ec61b11e80c3ffb9eb1d898be45cc +dist/2024-10-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=26a67116e52dc1fcf179dd226fc28e3e21f2d2b482330d254b5882502573ee6b +dist/2024-10-16/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=d051ae1bc98060db4a2ca7fa3c3dfc6c3107632631edac41d553e4b192ccc2d3 +dist/2024-10-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=dc34a8335b1a9dc077e38b4e4a8222d84340de604a6af547fa17bb142cd0c4da +dist/2024-10-16/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=2d5c375d09bcaad6f983d4c4e0762532feb1d3706beacbf3a8d2e4fd75bf0c71 +dist/2024-10-16/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=30c73a59d9138a542337fbb2be848a152172be272a25a1ad9a28f37510e35e94 +dist/2024-10-16/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=467775974be97da92015790d49cb4f89d967ed1fd7846456b4b30e20f9585501 +dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=06db2989a00b1913822cec211225b0d37143dfe1e62d394c18c04954f7396ac0 +dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=65de9bf3cfc8ac6910953b2d3b2e9de532220f692519875e7da50a6493500fe5 +dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=26a6aec0f92b238c4d75c9eda3ecbb8bf0f1628ea5bdf52941e7b5ca398ec03a +dist/2024-10-16/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=7a4b72ba1d507f418b30d7a110eb5e9025872e2398f0aa68abbef150f4c49ef1 +dist/2024-10-16/rust-std-beta-wasm32-unknown-emscripten.tar.gz=cf04dc8f1df723dbca4fa3a1155dc3bced6b3c96588bf41f6bcc196b74ae19cf +dist/2024-10-16/rust-std-beta-wasm32-unknown-emscripten.tar.xz=4fd17a62d10d27c13818cc3dbe1c62aa85d9c7123b88310d12cc40939010ec97 +dist/2024-10-16/rust-std-beta-wasm32-unknown-unknown.tar.gz=64ddae5e3e08ede16960f50595c4205de9962e0f5b8de9de5df1e9a8946bf66a +dist/2024-10-16/rust-std-beta-wasm32-unknown-unknown.tar.xz=0d6449807c02e1ef817fa2d378e77d9becd3a1560192bc9fdfad84cdee5cc8b3 +dist/2024-10-16/rust-std-beta-wasm32-wasi.tar.gz=c4ba753891162f604effac480ded4c536f294e39768f41d7b4fea1ab28c71be3 +dist/2024-10-16/rust-std-beta-wasm32-wasi.tar.xz=46a6f680f19ee2ddeb41e7aa13bb91a893ae27ae89ec41c36094f6e4db4a3e0d +dist/2024-10-16/rust-std-beta-wasm32-wasip1.tar.gz=3f89ca539044a79abd2b25f12d08ae954a7fcdcdf0288239c57d241b225776f9 +dist/2024-10-16/rust-std-beta-wasm32-wasip1.tar.xz=18a922eb41f5c907bfb624d18ca882dfd569f6775105dcdc29e7c7eb49187859 +dist/2024-10-16/rust-std-beta-wasm32-wasip1-threads.tar.gz=6dec5910a96e7a8e0713c109c993df44094e03fc8ac90b1a99f72dfdf84798f7 +dist/2024-10-16/rust-std-beta-wasm32-wasip1-threads.tar.xz=00e21ba70b0ee2760dcd51bf68f6be74c5cf38fc301476f406bf1f1d21ae7503 +dist/2024-10-16/rust-std-beta-wasm32-wasip2.tar.gz=c0b620ffb0debcd0f20155b1be250627450f14b4f62b32d9d9e4ee4c4e57cca7 +dist/2024-10-16/rust-std-beta-wasm32-wasip2.tar.xz=4d14c5de2f92b67c99e6fd2342d4ee968805d9eb68d4f9d1f549bb27e866f3b0 +dist/2024-10-16/rust-std-beta-x86_64-apple-darwin.tar.gz=b3ffba3cdef26174462e65847414458eba1c6aea63a78f6087497a04b427295b +dist/2024-10-16/rust-std-beta-x86_64-apple-darwin.tar.xz=1923ee9008ca30677642d1e66463555ba6fcee88dc0ed947e0ece7e4ce4efdd4 +dist/2024-10-16/rust-std-beta-x86_64-apple-ios.tar.gz=e8f1cd196c5e3b10a58f640cc8bdf3d015e1b23d49724112aaa7e4019cf01107 +dist/2024-10-16/rust-std-beta-x86_64-apple-ios.tar.xz=5fec3b22adc67fc6e4ef2cb873d446cb1520cfcee2ef4248e3dcc2816ada683e +dist/2024-10-16/rust-std-beta-x86_64-apple-ios-macabi.tar.gz=852e5067d47ac896c18e424cedcb984b0b4724b7fcd05e550151de2781603737 +dist/2024-10-16/rust-std-beta-x86_64-apple-ios-macabi.tar.xz=2333f02b870c6e7b673f5e8e166bf9166c3f6d1586daafa4eeb626d8de5b305e +dist/2024-10-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=5c2bfde266aefa83ef9e65448900f4aa73e1d91de3719ada2512230a69090e2c +dist/2024-10-16/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=218f4a4861812e38992bf261e390e95fbe67402f89827e6ac1b68fa42c705166 +dist/2024-10-16/rust-std-beta-x86_64-linux-android.tar.gz=5cd9859a22f77dffae58fb6573a8f5e23dc75bf030f54c152714777e5a01eef3 +dist/2024-10-16/rust-std-beta-x86_64-linux-android.tar.xz=be754bee393794ac427718b687f5e4aaf61aa1544795ed0da0b9d20e77e45803 +dist/2024-10-16/rust-std-beta-x86_64-pc-solaris.tar.gz=556f48c0ee8276bc847f3519dc0dfb72bd11cf27add709815da47f5cbb48716d +dist/2024-10-16/rust-std-beta-x86_64-pc-solaris.tar.xz=aa185610d66b606913d1102f62b62c5bbf9c5baf2e091d14d37c30b1526fb583 +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=1a7dd15c91fb1597593b27dc0b72bc0b1a6e758935efae3c9db714cd624d7639 +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=be18c0a1f2d0a1852c81ac1619a01d04d0c8c22472655710f643d86cb559508d +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=e18f210cfe890af8285da5f99cc476770daa78cddb7f8213f7f26f66111e17ef +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=b207877400dbfad09b6a3c2917516b63faa159f922ad03911736634ff46898d1 +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=6f277d2e2e9a9057e2a2c8045c3949ab36ee8ed58b64829b10470e0c6b111671 +dist/2024-10-16/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=51a102726ddf492dbc530437047fcb4d5e542dc4ace0e64da21c7ec79ebc001c +dist/2024-10-16/rust-std-beta-x86_64-unknown-freebsd.tar.gz=eeb6a46dd78fe3b477454c256ba8486b906e7a7ed044e686bd4f8c868265bd90 +dist/2024-10-16/rust-std-beta-x86_64-unknown-freebsd.tar.xz=67e103b9742ebf2798fe8e2647a6755a1d253301fea13a5193ced5bc394b9a0c +dist/2024-10-16/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=b42fcd18458cff0ffa0902a0797e9b42cdf9475f5e84279972e4010608a14ba3 +dist/2024-10-16/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=878e3950e0aefbd5c5c155f1ba2a4e8abebab10e3e77311403fc2c475e6da9df +dist/2024-10-16/rust-std-beta-x86_64-unknown-illumos.tar.gz=d72be5ca5fde3ac33da483058b8132707c93647652245864c988158e6dd70ca1 +dist/2024-10-16/rust-std-beta-x86_64-unknown-illumos.tar.xz=270959bb47366b7276717b677c5303ba0d579c9fd1f98fcf3774ce033caf0015 +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=33370d376f3ecd80ddb5f614eef222c601e2df5dd18ae98ec034922790f56218 +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=061a262fe98e6e1b41df6f9f60367259d44215f528938574098ede8698985c94 +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=70328a15c8e29be07f248bb073336f06eba613c377ea4e98a1e0a4abe5e2eb6e +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=ac389ebe5ca69cb382fd104161c9068bd8aa4d28960d578f2d925faafffb61da +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=22d350bc0718b999d88e715cba73ef1860e1b1b8efac026f46d9050952d739b3 +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=0761b9cb94210ee40fd0dbde38cd049a9e727a73da4ebc2cf10e5db92e6860de +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=35f975847adac17d19abba5385b951ce2015dd8b62ce4b0a716ac612808cc9d7 +dist/2024-10-16/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=5a9679805c1bdfa835aee94ed0d3ed4d2b4d0b6a8e2ec4471fcbcefd331cb200 +dist/2024-10-16/rust-std-beta-x86_64-unknown-netbsd.tar.gz=e4269be360d9823bccf6f7d71e4f51feeb8e955c7851d5bb6527055d709b68b7 +dist/2024-10-16/rust-std-beta-x86_64-unknown-netbsd.tar.xz=58880cc63fb93bbbb78fa4268eb69b37464b429de2f007abf05f5fd7c53aec8a +dist/2024-10-16/rust-std-beta-x86_64-unknown-none.tar.gz=42c77c14c433f43a092bef5ea0cfa60aea747301a9499c66bdd81d7998a74143 +dist/2024-10-16/rust-std-beta-x86_64-unknown-none.tar.xz=0cdfb3cf58d8f6db3bd65f4848aec8a431ffb4e1a5f79e56ceafe09849a96ac3 +dist/2024-10-16/rust-std-beta-x86_64-unknown-redox.tar.gz=35ba471138c115ac3e1ac3560fe8590038cb6002d22a45dd92f09a868270d223 +dist/2024-10-16/rust-std-beta-x86_64-unknown-redox.tar.xz=f250b60b52e2f84864406a0ef7e2f8896e1373f4f14f555a47a2019fd370f553 +dist/2024-10-16/rust-std-beta-x86_64-unknown-uefi.tar.gz=7332cbab92c48611604eb13ac025b845fd0dc0bfe838a4edb02f8266a5245aeb +dist/2024-10-16/rust-std-beta-x86_64-unknown-uefi.tar.xz=7cbef4955ee702d845116c59742194b1019d67f564145cf809ecec67245ca8af +dist/2024-10-16/cargo-beta-aarch64-apple-darwin.tar.gz=59321dd2f962c7b14514fdf1ec96907c16735a03a799479055f40f17883b8b6e +dist/2024-10-16/cargo-beta-aarch64-apple-darwin.tar.xz=336c7dff9f3a1d9de819a32f62eb518dd94d45ee591afb01d329127a2146c3fb +dist/2024-10-16/cargo-beta-aarch64-pc-windows-msvc.tar.gz=00c53e3a327909882282a32850c82e4aa18508a5e355532951d380e985b75c79 +dist/2024-10-16/cargo-beta-aarch64-pc-windows-msvc.tar.xz=39d09b49740b0512a84fd5351d473c5802de30721f621cf99ccd0178d8eebd60 +dist/2024-10-16/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=dcb522627c49811d2e6eb133725e301089a4942da1347721ea28f2cdd670685a +dist/2024-10-16/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=b9ce402bb130d35e482ee360f8f142726ff51bac3954aeed14800eef0bd96f6d +dist/2024-10-16/cargo-beta-aarch64-unknown-linux-musl.tar.gz=670c0b78cd5c985e6bacb2bb2cc3a5a2478c2623992c4cc35d0d4c624e1b4b16 +dist/2024-10-16/cargo-beta-aarch64-unknown-linux-musl.tar.xz=8a936c0c457a1d5c659611e7a69fe9934313d9ceea04c0a0eb393e28544ce7b1 +dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=10150caa2130a73443942f1dde7c849172b57b7b9e07e8939cd6c126c701d7d7 +dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4dc0ffb898e66661a1b9844b965a0b0ca115bd6d9bb25fd5c5df022fdbeb56bf +dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=6db24d0a3eb7de6e3d40dceccf6a92ed86e170e0c4dd2ebc9702652655ad664b +dist/2024-10-16/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=c5699a6a4ad49c34a77c94a4982b1a0ea7f6dea84d2771c24fdc05dfe9d4cdb4 +dist/2024-10-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=f5621b39e7608e8461b559f3c3e57969e7eadce82798b395ba41e6302b2e0283 +dist/2024-10-16/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=d7f62c0ac375f56d9ebbd0edbfaee4684d7d47ed8ad38bf7d25fb75a5770bdb1 +dist/2024-10-16/cargo-beta-i686-pc-windows-gnu.tar.gz=b895fa9240c3a6c089cde6b08a21408b5a6f38818c4a9cf25394b17e9610da96 +dist/2024-10-16/cargo-beta-i686-pc-windows-gnu.tar.xz=e26de92566339b932cdf4a4ee90464f1f3863d89534c03a3c9f9a632a278993d +dist/2024-10-16/cargo-beta-i686-pc-windows-msvc.tar.gz=ba64512c0732f5821ac4d1eb7fb53c0f340847c0cbc7dd5f88f67e03bc3f58ee +dist/2024-10-16/cargo-beta-i686-pc-windows-msvc.tar.xz=cf9872ad8ce5621faf517c2796620f24c1a99bccff7f328b7e7650e89e604b22 +dist/2024-10-16/cargo-beta-i686-unknown-linux-gnu.tar.gz=23496080baad6b976f8680b7f6c856461a410a4dce5c66a41cfa220d9479cd95 +dist/2024-10-16/cargo-beta-i686-unknown-linux-gnu.tar.xz=9799594bddbe1e04e1d625a6ead04efdd4749d4f0773585d21ba2be6636f0bee +dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=5a1b95969f002c25717751337951aed39e6f6256ee58acce150d5ffaf0046300 +dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=36bab05ec8b39c7e230ed78f64b2680ea21fa9f7997c980c22edde61c0799b5a +dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-musl.tar.gz=19bfbd70b98c0bbbf29a0a796572d1661b8902132087173ca0e6aaadb4d51d09 +dist/2024-10-16/cargo-beta-loongarch64-unknown-linux-musl.tar.xz=629e42e188447a392bfc7cef5fe04c31380ee30523dc0bc33b0f3c02bd2fd82c +dist/2024-10-16/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=5d8b1daa253ebe0750e6f073b8367b053de09b4f209327d4114bfa60b2bb5602 +dist/2024-10-16/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=545d7ad3b7b0b5d2ec0b4bb70b7e31dd823048d6087d6c3fa2139f307ea35fbb +dist/2024-10-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2111cbc7586a1e58dc7e6e54a63157f9606f5586c7bb72ffa15f1a94284d4c97 +dist/2024-10-16/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=0d6702d3ec5a6aa9dfb06d565e4e16b27cd3d445871bf2344c876d7ffe2f8a32 +dist/2024-10-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=0f750831b518b452a2ac17c9bab3a02f30f58bba6ffcd962eed06012102c7b31 +dist/2024-10-16/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=6d476e16109e9bc5dd055c537a9382ce154d2837a32bc2c165a1aec76ba1ba43 +dist/2024-10-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=850bbca95670afa1262b5d46bb02f0bb367c83f851bc2a9817f8bf2eda9bd2ef +dist/2024-10-16/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=f42b3b5cb506886bcfc92c0a7f3dd3d0668bdda0f2db657b98becb4c0e99bfd1 +dist/2024-10-16/cargo-beta-s390x-unknown-linux-gnu.tar.gz=f3a8541b3e6c12f350fcfbf43a8efb2a8bb48a62e055d9dc522d568b94476f43 +dist/2024-10-16/cargo-beta-s390x-unknown-linux-gnu.tar.xz=12c5411791c715562c99dd211095c9924142053d510e17e6ec50b7b8b927eda1 +dist/2024-10-16/cargo-beta-x86_64-apple-darwin.tar.gz=95885bfcf5fc1de80d0f9b5415dd261136d5577b7d61716c184a6c6379acca21 +dist/2024-10-16/cargo-beta-x86_64-apple-darwin.tar.xz=881c9d88bf2a848f5b5cd61d18068e2dda3542a65e93ab373e3a047cc30369d2 +dist/2024-10-16/cargo-beta-x86_64-pc-windows-gnu.tar.gz=c04ca1768c5925d5c7e19d5f232adbda355469974b19a2a130a6967db94b56c3 +dist/2024-10-16/cargo-beta-x86_64-pc-windows-gnu.tar.xz=bc02593e98f5393ce2032fb605ec2bc053a1a19311a5a80d27c3a552ec8b968b +dist/2024-10-16/cargo-beta-x86_64-pc-windows-msvc.tar.gz=8ffb930c33ad454806f2f61a10949a3fa5b92b9313454927dbd76928955ed7f2 +dist/2024-10-16/cargo-beta-x86_64-pc-windows-msvc.tar.xz=ef0bbe8512b3dc9bdc9f3a47abf2834bcde1fd7f59e319f7c7040b7100ba1f8a +dist/2024-10-16/cargo-beta-x86_64-unknown-freebsd.tar.gz=eb21f7739dbd7c120dc9552360e8aa6e1e0eee14d80ea16e3dcecb9e94efe7c0 +dist/2024-10-16/cargo-beta-x86_64-unknown-freebsd.tar.xz=9e287f3d0c7e402dbc121cd737fd2360dfcd97fa886770aae93c07474494bb77 +dist/2024-10-16/cargo-beta-x86_64-unknown-illumos.tar.gz=1cb86b6953ec99e95d92d61ead263021d16921cfe6152b6331efb838c46be85c +dist/2024-10-16/cargo-beta-x86_64-unknown-illumos.tar.xz=c356e671ca97dcb4d945567e33f06911d5269fdebc19fe83a9313f574d446576 +dist/2024-10-16/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=7613e679837e2769b9e8df5b8785fdb7e51665379e64547bae9d6015eb8e45c0 +dist/2024-10-16/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=39ae7207f84ee3da16ee11271070e8b82d2991cde29771d5154bb2957d9beccc +dist/2024-10-16/cargo-beta-x86_64-unknown-linux-musl.tar.gz=4dfaa69f4377bb724eb7d1990aea7ac219a960b690601769f8e06b72f59f86b4 +dist/2024-10-16/cargo-beta-x86_64-unknown-linux-musl.tar.xz=4cf72f3f0048e8cfb2b05566cbc1d76e9730cf1f71f9d0f3a71bd9379f30b08c +dist/2024-10-16/cargo-beta-x86_64-unknown-netbsd.tar.gz=e1d3ff748dcf1777bc2d999ec82f0b8a67295f91a9cb07a9c1123cd5424928c3 +dist/2024-10-16/cargo-beta-x86_64-unknown-netbsd.tar.xz=7e21e89e218118d536d489d16e77e667df7ba7c809135ba179e7097a2243df5d +dist/2024-10-16/clippy-beta-aarch64-apple-darwin.tar.gz=244ed83cac923e00647cdd3aab9d0479cf420991e9e06eee5ffd8acc9e5a199e +dist/2024-10-16/clippy-beta-aarch64-apple-darwin.tar.xz=6dd93a671fca0efb2d3b8cc461aba66483624327a382fd714a526832034c8438 +dist/2024-10-16/clippy-beta-aarch64-pc-windows-msvc.tar.gz=56710fa9c7d46fb881903e08e407c258e3ffc75ce3de0226dcdc3709dc59180e +dist/2024-10-16/clippy-beta-aarch64-pc-windows-msvc.tar.xz=6ee782709786c310fb1e887cc576e7e61b0a4b120f6a46c7dea1e2f2bf7dad1d +dist/2024-10-16/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=06f0ee2195349921d1ae791fa1628fceaa7adb377968fa09dbe17aa77c762a47 +dist/2024-10-16/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=6e792e91db8b54e0cfb9eaed8187b5202ac5d5735ed0f73080a6a73bf15ce683 +dist/2024-10-16/clippy-beta-aarch64-unknown-linux-musl.tar.gz=bde52962b121472cd1b755c506b9362ff88ec582cb3fe9d307948c51f4d96f1c +dist/2024-10-16/clippy-beta-aarch64-unknown-linux-musl.tar.xz=70a06d5b8175d078bd246adf45f3058d362f0b128f1dc11d3797840b28692bf5 +dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=ab8b54d8436dbc6af279a048d2b75eea9eabfa369f23c51fc1c47388f642a755 +dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=a2715009144defc9aea3ff0d6a15485d8feedd37b333658470d479600fe87ffd +dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=a1863b47208051a231f9571bdac3628d8afdfca7eac3b1cb7a04a843c176ae80 +dist/2024-10-16/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=a5926e8e3e2867a8fa87db77dc26bd18734f84a4a685374dda07d50d21068f62 +dist/2024-10-16/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=f70eabd386aac93c676485bd42845e62b34c034b8710bf0db24a440c03b15bce +dist/2024-10-16/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=cfde41ebe7398d0858bf507b9322c5f4959becd5a3a4624027b4bf3321730a29 +dist/2024-10-16/clippy-beta-i686-pc-windows-gnu.tar.gz=3d988126d6a0ed9133b73b8aea3b16d6355db8ad83254a7499f7dc3b414d62f8 +dist/2024-10-16/clippy-beta-i686-pc-windows-gnu.tar.xz=6efe88aab2daa0c7df17bbb449c2b815e085ca7e859b17bb578978d18ca2ea04 +dist/2024-10-16/clippy-beta-i686-pc-windows-msvc.tar.gz=2c2eb32ebe3ec89a985c07ce87cc1dbc627f5f8588aeac72fd381c6e19034095 +dist/2024-10-16/clippy-beta-i686-pc-windows-msvc.tar.xz=fe2d2ae70e0ce102794450d4259b706d3bda2c5b05bd21a863b2ecd8ed54274b +dist/2024-10-16/clippy-beta-i686-unknown-linux-gnu.tar.gz=0d633381b174f04523f13cc574e79af5041a231aa61b0befc406c7e3ccb0ebf3 +dist/2024-10-16/clippy-beta-i686-unknown-linux-gnu.tar.xz=029558aecdd4862dc74ce9726a462f1d34a7e2a6eda5bf791995dfd6933096e7 +dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=2bdaa7f730f30db62ed0661f135227c54249786a78a8022428ead03766c9e29b +dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=2a4f5982eac9cb5e8372d35c13a7832d532a31e5c38d13b0643d16832e1e341e +dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-musl.tar.gz=a9a1fc5b74e19a567c45ce1789c7bfd50b28774bca8320886108e4a18a1d7765 +dist/2024-10-16/clippy-beta-loongarch64-unknown-linux-musl.tar.xz=9e957652f80b2de14c5a8f5faaa5662d0ebd26e18b2bc5d248587d72413e483b +dist/2024-10-16/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=a9fa9caea0f784ed096b3ff204a8261126102e05456c52d544c7036f9ee30c41 +dist/2024-10-16/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=0e3d3472e3e73b02aca8797ecaa2471e472d361b0c44126e4bfc2d25a8fad96c +dist/2024-10-16/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=211c52eed69942aed1e6b1fb4799232ea4fd3f898a44a4bb6343336e89dfec74 +dist/2024-10-16/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=8c07b34223e465e17094b7e20efdbf8ec6ef5aa042485d3cfbc6ef58dbca0be9 +dist/2024-10-16/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=b3fc3cc6e81ef118eada3c01fc3535dfc622b92377d8e735f80d7661b4b847fb +dist/2024-10-16/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=e885c534589fac79046bb31b92aefe7674dee13c8df1a456e91ca63e9d92c6d5 +dist/2024-10-16/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=fcfbf29d105ade4a6d7537dc44d01c6de2de70d066afd8ac3af58bf3bcb6f7d0 +dist/2024-10-16/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=a5425df8cd724fd992de26434090e157e9d148d063161bfb43789d6b4234ad02 +dist/2024-10-16/clippy-beta-s390x-unknown-linux-gnu.tar.gz=ab96fc1c538a9a526124bc2cf3e97edd655f29f8d6d310b3b5f017cfbe6311e3 +dist/2024-10-16/clippy-beta-s390x-unknown-linux-gnu.tar.xz=096de4e9f80f40a294dfd1ba32e9de038c3449b2760189a5c9e46cf8e36dc0d6 +dist/2024-10-16/clippy-beta-x86_64-apple-darwin.tar.gz=5614651ef2acd5ce1d43cc2504d353e471d9c8c425c16e3649f81e1cef44b86f +dist/2024-10-16/clippy-beta-x86_64-apple-darwin.tar.xz=26e39442af2251c52bcd275c7ae25a88211ec2f582bbe7a29724f816768c9781 +dist/2024-10-16/clippy-beta-x86_64-pc-windows-gnu.tar.gz=b2626513cbcd9b1456dce8543c2b11458eb052434f9ca84a6e926a77e5be2362 +dist/2024-10-16/clippy-beta-x86_64-pc-windows-gnu.tar.xz=87403c11e1b92bbbc2651183b2b480c41d9c7e0fa6f08551702c6ab308fbbf5e +dist/2024-10-16/clippy-beta-x86_64-pc-windows-msvc.tar.gz=929029e67d34bc813061c524490b8f0030d31097fc1fd439acd4d8c3545589a1 +dist/2024-10-16/clippy-beta-x86_64-pc-windows-msvc.tar.xz=1584df60f086c6af01f06023236f612bf59be9d5b991bd09ed66f4c505737533 +dist/2024-10-16/clippy-beta-x86_64-unknown-freebsd.tar.gz=d5ee8cfefbf164d33529f1a777437f49216e93173a2ac04b605e74fea89fc6a3 +dist/2024-10-16/clippy-beta-x86_64-unknown-freebsd.tar.xz=9469aead14fc03ebe984e51bbee0db6d1cd8e877b67ca361c44939e2464a95fe +dist/2024-10-16/clippy-beta-x86_64-unknown-illumos.tar.gz=79bd918b2a391cbeb885b7075b1e0534054c81784c332a2aa8539d0e1cd15f69 +dist/2024-10-16/clippy-beta-x86_64-unknown-illumos.tar.xz=16b808026a4fdfaa85a4ac01b01b4fc79c4824a651bd4e412e4ee9b0011eca4c +dist/2024-10-16/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=62224af7a1831140fc3f06e7e918191e9443751549ec5c96afdcb3ffb5b18e06 +dist/2024-10-16/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=78bab115fa696fc95d911655575032fc9af324c8b6df136044f11681239e5c41 +dist/2024-10-16/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1a76ea2b1596acd396585d78d01be5d3b795641d7b20f84379cd2c344e7536e9 +dist/2024-10-16/clippy-beta-x86_64-unknown-linux-musl.tar.xz=63ac980b41b0a3b744d94727af6ee1679b8bc4c50db4ef68402d0253b1852ffb +dist/2024-10-16/clippy-beta-x86_64-unknown-netbsd.tar.gz=eba61354aecfea64815a68b569122e029501d85876d37f5ea4119f36f932e146 +dist/2024-10-16/clippy-beta-x86_64-unknown-netbsd.tar.xz=37f9395e78a2bf2977b38929b9511e9668f26e23705d025609f028b282aeaee2 +dist/2024-10-16/rustfmt-nightly-aarch64-apple-darwin.tar.gz=05cc308cd0c35063b43a45dab3e84001e2d580b10431c74899a86cd8971e5b36 +dist/2024-10-16/rustfmt-nightly-aarch64-apple-darwin.tar.xz=aede50889786bc1e902162b9347cf59ee67b15e902b0ed78d7187d3c24a7c4a0 +dist/2024-10-16/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=1c25ee283dbc720b471d435ed952e6d794ecacafd4c889a2ad8d43725cba8ded +dist/2024-10-16/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=67602978481a53b0b4681523d94bf79ad731a369cc088c3b0adf8e7d54b1fbce +dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=ed7c9c38071f9d1e632104ff1d9a9407efec99d74eabd127db795c56e84b9d73 +dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=65ee60bfefa1334cece9f5da72789d90b4b5918e7afea2b47aa4d1450d9a1237 +dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=e92d5ddf80c94bdc34697bec4d7a1b1ea677e5fc6c68c41059a7829e53e95505 +dist/2024-10-16/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=2f1737178817318d1543deabd865aa83a1f395a36cc83e3717157b4dad827f22 +dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=a4be0eb92a011ed940db67973d5fb62c4b5d3fdd52a08981223c5fa5278826b5 +dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=a47b2dab4f20f53e6c29fbce06383144a67ece61a63f33c3fb86beaabfe4bce5 +dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=7bfef0a8b7cb4a905ad145311c320a8ccb2048e806ef68688a1423009770b35a +dist/2024-10-16/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=d944161b92bdd74f3ba533b94b67a3a361a01b82fa5c156710608f00c46913ec +dist/2024-10-16/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=46a46ad32e2829550e301a84212f057faf21bf67ff6862f77f11cb0e13f80453 +dist/2024-10-16/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d917336a949ad5a5f0fcfe1ef261d87d4dcbde22b467258543c50715a9041d64 +dist/2024-10-16/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=38a9cd401774ff1d832e536ed0aca9a3f0d5593814bd6db9ba4f8341a5545fd3 +dist/2024-10-16/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=fa2194663d11d517bbd67c157fc40cf67149246c391e9b8adf0a46c2eb96c860 +dist/2024-10-16/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=c5271c244d8055401d3d3a97873064b93915dbcc52108cb9b61381af1ebe99ad +dist/2024-10-16/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=56c6a0cedf3ec4667d65a209477cfe0d395e534654b49e28efbd3836e8a0dae7 +dist/2024-10-16/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=c4325b80bfc63dc58c4632ede188efdc94aa4cad49abfa4e57d81faad673a35c +dist/2024-10-16/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=35b4fba91cad3bf9e627d59baf1f1864e30d002b05696c61498e73fd0e0f299f +dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=b2f856cc81be2c6f2c4250ec88cbab0a51c3d59e73fefd66cae9b1a91a32b0bb +dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=1b1a40377a8a13b74f62f5bb382cb8056930c543b97261d32613c53826c758da +dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.gz=98b1f0fc4f45eae47a6cae7e7d4d9734979d8f860c7c96da281fa1d9ed3ca39f +dist/2024-10-16/rustfmt-nightly-loongarch64-unknown-linux-musl.tar.xz=bae7dbd1342d5aa89c335f1dcdac0d93f5cd8198ce9f869ef4c32dba8bc6c0d7 +dist/2024-10-16/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=cb5dc166002aba8a95f7e10d2d9e93a66d51483540c7e733b528bfccdbc74d9f +dist/2024-10-16/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=c070a48d0aad7ce42cfe5eba9477a0f54a9e04c9ec5c770e91bd2db55d0d764a +dist/2024-10-16/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=424c0d9a047ac228cfed286d0a2936b857e1c575ddebd931ca634e0501c125da +dist/2024-10-16/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=b067b3d095a5b53191ff148d0e89baed0b53c2099142d885961220548b904c52 +dist/2024-10-16/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=01acab58a327ee34d100e67a4a40a9efb66a64d478d6bcaaf94ce35874296c42 +dist/2024-10-16/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=c1a715f7502ef54a236d4ebe15488ec4c1c5cc5b1c50eea416a5b9c57de66f53 +dist/2024-10-16/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=cb014573a52f2d6776e47f3f728ae1e8b05feac2274c5916b1545675e658fc15 +dist/2024-10-16/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=5abf6bf36bcb57c0492e9bb4953ef78a61acf347d20ab788b4b31da44ae3bd39 +dist/2024-10-16/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=0bee2c4ea3f8ba07c189f7e2e0df1b2627b7bb638823fde2839d46a353e0480a +dist/2024-10-16/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=df352612d69dff13b59da185581a48062e54ee07161b1fe205b92d0687a4e896 +dist/2024-10-16/rustfmt-nightly-x86_64-apple-darwin.tar.gz=b7b44f5fb37fac58a83c2220a68c251513fcca96c51a71b189152a78cf095cf9 +dist/2024-10-16/rustfmt-nightly-x86_64-apple-darwin.tar.xz=f5876f1d8181880e4ecb71eaa2477b0431dd0bbb45e6a4da8f20bc31426cb43d +dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=cae33e30d7b2e5589a6fe681345f6edbf406aa803d0d521ea182a575ee32dca2 +dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=21324d7c6949bd12c841db8904d9485dd709f8c324e7aea31f2a9eb2a32844c0 +dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=cfccffb90721492cc79212ba49dd88361c6d38eab24ca4fbfd8110c2eefea001 +dist/2024-10-16/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=05c528e683c40467ed3911ec5f852914e117fd71e8a0826f17d91295d4f1b047 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=97cd5e773bfebd3e1d78dc3d486a75b969e30f1dd0311d07c337440d275d0443 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=19989c6e9ce4d67e068d449b92dfedd8e07bd1a287cee0410f43aa43432346f9 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=c3d8ed4650b4f7902a8643bfee849926892aea2e664400b858f61000966042cd +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=6b0dce2bb77036d154d15ffb2495480ed8c8cc441dc8979b4fd767af80e0736d +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=de7b427a783d588a778a2301a1bf8e4fec076ede2006e275f45d82a87e965feb +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=43fdb72c7e74c86eedbb01631ec357c2cf469512c0c591d15f35f747bcfbbd30 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=3fccaaf7106f47302eb3c489dd722a91727e25351278a17f81d06fbb4cd4041d +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=988d6c342a4561790d1024455be643e17525ae07e02fe5238fc61d00c91d3cd6 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=71c10377a84b3bd612a83cd2822bc6c0eb4a540c681114d63be368da84ef3766 +dist/2024-10-16/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=1e6a3c7080334663ef6fe246eae3482a05446b83c8a0c659084ca8186b9cab01 +dist/2024-10-16/rustc-nightly-aarch64-apple-darwin.tar.gz=e68c96b5d6fc204944cd1bfd80e2c6a8332dedede98a968e170fa657e012ec1f +dist/2024-10-16/rustc-nightly-aarch64-apple-darwin.tar.xz=9f7138fecf991a17483e0359c7a5a0b4292cffeafdd4b52b7c1021cbf993ec5c +dist/2024-10-16/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=0f31c36e6b6b765e9814dd193861e2ae2a176160f22aaff6211a6da3efbc1fd0 +dist/2024-10-16/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=ab4cbc70a6002bdba2955fbbdd99f03d3e54d14d32bd2f7250be6a323f39dfd9 +dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=e088594f42b88494401df68cc60b8d94a4c1199e3549aa6dffd513b0c5f7508a +dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=a204d11814dfb6a3283ed84abf8b88492283eb6cfbec018a0f249d496e2db5f1 +dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=802ae62e1023c460739670a12b8a331637cec02aec14769bf0bbdbad44217555 +dist/2024-10-16/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9ab24e33a80a442a540720377855710c2b33617531daa625dff537d1251bb9b4 +dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=08a139d7e1ad8559d3add81416581984d24eb997f5d03f2ea85a76eac62df57e +dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=dc9dface28b81a1b241a6ad034cd910221866cff7188d94929bd80e3d2dc1598 +dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=ecfb3225d805cb7faeb185e43471b35decc735c1330bcb45d54cbb93fac0db4f +dist/2024-10-16/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=60437f2b7cd51cebff36687bc904c7493ef834e39033c08e35883b3de03ed15f +dist/2024-10-16/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=aab495b49ad218fbaf6f36e0dc82ae76dd867ca77411568f15039e494154d890 +dist/2024-10-16/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=51648f6d14e8684c3f258ede3e97371c1530be584b5bc47a92b7bce84d70b397 +dist/2024-10-16/rustc-nightly-i686-pc-windows-gnu.tar.gz=6bf818c20105a30461336053b40b9b298388b341766536137a3fd6039e7885ad +dist/2024-10-16/rustc-nightly-i686-pc-windows-gnu.tar.xz=60346687b8359a3df7bc4d7beb5532be716bb699fe8aec76664b5b5b4d7cacfc +dist/2024-10-16/rustc-nightly-i686-pc-windows-msvc.tar.gz=48b542959792f1cb4c316ee417fec68ccab0ee76a68accbe667fc56ca9d5a367 +dist/2024-10-16/rustc-nightly-i686-pc-windows-msvc.tar.xz=b83ebe192f8e2d82fdb0765952e69e4234f11fd6a0a4a69d089b2df42a3c637f +dist/2024-10-16/rustc-nightly-i686-unknown-linux-gnu.tar.gz=03b36beaf28462424b3b70e6a944d24a22a551c4fd9c245cfd5eef464047ec30 +dist/2024-10-16/rustc-nightly-i686-unknown-linux-gnu.tar.xz=e00e81bfca624087f97ae2ff675adf08a72519240e31cfaf0f4da238d7be8050 +dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=f71e27157be06043624ebb769cffc92593d4db6d2a9edabec6815d0f9be64b9f +dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=5bd77608b891be20b38739d2b1cd4319feeb13f92214e550a01c599349fd6ce2 +dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-musl.tar.gz=0cda1b3a287843431991468cf8dea7a34221d42153e9421ed89a8f58d048e01b +dist/2024-10-16/rustc-nightly-loongarch64-unknown-linux-musl.tar.xz=57f3a4d73a40ffe0dad530334f2e584c1279ce3b81458023f034bf8c35dc6641 +dist/2024-10-16/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=5d7c5164b12ad921f1d8461d0edeb17566bf4d5861d6b0f18f66ac1a91b7306d +dist/2024-10-16/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=8ba849b777182977ad9b87c002bff49ff9ad2007932abab98509e96274b9c7d9 +dist/2024-10-16/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=03c12e5d01a6f0b66dfd728610fc0df2f3bef8d5cf418a4d5a385b11f35ecd81 +dist/2024-10-16/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=db0b2d5a9a12c9c8aa0d5d3a320ef8f815ea2ac84718e1bbe94514e7480db6b5 +dist/2024-10-16/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=2e3a85da6e7a74b079a5bbbbcd433e0271b89b873aec22c19537669bd908a98c +dist/2024-10-16/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=2b19af7ec21a9e442975b073455e4b3a2711832f6f4a521335034f47dd7725e3 +dist/2024-10-16/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=c293489afe56e4ab984bab7c0ea8db292464b1b0a83b3efac3d38079f71303b2 +dist/2024-10-16/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=fad8d9fce164461c81c5fca56c3557e76635f70ad755cfdb1a448faf161a6b02 +dist/2024-10-16/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=1a4d7fb7e5d74649270e79fcdd5b7686bf3db6985d3a781ebb1f069404639884 +dist/2024-10-16/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=cb1ca19ca8a99b68a1665937c2bfde2a275ff2746cd8b50e097202352a0f7cba +dist/2024-10-16/rustc-nightly-x86_64-apple-darwin.tar.gz=32d6c59ee1bb8d1449393b37ae9399d24ecbfcaa6dc5831ad2bdfb3a586c8ab9 +dist/2024-10-16/rustc-nightly-x86_64-apple-darwin.tar.xz=5a9237c1b359da2c6aac0d6c9202f527d5982310477c414c3c03c6eee50feaf3 +dist/2024-10-16/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=9b03ad10b3e5de01a813fd9be676135de072de0d3fe6db63e82ff881b9d81c51 +dist/2024-10-16/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=1e7b91da95fa7fba74c4f8937fc9e02b592c4a66260aab1a4feca24e136501e3 +dist/2024-10-16/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=59efe9285d460cf8080d3aaed31742cc7ae5dffebb9bdd3410be22a061fa8dc0 +dist/2024-10-16/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=e64edab835454e2024081b9c447798075cc2df3703a8b627d9661c32233c8540 +dist/2024-10-16/rustc-nightly-x86_64-unknown-freebsd.tar.gz=c1ceabe8ad4f89b401a72a6a02843a5f31267cb9762d1a8c30dbcb51c1967488 +dist/2024-10-16/rustc-nightly-x86_64-unknown-freebsd.tar.xz=456708749343846153490593eebc55d78ae347d0a1096d0fdbea19c99aa24d9e +dist/2024-10-16/rustc-nightly-x86_64-unknown-illumos.tar.gz=e01be583da5371501755ca0f6d44cd2abef40543d7d97448933e27ba0de78c8e +dist/2024-10-16/rustc-nightly-x86_64-unknown-illumos.tar.xz=42dca4d9e7d76109a3c963b5783554d6ce0171001d744f3fa6b5001bc6ad66a1 +dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=4464cc28f6a15d5a2a1de098f28224848d0b91779bb70ace3106f3a6208d25dd +dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=5f9b9cf42730255c27bef5187241736693b5e39de9fde935da25c9f33deb4325 +dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=d6c2b41d4fff28d12b254d3cdab480ac4a81054e50794b6cfb7ed30065cad5a1 +dist/2024-10-16/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=1acfe2f78ff7aa747e5b307b40ff5a8be5e8076897b78b2fb5828d1bb1d74cf1 +dist/2024-10-16/rustc-nightly-x86_64-unknown-netbsd.tar.gz=9d5bfab5bfb9e6d627a5acd1f54fb164538e84c449aa3ea15841636257ec7ab4 +dist/2024-10-16/rustc-nightly-x86_64-unknown-netbsd.tar.xz=dddd1663a821d99ea19864435e1c7daed6bcb4fd914e6b79c94d644836bc8d1a \ No newline at end of file From acb09bf741ba439356e824dd10a07054c6656fb6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 14 Oct 2024 14:46:44 -0700 Subject: [PATCH 104/118] update bootstrap configs --- compiler/rustc_const_eval/src/lib.rs | 4 +-- compiler/rustc_data_structures/src/steal.rs | 2 +- compiler/rustc_lint/src/if_let_rescope.rs | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 1 - compiler/rustc_next_trait_solver/src/lib.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 2 +- library/alloc/src/lib.rs | 2 -- library/alloc/tests/lib.rs | 1 - library/alloc/tests/vec.rs | 2 +- library/core/src/arch.rs | 35 ------------------- library/core/src/array/mod.rs | 1 - library/core/src/cell.rs | 1 - library/core/src/char/methods.rs | 4 --- library/core/src/intrinsics.rs | 4 --- library/core/src/lib.rs | 3 -- library/core/src/mem/maybe_uninit.rs | 3 -- library/core/src/mem/mod.rs | 1 - library/core/src/num/mod.rs | 2 -- library/core/src/option.rs | 4 --- library/core/src/ptr/mod.rs | 5 +-- library/core/src/ptr/mut_ptr.rs | 2 -- library/core/src/ptr/non_null.rs | 1 - library/core/src/result.rs | 2 -- library/core/src/slice/ascii.rs | 2 -- library/core/src/slice/mod.rs | 12 ------- library/core/src/slice/raw.rs | 2 -- library/core/src/str/converts.rs | 1 - library/core/src/str/mod.rs | 4 --- library/core/tests/atomic.rs | 2 +- library/core/tests/lib.rs | 1 - library/std/src/lib.rs | 1 - src/tools/miri/src/lib.rs | 4 +-- .../import-of-type-ir-inherent.rs | 3 -- .../import-of-type-ir-inherent.stderr | 8 ++--- .../internal-lints/query_completeness.rs | 2 -- .../internal-lints/query_completeness.stderr | 4 +-- 36 files changed, 17 insertions(+), 115 deletions(-) diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index cbe8a043fba0..39e2d3b4ebbb 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,8 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![cfg_attr(not(bootstrap), feature(unqualified_local_imports))] -#![cfg_attr(not(bootstrap), warn(unqualified_local_imports))] #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] @@ -15,7 +13,9 @@ #![feature(strict_provenance)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(unqualified_local_imports)] #![feature(yeet_expr)] +#![warn(unqualified_local_imports)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs index aaa95f6b7f19..0d79d98b5d96 100644 --- a/compiler/rustc_data_structures/src/steal.rs +++ b/compiler/rustc_data_structures/src/steal.rs @@ -57,7 +57,7 @@ impl Steal { /// /// This should not be used within rustc as it leaks information not tracked /// by the query system, breaking incremental compilation. - #[cfg_attr(not(bootstrap), rustc_lint_untracked_query_information)] + #[rustc_lint_untracked_query_information] pub fn is_stolen(&self) -> bool { self.value.borrow().is_none() } diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index cdd0e80c4589..58fd11fcc293 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -24,7 +24,7 @@ declare_lint! { /// ### Example /// /// ```rust,edition2021 - /// #![cfg_attr(not(bootstrap), feature(if_let_rescope))] // Simplify this in bootstrap bump. + /// #![feature(if_let_rescope)] /// #![warn(if_let_rescope)] /// #![allow(unused_variables)] /// diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index da603df9a9a9..f532b9b153b2 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1871,7 +1871,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #[cfg_attr(bootstrap)] compile_error!(); // Remove this in bootstrap bump. /// #![deny(elided_named_lifetimes)] /// struct Foo; /// impl Foo { diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index de74ac328041..d67ae2550d96 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -5,7 +5,7 @@ //! So if you got to this crate from the old solver, it's totally normal. // tidy-alphabetical-start -#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))] +#![allow(rustc::usage_of_type_ir_inherent)] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 51c887fc4daa..9e6d1f424ba4 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,11 +1,11 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] +#![allow(rustc::usage_of_type_ir_inherent)] #![cfg_attr( feature = "nightly", feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) )] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))] #![warn(unreachable_pub)] // tidy-alphabetical-end diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 50bf385d671e..12512f0dd8c8 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -162,8 +162,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] -#![cfg_attr(bootstrap, feature(const_refs_to_cell))] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(test))] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 3ec4332c71b3..301126b5d4d3 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -5,7 +5,6 @@ #![feature(btree_extract_if)] #![feature(cow_is_borrowed)] #![feature(const_heap)] -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![feature(const_try)] #![feature(core_intrinsics)] #![feature(extract_if)] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index f508a3e4c22e..0f27fdff3e18 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1288,7 +1288,7 @@ fn test_from_iter_specialization_panic_during_iteration_drops() { #[test] #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint -#[cfg_attr(not(bootstrap), allow(static_mut_refs))] +#[allow(static_mut_refs)] fn test_from_iter_specialization_panic_during_drop_doesnt_leak() { static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5]; static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2]; diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs index 4945c045bc63..57f456c98b3c 100644 --- a/library/core/src/arch.rs +++ b/library/core/src/arch.rs @@ -3,9 +3,6 @@ #[allow(unused_imports)] #[stable(feature = "simd_arch", since = "1.27.0")] pub use crate::core_arch::arch::*; -#[unstable(feature = "naked_functions", issue = "90957")] -#[cfg(bootstrap)] -pub use crate::naked_asm; /// Inline assembly. /// @@ -20,37 +17,6 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } -/// Inline assembly used in combination with `#[naked]` functions. -/// -/// Refer to [Rust By Example] for a usage guide and the [reference] for -/// detailed information about the syntax and available options. -/// -/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html -/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html -#[unstable(feature = "naked_functions", issue = "90957")] -#[macro_export] -#[cfg(bootstrap)] -macro_rules! naked_asm { - ([$last:expr], [$($pushed:expr),*]) => { - #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] - { - core::arch::asm!($($pushed),*, options(att_syntax, noreturn)) - } - #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] - { - core::arch::asm!($($pushed),* , $last, options(noreturn)) - } - }; - - ([$first:expr $(, $rest:expr)*], [$($pushed:expr),*]) => { - naked_asm!([$($rest),*], [$($pushed,)* $first]); - }; - - ($($expr:expr),* $(,)?) => { - naked_asm!([$($expr),*], []); - }; -} - /// Inline assembly used in combination with `#[naked]` functions. /// /// Refer to [Rust By Example] for a usage guide and the [reference] for @@ -60,7 +26,6 @@ macro_rules! naked_asm { /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html #[unstable(feature = "naked_functions", issue = "90957")] #[rustc_builtin_macro] -#[cfg(not(bootstrap))] pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 72f488789048..9b28b8b613e8 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -147,7 +147,6 @@ pub const fn from_ref(s: &T) -> &[T; 1] { /// Converts a mutable reference to `T` into a mutable reference to an array of length 1 (without copying). #[stable(feature = "array_from_ref", since = "1.53.0")] #[rustc_const_stable(feature = "const_array_from_ref", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn from_mut(s: &mut T) -> &mut [T; 1] { // SAFETY: Converting `&mut T` to `&mut [T; 1]` is sound. unsafe { &mut *(s as *mut T).cast::<[T; 1]>() } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 0945845021ee..e1fa43296d02 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2181,7 +2181,6 @@ impl UnsafeCell { /// ``` #[inline(always)] #[stable(feature = "unsafe_cell_get_mut", since = "1.50.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_unsafecell_get_mut", since = "1.83.0")] pub const fn get_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 1abfaa46ec66..30c0fff3104c 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -676,7 +676,6 @@ impl char { #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[rustc_const_stable(feature = "const_char_encode_utf8", since = "1.83.0")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str { // SAFETY: `char` is not a surrogate, so this is valid UTF-8. unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) } @@ -1284,7 +1283,6 @@ impl char { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -1311,7 +1309,6 @@ impl char { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } @@ -1777,7 +1774,6 @@ const fn len_utf16(code: u32) -> usize { #[doc(hidden)] #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] { const fn panic_at_const(_code: u32, _len: usize, _dst_len: usize) { // Note that we cannot format in constant expressions. diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index ca5b9fc98b93..69ad4f415196 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1807,7 +1807,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf16(a: f16, b: f16, c: f16) -> f16; /// Returns `a * b + c` for `f32` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1820,7 +1819,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf32(a: f32, b: f32, c: f32) -> f32; /// Returns `a * b + c` for `f64` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1833,7 +1831,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf64(a: f64, b: f64, c: f64) -> f64; /// Returns `a * b + c` for `f128` values, non-deterministically executing /// either a fused multiply-add or two operations with rounding of the @@ -1846,7 +1843,6 @@ extern "rust-intrinsic" { /// is selected, and that may depend on optimization level and context, for /// example. #[rustc_nounwind] - #[cfg(not(bootstrap))] pub fn fmuladdf128(a: f128, b: f128, c: f128) -> f128; /// Returns the largest integer less than or equal to an `f16`. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ccd6534de9b2..7060da172f33 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -173,9 +173,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] -#![cfg_attr(bootstrap, feature(const_refs_to_cell))] -#![cfg_attr(bootstrap, feature(const_refs_to_static))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index bb01d4e642cf..ea73cfc37810 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -570,7 +570,6 @@ impl MaybeUninit { /// until they are, it is advisable to avoid them.) #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline(always)] pub const fn as_mut_ptr(&mut self) -> *mut T { // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer. @@ -910,7 +909,6 @@ impl MaybeUninit { /// }; /// ``` #[stable(feature = "maybe_uninit_ref", since = "1.55.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable( feature = "const_maybe_uninit_assume_init", since = "CURRENT_RUSTC_VERSION" @@ -1000,7 +998,6 @@ impl MaybeUninit { /// /// [`assume_init_mut`]: MaybeUninit::assume_init_mut #[unstable(feature = "maybe_uninit_slice", issue = "63569")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")] #[inline(always)] pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index ada804633065..74b198c4fdd4 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -857,7 +857,6 @@ pub fn take(dest: &mut T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you don't need the old value, you can just assign the new value directly"] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")] pub const fn replace(dest: &mut T, src: T) -> T { diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index f55d55171f29..5e2f45884dd7 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -626,7 +626,6 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -653,7 +652,6 @@ impl u8 { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 661176ce9fcf..0b996c40c04c 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -723,7 +723,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn as_mut(&mut self) -> Option<&mut T> { match *self { @@ -1716,7 +1715,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn take(&mut self) -> Option { // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready @@ -1775,7 +1773,6 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_replace", since = "1.31.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) @@ -1937,7 +1934,6 @@ impl Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_option", since = "1.83.0")] pub const fn copied(self) -> Option where diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 61b48e312cfe..09ff7f8cab17 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1265,7 +1265,6 @@ const unsafe fn swap_nonoverlapping_simple_untyped(x: *mut T, y: *mut T, coun /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_replace"] pub const unsafe fn replace(dst: *mut T, src: T) -> T { @@ -1518,7 +1517,6 @@ pub const unsafe fn read(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_diagnostic_item = "ptr_read_unaligned"] pub const unsafe fn read_unaligned(src: *const T) -> T { @@ -1725,7 +1723,6 @@ pub const unsafe fn write(dst: *mut T, src: T) { /// ``` #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_refs_to_cell))] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write_unaligned"] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces @@ -1918,7 +1915,7 @@ pub unsafe fn write_volatile(dst: *mut T, src: T) { /// than trying to adapt this to accommodate that change. /// /// Any questions go to @nagisa. -#[cfg_attr(not(bootstrap), allow(ptr_to_integer_transmute_in_consts))] +#[allow(ptr_to_integer_transmute_in_consts)] #[lang = "align_offset"] pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usize { // FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <= diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index d7ce197848b2..613d2c91ac63 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1678,7 +1678,6 @@ impl *mut T { /// /// ``` /// #![feature(const_pointer_is_aligned)] - /// # #![cfg_attr(bootstrap, feature(const_mut_refs))] /// /// // On some platforms, the alignment of primitives is less than their size. /// #[repr(align(4))] @@ -1804,7 +1803,6 @@ impl *mut T { /// ``` /// #![feature(pointer_is_aligned_to)] /// #![feature(const_pointer_is_aligned)] - /// # #![cfg_attr(bootstrap, feature(const_mut_refs))] /// /// // On some platforms, the alignment of i32 is less than 4. /// #[repr(align(4))] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c68391363485..dfd0bd8fd1e5 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -394,7 +394,6 @@ impl NonNull { /// /// [the module documentation]: crate::ptr#safety #[stable(feature = "nonnull", since = "1.25.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_ptr_as_ref", since = "1.83.0")] #[must_use] #[inline(always)] diff --git a/library/core/src/result.rs b/library/core/src/result.rs index e84c4e3a2398..330d1eb14edb 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -735,7 +735,6 @@ impl Result { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_result", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> { match *self { Ok(ref mut x) => Ok(x), @@ -1589,7 +1588,6 @@ impl Result<&mut T, E> { #[inline] #[stable(feature = "result_copied", since = "1.59.0")] #[rustc_const_stable(feature = "const_result", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_allow_const_fn_unstable(const_precise_live_drops)] pub const fn copied(self) -> Result where diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 8d8ac6a1d2a1..a03e9fbae112 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -69,7 +69,6 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; @@ -92,7 +91,6 @@ impl [u8] { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 9fdcea1f7b73..dbcfe9464401 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -171,7 +171,6 @@ impl [T] { /// assert_eq!(None, y.first_mut()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -214,7 +213,6 @@ impl [T] { /// assert_eq!(x, &[3, 4, 5]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -257,7 +255,6 @@ impl [T] { /// assert_eq!(x, &[4, 5, 3]); /// ``` #[stable(feature = "slice_splits", since = "1.5.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -300,7 +297,6 @@ impl [T] { /// assert_eq!(None, y.last_mut()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_slice_first_last", since = "1.83.0")] #[inline] #[must_use] @@ -357,7 +353,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn first_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { None @@ -423,7 +418,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_first_chunk_mut( &mut self, ) -> Option<(&mut [T; N], &mut [T])> { @@ -494,7 +488,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_last_chunk_mut( &mut self, ) -> Option<(&mut [T], &mut [T; N])> { @@ -564,7 +557,6 @@ impl [T] { #[inline] #[stable(feature = "slice_first_last_chunk", since = "1.77.0")] #[rustc_const_stable(feature = "const_slice_first_last_chunk", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn last_chunk_mut(&mut self) -> Option<&mut [T; N]> { if self.len() < N { None @@ -853,7 +845,6 @@ impl [T] { /// [`as_mut_ptr`]: slice::as_mut_ptr #[stable(feature = "slice_ptr_range", since = "1.48.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell))] #[inline] #[must_use] pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { @@ -1908,7 +1899,6 @@ impl [T] { #[track_caller] #[must_use] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) { match self.split_at_mut_checked(mid) { Some(pair) => pair, @@ -2011,7 +2001,6 @@ impl [T] { /// ``` #[stable(feature = "slice_split_at_unchecked", since = "1.79.0")] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { @@ -2112,7 +2101,6 @@ impl [T] { /// ``` #[stable(feature = "split_at_checked", since = "1.80.0")] #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[inline] #[must_use] pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut [T], &mut [T])> { diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 976749cc148c..89840881c4d9 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -172,7 +172,6 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] #[rustc_diagnostic_item = "slice_from_raw_parts_mut"] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { @@ -205,7 +204,6 @@ pub const fn from_ref(s: &T) -> &[T] { /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_stable(feature = "const_slice_from_ref", since = "1.83.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[must_use] pub const fn from_mut(s: &mut T) -> &mut [T] { array::from_mut(s) diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index b61ed454cd9e..c997e5e443da 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -195,7 +195,6 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[inline] #[must_use] #[stable(feature = "str_mut_extras", since = "1.20.0")] -#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_from_utf8_unchecked_mut", since = "1.83.0")] #[rustc_diagnostic_item = "str_from_utf8_unchecked_mut"] pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 09938dda262c..89addc4cb747 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -339,7 +339,6 @@ impl str { /// assert_eq!("🍔∈🌏", s); /// ``` #[stable(feature = "str_mut_extras", since = "1.20.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[must_use] #[inline(always)] @@ -386,7 +385,6 @@ impl str { /// It is your responsibility to make sure that the string slice only gets /// modified in a way that it remains valid UTF-8. #[stable(feature = "str_as_mut_ptr", since = "1.36.0")] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] #[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")] #[rustc_never_returns_null_ptr] #[must_use] @@ -2477,7 +2475,6 @@ impl str { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; @@ -2506,7 +2503,6 @@ impl str { #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] - #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 2bdaeb3845a7..0ffba538b207 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -229,7 +229,7 @@ fn static_init() { #[test] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint -#[cfg_attr(not(bootstrap), allow(static_mut_refs))] +#[allow(static_mut_refs)] fn atomic_access_bool() { static mut ATOMIC: AtomicBool = AtomicBool::new(false); diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 37e7db1157c8..bfc0b638b7e6 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -1,5 +1,4 @@ // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_match))] #![feature(alloc_layout_extra)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ed448e50e60e..3ab652383689 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -279,7 +279,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(const_mut_refs))] #![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f089d1e1bcc3..9814858beaa9 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -14,6 +14,7 @@ #![feature(strict_provenance)] #![feature(exposed_provenance)] #![feature(pointer_is_aligned_to)] +#![feature(unqualified_local_imports)] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, @@ -42,13 +43,12 @@ )] #![warn( rust_2018_idioms, + unqualified_local_imports, clippy::cast_possible_wrap, // unsigned -> signed clippy::cast_sign_loss, // signed -> unsigned clippy::cast_lossless, clippy::cast_possible_truncation, )] -#![cfg_attr(not(bootstrap), feature(unqualified_local_imports))] -#![cfg_attr(not(bootstrap), warn(unqualified_local_imports))] // Needed for rustdoc from bootstrap (with `-Znormalize-docs`). #![recursion_limit = "256"] diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs index 08d86606a6ba..a26d00b77ac4 100644 --- a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs +++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs @@ -1,8 +1,5 @@ //@ compile-flags: -Z unstable-options -// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run. -//@ ignore-stage1 - #![feature(rustc_private)] #![deny(rustc::usage_of_type_ir_inherent)] diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr index cc6cb9170c0d..3326b1047ac8 100644 --- a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr +++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr @@ -1,18 +1,18 @@ error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:11:20 + --> $DIR/import-of-type-ir-inherent.rs:8:20 | LL | use rustc_type_ir::inherent::*; | ^^^^^^^^ | = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler note: the lint level is defined here - --> $DIR/import-of-type-ir-inherent.rs:7:9 + --> $DIR/import-of-type-ir-inherent.rs:4:9 | LL | #![deny(rustc::usage_of_type_ir_inherent)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:13:20 + --> $DIR/import-of-type-ir-inherent.rs:10:20 | LL | use rustc_type_ir::inherent; | ^^^^^^^^ @@ -20,7 +20,7 @@ LL | use rustc_type_ir::inherent; = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver - --> $DIR/import-of-type-ir-inherent.rs:15:20 + --> $DIR/import-of-type-ir-inherent.rs:12:20 | LL | use rustc_type_ir::inherent::Predicate; | ^^^^^^^^ diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.rs b/tests/ui-fulldeps/internal-lints/query_completeness.rs index 50b0fb4c3fc0..791f4599273c 100644 --- a/tests/ui-fulldeps/internal-lints/query_completeness.rs +++ b/tests/ui-fulldeps/internal-lints/query_completeness.rs @@ -1,6 +1,4 @@ //@ compile-flags: -Z unstable-options -// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run. -//@ ignore-stage1 (requires matching sysroot built with in-tree compiler) #![feature(rustc_private)] #![deny(rustc::untracked_query_information)] diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.stderr b/tests/ui-fulldeps/internal-lints/query_completeness.stderr index 35bb867f40e8..e17c2a891cf6 100644 --- a/tests/ui-fulldeps/internal-lints/query_completeness.stderr +++ b/tests/ui-fulldeps/internal-lints/query_completeness.stderr @@ -1,12 +1,12 @@ error: `is_stolen` accesses information that is not tracked by the query system - --> $DIR/query_completeness.rs:12:15 + --> $DIR/query_completeness.rs:10:15 | LL | let _ = x.is_stolen(); | ^^^^^^^^^ | = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale note: the lint level is defined here - --> $DIR/query_completeness.rs:5:9 + --> $DIR/query_completeness.rs:3:9 | LL | #![deny(rustc::untracked_query_information)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 618b0cb0469fe219bd5e668bb5a63d3ee1568abc Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 15 Oct 2024 20:16:16 -0700 Subject: [PATCH 105/118] update STAGE0_MISSING_TARGETS --- src/bootstrap/src/core/sanity.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 6fbdd76ed5b6..fabb4f2b13bc 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,10 +34,6 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined - "armv7-rtems-eabihf", - "riscv32e-unknown-none-elf", - "riscv32em-unknown-none-elf", - "riscv32emc-unknown-none-elf", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM From cd60224af72a380dad27f01afc08c7374105525b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 15 Oct 2024 20:53:26 -0700 Subject: [PATCH 106/118] Fix `clippy::needless-lifetimes` in bootstrap --- src/bootstrap/src/core/build_steps/tool.rs | 2 +- src/bootstrap/src/core/builder.rs | 2 +- src/bootstrap/src/core/config/config.rs | 4 ++-- src/bootstrap/src/utils/cache.rs | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a01497c2bb98..f1a10c3296e9 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1096,7 +1096,7 @@ tool_extended!((self, builder), Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"]; ); -impl<'a> Builder<'a> { +impl Builder<'_> { /// Gets a `BootstrapCommand` which is ready to run `tool` in `stage` built for /// `host`. pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand { diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 9ac0b0a01f7e..15c6f303f94a 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -63,7 +63,7 @@ pub struct Builder<'a> { pub paths: Vec, } -impl<'a> Deref for Builder<'a> { +impl Deref for Builder<'_> { type Target = Build; fn deref(&self) -> &Self::Target { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index eb571f920df2..c2ab439891ea 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -996,7 +996,7 @@ impl<'de> Deserialize<'de> for RustOptimize { struct OptimizeVisitor; -impl<'de> serde::de::Visitor<'de> for OptimizeVisitor { +impl serde::de::Visitor<'_> for OptimizeVisitor { type Value = RustOptimize; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -1071,7 +1071,7 @@ impl<'de> Deserialize<'de> for LldMode { { struct LldModeVisitor; - impl<'de> serde::de::Visitor<'de> for LldModeVisitor { + impl serde::de::Visitor<'_> for LldModeVisitor { type Value = LldMode; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/bootstrap/src/utils/cache.rs b/src/bootstrap/src/utils/cache.rs index 3f78b04d44aa..29342cc5a2c5 100644 --- a/src/bootstrap/src/utils/cache.rs +++ b/src/bootstrap/src/utils/cache.rs @@ -39,17 +39,17 @@ impl PartialEq for Interned { *self == other } } -impl<'a> PartialEq<&'a str> for Interned { +impl PartialEq<&str> for Interned { fn eq(&self, other: &&str) -> bool { **self == **other } } -impl<'a, T> PartialEq<&'a Interned> for Interned { +impl PartialEq<&Interned> for Interned { fn eq(&self, other: &&Self) -> bool { self.0 == other.0 } } -impl<'a, T> PartialEq> for &'a Interned { +impl PartialEq> for &Interned { fn eq(&self, other: &Interned) -> bool { self.0 == other.0 } From 0804d1bc27bd9b64c1302851f047316f086a0d1a Mon Sep 17 00:00:00 2001 From: Juniper Tyree <50025784+juntyr@users.noreply.github.com> Date: Sat, 12 Oct 2024 08:03:02 +0300 Subject: [PATCH 107/118] Add wasm32-unknown-emscripten platform support document Co-authored-by: Hood Chatham Co-authored-by: Alex Crichton Co-authored-by: Kleis Auke Wolthuizen --- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 +- .../wasm32-unknown-emscripten.md | 168 ++++++++++++++++++ .../wasm32-unknown-unknown.md | 4 +- 4 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index b1a5bd604eb3..795908b32c0b 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -84,6 +84,7 @@ - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) - [wasm32-wasip2](platform-support/wasm32-wasip2.md) + - [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md) - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md) - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 0ef95ba64a1f..022fc9da7e03 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -190,7 +190,7 @@ target | std | notes [`thumbv8m.base-none-eabi`](platform-support/thumbv8m.base-none-eabi.md) | * | Bare Armv8-M Baseline [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat -`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten +[`wasm32-unknown-emscripten`](platform-support/wasm32-unknown-emscripten.md) | ✓ | WebAssembly via Emscripten [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md new file mode 100644 index 000000000000..7a9cd4b522b9 --- /dev/null +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-emscripten.md @@ -0,0 +1,168 @@ +# `wasm32-unknown-emscripten` + +**Tier: 2** + +The `wasm32-unknown-emscripten` target is a WebAssembly compilation target which +uses the [Emscripten](https://emscripten.org/) compiler toolchain. Emscripten is +a C/C++ toolchain designed to make it as easy as possible to port C/C++ code +written for Linux to run on the web or in other JavaScript runtimes such as Node. +It thus provides POSIX-compatible (musl) `libc` and `libstd` implementations and +many Linux APIs, access to the OpenGL and SDL APIs, and the ability to run arbitrary +JavaScript code, all based on web APIs using JS glue code. With the +`wasm32-unknown-emscripten` target, Rust code can interoperate with Emscripten's +ecosystem, C/C++ and JS code, and web APIs. + +One existing user of this target is the +[`pyodide` project](https://pyodide.org/) which provides a Python runtime in +WebAssembly using Emscripten and compiles Python extension modules written in Rust +to the `wasm32-unknown-emscripten` target. + +If you want to generate a standalone WebAssembly binary that does not require +access to the web APIs or the Rust standard library, the +[`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) target may be better +suited for you. However, [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) +does not (easily) support interop with C/C++ code. Please refer to the +[wasm-bindgen](https://crates.io/crates/wasm-bindgen) crate in case you want to +interoperate with JavaScript with this target. + +Like Emscripten, the WASI targets [`wasm32-wasip1`](./wasm32-wasip1.md) and +[`wasm32-wasip2`](./wasm32-wasip2.md) also provide access to the host environment, +support interop with C/C++ (and other languages), and support most of the Rust +standard library. While the WASI targets are portable across different hosts +(web and non-web), WASI has no standard way of accessing web APIs, whereas +Emscripten has the ability to run arbitrary JS from WASM and access many web APIs. +If you are only targeting the web and need to access web APIs, the +`wasm32-unknown-emscripten` target may be preferable. + +## Target maintainers + +- Hood Chatham, https://github.com/hoodmane +- Juniper Tyree, https://github.com/juntyr + +## Requirements + +This target is cross-compiled. The Emscripten compiler toolchain `emcc` must be +installed to link WASM binaries for this target. You can install `emcc` using: + +```sh +git clone https://github.com/emscripten-core/emsdk.git --depth 1 +./emsdk/emsdk install 3.1.68 +./emsdk/emsdk activate 3.1.68 +source ./emsdk/emsdk_env.sh +``` + +Please refer to for +further details and instructions. + +## Building the target + +Building this target can be done by: + +* Configure the `wasm32-unknown-emscripten` target to get built. +* Ensure the `WebAssembly` target backend is not disabled in LLVM. + +These are all controlled through `config.toml` options. It should be possible +to build this target on any platform. A minimal example configuration would be: + +```toml +[llvm] +targets = "WebAssembly" + +[build] +build-stage = 1 +target = ["wasm32-unknown-emscripten"] +``` + +## Building Rust programs + +Rust programs can be compiled by adding this target via rustup: + +```sh +$ rustup target add wasm32-unknown-emscripten +``` + +and then compiling with the target: + +```sh +$ rustc foo.rs --target wasm32-unknown-emscripten +$ file foo.wasm +``` + +## Cross-compilation + +This target can be cross-compiled from any host. + +## Emscripten ABI Compatibility + +The Emscripten compiler toolchain does not follow a semantic versioning scheme +that clearly indicates when breaking changes to the ABI can be made. Additionally, +Emscripten offers many different ABIs even for a single version of Emscripten +depending on the linker flags used, e.g. `-fexceptions` and `-sWASM_BIGINT`. If +the ABIs mismatch, your code may exhibit undefined behaviour. + +To ensure that the ABIs of your Rust code, of the Rust standard library, and of +other code compiled for Emscripten all match, you should rebuild the Rust standard +library with your local Emscripten version and settings using: + +```sh +cargo +nightly -Zbuild-std build +``` + +If you still want to use the pre-compiled `std` from rustup, you should ensure +that your local Emscripten matches the version used by Rust and be careful about +any `-C link-arg`s that you compiled your Rust code with. + +## Testing + +This target is not extensively tested in CI for the rust-lang/rust repository. It +can be tested locally, for example, with: + +```sh +./x.py test --target wasm32-unknown-emscripten --skip src/tools/linkchecker +``` + +To run these tests, both `emcc` and `node` need to be in your `$PATH`. You can +install `node`, for example, using `nvm` by following the instructions at +. + +If you need to test WebAssembly compatibility *in general*, it is recommended +to test the [`wasm32-wasip1`](./wasm32-wasip1.md) target instead. + +## Conditionally compiling code + +It's recommended to conditionally compile code for this target with: + +```text +#[cfg(target_os = "emscripten")] +``` + +It may sometimes be necessary to conditionally compile code for WASM targets +which do *not* use emscripten, which can be achieved with: + +```text +#[cfg(all(target_family = "wasm", not(target_os = "emscripten)))] +``` + +## Enabled WebAssembly features + +WebAssembly is an evolving standard which adds new features such as new +instructions over time. This target's default set of supported WebAssembly +features will additionally change over time. The `wasm32-unknown-emscripten` target +inherits the default settings of LLVM which typically, but not necessarily, matches +the default settings of Emscripten as well. At link time, `emcc` configures the +linker to use Emscripten's settings. + +Please refer to the [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) +target's documentation on which WebAssembly features Rust enables by default, how +features can be disabled, and how Rust code can be conditionally compiled based on +which features are enabled. + +Note that Rust code compiled for `wasm32-unknown-emscripten` currently enables +`-fexceptions` (JS exceptions) by default unless the Rust code is compiled with +`-Cpanic=abort`. `-fwasm-exceptions` (WASM exceptions) is not yet currently supported, +see . + +Please refer to the [Emscripten ABI compatibility](#emscripten-abi-compatibility) +section to ensure that the features that are enabled do not cause an ABI mismatch +between your Rust code, the pre-compiled Rust standard library, and other code compiled +for Emscripten. diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md index 0e06a820a22c..48a8df0c4a86 100644 --- a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md +++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md @@ -46,8 +46,8 @@ This target currently has no equivalent in C/C++. There is no C/C++ toolchain for this target. While interop is theoretically possible it's recommended to instead use one of: -* `wasm32-unknown-emscripten` - for web-based use cases the Emscripten - toolchain is typically chosen for running C/C++. +* [`wasm32-unknown-emscripten`](./wasm32-unknown-emscripten.md) - for web-based + use cases the Emscripten toolchain is typically chosen for running C/C++. * [`wasm32-wasip1`](./wasm32-wasip1.md) - the wasi-sdk toolchain is used to compile C/C++ on this target and can interop with Rust code. WASI works on the web so far as there's no blocker, but an implementation of WASI APIs From 5eb863698964b026149f4ed9f958639eb290f5b3 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 16 Oct 2024 09:41:49 +0200 Subject: [PATCH 108/118] Handle gracefully true/false in `cfg(target(..))` compact --- compiler/rustc_attr/src/builtin.rs | 8 +++++++- tests/ui/cfg/cfg-target-compact-errors.rs | 4 ++++ tests/ui/cfg/cfg-target-compact-errors.stderr | 8 +++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index c1db4d07dfc8..bbb174976844 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -723,7 +723,13 @@ pub fn eval_condition( } mis.iter().fold(true, |res, mi| { - let mut mi = mi.meta_item().unwrap().clone(); + let Some(mut mi) = mi.meta_item().cloned() else { + dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { + span: mi.span(), + }); + return false; + }; + if let [seg, ..] = &mut mi.path.segments[..] { seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name)); } diff --git a/tests/ui/cfg/cfg-target-compact-errors.rs b/tests/ui/cfg/cfg-target-compact-errors.rs index daacbb2851d1..e00d42fe4d96 100644 --- a/tests/ui/cfg/cfg-target-compact-errors.rs +++ b/tests/ui/cfg/cfg-target-compact-errors.rs @@ -14,4 +14,8 @@ fn two() {} //~^ ERROR invalid predicate `target_pointer` fn three() {} +#[cfg(target(true))] +//~^ ERROR `cfg` predicate key must be an identifier +fn four() {} + fn main() {} diff --git a/tests/ui/cfg/cfg-target-compact-errors.stderr b/tests/ui/cfg/cfg-target-compact-errors.stderr index bb858301eb58..219d9732c32b 100644 --- a/tests/ui/cfg/cfg-target-compact-errors.stderr +++ b/tests/ui/cfg/cfg-target-compact-errors.stderr @@ -16,7 +16,13 @@ error[E0537]: invalid predicate `target_pointer` LL | #[cfg(target(os = "linux", pointer(width = "64")))] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: `cfg` predicate key must be an identifier + --> $DIR/cfg-target-compact-errors.rs:17:14 + | +LL | #[cfg(target(true))] + | ^^^^ + +error: aborting due to 4 previous errors Some errors have detailed explanations: E0537, E0565. For more information about an error, try `rustc --explain E0537`. From 476ea45c68223e4b2f9674d20f1aff8dd52fe1fb Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 16 Oct 2024 12:22:14 +0200 Subject: [PATCH 109/118] Emscripten: Xfail backtrace ui tests It is possible to link libunwind and use the normal backtrace code, but it fails to symbolize stack traces. I investigated and could get the list of instruction pointers and symbol names, but I'm not sure how to use the dwarf info to map from instruction pointer to source location. In any case, fixing this is probably not a high priority. See https://github.com/rust-lang/rust/issues/131738 --- tests/ui/backtrace/dylib-dep.rs | 1 + tests/ui/backtrace/line-tables-only.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/ui/backtrace/dylib-dep.rs b/tests/ui/backtrace/dylib-dep.rs index fcd1f92e28eb..a41931ad5489 100644 --- a/tests/ui/backtrace/dylib-dep.rs +++ b/tests/ui/backtrace/dylib-dep.rs @@ -9,6 +9,7 @@ //@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written). //@ needs-unwind //@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes +//@ ignore-emscripten Requires custom symbolization code //@ aux-crate: dylib_dep_helper=dylib-dep-helper.rs //@ aux-crate: auxiliary=dylib-dep-helper-aux.rs //@ run-pass diff --git a/tests/ui/backtrace/line-tables-only.rs b/tests/ui/backtrace/line-tables-only.rs index 044f59e483ab..6624c71e184b 100644 --- a/tests/ui/backtrace/line-tables-only.rs +++ b/tests/ui/backtrace/line-tables-only.rs @@ -10,6 +10,7 @@ //@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only //@ ignore-android FIXME #17520 //@ ignore-fuchsia Backtraces not symbolized +//@ ignore-emscripten Requires custom symbolization code //@ needs-unwind //@ aux-build: line-tables-only-helper.rs From 89ea9e44f073a67a2b92de2ede5985acb1f810ec Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Wed, 16 Oct 2024 12:36:44 +0200 Subject: [PATCH 110/118] Fix trivially_copy_pass_by_ref in stable_mir --- compiler/stable_mir/src/mir/body.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 742469a1c932..f96487cc53c9 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -1028,7 +1028,7 @@ impl ProjectionElem { ProjectionElem::Field(_idx, fty) => Ok(*fty), ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => Self::index_ty(ty), ProjectionElem::Subslice { from, to, from_end } => { - Self::subslice_ty(ty, from, to, from_end) + Self::subslice_ty(ty, *from, *to, *from_end) } ProjectionElem::Downcast(_) => Ok(ty), ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => Ok(*ty), @@ -1039,13 +1039,13 @@ impl ProjectionElem { ty.kind().builtin_index().ok_or_else(|| error!("Cannot index non-array type: {ty:?}")) } - fn subslice_ty(ty: Ty, from: &u64, to: &u64, from_end: &bool) -> Result { + fn subslice_ty(ty: Ty, from: u64, to: u64, from_end: bool) -> Result { let ty_kind = ty.kind(); match ty_kind { TyKind::RigidTy(RigidTy::Slice(..)) => Ok(ty), TyKind::RigidTy(RigidTy::Array(inner, _)) if !from_end => Ty::try_new_array( inner, - to.checked_sub(*from).ok_or_else(|| error!("Subslice overflow: {from}..{to}"))?, + to.checked_sub(from).ok_or_else(|| error!("Subslice overflow: {from}..{to}"))?, ), TyKind::RigidTy(RigidTy::Array(inner, size)) => { let size = size.eval_target_usize()?; From a10a44956e4efddf4fdf0f7a8b10796b9ae965ea Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Wed, 16 Oct 2024 13:31:23 +0200 Subject: [PATCH 111/118] Fix needless_lifetimes in stable_mir --- compiler/stable_mir/src/mir/visit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index e2d1ff7fdd3a..85205528979c 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -487,7 +487,7 @@ pub struct PlaceRef<'a> { pub projection: &'a [ProjectionElem], } -impl<'a> PlaceRef<'a> { +impl PlaceRef<'_> { /// Get the type of this place. pub fn ty(&self, locals: &[LocalDecl]) -> Result { self.projection.iter().fold(Ok(locals[self.local].ty), |place_ty, elem| elem.ty(place_ty?)) From b2b4ad4cc94077eba1331acc534b5e36ae3e2603 Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Wed, 16 Oct 2024 15:44:16 +0200 Subject: [PATCH 112/118] Fix explicit_iter_loop in rustc_serialize --- compiler/rustc_serialize/src/serialize.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index bae5f259fccf..db8555edd0f8 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -288,7 +288,7 @@ impl> Decodable for Rc { impl> Encodable for [T] { default fn encode(&self, s: &mut S) { s.emit_usize(self.len()); - for e in self.iter() { + for e in self { e.encode(s); } } @@ -527,7 +527,7 @@ impl> Decodable for ThinVec { impl> Encodable for VecDeque { fn encode(&self, s: &mut S) { s.emit_usize(self.len()); - for e in self.iter() { + for e in self { e.encode(s); } } @@ -547,7 +547,7 @@ where { fn encode(&self, e: &mut S) { e.emit_usize(self.len()); - for (key, val) in self.iter() { + for (key, val) in self { key.encode(e); val.encode(e); } @@ -571,7 +571,7 @@ where { fn encode(&self, s: &mut S) { s.emit_usize(self.len()); - for e in self.iter() { + for e in self { e.encode(s); } } @@ -595,7 +595,7 @@ where { fn encode(&self, e: &mut E) { e.emit_usize(self.len()); - for (key, val) in self.iter() { + for (key, val) in self { key.encode(e); val.encode(e); } @@ -621,7 +621,7 @@ where { fn encode(&self, s: &mut E) { s.emit_usize(self.len()); - for e in self.iter() { + for e in self { e.encode(s); } } @@ -646,7 +646,7 @@ where { fn encode(&self, e: &mut E) { e.emit_usize(self.len()); - for (key, val) in self.iter() { + for (key, val) in self { key.encode(e); val.encode(e); } @@ -672,7 +672,7 @@ where { fn encode(&self, s: &mut E) { s.emit_usize(self.len()); - for e in self.iter() { + for e in self { e.encode(s); } } From 6d82559bc1d5e02705cec0726a25704882c79365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 12 Oct 2024 12:34:58 +0200 Subject: [PATCH 113/118] rustdoc: Rename "object safe" to "dyn compatible" --- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render/print_item.rs | 14 ++++++------ src/librustdoc/html/render/sidebar.rs | 6 +++--- src/librustdoc/json/conversions.rs | 2 +- tests/rustdoc/dyn-compatibility.rs | 27 ++++++++++++++++++++++++ tests/rustdoc/sidebar/sidebar-items.rs | 6 +++--- tests/rustdoc/trait-object-safe.rs | 27 ------------------------ 8 files changed, 44 insertions(+), 42 deletions(-) create mode 100644 tests/rustdoc/dyn-compatibility.rs delete mode 100644 tests/rustdoc/trait-object-safe.rs diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index bc5bf4c05838..44295fa0cd94 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1450,7 +1450,7 @@ impl Trait { pub(crate) fn safety(&self, tcx: TyCtxt<'_>) -> hir::Safety { tcx.trait_def(self.def_id).safety } - pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool { + pub(crate) fn is_dyn_compatible(&self, tcx: TyCtxt<'_>) -> bool { tcx.is_dyn_compatible(self.def_id) } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5dacabd031e0..315b7742a4cf 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -2002,7 +2002,7 @@ fn init_id_map() -> FxHashMap, usize> { map.insert("required-associated-consts".into(), 1); map.insert("required-methods".into(), 1); map.insert("provided-methods".into(), 1); - map.insert("object-safety".into(), 1); + map.insert("dyn-compatibility".into(), 1); map.insert("implementors".into(), 1); map.insert("synthetic-implementors".into(), 1); map.insert("implementations-list".into(), 1); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3c96f8736814..5e9cbef99a95 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -934,16 +934,18 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let cache = &cloned_shared.cache; let mut extern_crates = FxIndexSet::default(); - if !t.is_object_safe(cx.tcx()) { + if !t.is_dyn_compatible(cx.tcx()) { + // FIXME(dyn_compat_renaming): Update the URL once the Reference is updated. write_section_heading( w, - "Object Safety", - "object-safety", + "Dyn Compatibility", + "dyn-compatibility", None, &format!( - "

", + "

This trait is not \ + dyn compatible.

\ +

In older versions of Rust, dyn compatibility was called \"object safety\", \ + so this trait is not object safe.

", base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL ), ); diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index e7706e7fdeae..6df9486e6580 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -315,10 +315,10 @@ fn sidebar_trait<'a>( ); sidebar_assoc_items(cx, it, blocks); - if !t.is_object_safe(cx.tcx()) { + if !t.is_dyn_compatible(cx.tcx()) { blocks.push(LinkBlock::forced( - Link::new("object-safety", "Object Safety"), - "object-safety-note", + Link::new("dyn-compatibility", "Dyn Compatibility"), + "dyn-compatibility-note", )); } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index b8791c9918b1..77e7d83090b9 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -672,7 +672,7 @@ impl FromClean for Trait { let tcx = renderer.tcx; let is_auto = trait_.is_auto(tcx); let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe; - let is_object_safe = trait_.is_object_safe(tcx); + let is_object_safe = trait_.is_dyn_compatible(tcx); let clean::Trait { items, generics, bounds, .. } = trait_; Trait { is_auto, diff --git a/tests/rustdoc/dyn-compatibility.rs b/tests/rustdoc/dyn-compatibility.rs new file mode 100644 index 000000000000..9115f93bc3ba --- /dev/null +++ b/tests/rustdoc/dyn-compatibility.rs @@ -0,0 +1,27 @@ +#![crate_name = "foo"] + +//@ has 'foo/trait.DynIncompatible.html' +//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.' +//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility' +pub trait DynIncompatible { + fn foo() -> Self; +} + +//@ has 'foo/trait.DynIncompatible2.html' +//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.' +//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility' +pub trait DynIncompatible2 { + fn foo(i: T); +} + +//@ has 'foo/trait.DynCompatible.html' +//@ !has - '//*[@class="dyn-compatibility-info"]' '' +//@ !has - '//*[@id="dyn-compatibility"]' '' +pub trait DynCompatible { + fn foo(&self); +} + +//@ has 'foo/struct.Foo.html' +//@ count - '//*[@class="dyn-compatibility-info"]' 0 +//@ count - '//*[@id="dyn-compatibility"]' 0 +pub struct Foo; diff --git a/tests/rustdoc/sidebar/sidebar-items.rs b/tests/rustdoc/sidebar/sidebar-items.rs index f3812143a7da..57c2eee91a92 100644 --- a/tests/rustdoc/sidebar/sidebar-items.rs +++ b/tests/rustdoc/sidebar/sidebar-items.rs @@ -14,7 +14,7 @@ //@ has - '//*[@class="sidebar-elems"]//section//a' 'Output' //@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types' //@ has - '//*[@class="sidebar-elems"]//section//a' 'Extra' -//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety' +//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#dyn-compatibility"]' 'Dyn Compatibility' pub trait Foo { const FOO: usize; const BAR: u32 = 0; @@ -25,9 +25,9 @@ pub trait Foo { fn bar() -> Self::Output; } -//@ has foo/trait.Safe.html +//@ has foo/trait.DynCompatible.html //@ !has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' '' -pub trait Safe { +pub trait DynCompatible { fn access(&self); } diff --git a/tests/rustdoc/trait-object-safe.rs b/tests/rustdoc/trait-object-safe.rs deleted file mode 100644 index b4e986c8f69c..000000000000 --- a/tests/rustdoc/trait-object-safe.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![crate_name = "foo"] - -//@ has 'foo/trait.Unsafe.html' -//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.' -//@ has - '//*[@id="object-safety"]' 'Object Safety' -pub trait Unsafe { - fn foo() -> Self; -} - -//@ has 'foo/trait.Unsafe2.html' -//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.' -//@ has - '//*[@id="object-safety"]' 'Object Safety' -pub trait Unsafe2 { - fn foo(i: T); -} - -//@ has 'foo/trait.Safe.html' -//@ !has - '//*[@class="object-safety-info"]' '' -//@ !has - '//*[@id="object-safety"]' '' -pub trait Safe { - fn foo(&self); -} - -//@ has 'foo/struct.Foo.html' -//@ count - '//*[@class="object-safety-info"]' 0 -//@ count - '//*[@id="object-safety"]' 0 -pub struct Foo; From 8991fd4bed6583757c5df3f37b7c17fd58963f09 Mon Sep 17 00:00:00 2001 From: Charles Celerier Date: Tue, 15 Oct 2024 15:47:10 -0400 Subject: [PATCH 114/118] Ignore lint-non-snake-case-crate#proc_macro_ on targets without unwind The lint-non-snake-case-crate test may emit a warning in stderr if the target does not support unwinding ``` warning: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic ``` Consequently, the test will fail on targets that don't support unwinding as written. This change prevents lint-non-snake-case-crate#proc_macro_ from running on targets that don't support unwind by using the needs-unwind directive. --- .../non-snake-case/lint-non-snake-case-crate.cdylib_.stderr | 4 ++-- .../non-snake-case/lint-non-snake-case-crate.dylib_.stderr | 4 ++-- .../lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr | 4 ++-- .../lint-non-snake-case-crate.proc_macro_.stderr | 4 ++-- .../non-snake-case/lint-non-snake-case-crate.rlib_.stderr | 4 ++-- tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs | 4 ++++ .../lint-non-snake-case-crate.staticlib_.stderr | 4 ++-- 7 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.cdylib_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.dylib_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.lib_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.proc_macro_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rlib_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs index 57604d99a07b..097b246c1650 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs @@ -22,6 +22,10 @@ //@[rlib_] compile-flags: --crate-type=rlib //@[staticlib_] compile-flags: --crate-type=staticlib +// The compiler may emit a warning that causes stderr output +// that contains a warning this test does not wish to check. +//@[proc_macro_] needs-unwind + #![crate_name = "NonSnakeCase"] //[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name #![deny(non_snake_case)] diff --git a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr index 9bccb270627d..140d72b97421 100644 --- a/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr +++ b/tests/ui/lint/non-snake-case/lint-non-snake-case-crate.staticlib_.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name - --> $DIR/lint-non-snake-case-crate.rs:25:18 + --> $DIR/lint-non-snake-case-crate.rs:29:18 | LL | #![crate_name = "NonSnakeCase"] | ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case` | note: the lint level is defined here - --> $DIR/lint-non-snake-case-crate.rs:27:9 + --> $DIR/lint-non-snake-case-crate.rs:31:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ From 682bca30ccbfe1dc94e8c1abbd458d7f7be18077 Mon Sep 17 00:00:00 2001 From: dufucun Date: Thu, 17 Oct 2024 00:16:19 +0800 Subject: [PATCH 115/118] Fix mismatched quotation mark --- tests/ui/mir/mir-inlining/always-encode-mirs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/mir/mir-inlining/always-encode-mirs.rs b/tests/ui/mir/mir-inlining/always-encode-mirs.rs index 9029ff6499b0..4553560baaa6 100644 --- a/tests/ui/mir/mir-inlining/always-encode-mirs.rs +++ b/tests/ui/mir/mir-inlining/always-encode-mirs.rs @@ -1,6 +1,6 @@ // Regression test for MIR inlining with -Zalways-encode-mir enabled in the auxiliary crate. // Previously we inlined function not eligible for inlining which lead to linking error: -// undefined reference to `internal::S' +// undefined reference to `internal::S` // //@ aux-build:internal.rs //@ build-pass From 4ba20f6a080724faca9e38647d4c66056871a8f2 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Thu, 17 Oct 2024 05:05:38 +0000 Subject: [PATCH 116/118] 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 8b9e7efdff90..d0f9fa7ac429 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -17a19e684cdf3ca088af8b4da6a6209d128913f4 +dd5127615ad626741a1116d022cf784637ac05df From 080103f1edeea36827a51a9f663cf86638b44cb5 Mon Sep 17 00:00:00 2001 From: ash Date: Sun, 20 Oct 2024 08:34:15 -0600 Subject: [PATCH 117/118] misapplied optimize attribute throws a compilation error (#128488) --- compiler/rustc_passes/messages.ftl | 6 +-- compiler/rustc_passes/src/check_attr.rs | 30 ++++++------- compiler/rustc_passes/src/errors.rs | 12 ++++-- tests/ui/attributes/optimize.rs | 22 ++++++++-- tests/ui/attributes/optimize.stderr | 42 +++++++++++++------ tests/ui/coroutine/other-attribute-on-gen.rs | 40 ++++++++++++++++++ .../feature-gate-optimize_attribute.rs | 6 --- .../feature-gate-optimize_attribute.stderr | 30 +++---------- 8 files changed, 117 insertions(+), 71 deletions(-) create mode 100644 tests/ui/coroutine/other-attribute-on-gen.rs diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index e5a14f6a1565..3613b7b862d7 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -553,9 +553,9 @@ passes_only_has_effect_on = *[unspecified] (unspecified--this is a compiler bug) } -passes_optimize_not_fn_or_closure = - attribute should be applied to function or closure - .label = not a function or closure +passes_optimize_invalid_target = + attribute applied to an invalid target + .label = invalid target passes_outer_crate_level_attr = crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4516ea94cad7..8b30546d5cce 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -124,7 +124,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } [sym::inline, ..] => self.check_inline(hir_id, attr, span, target), [sym::coverage, ..] => self.check_coverage(attr, span, target), - [sym::optimize, ..] => self.check_optimize(hir_id, attr, target), + [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target), [sym::no_sanitize, ..] => { self.check_applied_to_fn_or_method(hir_id, attr, span, target) } @@ -433,23 +433,19 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks that `#[optimize(..)]` is applied to a function/closure/method, /// or to an impl block or module. - // FIXME(#128488): this should probably be elevated to an error? - fn check_optimize(&self, hir_id: HirId, attr: &Attribute, target: Target) { - match target { + fn check_optimize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) { + let is_valid = matches!( + target, Target::Fn - | Target::Closure - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) - | Target::Impl - | Target::Mod => {} - - _ => { - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::OptimizeNotFnOrClosure, - ); - } + | Target::Closure + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) + ); + if !is_valid { + self.dcx().emit_err(errors::OptimizeInvalidTarget { + attr_span: attr.span, + defn_span: span, + on_crate: hir_id == CRATE_HIR_ID, + }); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6dc3dfba58f0..f01ddbd47efe 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -76,9 +76,15 @@ pub(crate) struct CoverageNotFnOrClosure { pub defn_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_optimize_not_fn_or_closure)] -pub(crate) struct OptimizeNotFnOrClosure; +#[derive(Diagnostic)] +#[diag(passes_optimize_invalid_target)] +pub(crate) struct OptimizeInvalidTarget { + #[primary_span] + pub attr_span: Span, + #[label] + pub defn_span: Span, + pub on_crate: bool, +} #[derive(Diagnostic)] #[diag(passes_should_be_applied_to_fn)] diff --git a/tests/ui/attributes/optimize.rs b/tests/ui/attributes/optimize.rs index b01806165c1f..7a1cc1be9eec 100644 --- a/tests/ui/attributes/optimize.rs +++ b/tests/ui/attributes/optimize.rs @@ -3,11 +3,13 @@ #![deny(unused_attributes)] #![allow(dead_code)] -#[optimize(speed)] //~ ERROR attribute should be applied to function or closure +//@ edition: 2018 + +#[optimize(speed)] //~ ERROR attribute applied to an invalid target struct F; fn invalid() { - #[optimize(speed)] //~ ERROR attribute should be applied to function or closure + #[optimize(speed)] //~ ERROR attribute applied to an invalid target { 1 }; @@ -16,13 +18,25 @@ fn invalid() { #[optimize(speed)] fn valid() {} -#[optimize(speed)] +#[optimize(speed)] //~ ERROR attribute applied to an invalid target mod valid_module {} -#[optimize(speed)] +#[optimize(speed)] //~ ERROR attribute applied to an invalid target impl F {} fn main() { let _ = #[optimize(speed)] (|| 1); } + +use std::future::Future; + +fn async_block() -> impl Future { + #[optimize(speed)] + async { } +} + +#[optimize(speed)] +async fn async_fn() { + () +} diff --git a/tests/ui/attributes/optimize.stderr b/tests/ui/attributes/optimize.stderr index 3c445d73c2ed..ad9309d27a5a 100644 --- a/tests/ui/attributes/optimize.stderr +++ b/tests/ui/attributes/optimize.stderr @@ -1,20 +1,36 @@ -error: attribute should be applied to function or closure - --> $DIR/optimize.rs:6:1 +error: attribute applied to an invalid target + --> $DIR/optimize.rs:8:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/optimize.rs:3:9 - | -LL | #![deny(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ +LL | struct F; + | --------- invalid target -error: attribute should be applied to function or closure - --> $DIR/optimize.rs:10:5 +error: attribute applied to an invalid target + --> $DIR/optimize.rs:12:5 | -LL | #[optimize(speed)] - | ^^^^^^^^^^^^^^^^^^ +LL | #[optimize(speed)] + | ^^^^^^^^^^^^^^^^^^ +LL | / { +LL | | 1 +LL | | }; + | |_____- invalid target -error: aborting due to 2 previous errors +error: attribute applied to an invalid target + --> $DIR/optimize.rs:21:1 + | +LL | #[optimize(speed)] + | ^^^^^^^^^^^^^^^^^^ +LL | mod valid_module {} + | ------------------- invalid target + +error: attribute applied to an invalid target + --> $DIR/optimize.rs:24:1 + | +LL | #[optimize(speed)] + | ^^^^^^^^^^^^^^^^^^ +LL | impl F {} + | --------- invalid target + +error: aborting due to 4 previous errors diff --git a/tests/ui/coroutine/other-attribute-on-gen.rs b/tests/ui/coroutine/other-attribute-on-gen.rs new file mode 100644 index 000000000000..0f26dc6860dd --- /dev/null +++ b/tests/ui/coroutine/other-attribute-on-gen.rs @@ -0,0 +1,40 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ run-pass +#![feature(gen_blocks)] +#![feature(optimize_attribute)] +#![feature(stmt_expr_attributes)] +#![feature(async_iterator)] +#![allow(dead_code)] + +// make sure that other attributes e.g. `optimize` can be applied to gen blocks and functions + +fn main() { } + +fn optimize_gen_block() -> impl Iterator { + #[optimize(speed)] + gen { yield (); } +} + +#[optimize(speed)] +gen fn optimize_gen_fn() -> i32 { + yield 1; + yield 2; + yield 3; +} + +#[optimize(speed)] +async gen fn optimize_async_gen_fn() -> i32 { + yield 1; + yield 2; + yield 3; +} + +use std::async_iter::AsyncIterator; + +pub fn deduce() -> impl AsyncIterator { + #[optimize(size)] + async gen { + yield (); + } +} diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs index 15aa3a6af4ca..7f9cada6a47d 100644 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.rs +++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.rs @@ -1,8 +1,4 @@ #![crate_type="rlib"] -#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature - -#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature -mod module { #[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature fn size() {} @@ -14,5 +10,3 @@ fn speed() {} //~^ ERROR the `#[optimize]` attribute is an experimental feature //~| ERROR E0722 fn not_known() {} - -} diff --git a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr index 609526150ba2..ca8f4a078f09 100644 --- a/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr +++ b/tests/ui/feature-gates/feature-gate-optimize_attribute.stderr @@ -1,15 +1,5 @@ error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:2:1 - | -LL | #![optimize(speed)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:4:1 + --> $DIR/feature-gate-optimize_attribute.rs:3:1 | LL | #[optimize(size)] | ^^^^^^^^^^^^^^^^^ @@ -19,17 +9,7 @@ LL | #[optimize(size)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:7:1 - | -LL | #[optimize(size)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #54882 for more information - = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:10:1 + --> $DIR/feature-gate-optimize_attribute.rs:6:1 | LL | #[optimize(speed)] | ^^^^^^^^^^^^^^^^^^ @@ -39,7 +19,7 @@ LL | #[optimize(speed)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: the `#[optimize]` attribute is an experimental feature - --> $DIR/feature-gate-optimize_attribute.rs:13:1 + --> $DIR/feature-gate-optimize_attribute.rs:9:1 | LL | #[optimize(banana)] | ^^^^^^^^^^^^^^^^^^^ @@ -49,12 +29,12 @@ LL | #[optimize(banana)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0722]: invalid argument - --> $DIR/feature-gate-optimize_attribute.rs:13:12 + --> $DIR/feature-gate-optimize_attribute.rs:9:12 | LL | #[optimize(banana)] | ^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0658, E0722. For more information about an error, try `rustc --explain E0658`. From 8640c43c684a1d11f6aad2ccc86accc6844981ac Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 17 Oct 2024 08:32:40 +0200 Subject: [PATCH 118/118] data-race test: disable address reuse that can incur accidental sync --- src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs index f4c009456d29..55491da9f60d 100644 --- a/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs +++ b/src/tools/miri/tests/fail-dep/libc/socketpair-data-race.rs @@ -1,7 +1,7 @@ //! This is a regression test for : we had some //! faulty logic around `release_clock` that led to this code not reporting a data race. //@ignore-target: windows # no libc socketpair on Windows -//@compile-flags: -Zmiri-preemption-rate=0 +//@compile-flags: -Zmiri-preemption-rate=0 -Zmiri-address-reuse-rate=0 use std::thread; fn main() {