From 04d9d864b39c56aa6efa6b5f7845b4735d7a6428 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 31 Mar 2025 14:53:39 +0800 Subject: [PATCH 01/17] std: clarify Mutex::get_mut more clearly Signed-off-by: xizheyin --- library/std/src/sync/poison/mutex.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 9362c764173a8..adb74bb6f3de7 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -582,7 +582,9 @@ impl Mutex { /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `Mutex` mutably, no actual locking needs to - /// take place -- the mutable borrow statically guarantees no locks exist. + /// take place -- the mutable borrow statically guarantees no new locks can be acquired + /// while this reference exists. Note that this method does not clear any previous abandoned locks + /// (e.g., via [`forget()`] on a [`MutexGuard`]). /// /// # Errors /// @@ -599,6 +601,8 @@ impl Mutex { /// *mutex.get_mut().unwrap() = 10; /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` + /// + /// [`forget()`]: mem::forget #[stable(feature = "mutex_get_mut", since = "1.6.0")] pub fn get_mut(&mut self) -> LockResult<&mut T> { let data = self.data.get_mut(); From ffb209710568fcb09d6971a509e6c64689da4982 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 31 Mar 2025 15:07:51 +0800 Subject: [PATCH 02/17] std: clarify RefCell::get_mut more clearly Signed-off-by: xizheyin --- library/core/src/cell.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 1a320b316a41a..420b08079379d 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1163,7 +1163,9 @@ impl RefCell { /// Since this method borrows `RefCell` mutably, it is statically guaranteed /// that no borrows to the underlying data exist. The dynamic checks inherent /// in [`borrow_mut`] and most other methods of `RefCell` are therefore - /// unnecessary. + /// unnecessary. Note that this method does not reset the borrowing state if borrows were previously leaked + /// (e.g., via [`forget()`] on a [`Ref`] or [`RefMut`]). For that purpose, + /// consider using the unstable [`undo_leak`] method. /// /// This method can only be called if `RefCell` can be mutably borrowed, /// which in general is only the case directly after the `RefCell` has @@ -1174,6 +1176,8 @@ impl RefCell { /// Use [`borrow_mut`] to get mutable access to the underlying data then. /// /// [`borrow_mut`]: RefCell::borrow_mut() + /// [`forget()`]: mem::forget + /// [`undo_leak`]: RefCell::undo_leak() /// /// # Examples /// From 0162f29436d7992ca5f3b642a282045afd922a26 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Mon, 31 Mar 2025 15:11:23 +0800 Subject: [PATCH 03/17] std: clarify RwLock::get_mut more clearly Signed-off-by: xizheyin --- library/std/src/sync/poison/rwlock.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index f9d9321f5f2d8..a2abd4f692ec2 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -608,7 +608,9 @@ impl RwLock { /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `RwLock` mutably, no actual locking needs to - /// take place -- the mutable borrow statically guarantees no locks exist. + /// take place -- the mutable borrow statically guarantees no new locks can be acquired + /// while this reference exists. Note that this method does not clear any previously abandoned locks + /// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]). /// /// # Errors /// From 39c6b6c7d2834ee79cc518c42995b54d835544f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 7 Apr 2025 17:28:38 +0200 Subject: [PATCH 04/17] Fix CSS --- src/librustdoc/html/static/css/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index aa8df35258dff..74d23b3143f44 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1447,7 +1447,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ cursor: pointer; } .setting-check input { - flex-shrink: 0, + flex-shrink: 0; } .setting-radio input:checked { From 30f56df6f9fe396758213b5d9339e774339f5455 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 7 Apr 2025 17:28:28 +0200 Subject: [PATCH 05/17] Add regression test for #139282 --- tests/rustdoc-gui/settings.goml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 4ab5b83d7c41d..11d3696ccf6a5 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -314,6 +314,13 @@ compare-elements-position: (".sub form", "#settings", ["x"]) // Check that setting-line has the same margin in this mode as in the popover. assert-css: (".setting-line", {"margin": |setting_line_margin|}) +// We will check that the checkboxes size doesn't change either. +assert-size: ( + "#settings label > input[type='checkbox']", + {"width": 19, "height": 19}, + ALL, +) + // We now check the display with JS disabled. assert-false: "noscript section" javascript: false @@ -327,3 +334,10 @@ reload: set-window-size: (300, 1000) wait-for: "#settings" assert-css: (".setting-radio", {"cursor": "pointer"}) + +// We ensure that the checkboxes size didn't change. +assert-size: ( + "#settings label > input[type='checkbox']", + {"width": 19, "height": 19}, + ALL, +) From f2dee82052783ad6447d69aa26869db1f71f04cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Tue, 8 Apr 2025 17:07:41 +0200 Subject: [PATCH 06/17] Update 'u8'-to-and-from-'i8' suggestions; --- library/core/src/num/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 151e128cd78a9..4c51fcf3b5202 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -99,8 +99,8 @@ macro_rules! i8_xe_bytes_doc { **Note**: This function is meaningless on `i8`. Byte order does not exist as a concept for byte-sized integers. This function is only provided in symmetry -with larger integer types. You can cast from and to `u8` using `as i8` and `as -u8`. +with larger integer types. You can cast from and to `u8` using +[`cast_signed`](u8::cast_signed) and [`cast_unsigned`](Self::cast_unsigned). " }; From ec3820a10dbf4976fa19a79bfac945dfee8dd20f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 17 Mar 2025 17:24:02 -0300 Subject: [PATCH 07/17] Add .use block test --- tests/ui/ergonomic-clones/dotuse/block.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/ui/ergonomic-clones/dotuse/block.rs diff --git a/tests/ui/ergonomic-clones/dotuse/block.rs b/tests/ui/ergonomic-clones/dotuse/block.rs new file mode 100644 index 0000000000000..2e423c67d02b7 --- /dev/null +++ b/tests/ui/ergonomic-clones/dotuse/block.rs @@ -0,0 +1,11 @@ +//@ check-pass + +#![feature(ergonomic_clones)] +#![allow(incomplete_features)] + +fn use_block_test(x: i32) -> i32 { + let x = { let x = x + 1; x }.use; + x +} + +fn main() {} From c717c599604c50454933fe58f8a23aa0a0236b5b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 17 Mar 2025 17:24:16 -0300 Subject: [PATCH 08/17] Add multiple closure use variants --- .../closure/multiple-use-variants.rs | 35 +++++++++++++++++++ .../closure/multiple-use-variants.stderr | 13 +++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/ui/ergonomic-clones/closure/multiple-use-variants.rs create mode 100644 tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr diff --git a/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs b/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs new file mode 100644 index 0000000000000..e2e9820a740f2 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/multiple-use-variants.rs @@ -0,0 +1,35 @@ +#![feature(ergonomic_clones)] +#![allow(incomplete_features)] + +use std::clone::UseCloned; + +fn takes_val(_: T) {} +fn takes_ref<'a, T>(_: &'a T) {} + +#[derive(Clone)] +struct Inner<'a, T>(&'a T); + +impl<'a, T> UseCloned for Inner<'a, T> where T: Clone {} + +fn main() { + let v = String::new(); + let inner = Inner(&v); + + let _ = use || { + takes_ref(inner.0); + takes_val(inner.0) + }; + let _ = use || { + takes_ref(inner.0); + takes_val(inner.0); + takes_val(inner.0); + takes_val(inner) + }; + let _ = use || { + takes_ref(inner.0); + takes_val(inner.0); + takes_val(inner); + takes_val(inner) + //~^ ERROR: use of moved value: `inner` [E0382] + }; +} diff --git a/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr b/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr new file mode 100644 index 0000000000000..7b25ca9bba83a --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/multiple-use-variants.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `inner` + --> $DIR/multiple-use-variants.rs:32:19 + | +LL | takes_val(inner); + | ----- value moved here +LL | takes_val(inner) + | ^^^^^ value used here after move + | + = note: move occurs because `inner` has type `Inner<'_, String>`, which does not implement the `Copy` trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. From 3f21ebcb7a7cdb11c29a5f47718ad6a5b0e12fdd Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 13 Mar 2025 18:31:34 -0300 Subject: [PATCH 09/17] Test interaction between RFC 2229 migration and use closures --- .../closure/rfc2229-migration.fixed | 26 ++++++++++++++++++ .../closure/rfc2229-migration.rs | 25 +++++++++++++++++ .../closure/rfc2229-migration.stderr | 27 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed create mode 100644 tests/ui/ergonomic-clones/closure/rfc2229-migration.rs create mode 100644 tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed b/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed new file mode 100644 index 0000000000000..fa83b53526a85 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.fixed @@ -0,0 +1,26 @@ +//@ run-rustfix +//@ edition:2018 +//@ check-pass +#![feature(ergonomic_clones)] +#![warn(rust_2021_compatibility)] +#![allow(incomplete_features)] + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +fn main() { + let a = (Foo(0), Foo(1)); + let f = use || { + let _ = &a; + //~^ HELP: add a dummy + //~| WARNING: drop order + let x = a.0; + println!("{:?}", x); + }; + f(); +} diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs b/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs new file mode 100644 index 0000000000000..4070e5c35a441 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.rs @@ -0,0 +1,25 @@ +//@ run-rustfix +//@ edition:2018 +//@ check-pass +#![feature(ergonomic_clones)] +#![warn(rust_2021_compatibility)] +#![allow(incomplete_features)] + +#[derive(Debug)] +struct Foo(i32); +impl Drop for Foo { + fn drop(&mut self) { + println!("{:?} dropped", self.0); + } +} + +fn main() { + let a = (Foo(0), Foo(1)); + let f = use || { + //~^ HELP: add a dummy + //~| WARNING: drop order + let x = a.0; + println!("{:?}", x); + }; + f(); +} diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr new file mode 100644 index 0000000000000..b980be6cb86bf --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr @@ -0,0 +1,27 @@ +warning: changes to closure capture in Rust 2021 will affect drop order + --> $DIR/rfc2229-migration.rs:18:13 + | +LL | let f = use || { + | ^^^^^^ +... +LL | let x = a.0; + | --- in Rust 2018, this closure captures all of `a`, but in Rust 2021, it will only capture `a.0` +... +LL | } + | - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure + | + = note: for more information, see +note: the lint level is defined here + --> $DIR/rfc2229-migration.rs:5:9 + | +LL | #![warn(rust_2021_compatibility)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(rust_2021_incompatible_closure_captures)]` implied by `#[warn(rust_2021_compatibility)]` +help: add a dummy let to cause `a` to be fully captured + | +LL ~ let f = use || { +LL + let _ = &a; + | + +warning: 1 warning emitted + From ca4a58241bee6e5cd42ac26a73747cc04a8316c5 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 17 Mar 2025 17:50:36 -0300 Subject: [PATCH 10/17] Add spawn thread test --- .../closure/spawn-thread.edition2018.stderr | 28 +++++++++++ .../ergonomic-clones/closure/spawn-thread.rs | 50 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr create mode 100644 tests/ui/ergonomic-clones/closure/spawn-thread.rs diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr new file mode 100644 index 0000000000000..ac8e1c5fa858d --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr @@ -0,0 +1,28 @@ +error[E0382]: use of moved value: `x` + --> $DIR/spawn-thread.rs:15:42 + | +LL | let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1)); + | - move occurs because `x` has type `(Arc, Arc>, Arc)`, which does not implement the `Copy` trait +LL | for _ in 0..10 { + | -------------- inside of this loop +LL | let handler = std::thread::spawn(use || { + | __________________________________________-^^^^^ +LL | | +LL | | drop((x.0, x.1, x.2)); + | | --- use occurs due to use in closure +LL | | }); + | |_________- value moved here, in previous iteration of loop + | +help: consider moving the expression out of the loop so it is only moved once + | +LL ~ let mut value = std::thread::spawn(use || { +LL + +LL + drop((x.0, x.1, x.2)); +LL + }); +LL ~ for _ in 0..10 { +LL ~ let handler = value; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.rs b/tests/ui/ergonomic-clones/closure/spawn-thread.rs new file mode 100644 index 0000000000000..289d446c6e6f7 --- /dev/null +++ b/tests/ui/ergonomic-clones/closure/spawn-thread.rs @@ -0,0 +1,50 @@ +//@ revisions: edition2018 edition2024 +//@ [edition2018] edition: 2018 +//@ [edition2024] edition: 2024 +//@ [edition2024] check-pass + +#![feature(ergonomic_clones)] +#![allow(incomplete_features)] + +use std::sync::Arc; + +fn foo() { + // The type is a tuple and doesn't implement UseCloned + let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1)); + for _ in 0..10 { + let handler = std::thread::spawn(use || { + //[edition2018]~^ ERROR use of moved value: `x` [E0382] + drop((x.0, x.1, x.2)); + }); + handler.join().unwrap(); + } +} + +fn bar() { + let x = Arc::new("foo".to_owned()); + let y = Arc::new(vec![1, 2, 3]); + let z = Arc::new(1); + + for _ in 0..10 { + let handler = std::thread::spawn(use || { + drop((x, y, z)); + }); + handler.join().unwrap(); + } +} + +fn baz() { + use std::sync::Arc; + use std::thread; + + let five = Arc::new(5); + + for _ in 0..10 { + let handler = thread::spawn(use || { + println!("{five:?}"); + }); + handler.join().unwrap(); + } +} + +fn main() {} From df6254f7a204b383bd8346880247a68dc32cab32 Mon Sep 17 00:00:00 2001 From: Jonathan Gruner Date: Tue, 8 Apr 2025 20:49:50 +0200 Subject: [PATCH 11/17] report call site of inlined scopes for large assignment lints --- .../src/mono_checks/move_check.rs | 20 +++++++++++++--- tests/ui/lint/large_assignments/inline_mir.rs | 24 +++++++++++++++++++ .../lint/large_assignments/inline_mir.stderr | 15 ++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 tests/ui/lint/large_assignments/inline_mir.rs create mode 100644 tests/ui/lint/large_assignments/inline_mir.stderr diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 838bfdab1ea59..946714e3e48a1 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -162,13 +162,27 @@ impl<'tcx> MoveCheckVisitor<'tcx> { // but correct span? This would make the lint at least accept crate-level lint attributes. return; }; + + // If the source scope is inlined by the MIR inliner, report the lint on the call site. + let reported_span = self + .body + .source_scopes + .get(source_info.scope) + .and_then(|source_scope_data| source_scope_data.inlined) + .map(|(_, call_site)| call_site) + .unwrap_or(span); + self.tcx.emit_node_span_lint( LARGE_ASSIGNMENTS, lint_root, - span, - LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 }, + reported_span, + LargeAssignmentsLint { + span: reported_span, + size: too_large_size.bytes(), + limit: limit as u64, + }, ); - self.move_size_spans.push(span); + self.move_size_spans.push(reported_span); } } diff --git a/tests/ui/lint/large_assignments/inline_mir.rs b/tests/ui/lint/large_assignments/inline_mir.rs new file mode 100644 index 0000000000000..fc27b8ff244d1 --- /dev/null +++ b/tests/ui/lint/large_assignments/inline_mir.rs @@ -0,0 +1,24 @@ +#![feature(large_assignments)] +#![deny(large_assignments)] +#![move_size_limit = "1000"] + +//! Tests that with `-Zinline-mir`, we do NOT get an error that points to the +//! implementation of `UnsafeCell` since that is not actionable by the user: +//! +//! ```text +//! error: moving 9999 bytes +//! --> /rustc/FAKE_PREFIX/library/core/src/cell.rs:2054:9 +//! | +//! = note: value moved from here +//! ``` +//! +//! We want the diagnostics to point to the relevant user code. + +//@ build-fail +//@ compile-flags: -Zmir-opt-level=1 -Zinline-mir + +pub fn main() { + let data = [10u8; 9999]; + let cell = std::cell::UnsafeCell::new(data); //~ ERROR large_assignments + std::hint::black_box(cell); +} diff --git a/tests/ui/lint/large_assignments/inline_mir.stderr b/tests/ui/lint/large_assignments/inline_mir.stderr new file mode 100644 index 0000000000000..d9010e24d03be --- /dev/null +++ b/tests/ui/lint/large_assignments/inline_mir.stderr @@ -0,0 +1,15 @@ +error: moving 9999 bytes + --> $DIR/inline_mir.rs:22:16 + | +LL | let cell = std::cell::UnsafeCell::new(data); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here + | + = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` +note: the lint level is defined here + --> $DIR/inline_mir.rs:2:9 + | +LL | #![deny(large_assignments)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 6d71fc15d8983960745bf2f61ab74ca272f0585f Mon Sep 17 00:00:00 2001 From: Jonathan Gruner Date: Tue, 8 Apr 2025 21:22:20 +0200 Subject: [PATCH 12/17] for large assignment lint, use the correct span for checking for duplicate lints --- .../src/mono_checks/move_check.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs index 946714e3e48a1..a484573f0d860 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/move_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/move_check.rs @@ -148,11 +148,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { span: Span, ) { let source_info = self.body.source_info(location); - for reported_span in &self.move_size_spans { - if reported_span.overlaps(span) { - return; - } - } + let lint_root = source_info.scope.lint_root(&self.body.source_scopes); let Some(lint_root) = lint_root else { // This happens when the issue is in a function from a foreign crate that @@ -172,6 +168,12 @@ impl<'tcx> MoveCheckVisitor<'tcx> { .map(|(_, call_site)| call_site) .unwrap_or(span); + for previously_reported_span in &self.move_size_spans { + if previously_reported_span.overlaps(reported_span) { + return; + } + } + self.tcx.emit_node_span_lint( LARGE_ASSIGNMENTS, lint_root, @@ -182,6 +184,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> { limit: limit as u64, }, ); + self.move_size_spans.push(reported_span); } } From 616406d2f186c47ede89b5d54eadc0ac5eae289e Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Tue, 8 Apr 2025 17:20:59 +0800 Subject: [PATCH 13/17] triagebot: roll compiler reviewers for rustc/unstable book --- triagebot.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 756536dc2e7b9..8a7797bd1ffe6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1338,9 +1338,11 @@ compiletest = [ "/src/doc/nomicon" = ["@ehuss"] "/src/doc/reference" = ["@ehuss"] "/src/doc/rust-by-example" = ["@ehuss"] +"/src/doc/rustc" = ["compiler", "@ehuss"] "/src/doc/rustc-dev-guide" = ["compiler"] "/src/doc/rustdoc" = ["rustdoc"] "/src/doc/style-guide" = ["style-team"] +"/src/doc/unstable-book" = ["compiler"] "/src/etc" = ["@Mark-Simulacrum"] "/src/librustdoc" = ["rustdoc"] "/src/llvm-project" = ["@cuviper"] From cffc5c21fc49e86859ea5601a4f80d4446b594e9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 7 Apr 2025 17:28:58 +0300 Subject: [PATCH 14/17] compiletest: Add directive `dont-require-annotations` for making matching on specific diagnostic kinds non-exhaustive --- src/tools/compiletest/src/directive-list.rs | 1 + src/tools/compiletest/src/errors.rs | 11 +++++++++- src/tools/compiletest/src/header.rs | 20 ++++++++++++++++- src/tools/compiletest/src/runtest.rs | 24 ++++++++++----------- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index b2ad5a3b3d0bb..44d9c0330f76e 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -22,6 +22,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "dont-check-compiler-stderr", "dont-check-compiler-stdout", "dont-check-failure-status", + "dont-require-annotations", "edition", "error-pattern", "exact-llvm-major-version", diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 9b59e4968a3dc..64d68eb7f23e5 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -8,7 +8,7 @@ use std::sync::OnceLock; use regex::Regex; use tracing::*; -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ErrorKind { Help, Error, @@ -40,6 +40,15 @@ impl ErrorKind { _ => return None, }) } + + pub fn expect_from_user_str(s: &str) -> ErrorKind { + ErrorKind::from_user_str(s).unwrap_or_else(|| { + panic!( + "unexpected diagnostic kind `{s}`, expected \ + `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`" + ) + }) + } } impl fmt::Display for ErrorKind { diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index a0178f4bcc576..36a9e5df5839b 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::BufReader; @@ -11,6 +11,7 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; +use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; use crate::header::needs::CachedNeedsConditions; @@ -196,6 +197,8 @@ pub struct TestProps { /// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios /// that don't otherwise want/need `-Z build-std`. pub add_core_stubs: bool, + /// Whether line annotatins are required for the given error kind. + pub require_annotations: HashMap, } mod directives { @@ -212,6 +215,7 @@ mod directives { pub const CHECK_RUN_RESULTS: &'static str = "check-run-results"; pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout"; pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr"; + pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations"; pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic"; pub const PRETTY_MODE: &'static str = "pretty-mode"; pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only"; @@ -297,6 +301,13 @@ impl TestProps { no_auto_check_cfg: false, has_enzyme: false, add_core_stubs: false, + require_annotations: HashMap::from([ + (ErrorKind::Help, true), + (ErrorKind::Note, true), + (ErrorKind::Error, true), + (ErrorKind::Warning, true), + (ErrorKind::Suggestion, false), + ]), } } @@ -570,6 +581,13 @@ impl TestProps { config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg); self.update_add_core_stubs(ln, config); + + if let Some(err_kind) = + config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) + { + self.require_annotations + .insert(ErrorKind::expect_from_user_str(&err_kind), false); + } }, ); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 13f3479247a23..872f5f6ce2967 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -710,10 +710,6 @@ impl<'test> TestCx<'test> { self.testpaths.file.display().to_string() }; - // If the testcase being checked contains at least one expected "help" - // message, then we'll ensure that all "help" messages are expected. - // Otherwise, all "help" messages reported by the compiler will be ignored. - // This logic also applies to "note" messages. let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help)); let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note)); @@ -801,9 +797,7 @@ impl<'test> TestCx<'test> { } /// Returns `true` if we should report an error about `actual_error`, - /// which did not match any of the expected error. We always require - /// errors/warnings to be explicitly listed, but only require - /// helps/notes if there are explicit helps/notes given. + /// which did not match any of the expected error. fn is_unexpected_compiler_message( &self, actual_error: &Error, @@ -811,12 +805,16 @@ impl<'test> TestCx<'test> { expect_note: bool, ) -> bool { actual_error.require_annotation - && match actual_error.kind { - Some(ErrorKind::Help) => expect_help, - Some(ErrorKind::Note) => expect_note, - Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true, - Some(ErrorKind::Suggestion) | None => false, - } + && actual_error.kind.map_or(false, |err_kind| { + // If the test being checked doesn't contain any "help" or "note" annotations, then + // we don't require annotating "help" or "note" (respecively) diagnostics at all. + let default_require_annotations = self.props.require_annotations[&err_kind]; + match err_kind { + ErrorKind::Help => expect_help && default_require_annotations, + ErrorKind::Note => expect_note && default_require_annotations, + _ => default_require_annotations, + } + }) } fn should_emit_metadata(&self, pm: Option) -> Emit { From 12829122bf2216e492e2befb0c1305b5efbfee7d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 9 Apr 2025 09:51:50 +0300 Subject: [PATCH 15/17] Migrate some tests to `dont-require-annotations` --- tests/ui/cfg/cfg_false_no_std-2.rs | 8 ++++---- tests/ui/panic-runtime/two-panic-runtimes.rs | 8 ++++---- tests/ui/panic-runtime/want-abort-got-unwind.rs | 8 ++++---- tests/ui/panic-runtime/want-abort-got-unwind2.rs | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ui/cfg/cfg_false_no_std-2.rs b/tests/ui/cfg/cfg_false_no_std-2.rs index 35e545aae34b8..349c49412ffa0 100644 --- a/tests/ui/cfg/cfg_false_no_std-2.rs +++ b/tests/ui/cfg/cfg_false_no_std-2.rs @@ -1,7 +1,6 @@ // Error, the linked empty library is `no_std` and doesn't provide a panic handler. -//@ compile-flags: --error-format=human -//@ error-pattern: `#[panic_handler]` function required, but not found +//@ dont-require-annotations:ERROR //@ dont-check-compiler-stderr //@ aux-build: cfg_false_lib_no_std_before.rs @@ -11,6 +10,7 @@ extern crate cfg_false_lib_no_std_before as _; fn main() {} -// FIXME: The second error is target-dependent. -//FIXME~? ERROR `#[panic_handler]` function required, but not found +//~? ERROR `#[panic_handler]` function required, but not found +// FIXME: This error is target-dependent, could be served by some "optional error" annotation +// instead of `dont-require-annotations`. //FIXME~? ERROR unwinding panics are not supported without std diff --git a/tests/ui/panic-runtime/two-panic-runtimes.rs b/tests/ui/panic-runtime/two-panic-runtimes.rs index 15c08cbe30d36..7add07ef60045 100644 --- a/tests/ui/panic-runtime/two-panic-runtimes.rs +++ b/tests/ui/panic-runtime/two-panic-runtimes.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength //@ build-fail -//@ compile-flags: --error-format=human -//@ error-pattern: cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2 +//@ dont-require-annotations:ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ aux-build:panic-runtime-unwind2.rs @@ -16,7 +15,8 @@ extern crate panic_runtime_lang_items; fn main() {} -// FIXME: The second and third errors are target-dependent. -//FIXME~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2 +//~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2 +// FIXME: These errors are target-dependent, could be served by some "optional error" annotation +// instead of `dont-require-annotations`. //FIXME~? ERROR the linked panic runtime `panic_runtime_unwind2` is not compiled with this crate's panic strategy `abort` //FIXME~? ERROR the crate `panic_runtime_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort` diff --git a/tests/ui/panic-runtime/want-abort-got-unwind.rs b/tests/ui/panic-runtime/want-abort-got-unwind.rs index ed61c2613df80..1ae2e623f1030 100644 --- a/tests/ui/panic-runtime/want-abort-got-unwind.rs +++ b/tests/ui/panic-runtime/want-abort-got-unwind.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength //@ build-fail -//@ compile-flags: --error-format=human -//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` +//@ dont-require-annotations:ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ compile-flags:-C panic=abort @@ -10,7 +9,8 @@ extern crate panic_runtime_unwind; fn main() {} -// FIXME: The first and third errors are target-dependent. +//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` +// FIXME: These errors are target-dependent, could be served by some "optional error" annotation +// instead of `dont-require-annotations`. //FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind -//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` //FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort` diff --git a/tests/ui/panic-runtime/want-abort-got-unwind2.rs b/tests/ui/panic-runtime/want-abort-got-unwind2.rs index 504fd779e09ac..dc4d3ea86d865 100644 --- a/tests/ui/panic-runtime/want-abort-got-unwind2.rs +++ b/tests/ui/panic-runtime/want-abort-got-unwind2.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength //@ build-fail -//@ compile-flags: --error-format=human -//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` +//@ dont-require-annotations:ERROR //@ dont-check-compiler-stderr //@ aux-build:panic-runtime-unwind.rs //@ aux-build:wants-panic-runtime-unwind.rs @@ -11,7 +10,8 @@ extern crate wants_panic_runtime_unwind; fn main() {} -// FIXME: The first and third errors are target-dependent. +//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` +// FIXME: These errors are target-dependent, could be served by some "optional error" annotation +// instead of `dont-require-annotations`. //FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind -//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort` //FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort` From 069fd0258853a0511bfa202a7983abffbae16115 Mon Sep 17 00:00:00 2001 From: timesince Date: Wed, 9 Apr 2025 18:46:50 +0800 Subject: [PATCH 16/17] Remove redundant words --- compiler/rustc_abi/src/lib.rs | 2 +- library/core/src/clone.rs | 2 +- src/doc/rustc-dev-guide/src/solve/opaque-types.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 843d5ca61dddb..59b74d2922145 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1829,7 +1829,7 @@ pub struct PointeeInfo { pub safe: Option, /// If `safe` is `Some`, then the pointer is either null or dereferenceable for this many bytes. /// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration - /// of this function call", i.e. it is UB for the memory that this pointer points to to be freed + /// of this function call", i.e. it is UB for the memory that this pointer points to be freed /// while this function is still running. /// The size can be zero if the pointer is not dereferenceable. pub size: Size, diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index e0ac0bfc5289f..647463098610d 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -427,7 +427,7 @@ pub unsafe trait CloneToUninit { /// read or dropped, because even if it was previously valid, it may have been partially /// overwritten. /// - /// The caller may wish to to take care to deallocate the allocation pointed to by `dest`, + /// The caller may wish to take care to deallocate the allocation pointed to by `dest`, /// if applicable, to avoid a memory leak (but this is not a requirement). /// /// Implementors should avoid leaking values by, upon unwinding, dropping all component values diff --git a/src/doc/rustc-dev-guide/src/solve/opaque-types.md b/src/doc/rustc-dev-guide/src/solve/opaque-types.md index 672aab7708018..509c34a4d3a75 100644 --- a/src/doc/rustc-dev-guide/src/solve/opaque-types.md +++ b/src/doc/rustc-dev-guide/src/solve/opaque-types.md @@ -33,7 +33,7 @@ For opaque types in the defining scope and in the implicit-negative coherence mo always done in two steps. Outside of the defining scope `normalizes-to` for opaques always returns `Err(NoSolution)`. -We start by trying to to assign the expected type as a hidden type. +We start by trying to assign the expected type as a hidden type. In the implicit-negative coherence mode, this currently always results in ambiguity without interacting with the opaque types storage. We could instead add allow 'defining' all opaque types, From f6faaee372c1f7fcf2b9ab49310ed07a94620722 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 8 Apr 2025 05:18:17 +0000 Subject: [PATCH 17/17] Report higher-ranked trait error when higher-ranked projection goal fails in new solver --- .../src/solve/fulfill/derive_errors.rs | 36 +++++++++- ...om-env-universe-err-project.current.stderr | 4 +- ...-from-env-universe-err-project.next.stderr | 26 ++----- ...candidate-from-env-universe-err-project.rs | 5 +- ...stderr => closure-mismatch.current.stderr} | 8 +-- .../closure-mismatch.next.stderr | 67 +++++++++++++++++++ tests/ui/mismatched_types/closure-mismatch.rs | 14 ++-- 7 files changed, 122 insertions(+), 38 deletions(-) rename tests/ui/mismatched_types/{closure-mismatch.stderr => closure-mismatch.current.stderr} (90%) create mode 100644 tests/ui/mismatched_types/closure-mismatch.next.stderr diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 3a939df25e07b..9cbe4147fb4ab 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -291,6 +291,34 @@ impl<'tcx> BestObligation<'tcx> { } } + /// When a higher-ranked projection goal fails, check that the corresponding + /// higher-ranked trait goal holds or not. This is because the process of + /// instantiating and then re-canonicalizing the binder of the projection goal + /// forces us to be unable to see that the leak check failed in the nested + /// `NormalizesTo` goal, so we don't fall back to the rigid projection check + /// that should catch when a projection goal fails due to an unsatisfied trait + /// goal. + fn detect_error_in_higher_ranked_projection( + &mut self, + goal: &inspect::InspectGoal<'_, 'tcx>, + ) -> ControlFlow> { + let tcx = goal.infcx().tcx; + if let Some(projection_clause) = goal.goal().predicate.as_projection_clause() + && !projection_clause.bound_vars().is_empty() + { + let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(tcx)); + self.with_derived_obligation(self.obligation.with(tcx, pred), |this| { + goal.infcx().visit_proof_tree_at_depth( + goal.goal().with(tcx, pred), + goal.depth() + 1, + this, + ) + }) + } else { + ControlFlow::Continue(()) + } + } + /// It is likely that `NormalizesTo` failed without any applicable candidates /// because the alias is not well-formed. /// @@ -374,7 +402,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { source: CandidateSource::Impl(impl_def_id), result: _, } = candidate.kind() - && goal.infcx().tcx.do_not_recommend_impl(impl_def_id) + && tcx.do_not_recommend_impl(impl_def_id) { trace!("#[do_not_recommend] -> exit"); return ControlFlow::Break(self.obligation.clone()); @@ -486,7 +514,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { if let Some(obligation) = goal .infcx() .visit_proof_tree_at_depth( - goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())), + goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())), goal.depth() + 1, self, ) @@ -496,7 +524,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } else if let Some(obligation) = goal .infcx() .visit_proof_tree_at_depth( - goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())), + goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())), goal.depth() + 1, self, ) @@ -506,6 +534,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> { } } + self.detect_error_in_higher_ranked_projection(goal)?; + ControlFlow::Break(self.obligation.clone()) } } diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr index 7b9fd6bb4c571..c8394575e71de 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr @@ -13,7 +13,7 @@ LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:53:30 + --> $DIR/candidate-from-env-universe-err-project.rs:52:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -22,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); found associated type `>::Assoc` error[E0308]: mismatched types - --> $DIR/candidate-from-env-universe-err-project.rs:53:30 + --> $DIR/candidate-from-env-universe-err-project.rs:52:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 6e0ec5620da0c..468dc3b082e5c 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -22,38 +22,20 @@ note: required by a bound in `projection_bound` LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound` -error[E0271]: type mismatch resolving `>::Assoc == usize` - --> $DIR/candidate-from-env-universe-err-project.rs:38:24 - | -LL | projection_bound::(); - | ^ type mismatch resolving `>::Assoc == usize` - | -note: types differ - --> $DIR/candidate-from-env-universe-err-project.rs:14:18 - | -LL | type Assoc = usize; - | ^^^^^ -note: required by a bound in `projection_bound` - --> $DIR/candidate-from-env-universe-err-project.rs:18:42 - | -LL | fn projection_bound Trait<'a, Assoc = usize>>() {} - | ^^^^^^^^^^^^^ required by this bound in `projection_bound` - error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:53:30 + --> $DIR/candidate-from-env-universe-err-project.rs:52:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/candidate-from-env-universe-err-project.rs:53:30 + --> $DIR/candidate-from-env-universe-err-project.rs:52:30 | LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -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/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs index a77d87f6fa78e..d70e392238218 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs @@ -36,9 +36,8 @@ fn function2>() { // does not use the leak check when trying the where-bound, causing us // to prefer it over the impl, resulting in a placeholder error. projection_bound::(); - //[next]~^ ERROR type mismatch resolving `>::Assoc == usize` - //[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied - //[current]~^^^ ERROR mismatched types + //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied + //[current]~^^ ERROR mismatched types } fn function3>() { diff --git a/tests/ui/mismatched_types/closure-mismatch.stderr b/tests/ui/mismatched_types/closure-mismatch.current.stderr similarity index 90% rename from tests/ui/mismatched_types/closure-mismatch.stderr rename to tests/ui/mismatched_types/closure-mismatch.current.stderr index 802110c6511de..378fe83ea89bd 100644 --- a/tests/ui/mismatched_types/closure-mismatch.stderr +++ b/tests/ui/mismatched_types/closure-mismatch.current.stderr @@ -1,5 +1,5 @@ error: implementation of `FnOnce` is not general enough - --> $DIR/closure-mismatch.rs:8:5 + --> $DIR/closure-mismatch.rs:12:5 | LL | baz(|_| ()); | ^^^^^^^^^^^ implementation of `FnOnce` is not general enough @@ -8,7 +8,7 @@ LL | baz(|_| ()); = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` error: implementation of `Fn` is not general enough - --> $DIR/closure-mismatch.rs:8:5 + --> $DIR/closure-mismatch.rs:12:5 | LL | baz(|_| ()); | ^^^^^^^^^^^ implementation of `Fn` is not general enough @@ -17,7 +17,7 @@ LL | baz(|_| ()); = note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough - --> $DIR/closure-mismatch.rs:11:5 + --> $DIR/closure-mismatch.rs:16:5 | LL | baz(|x| ()); | ^^^^^^^^^^^ implementation of `FnOnce` is not general enough @@ -26,7 +26,7 @@ LL | baz(|x| ()); = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` error: implementation of `Fn` is not general enough - --> $DIR/closure-mismatch.rs:11:5 + --> $DIR/closure-mismatch.rs:16:5 | LL | baz(|x| ()); | ^^^^^^^^^^^ implementation of `Fn` is not general enough diff --git a/tests/ui/mismatched_types/closure-mismatch.next.stderr b/tests/ui/mismatched_types/closure-mismatch.next.stderr new file mode 100644 index 0000000000000..6b4620aa8d1ba --- /dev/null +++ b/tests/ui/mismatched_types/closure-mismatch.next.stderr @@ -0,0 +1,67 @@ +error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}: Foo` is not satisfied + --> $DIR/closure-mismatch.rs:12:9 + | +LL | baz(|_| ()); + | --- ^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | + = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` + = note: expected a closure with signature `for<'a> fn(&'a ())` + found a closure with signature `fn(&())` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/closure-mismatch.rs:12:9 + | +LL | baz(|_| ()); + | ----^^^---- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant +note: required for `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` to implement `Foo` + --> $DIR/closure-mismatch.rs:7:18 + | +LL | impl Foo for T {} + | ------- ^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `baz` + --> $DIR/closure-mismatch.rs:9:11 + | +LL | fn baz(_: T) {} + | ^^^ required by this bound in `baz` + +error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}: Foo` is not satisfied + --> $DIR/closure-mismatch.rs:16:9 + | +LL | baz(|x| ()); + | --- ^^^^^^ unsatisfied trait bound + | | + | required by a bound introduced by this call + | + = help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` + = note: expected a closure with signature `for<'a> fn(&'a ())` + found a closure with signature `fn(&())` +note: this is a known limitation of the trait solver that will be lifted in the future + --> $DIR/closure-mismatch.rs:16:9 + | +LL | baz(|x| ()); + | ----^^^---- + | | | + | | the trait solver is unable to infer the generic types that should be inferred from this argument + | add turbofish arguments to this call to specify the types manually, even if it's redundant +note: required for `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` to implement `Foo` + --> $DIR/closure-mismatch.rs:7:18 + | +LL | impl Foo for T {} + | ------- ^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `baz` + --> $DIR/closure-mismatch.rs:9:11 + | +LL | fn baz(_: T) {} + | ^^^ required by this bound in `baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mismatched_types/closure-mismatch.rs b/tests/ui/mismatched_types/closure-mismatch.rs index efaed4dc1b99d..1a24c760a6af6 100644 --- a/tests/ui/mismatched_types/closure-mismatch.rs +++ b/tests/ui/mismatched_types/closure-mismatch.rs @@ -1,3 +1,7 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + trait Foo {} impl Foo for T {} @@ -6,9 +10,11 @@ fn baz(_: T) {} fn main() { baz(|_| ()); - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `Fn` is not general enough + //[current]~^ ERROR implementation of `FnOnce` is not general enough + //[current]~| ERROR implementation of `Fn` is not general enough + //[next]~^^^ ERROR Foo` is not satisfied baz(|x| ()); - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `Fn` is not general enough + //[current]~^ ERROR implementation of `FnOnce` is not general enough + //[current]~| ERROR implementation of `Fn` is not general enough + //[next]~^^^ ERROR Foo` is not satisfied }