From 60a0782390e2063d2d0a24c798bfd37cb2a42611 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Dec 2022 23:03:31 +0100 Subject: [PATCH 01/34] fix and extend dropck documentation --- library/core/src/marker.rs | 15 +++----- library/core/src/ops/drop.rs | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 07a7d45c7ebc..de285c99cb1f 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -668,16 +668,9 @@ impl !Sync for *mut T {} /// /// ## Ownership and the drop check /// -/// Adding a field of type `PhantomData` indicates that your -/// type owns data of type `T`. This in turn implies that when your -/// type is dropped, it may drop one or more instances of the type -/// `T`. This has bearing on the Rust compiler's [drop check] -/// analysis. -/// -/// If your struct does not in fact *own* the data of type `T`, it is -/// better to use a reference type, like `PhantomData<&'a T>` -/// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so -/// as not to indicate ownership. +/// Adding a field of type `PhantomData` indicates that your type *owns* data of type `T`. This +/// in turn has effects on the Rust compiler's [drop check] analysis, but that only matters in very +/// specific circumstances. For the exact rules, see the [drop check] documentation. /// /// ## Layout /// @@ -685,7 +678,7 @@ impl !Sync for *mut T {} /// * `size_of::>() == 0` /// * `align_of::>() == 1` /// -/// [drop check]: ../../nomicon/dropck.html +/// [drop check]: Drop#drop-check #[lang = "phantom_data"] #[stable(feature = "rust1", since = "1.0.0")] pub struct PhantomData; diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index a2c3d978cc4f..804d2c775fc0 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -132,6 +132,73 @@ /// are `Copy` get implicitly duplicated by the compiler, making it very /// hard to predict when, and how often destructors will be executed. As such, /// these types cannot have destructors. +/// +/// ## Drop check +/// +/// Dropping interacts with the borrow checker in subtle ways: when a type `T` is being implicitly +/// dropped as some variable of this type goes out of scope, the borrow checker needs to ensure that +/// calling `T`'s destructor at this moment is safe. In particular, it also needs to be safe to +/// recursively drop all the fields of `T`. For example, it is crucial that code like the following +/// is being rejected: +/// +/// ```compile_fail,E0597 +/// use std::cell::Cell; +/// +/// struct S<'a>(Cell>>, Box); +/// impl Drop for S<'_> { +/// fn drop(&mut self) { +/// if let Some(r) = self.0.get() { +/// // Print the contents of the `Box` in `r`. +/// println!("{}", r.1); +/// } +/// } +/// } +/// +/// fn main() { +/// // Set up two `S` that point to each other. +/// let s1 = S(Cell::new(None), Box::new(42)); +/// let s2 = S(Cell::new(Some(&s1)), Box::new(42)); +/// s1.0.set(Some(&s2)); +/// // Now they both get dropped. But whichever is the 2nd one +/// // to be dropped will access the `Box` in the first one, +/// // which is a use-after-free! +/// } +/// ``` +/// +/// The Nomicon discusses the need for [drop check in more detail][drop check]. +/// +/// To reject such code, the "drop check" analysis determines which types and lifetimes need to +/// still be live when `T` gets dropped: +/// - If `T` has no drop glue, then trivially nothing is required to be live. This is the case if +/// neither `T` nor any of its (recursive) fields have a destructor (`impl Drop`). [`PhantomData`] +/// and [`ManuallyDrop`] are considered to never have a destructor, no matter their field type. +/// - If `T` has drop glue, then, for all types `U` that are *owned* by any field of `T`, +/// recursively add the types and lifetimes that need to be live when `U` gets dropped. The set of +/// owned types is determined by recursively traversing `T`: +/// - Recursively descend through `PhantomData`, `Box`, tuples, and arrays (including arrays of +/// length 0). +/// - Stop at reference and raw pointer types as well as function pointers and function items; +/// they do not own anything. +/// - Stop at non-composite types (type parameters that remain generic in the current context and +/// base types such as integers and `bool`); these types are owned. +/// - When hitting an ADT with `impl Drop`, stop there; this type is owned. +/// - When hitting an ADT without `impl Drop`, recursively descend to its fields. (For an `enum`, +/// consider all fields of all variants.) +/// - Furthermore, if `T` implements `Drop`, then all generic (lifetime and type) parameters of `T` +/// must be live. +/// +/// In the above example, the last clause implies that `'a` must be live when `S<'a>` is dropped, +/// and hence the example is rejected. If we remove the `impl Drop`, the liveness requirement +/// disappears and the example is accepted. +/// +/// There exists an unstable way for a type to opt-out of the last clause; this is called "drop +/// check eyepatch" or `may_dangle`. For more details on this nightly-only feature, see the +/// [discussion in the Nomicon][nomicon]. +/// +/// [`ManuallyDrop`]: crate::mem::ManuallyDrop +/// [`PhantomData`]: crate::marker::PhantomData +/// [drop check]: ../../nomicon/dropck.html +/// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle #[lang = "drop"] #[stable(feature = "rust1", since = "1.0.0")] #[const_trait] From 967ebb9c3d21d1692b0fa51112eee71c1b4668c4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 15 Feb 2023 11:41:33 +0100 Subject: [PATCH 02/34] add test for may_dangle and ManuallyDrop --- tests/ui/drop/dropck-eyepatch-manuallydrop.rs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/ui/drop/dropck-eyepatch-manuallydrop.rs diff --git a/tests/ui/drop/dropck-eyepatch-manuallydrop.rs b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs new file mode 100644 index 000000000000..ff100cd941fd --- /dev/null +++ b/tests/ui/drop/dropck-eyepatch-manuallydrop.rs @@ -0,0 +1,22 @@ +// check-pass +//! This test checks that dropck knows that ManuallyDrop does not drop its field. +#![feature(dropck_eyepatch)] + +use std::mem::ManuallyDrop; + +struct S(ManuallyDrop); + +unsafe impl<#[may_dangle] T> Drop for S { + fn drop(&mut self) {} +} + +struct NonTrivialDrop<'a>(&'a str); +impl<'a> Drop for NonTrivialDrop<'a> { + fn drop(&mut self) {} +} + +fn main() { + let s = String::from("string"); + let _t = S(ManuallyDrop::new(NonTrivialDrop(&s))); + drop(s); +} From 6989246645ca911bebed10bd0d4b91a9f41406a8 Mon Sep 17 00:00:00 2001 From: vlad20012 Date: Tue, 9 May 2023 18:50:13 +0200 Subject: [PATCH 03/34] Reduce BitSet size used in `Borrows` dataflow analysis --- compiler/rustc_borrowck/src/dataflow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 94939c7e4cd7..167f245361a2 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -328,7 +328,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> { fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain { // bottom = nothing is reserved or activated yet; - BitSet::new_empty(self.borrow_set.len() * 2) + BitSet::new_empty(self.borrow_set.len()) } fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) { From d36e390d8176babedcf326581959958d447170cd Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 26 Mar 2023 16:18:30 +0200 Subject: [PATCH 04/34] Remove and fix useless drop of reference --- compiler/rustc_infer/src/infer/nll_relate/mod.rs | 2 +- compiler/rustc_middle/src/mir/visit.rs | 3 +-- library/std/src/sys/sgx/waitqueue/mod.rs | 2 +- library/std/src/sys/unix/fs.rs | 2 +- library/std/src/thread/tests.rs | 4 +++- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 88a0a81e276d..9c139d17c183 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -828,7 +828,7 @@ where } else { match variables.probe(vid) { TypeVariableValue::Known { value: u } => { - drop(variables); + drop(inner); self.relate(u, u) } TypeVariableValue::Unknown { universe: _universe } => { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 6718605ed0bc..d13b846d96a6 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -880,12 +880,11 @@ macro_rules! make_mir_visitor { ) { let Constant { span, - user_ty, + user_ty: _, // no visit method for this literal, } = constant; self.visit_span($(& $mutability)? *span); - drop(user_ty); // no visit method for this match literal { ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location), ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs index 61bb11d9a6fa..ca649ebd9d5f 100644 --- a/library/std/src/sys/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/sgx/waitqueue/mod.rs @@ -207,7 +207,7 @@ impl WaitQueue { let mut entry_guard = entry.lock(); let tcs = entry_guard.tcs; entry_guard.wake = true; - drop(entry); + drop(entry_guard); Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::Single(tcs) }) } else { Err(guard) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 22d2ae397137..09db5b11dbfd 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1210,7 +1210,7 @@ impl File { // Redox doesn't appear to support `UTIME_OMIT`. // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore // the same as for Redox. - drop(times); + let _ = times; Err(io::const_io_error!( io::ErrorKind::Unsupported, "setting file times not supported", diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 6c9ce6fa0ddb..b65e2572cc5e 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -375,7 +375,9 @@ fn test_scoped_threads_nll() { // this is mostly a *compilation test* for this exact function: fn foo(x: &u8) { thread::scope(|s| { - s.spawn(|| drop(x)); + s.spawn(|| match x { + _ => (), + }); }); } // let's also run it for good measure From 7dab6094bb5ca154e6642b9427cffb3370812409 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 27 Mar 2023 19:29:50 +0200 Subject: [PATCH 05/34] Remove useless drop of copy type --- compiler/rustc_builtin_macros/src/format_foreign.rs | 4 +--- library/core/src/task/poll.rs | 2 +- library/core/src/task/ready.rs | 4 ++-- library/std/src/panicking.rs | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs index bd9e903b6ba2..bd5356575ca8 100644 --- a/compiler/rustc_builtin_macros/src/format_foreign.rs +++ b/compiler/rustc_builtin_macros/src/format_foreign.rs @@ -562,15 +562,13 @@ pub(crate) mod printf { } if let Type = state { - drop(c); type_ = at.slice_between(next).unwrap(); // Don't use `move_to!` here, as we *can* be at the end of the input. at = next; } - drop(c); - drop(next); + let _ = c; // to avoid never used value end = at; let position = InnerSpan::new(start.at, end.at); diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 168516263f19..5283a576d1b2 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -116,7 +116,7 @@ impl Poll { /// let fut = Pin::new(&mut fut); /// /// let num = fut.poll(cx).ready()?; - /// # drop(num); + /// # let _ = num; // to silence unused warning /// // ... use num /// /// Poll::Ready(()) diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs index b1daf545fbe7..8d12625e88d0 100644 --- a/library/core/src/task/ready.rs +++ b/library/core/src/task/ready.rs @@ -22,7 +22,7 @@ use core::task::Poll; /// let fut = Pin::new(&mut fut); /// /// let num = ready!(fut.poll(cx)); -/// # drop(num); +/// # let _ = num; /// // ... use num /// /// Poll::Ready(()) @@ -44,7 +44,7 @@ use core::task::Poll; /// Poll::Ready(t) => t, /// Poll::Pending => return Poll::Pending, /// }; -/// # drop(num); +/// # let _ = num; // to silence unused warning /// # // ... use num /// # /// # Poll::Ready(()) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a46a29cbad60..6d59266b6f83 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -541,7 +541,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { // Lazily, the first time this gets called, run the actual string formatting. self.string.get_or_insert_with(|| { let mut s = String::new(); - drop(s.write_fmt(*inner)); + let _err = s.write_fmt(*inner); s }) } From 28cdbc2a641737b291de4e54f9c6cf070d7309be Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 26 Mar 2023 12:25:08 +0200 Subject: [PATCH 06/34] Uplift clippy::drop_ref to rustc --- compiler/rustc_lint/messages.ftl | 3 + .../rustc_lint/src/drop_forget_useless.rs | 76 +++++++++ compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/lints.rs | 9 ++ tests/ui/lint/drop_ref.rs | 99 ++++++++++++ tests/ui/lint/drop_ref.stderr | 151 ++++++++++++++++++ 6 files changed, 341 insertions(+) create mode 100644 compiler/rustc_lint/src/drop_forget_useless.rs create mode 100644 tests/ui/lint/drop_ref.rs create mode 100644 tests/ui/lint/drop_ref.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 71cf644eb501..7e6d65db0e8d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -520,3 +520,6 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass .specifically = this associated type bound is unsatisfied for `{$proj_ty}` lint_opaque_hidden_inferred_bound_sugg = add this bound + +lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value + .note = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs new file mode 100644 index 000000000000..734a43af4a2d --- /dev/null +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -0,0 +1,76 @@ +use rustc_hir::{Arm, Expr, ExprKind, Node}; +use rustc_span::sym; + +use crate::{lints::DropRefDiag, LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference + /// instead of an owned value. + /// + /// ### Example + /// + /// ```rust + /// # fn operation_that_requires_mutex_to_be_unlocked() {} // just to make it compile + /// # let mutex = std::sync::Mutex::new(1); // just to make it compile + /// let mut lock_guard = mutex.lock(); + /// std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex + /// // still locked + /// operation_that_requires_mutex_to_be_unlocked(); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `drop` on a reference will only drop the + /// reference itself, which is a no-op. It will not call the `drop` method (from + /// the `Drop` trait implementation) on the underlying referenced value, which + /// is likely what was intended. + pub DROP_REF, + Warn, + "calls to `std::mem::drop` with a reference instead of an owned value" +} + +declare_lint_pass!(DropForgetUseless => [DROP_REF]); + +impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + if let ExprKind::Call(path, [arg]) = expr.kind + && let ExprKind::Path(ref qpath) = path.kind + && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id() + && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) + { + let arg_ty = cx.typeck_results().expr_ty(arg); + let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); + match fn_name { + sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { + cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, note: arg.span }); + }, + _ => return, + }; + } + } +} + +// Dropping returned value of a function, as in the following snippet is considered idiomatic, see +// rust-lang/rust-clippy#9482 for examples. +// +// ``` +// match { +// => drop(fn_with_side_effect_and_returning_some_value()), +// .. +// } +// ``` +fn is_single_call_in_arm<'tcx>( + cx: &LateContext<'tcx>, + arg: &'tcx Expr<'_>, + drop_expr: &'tcx Expr<'_>, +) -> bool { + if matches!(arg.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)) { + let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id); + if let Some(Node::Arm(Arm { body, .. })) = &parent_node { + return body.hir_id == drop_expr.hir_id; + } + } + false +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 319eb2ea445e..5c7016633c2d 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -52,6 +52,7 @@ mod array_into_iter; pub mod builtin; mod context; mod deref_into_dyn_supertrait; +mod drop_forget_useless; mod early; mod enum_intrinsics_non_enums; mod errors; @@ -96,6 +97,7 @@ use rustc_span::Span; use array_into_iter::ArrayIntoIter; use builtin::*; use deref_into_dyn_supertrait::*; +use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use hidden_unicode_codepoints::*; @@ -201,6 +203,7 @@ late_lint_methods!( [ ForLoopsOverFallibles: ForLoopsOverFallibles, DerefIntoDynSupertrait: DerefIntoDynSupertrait, + DropForgetUseless: DropForgetUseless, HardwiredLints: HardwiredLints, ImproperCTypesDeclarations: ImproperCTypesDeclarations, ImproperCTypesDefinitions: ImproperCTypesDefinitions, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index d7bacc6485f1..a8696c81ab63 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -662,6 +662,15 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { pub end_span: Span, } +// drop_ref.rs +#[derive(LintDiagnostic)] +#[diag(lint_drop_ref)] +pub struct DropRefDiag<'a> { + pub arg_ty: Ty<'a>, + #[note] + pub note: Span, +} + // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] diff --git a/tests/ui/lint/drop_ref.rs b/tests/ui/lint/drop_ref.rs new file mode 100644 index 000000000000..db4f7569f6fa --- /dev/null +++ b/tests/ui/lint/drop_ref.rs @@ -0,0 +1,99 @@ +// check-pass + +#![warn(drop_ref)] + +struct SomeStruct; + +fn main() { + drop(&SomeStruct); //~ WARN calls to `std::mem::drop` + + let mut owned1 = SomeStruct; + drop(&owned1); //~ WARN calls to `std::mem::drop` + drop(&&owned1); //~ WARN calls to `std::mem::drop` + drop(&mut owned1); //~ WARN calls to `std::mem::drop` + drop(owned1); + + let reference1 = &SomeStruct; + drop(reference1); //~ WARN calls to `std::mem::drop` + + let reference2 = &mut SomeStruct; + drop(reference2); //~ WARN calls to `std::mem::drop` + + let ref reference3 = SomeStruct; + drop(reference3); //~ WARN calls to `std::mem::drop` +} + +#[allow(dead_code)] +fn test_generic_fn_drop(val: T) { + drop(&val); //~ WARN calls to `std::mem::drop` + drop(val); +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn drop(_val: T) {} + drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::drop(&SomeStruct); //~ WARN calls to `std::mem::drop` +} + +#[derive(Copy, Clone)] +pub struct Error; +fn produce_half_owl_error() -> Result<(), Error> { + Ok(()) +} + +fn produce_half_owl_ok() -> Result { + Ok(true) +} + +#[allow(dead_code)] +fn test_owl_result() -> Result<(), ()> { + produce_half_owl_error().map_err(|_| ())?; + produce_half_owl_ok().map(|_| ())?; + // the following should not be linted, + // we should not force users to use toilet closures + // to produce owl results when drop is more convenient + produce_half_owl_error().map_err(drop)?; + produce_half_owl_ok().map_err(drop)?; + Ok(()) +} + +#[allow(dead_code)] +fn test_owl_result_2() -> Result { + produce_half_owl_error().map_err(|_| ())?; + produce_half_owl_ok().map(|_| ())?; + // the following should not be linted, + // we should not force users to use toilet closures + // to produce owl results when drop is more convenient + produce_half_owl_error().map_err(drop)?; + produce_half_owl_ok().map(drop)?; + Ok(1) +} + +#[allow(unused)] +#[allow(clippy::unit_cmp)] +fn issue10122(x: u8) { + // This is a function which returns a reference and has a side-effect, which means + // that calling drop() on the function is considered an idiomatic way of achieving + // the side-effect in a match arm. + fn println_and(t: &T) -> &T { + println!("foo"); + t + } + + match x { + // Don't lint (copy type), we only care about side-effects + 0 => drop(println_and(&12)), + // Don't lint (no copy type), we only care about side-effects + 1 => drop(println_and(&String::new())), + 2 => { + // Lint, even if we only care about the side-effect, it's already in a block + drop(println_and(&13)); //~ WARN calls to `std::mem::drop` + }, + // Lint, idiomatic use is only in body of `Arm` + 3 if drop(println_and(&14)) == () => (), //~ WARN calls to `std::mem::drop` + // Lint, not a fn/method call + 4 => drop(&2), //~ WARN calls to `std::mem::drop` + _ => (), + } +} diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr new file mode 100644 index 000000000000..34e4050abcf6 --- /dev/null +++ b/tests/ui/lint/drop_ref.stderr @@ -0,0 +1,151 @@ +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:8:5 + | +LL | drop(&SomeStruct); + | ^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_ref.rs:8:10 + | +LL | drop(&SomeStruct); + | ^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/drop_ref.rs:3:9 + | +LL | #![warn(drop_ref)] + | ^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:11:5 + | +LL | drop(&owned1); + | ^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_ref.rs:11:10 + | +LL | drop(&owned1); + | ^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:12:5 + | +LL | drop(&&owned1); + | ^^^^^^^^^^^^^^ + | +note: argument has type `&&SomeStruct` + --> $DIR/drop_ref.rs:12:10 + | +LL | drop(&&owned1); + | ^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:13:5 + | +LL | drop(&mut owned1); + | ^^^^^^^^^^^^^^^^^ + | +note: argument has type `&mut SomeStruct` + --> $DIR/drop_ref.rs:13:10 + | +LL | drop(&mut owned1); + | ^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:17:5 + | +LL | drop(reference1); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_ref.rs:17:10 + | +LL | drop(reference1); + | ^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:20:5 + | +LL | drop(reference2); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type `&mut SomeStruct` + --> $DIR/drop_ref.rs:20:10 + | +LL | drop(reference2); + | ^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:23:5 + | +LL | drop(reference3); + | ^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_ref.rs:23:10 + | +LL | drop(reference3); + | ^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:28:5 + | +LL | drop(&val); + | ^^^^^^^^^^ + | +note: argument has type `&T` + --> $DIR/drop_ref.rs:28:10 + | +LL | drop(&val); + | ^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:36:5 + | +LL | std::mem::drop(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_ref.rs:36:20 + | +LL | std::mem::drop(&SomeStruct); + | ^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:91:13 + | +LL | drop(println_and(&13)); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&i32` + --> $DIR/drop_ref.rs:91:18 + | +LL | drop(println_and(&13)); + | ^^^^^^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:94:14 + | +LL | 3 if drop(println_and(&14)) == () => (), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&i32` + --> $DIR/drop_ref.rs:94:19 + | +LL | 3 if drop(println_and(&14)) == () => (), + | ^^^^^^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_ref.rs:96:14 + | +LL | 4 => drop(&2), + | ^^^^^^^^ + | +note: argument has type `&i32` + --> $DIR/drop_ref.rs:96:19 + | +LL | 4 => drop(&2), + | ^^ + +warning: 12 warnings emitted + From 3d1940d02e2986e161ad31236d67489dfab08ad3 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 26 Mar 2023 16:18:43 +0200 Subject: [PATCH 07/34] Drop uplifted clippy::drop_ref --- .../clippy/clippy_lints/src/declared_lints.rs | 1 - .../clippy_lints/src/drop_forget_ref.rs | 30 +--- .../clippy/clippy_lints/src/renamed_lints.rs | 1 + src/tools/clippy/tests/ui/drop_forget_copy.rs | 2 +- src/tools/clippy/tests/ui/drop_ref.rs | 97 ------------ src/tools/clippy/tests/ui/drop_ref.stderr | 147 ------------------ src/tools/clippy/tests/ui/rename.fixed | 2 + src/tools/clippy/tests/ui/rename.rs | 2 + src/tools/clippy/tests/ui/rename.stderr | 94 +++++------ 9 files changed, 58 insertions(+), 318 deletions(-) delete mode 100644 src/tools/clippy/tests/ui/drop_ref.rs delete mode 100644 src/tools/clippy/tests/ui/drop_ref.stderr diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 79d0f6f36079..07978d971db5 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -134,7 +134,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::double_parens::DOUBLE_PARENS_INFO, crate::drop_forget_ref::DROP_COPY_INFO, crate::drop_forget_ref::DROP_NON_DROP_INFO, - crate::drop_forget_ref::DROP_REF_INFO, crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, crate::drop_forget_ref::FORGET_REF_INFO, diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 11e1bcdf12d1..55d7c3247cdd 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -7,30 +7,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::drop` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `drop` on a reference will only drop the - /// reference itself, which is a no-op. It will not call the `drop` method (from - /// the `Drop` trait implementation) on the underlying referenced value, which - /// is likely what was intended. - /// - /// ### Example - /// ```ignore - /// let mut lock_guard = mutex.lock(); - /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex - /// // still locked - /// operation_that_requires_mutex_to_be_unlocked(); - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_REF, - correctness, - "calls to `std::mem::drop` with a reference instead of an owned value" -} - declare_clippy_lint! { /// ### What it does /// Checks for calls to `std::mem::forget` with a reference @@ -172,8 +148,6 @@ declare_clippy_lint! { "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value" } -const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \ - Dropping a reference does nothing"; const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ Forgetting a reference does nothing"; const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \ @@ -186,7 +160,6 @@ const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value t Forgetting such a type is the same as dropping it"; declare_lint_pass!(DropForgetRef => [ - DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY, @@ -206,7 +179,8 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg) = match fn_name { - sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => (DROP_REF, DROP_REF_SUMMARY), + // early return for uplifted lints: drop_ref + sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY), sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY), sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index 5e81a01a461a..c55eaa809cf0 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -32,6 +32,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::zero_width_space", "clippy::invisible_characters"), ("clippy::clone_double_ref", "suspicious_double_ref_op"), ("clippy::drop_bounds", "drop_bounds"), + ("clippy::drop_ref", "drop_ref"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"), diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs index a7276dd59f43..04293eb16bb7 100644 --- a/src/tools/clippy/tests/ui/drop_forget_copy.rs +++ b/src/tools/clippy/tests/ui/drop_forget_copy.rs @@ -1,5 +1,5 @@ #![warn(clippy::drop_copy, clippy::forget_copy)] -#![allow(clippy::toplevel_ref_arg, clippy::drop_ref, clippy::forget_ref, unused_mut)] +#![allow(clippy::toplevel_ref_arg, drop_ref, clippy::forget_ref, unused_mut)] use std::mem::{drop, forget}; use std::vec::Vec; diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/src/tools/clippy/tests/ui/drop_ref.rs deleted file mode 100644 index 10044e65f115..000000000000 --- a/src/tools/clippy/tests/ui/drop_ref.rs +++ /dev/null @@ -1,97 +0,0 @@ -#![warn(clippy::drop_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::map_err_ignore)] -#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)] - -use std::mem::drop; - -struct SomeStruct; - -fn main() { - drop(&SomeStruct); - - let mut owned1 = SomeStruct; - drop(&owned1); - drop(&&owned1); - drop(&mut owned1); - drop(owned1); //OK - - let reference1 = &SomeStruct; - drop(reference1); - - let reference2 = &mut SomeStruct; - drop(reference2); - - let ref reference3 = SomeStruct; - drop(reference3); -} - -#[allow(dead_code)] -fn test_generic_fn_drop(val: T) { - drop(&val); - drop(val); //OK -} - -#[allow(dead_code)] -fn test_similarly_named_function() { - fn drop(_val: T) {} - drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::drop(&SomeStruct); -} - -#[derive(Copy, Clone)] -pub struct Error; -fn produce_half_owl_error() -> Result<(), Error> { - Ok(()) -} - -fn produce_half_owl_ok() -> Result { - Ok(true) -} - -#[allow(dead_code)] -fn test_owl_result() -> Result<(), ()> { - produce_half_owl_error().map_err(|_| ())?; - produce_half_owl_ok().map(|_| ())?; - // the following should not be linted, - // we should not force users to use toilet closures - // to produce owl results when drop is more convenient - produce_half_owl_error().map_err(drop)?; - produce_half_owl_ok().map_err(drop)?; - Ok(()) -} - -#[allow(dead_code)] -fn test_owl_result_2() -> Result { - produce_half_owl_error().map_err(|_| ())?; - produce_half_owl_ok().map(|_| ())?; - // the following should not be linted, - // we should not force users to use toilet closures - // to produce owl results when drop is more convenient - produce_half_owl_error().map_err(drop)?; - produce_half_owl_ok().map(drop)?; - Ok(1) -} - -#[allow(unused)] -#[allow(clippy::unit_cmp)] -fn issue10122(x: u8) { - // This is a function which returns a reference and has a side-effect, which means - // that calling drop() on the function is considered an idiomatic way of achieving the side-effect - // in a match arm. - fn println_and(t: &T) -> &T { - println!("foo"); - t - } - - match x { - 0 => drop(println_and(&12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(&String::new())), // Don't lint (no copy type), we only care about side-effects - 2 => { - drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - }, - 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(&2), // Lint, not a fn/method call - _ => (), - } -} diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr deleted file mode 100644 index 293b9f6de832..000000000000 --- a/src/tools/clippy/tests/ui/drop_ref.stderr +++ /dev/null @@ -1,147 +0,0 @@ -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:11:5 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:11:10 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::drop-ref` implied by `-D warnings` - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:14:5 - | -LL | drop(&owned1); - | ^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:14:10 - | -LL | drop(&owned1); - | ^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:15:5 - | -LL | drop(&&owned1); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/drop_ref.rs:15:10 - | -LL | drop(&&owned1); - | ^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:16:5 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:16:10 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:20:5 - | -LL | drop(reference1); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:20:10 - | -LL | drop(reference1); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:23:5 - | -LL | drop(reference2); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:23:10 - | -LL | drop(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:26:5 - | -LL | drop(reference3); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:26:10 - | -LL | drop(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:31:5 - | -LL | drop(&val); - | ^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/drop_ref.rs:31:10 - | -LL | drop(&val); - | ^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:39:5 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:39:20 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:91:13 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:91:18 - | -LL | drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:93:14 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:93:19 - | -LL | 3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing - --> $DIR/drop_ref.rs:94:14 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:94:19 - | -LL | 4 => drop(&2), // Lint, not a fn/method call - | ^^ - -error: aborting due to 12 previous errors - diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 42a59f6d43df..1beb878fc75a 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -29,6 +29,7 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_ref)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] @@ -71,6 +72,7 @@ #![warn(clippy::invisible_characters)] #![warn(suspicious_double_ref_op)] #![warn(drop_bounds)] +#![warn(drop_ref)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 4d173e8cbbfa..7034daffdd6b 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -29,6 +29,7 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_ref)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] @@ -71,6 +72,7 @@ #![warn(clippy::zero_width_space)] #![warn(clippy::clone_double_ref)] #![warn(clippy::drop_bounds)] +#![warn(clippy::drop_ref)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loops_over_fallibles)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 0da4ed7520c8..7cf5562a7e3b 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:44:9 + --> $DIR/rename.rs:45:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,256 +7,262 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:46:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` +error: lint `clippy::drop_ref` has been renamed to `drop_ref` + --> $DIR/rename.rs:75:9 + | +LL | #![warn(clippy::drop_ref)] + | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref` + error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 43 previous errors +error: aborting due to 44 previous errors From 156f5563c7cb72947fc27365098217003cab2357 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 27 Mar 2023 20:59:59 +0200 Subject: [PATCH 08/34] Uplift clippy::drop_copy to rustc --- compiler/rustc_lint/messages.ftl | 3 + .../rustc_lint/src/drop_forget_useless.rs | 32 ++++- compiler/rustc_lint/src/lints.rs | 8 ++ tests/ui/lint/drop_copy.rs | 79 +++++++++++ tests/ui/lint/drop_copy.stderr | 128 ++++++++++++++++++ 5 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/drop_copy.rs create mode 100644 tests/ui/lint/drop_copy.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 7e6d65db0e8d..d52b77776904 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -523,3 +523,6 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value .note = argument has type `{$arg_ty}` + +lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy`. + .note = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 734a43af4a2d..9b667a50fe1f 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,7 +1,7 @@ use rustc_hir::{Arm, Expr, ExprKind, Node}; use rustc_span::sym; -use crate::{lints::DropRefDiag, LateContext, LateLintPass, LintContext}; +use crate::{lints::{DropRefDiag, DropCopyDiag}, LateContext, LateLintPass, LintContext}; declare_lint! { /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference @@ -31,7 +31,31 @@ declare_lint! { "calls to `std::mem::drop` with a reference instead of an owned value" } -declare_lint_pass!(DropForgetUseless => [DROP_REF]); +declare_lint! { + /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value + /// that derives the Copy trait. + /// + /// ### Example + /// + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::drop(x); // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `std::mem::drop` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the + /// value will be copied and moved into the function on invocation. + pub DROP_COPY, + Warn, + "calls to `std::mem::drop` with a value that implements Copy" +} + +declare_lint_pass!(DropForgetUseless => [DROP_REF, DROP_COPY]); impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { @@ -41,11 +65,15 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id) { let arg_ty = cx.typeck_results().expr_ty(arg); + let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, note: arg.span }); }, + sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { + cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, note: arg.span }); + } _ => return, }; } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a8696c81ab63..a91e20eb2185 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -671,6 +671,14 @@ pub struct DropRefDiag<'a> { pub note: Span, } +#[derive(LintDiagnostic)] +#[diag(lint_drop_copy)] +pub struct DropCopyDiag<'a> { + pub arg_ty: Ty<'a>, + #[note] + pub note: Span, +} + // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] diff --git a/tests/ui/lint/drop_copy.rs b/tests/ui/lint/drop_copy.rs new file mode 100644 index 000000000000..0adcd34505f0 --- /dev/null +++ b/tests/ui/lint/drop_copy.rs @@ -0,0 +1,79 @@ +// check-pass + +#![warn(drop_copy)] + +use std::mem::drop; +use std::vec::Vec; + +#[derive(Copy, Clone)] +struct SomeStruct; + +struct AnotherStruct { + x: u8, + y: u8, + z: Vec, +} + +impl Clone for AnotherStruct { + fn clone(&self) -> AnotherStruct { + AnotherStruct { + x: self.x, + y: self.y, + z: self.z.clone(), + } + } +} + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let s3 = &s1; + let mut s4 = s1; + let ref s5 = s1; + + drop(s1); //~ WARN calls to `std::mem::drop` + drop(s2); //~ WARN calls to `std::mem::drop` + drop(s3); //~ WARN calls to `std::mem::drop` + drop(s4); //~ WARN calls to `std::mem::drop` + drop(s5); //~ WARN calls to `std::mem::drop` + + let a1 = AnotherStruct { + x: 255, + y: 0, + z: vec![1, 2, 3], + }; + let a2 = &a1; + let mut a3 = a1.clone(); + let ref a4 = a1; + let a5 = a1.clone(); + + drop(a2); //~ WARN calls to `std::mem::drop` + drop(a3); + drop(a4); //~ WARN calls to `std::mem::drop` + drop(a5); +} + +#[allow(unused)] +#[allow(clippy::unit_cmp)] +fn issue9482(x: u8) { + fn println_and(t: T) -> T { + println!("foo"); + t + } + + match x { + // Don't lint (copy type), we only care about side-effects + 0 => drop(println_and(12)), + // Don't lint (no copy type), we only care about side-effects + 1 => drop(println_and(String::new())), + 2 => { + // Lint, even if we only care about the side-effect, it's already in a block + drop(println_and(13)); //~ WARN calls to `std::mem::drop` + }, + // Lint, idiomatic use is only in body of `Arm` + 3 if drop(println_and(14)) == () => (), //~ WARN calls to `std::mem::drop` + // Lint, not a fn/method call + 4 => drop(2),//~ WARN calls to `std::mem::drop` + _ => (), + } +} diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr new file mode 100644 index 000000000000..03d0b392e2b4 --- /dev/null +++ b/tests/ui/lint/drop_copy.stderr @@ -0,0 +1,128 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:34:5 + | +LL | drop(s1); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_copy.rs:34:10 + | +LL | drop(s1); + | ^^ +note: the lint level is defined here + --> $DIR/drop_copy.rs:3:9 + | +LL | #![warn(drop_copy)] + | ^^^^^^^^^ + +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:35:5 + | +LL | drop(s2); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_copy.rs:35:10 + | +LL | drop(s2); + | ^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_copy.rs:36:5 + | +LL | drop(s3); + | ^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_copy.rs:36:10 + | +LL | drop(s3); + | ^^ + = note: `#[warn(drop_ref)]` on by default + +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:37:5 + | +LL | drop(s4); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_copy.rs:37:10 + | +LL | drop(s4); + | ^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_copy.rs:38:5 + | +LL | drop(s5); + | ^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/drop_copy.rs:38:10 + | +LL | drop(s5); + | ^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_copy.rs:50:5 + | +LL | drop(a2); + | ^^^^^^^^ + | +note: argument has type `&AnotherStruct` + --> $DIR/drop_copy.rs:50:10 + | +LL | drop(a2); + | ^^ + +warning: calls to `std::mem::drop` with a reference instead of an owned value + --> $DIR/drop_copy.rs:52:5 + | +LL | drop(a4); + | ^^^^^^^^ + | +note: argument has type `&AnotherStruct` + --> $DIR/drop_copy.rs:52:10 + | +LL | drop(a4); + | ^^ + +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:71:13 + | +LL | drop(println_and(13)); + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `i32` + --> $DIR/drop_copy.rs:71:18 + | +LL | drop(println_and(13)); + | ^^^^^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:74:14 + | +LL | 3 if drop(println_and(14)) == () => (), + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `i32` + --> $DIR/drop_copy.rs:74:19 + | +LL | 3 if drop(println_and(14)) == () => (), + | ^^^^^^^^^^^^^^^ + +warning: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_copy.rs:76:14 + | +LL | 4 => drop(2), + | ^^^^^^^ + | +note: argument has type `i32` + --> $DIR/drop_copy.rs:76:19 + | +LL | 4 => drop(2), + | ^ + +warning: 10 warnings emitted + From bbb24ce3da5a6b3e5e864fd76e2dd304a55216c6 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 27 Mar 2023 21:05:43 +0200 Subject: [PATCH 09/34] Drop uplifted clippy::drop_copy --- .../clippy/clippy_lints/src/declared_lints.rs | 1 - .../clippy_lints/src/drop_forget_ref.rs | 29 +----- .../clippy/clippy_lints/src/renamed_lints.rs | 1 + src/tools/clippy/tests/ui/drop_forget_copy.rs | 2 +- .../clippy/tests/ui/drop_forget_copy.stderr | 80 ++++++++-------- .../tests/ui/multiple_unsafe_ops_per_block.rs | 2 +- src/tools/clippy/tests/ui/rename.fixed | 2 + src/tools/clippy/tests/ui/rename.rs | 2 + src/tools/clippy/tests/ui/rename.stderr | 96 ++++++++++--------- .../tests/ui/unknown_clippy_lints.fixed | 2 +- .../tests/ui/unknown_clippy_lints.stderr | 2 +- 11 files changed, 102 insertions(+), 117 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 07978d971db5..81288ca91015 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -132,7 +132,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::doc::NEEDLESS_DOCTEST_MAIN_INFO, crate::doc::UNNECESSARY_SAFETY_DOC_INFO, crate::double_parens::DOUBLE_PARENS_INFO, - crate::drop_forget_ref::DROP_COPY_INFO, crate::drop_forget_ref::DROP_NON_DROP_INFO, crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 55d7c3247cdd..9858243f3397 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -29,28 +29,6 @@ declare_clippy_lint! { "calls to `std::mem::forget` with a reference instead of an owned value" } -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::drop` with a value - /// that derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::drop` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the - /// value will be copied and moved into the function on invocation. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::drop(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub DROP_COPY, - correctness, - "calls to `std::mem::drop` with a value that implements Copy" -} - declare_clippy_lint! { /// ### What it does /// Checks for calls to `std::mem::forget` with a value that @@ -150,8 +128,6 @@ declare_clippy_lint! { const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ Forgetting a reference does nothing"; -const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \ - Dropping a copy leaves the original intact"; const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ Forgetting a copy leaves the original intact"; const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \ @@ -161,7 +137,6 @@ const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value t declare_lint_pass!(DropForgetRef => [ FORGET_REF, - DROP_COPY, FORGET_COPY, DROP_NON_DROP, FORGET_NON_DROP, @@ -179,10 +154,10 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg) = match fn_name { - // early return for uplifted lints: drop_ref + // early return for uplifted lints: drop_ref, drop_copy sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY), - sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY), + sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index c55eaa809cf0..31c9f39c9bf0 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -32,6 +32,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::zero_width_space", "clippy::invisible_characters"), ("clippy::clone_double_ref", "suspicious_double_ref_op"), ("clippy::drop_bounds", "drop_bounds"), + ("clippy::drop_copy", "drop_copy"), ("clippy::drop_ref", "drop_ref"), ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs index 04293eb16bb7..f723b03a979c 100644 --- a/src/tools/clippy/tests/ui/drop_forget_copy.rs +++ b/src/tools/clippy/tests/ui/drop_forget_copy.rs @@ -1,4 +1,4 @@ -#![warn(clippy::drop_copy, clippy::forget_copy)] +#![warn(drop_copy, clippy::forget_copy)] #![allow(clippy::toplevel_ref_arg, drop_ref, clippy::forget_ref, unused_mut)] use std::mem::{drop, forget}; diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr index 90bef1c3c439..3b19cf3968f6 100644 --- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr +++ b/src/tools/clippy/tests/ui/drop_forget_copy.stderr @@ -1,40 +1,3 @@ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:33:5 - | -LL | drop(s1); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:33:10 - | -LL | drop(s1); - | ^^ - = note: `-D clippy::drop-copy` implied by `-D warnings` - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:34:5 - | -LL | drop(s2); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:34:10 - | -LL | drop(s2); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:36:5 - | -LL | drop(s4); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:36:10 - | -LL | drop(s4); - | ^^ - error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact --> $DIR/drop_forget_copy.rs:39:5 | @@ -72,7 +35,44 @@ note: argument has type `SomeStruct` LL | forget(s4); | ^^ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact +error: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_forget_copy.rs:33:5 + | +LL | drop(s1); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_forget_copy.rs:33:10 + | +LL | drop(s1); + | ^^ + = note: `-D drop-copy` implied by `-D warnings` + +error: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_forget_copy.rs:34:5 + | +LL | drop(s2); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_forget_copy.rs:34:10 + | +LL | drop(s2); + | ^^ + +error: calls to `std::mem::drop` with a value that implements `Copy`. + --> $DIR/drop_forget_copy.rs:36:5 + | +LL | drop(s4); + | ^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/drop_forget_copy.rs:36:10 + | +LL | drop(s4); + | ^^ + +error: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_forget_copy.rs:80:13 | LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block @@ -84,7 +84,7 @@ note: argument has type `i32` LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block | ^^^^^^^^^^^^^^^ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact +error: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_forget_copy.rs:82:14 | LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` @@ -96,7 +96,7 @@ note: argument has type `i32` LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` | ^^^^^^^^^^^^^^^ -error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact +error: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_forget_copy.rs:83:14 | LL | 4 => drop(2), // Lint, not a fn/method call diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs index 73ef35c8c366..f28153e56b0f 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -2,7 +2,7 @@ #![allow(unused)] #![allow(deref_nullptr)] #![allow(clippy::unnecessary_operation)] -#![allow(clippy::drop_copy)] +#![allow(drop_copy)] #![warn(clippy::multiple_unsafe_ops_per_block)] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 1beb878fc75a..a618dcd806fb 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -29,6 +29,7 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] @@ -72,6 +73,7 @@ #![warn(clippy::invisible_characters)] #![warn(suspicious_double_ref_op)] #![warn(drop_bounds)] +#![warn(drop_copy)] #![warn(drop_ref)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 7034daffdd6b..bca0cba7ee80 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -29,6 +29,7 @@ #![allow(clippy::invisible_characters)] #![allow(suspicious_double_ref_op)] #![allow(drop_bounds)] +#![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] #![allow(array_into_iter)] @@ -72,6 +73,7 @@ #![warn(clippy::zero_width_space)] #![warn(clippy::clone_double_ref)] #![warn(clippy::drop_bounds)] +#![warn(clippy::drop_copy)] #![warn(clippy::drop_ref)] #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 7cf5562a7e3b..1f1cc932b38f 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:45:9 + --> $DIR/rename.rs:46:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,262 +7,268 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` +error: lint `clippy::drop_copy` has been renamed to `drop_copy` + --> $DIR/rename.rs:76:9 + | +LL | #![warn(clippy::drop_copy)] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy` + error: lint `clippy::drop_ref` has been renamed to `drop_ref` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:87:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:88:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 44 previous errors +error: aborting due to 45 previous errors diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed index 0c269d650c8c..49c0e4dc7eb1 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed @@ -10,7 +10,7 @@ #[warn(clippy::unnecessary_cast)] #[warn(clippy::useless_transmute)] // Shouldn't suggest rustc lint name(`dead_code`) -#[warn(clippy::drop_copy)] +#[warn(clippy::eq_op)] // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) #[warn(clippy::unused_self)] // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr index 421bf5ffa9a7..584c428932fe 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr @@ -34,7 +34,7 @@ error: unknown lint: `clippy::dead_cod` --> $DIR/unknown_clippy_lints.rs:13:8 | LL | #[warn(clippy::dead_cod)] - | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy` + | ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op` error: unknown lint: `clippy::unused_colle` --> $DIR/unknown_clippy_lints.rs:15:8 From 1ef9c163aa37417e7596d884e912ffea1fb40932 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 28 Mar 2023 18:31:21 +0200 Subject: [PATCH 10/34] Uplift clippy::forget_ref to rustc --- compiler/rustc_lint/messages.ftl | 3 + .../rustc_lint/src/drop_forget_useless.rs | 30 ++++- compiler/rustc_lint/src/lints.rs | 8 ++ tests/ui/lint/forget_ref.rs | 39 ++++++ tests/ui/lint/forget_ref.stderr | 115 ++++++++++++++++++ 5 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/forget_ref.rs create mode 100644 tests/ui/lint/forget_ref.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index d52b77776904..a570f03e28cb 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -526,3 +526,6 @@ lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned v lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy`. .note = argument has type `{$arg_ty}` + +lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value + .note = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 9b667a50fe1f..32594178fe81 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,7 +1,7 @@ use rustc_hir::{Arm, Expr, ExprKind, Node}; use rustc_span::sym; -use crate::{lints::{DropRefDiag, DropCopyDiag}, LateContext, LateLintPass, LintContext}; +use crate::{lints::{DropRefDiag, DropCopyDiag, ForgetRefDiag}, LateContext, LateLintPass, LintContext}; declare_lint! { /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference @@ -31,6 +31,29 @@ declare_lint! { "calls to `std::mem::drop` with a reference instead of an owned value" } +declare_lint! { + /// The `forget_ref` lint checks for calls to `std::mem::forget` with a reference + /// instead of an owned value. + /// + /// ### Example + /// + /// ```rust + /// let x = Box::new(1); + /// std::mem::forget(&x); // Should have been forget(x), x will still be dropped + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `forget` on a reference will only forget the + /// reference itself, which is a no-op. It will not forget the underlying + /// referenced value, which is likely what was intended. + pub FORGET_REF, + Warn, + "calls to `std::mem::forget` with a reference instead of an owned value" +} + declare_lint! { /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value /// that derives the Copy trait. @@ -55,7 +78,7 @@ declare_lint! { "calls to `std::mem::drop` with a value that implements Copy" } -declare_lint_pass!(DropForgetUseless => [DROP_REF, DROP_COPY]); +declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY]); impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { @@ -71,6 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, note: arg.span }); }, + sym::mem_forget if arg_ty.is_ref() => { + cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, note: arg.span }); + }, sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, note: arg.span }); } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index a91e20eb2185..2431c3707f5d 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -679,6 +679,14 @@ pub struct DropCopyDiag<'a> { pub note: Span, } +#[derive(LintDiagnostic)] +#[diag(lint_forget_ref)] +pub struct ForgetRefDiag<'a> { + pub arg_ty: Ty<'a>, + #[note] + pub note: Span, +} + // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] diff --git a/tests/ui/lint/forget_ref.rs b/tests/ui/lint/forget_ref.rs new file mode 100644 index 000000000000..13f6d4be3d15 --- /dev/null +++ b/tests/ui/lint/forget_ref.rs @@ -0,0 +1,39 @@ +// check-pass + +#![warn(forget_ref)] + +use std::mem::forget; + +struct SomeStruct; + +fn main() { + forget(&SomeStruct); //~ WARN calls to `std::mem::forget` + + let mut owned = SomeStruct; + forget(&owned); //~ WARN calls to `std::mem::forget` + forget(&&owned); //~ WARN calls to `std::mem::forget` + forget(&mut owned); //~ WARN calls to `std::mem::forget` + forget(owned); + + let reference1 = &SomeStruct; + forget(&*reference1); //~ WARN calls to `std::mem::forget` + + let reference2 = &mut SomeStruct; + forget(reference2); //~ WARN calls to `std::mem::forget` + + let ref reference3 = SomeStruct; + forget(reference3); //~ WARN calls to `std::mem::forget` +} + +#[allow(dead_code)] +fn test_generic_fn_forget(val: T) { + forget(&val); //~ WARN calls to `std::mem::forget` + forget(val); +} + +#[allow(dead_code)] +fn test_similarly_named_function() { + fn forget(_val: T) {} + forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name + std::mem::forget(&SomeStruct); //~ WARN calls to `std::mem::forget` +} diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr new file mode 100644 index 000000000000..abb45443e4e9 --- /dev/null +++ b/tests/ui/lint/forget_ref.stderr @@ -0,0 +1,115 @@ +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:10:5 + | +LL | forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_ref.rs:10:12 + | +LL | forget(&SomeStruct); + | ^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/forget_ref.rs:3:9 + | +LL | #![warn(forget_ref)] + | ^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:13:5 + | +LL | forget(&owned); + | ^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_ref.rs:13:12 + | +LL | forget(&owned); + | ^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:14:5 + | +LL | forget(&&owned); + | ^^^^^^^^^^^^^^^ + | +note: argument has type `&&SomeStruct` + --> $DIR/forget_ref.rs:14:12 + | +LL | forget(&&owned); + | ^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:15:5 + | +LL | forget(&mut owned); + | ^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&mut SomeStruct` + --> $DIR/forget_ref.rs:15:12 + | +LL | forget(&mut owned); + | ^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:19:5 + | +LL | forget(&*reference1); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_ref.rs:19:12 + | +LL | forget(&*reference1); + | ^^^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:22:5 + | +LL | forget(reference2); + | ^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&mut SomeStruct` + --> $DIR/forget_ref.rs:22:12 + | +LL | forget(reference2); + | ^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:25:5 + | +LL | forget(reference3); + | ^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_ref.rs:25:12 + | +LL | forget(reference3); + | ^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:30:5 + | +LL | forget(&val); + | ^^^^^^^^^^^^ + | +note: argument has type `&T` + --> $DIR/forget_ref.rs:30:12 + | +LL | forget(&val); + | ^^^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_ref.rs:38:5 + | +LL | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_ref.rs:38:22 + | +LL | std::mem::forget(&SomeStruct); + | ^^^^^^^^^^^ + +warning: 9 warnings emitted + From cf6d2272c51406c03d8e1b1b3e7c1d36a5535877 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 28 Mar 2023 18:40:54 +0200 Subject: [PATCH 11/34] Drop uplifted clippy::forget_ref --- .../clippy/clippy_lints/src/declared_lints.rs | 1 - .../clippy_lints/src/drop_forget_ref.rs | 29 +---- .../clippy/clippy_lints/src/renamed_lints.rs | 1 + src/tools/clippy/tests/ui/drop_forget_copy.rs | 2 +- src/tools/clippy/tests/ui/forget_ref.rs | 50 -------- src/tools/clippy/tests/ui/forget_ref.stderr | 111 ------------------ src/tools/clippy/tests/ui/rename.fixed | 2 + src/tools/clippy/tests/ui/rename.rs | 2 + src/tools/clippy/tests/ui/rename.stderr | 98 ++++++++-------- 9 files changed, 60 insertions(+), 236 deletions(-) delete mode 100644 src/tools/clippy/tests/ui/forget_ref.rs delete mode 100644 src/tools/clippy/tests/ui/forget_ref.stderr diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 81288ca91015..255df2b7e466 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -135,7 +135,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::drop_forget_ref::DROP_NON_DROP_INFO, crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, - crate::drop_forget_ref::FORGET_REF_INFO, crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO, crate::duplicate_mod::DUPLICATE_MOD_INFO, crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 9858243f3397..23ec7f15aaa7 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -7,28 +7,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a reference - /// instead of an owned value. - /// - /// ### Why is this bad? - /// Calling `forget` on a reference will only forget the - /// reference itself, which is a no-op. It will not forget the underlying - /// referenced - /// value, which is likely what was intended. - /// - /// ### Example - /// ```rust - /// let x = Box::new(1); - /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_REF, - correctness, - "calls to `std::mem::forget` with a reference instead of an owned value" -} - declare_clippy_lint! { /// ### What it does /// Checks for calls to `std::mem::forget` with a value that @@ -126,8 +104,6 @@ declare_clippy_lint! { "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value" } -const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \ - Forgetting a reference does nothing"; const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ Forgetting a copy leaves the original intact"; const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \ @@ -136,7 +112,6 @@ const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value t Forgetting such a type is the same as dropping it"; declare_lint_pass!(DropForgetRef => [ - FORGET_REF, FORGET_COPY, DROP_NON_DROP, FORGET_NON_DROP, @@ -154,9 +129,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg) = match fn_name { - // early return for uplifted lints: drop_ref, drop_copy + // early return for uplifted lints: drop_ref, drop_copy, forget_ref sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, - sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY), + sym::mem_forget if arg_ty.is_ref() => return, sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => { diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index 31c9f39c9bf0..d5b1883e0b27 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -37,6 +37,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"), + ("clippy::forget_ref", "forget_ref"), ("clippy::into_iter_on_array", "array_into_iter"), ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"), ("clippy::invalid_ref", "invalid_value"), diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs index f723b03a979c..ebe60ebbd304 100644 --- a/src/tools/clippy/tests/ui/drop_forget_copy.rs +++ b/src/tools/clippy/tests/ui/drop_forget_copy.rs @@ -1,5 +1,5 @@ #![warn(drop_copy, clippy::forget_copy)] -#![allow(clippy::toplevel_ref_arg, drop_ref, clippy::forget_ref, unused_mut)] +#![allow(clippy::toplevel_ref_arg, drop_ref, forget_ref, unused_mut)] use std::mem::{drop, forget}; use std::vec::Vec; diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs deleted file mode 100644 index 031b415f56ff..000000000000 --- a/src/tools/clippy/tests/ui/forget_ref.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![warn(clippy::forget_ref)] -#![allow(clippy::toplevel_ref_arg)] -#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)] -#![allow(clippy::borrow_deref_ref)] - -use std::mem::forget; - -struct SomeStruct; - -fn main() { - forget(&SomeStruct); - - let mut owned = SomeStruct; - forget(&owned); - forget(&&owned); - forget(&mut owned); - forget(owned); //OK - - let reference1 = &SomeStruct; - forget(&*reference1); - - let reference2 = &mut SomeStruct; - forget(reference2); - - let ref reference3 = SomeStruct; - forget(reference3); -} - -#[allow(dead_code)] -fn test_generic_fn_forget(val: T) { - forget(&val); - forget(val); //OK -} - -#[allow(dead_code)] -fn test_similarly_named_function() { - fn forget(_val: T) {} - forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name - std::mem::forget(&SomeStruct); -} - -#[derive(Copy, Clone)] -pub struct Error; -fn produce_half_owl_error() -> Result<(), Error> { - Ok(()) -} - -fn produce_half_owl_ok() -> Result { - Ok(true) -} diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr deleted file mode 100644 index 011cdefc665f..000000000000 --- a/src/tools/clippy/tests/ui/forget_ref.stderr +++ /dev/null @@ -1,111 +0,0 @@ -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:11:5 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:11:12 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^ - = note: `-D clippy::forget-ref` implied by `-D warnings` - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:14:5 - | -LL | forget(&owned); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:14:12 - | -LL | forget(&owned); - | ^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:15:5 - | -LL | forget(&&owned); - | ^^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/forget_ref.rs:15:12 - | -LL | forget(&&owned); - | ^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:16:5 - | -LL | forget(&mut owned); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:16:12 - | -LL | forget(&mut owned); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:20:5 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:20:12 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:23:5 - | -LL | forget(reference2); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:23:12 - | -LL | forget(reference2); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:26:5 - | -LL | forget(reference3); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:26:12 - | -LL | forget(reference3); - | ^^^^^^^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:31:5 - | -LL | forget(&val); - | ^^^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/forget_ref.rs:31:12 - | -LL | forget(&val); - | ^^^^ - -error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing - --> $DIR/forget_ref.rs:39:5 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:39:22 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^ - -error: aborting due to 9 previous errors - diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index a618dcd806fb..6cb2f82c117a 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -32,6 +32,7 @@ #![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] @@ -78,6 +79,7 @@ #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] +#![warn(forget_ref)] #![warn(array_into_iter)] #![warn(invalid_atomic_ordering)] #![warn(invalid_value)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index bca0cba7ee80..72acc312d548 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -32,6 +32,7 @@ #![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] #![allow(invalid_value)] @@ -78,6 +79,7 @@ #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loops_over_fallibles)] +#![warn(clippy::forget_ref)] #![warn(clippy::into_iter_on_array)] #![warn(clippy::invalid_atomic_ordering)] #![warn(clippy::invalid_ref)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 1f1cc932b38f..2847cdbba5df 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:46:9 + --> $DIR/rename.rs:47:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,268 +7,274 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `drop_copy` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy` error: lint `clippy::drop_ref` has been renamed to `drop_ref` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` +error: lint `clippy::forget_ref` has been renamed to `forget_ref` + --> $DIR/rename.rs:82:9 + | +LL | #![warn(clippy::forget_ref)] + | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref` + error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:83:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:87:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:88:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:89:9 + --> $DIR/rename.rs:91:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:90:9 + --> $DIR/rename.rs:92:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 45 previous errors +error: aborting due to 46 previous errors From 971b9b23b5ce0573dcc28e928410b4795b548bcc Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 28 Mar 2023 18:47:37 +0200 Subject: [PATCH 12/34] Uplift clippy::forget_copy to rustc --- compiler/rustc_lint/messages.ftl | 3 + .../rustc_lint/src/drop_forget_useless.rs | 38 ++++++- compiler/rustc_lint/src/lints.rs | 8 ++ tests/ui/lint/forget_copy.rs | 56 ++++++++++ tests/ui/lint/forget_copy.stderr | 104 ++++++++++++++++++ 5 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/forget_copy.rs create mode 100644 tests/ui/lint/forget_copy.stderr diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index a570f03e28cb..0db4b3160dfb 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -529,3 +529,6 @@ lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy`. lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value .note = argument has type `{$arg_ty}` + +lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy`. + .note = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index 32594178fe81..e72439439a4b 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -1,7 +1,10 @@ use rustc_hir::{Arm, Expr, ExprKind, Node}; use rustc_span::sym; -use crate::{lints::{DropRefDiag, DropCopyDiag, ForgetRefDiag}, LateContext, LateLintPass, LintContext}; +use crate::{ + lints::{DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag}, + LateContext, LateLintPass, LintContext, +}; declare_lint! { /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference @@ -78,7 +81,35 @@ declare_lint! { "calls to `std::mem::drop` with a value that implements Copy" } -declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY]); +declare_lint! { + /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value + /// that derives the Copy trait. + /// + /// ### Example + /// + /// ```rust + /// let x: i32 = 42; // i32 implements Copy + /// std::mem::forget(x); // A copy of x is passed to the function, leaving the + /// // original unaffected + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling `std::mem::forget` [does nothing for types that + /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the + /// value will be copied and moved into the function on invocation. + /// + /// An alternative, but also valid, explanation is that Copy types do not + /// implement the Drop trait, which means they have no destructors. Without a + /// destructor, there is nothing for `std::mem::forget` to ignore. + pub FORGET_COPY, + Warn, + "calls to `std::mem::forget` with a value that implements Copy" +} + +declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]); impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { @@ -100,6 +131,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, note: arg.span }); } + sym::mem_forget if is_copy => { + cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, note: arg.span }); + } _ => return, }; } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 2431c3707f5d..102a149a410c 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -687,6 +687,14 @@ pub struct ForgetRefDiag<'a> { pub note: Span, } +#[derive(LintDiagnostic)] +#[diag(lint_forget_copy)] +pub struct ForgetCopyDiag<'a> { + pub arg_ty: Ty<'a>, + #[note] + pub note: Span, +} + // hidden_unicode_codepoints.rs #[derive(LintDiagnostic)] #[diag(lint_hidden_unicode_codepoints)] diff --git a/tests/ui/lint/forget_copy.rs b/tests/ui/lint/forget_copy.rs new file mode 100644 index 000000000000..a6b17b76971f --- /dev/null +++ b/tests/ui/lint/forget_copy.rs @@ -0,0 +1,56 @@ +// check-pass + +#![warn(forget_copy)] + +use std::mem::forget; +use std::vec::Vec; + +#[derive(Copy, Clone)] +struct SomeStruct; + +struct AnotherStruct { + x: u8, + y: u8, + z: Vec, +} + +impl Clone for AnotherStruct { + fn clone(&self) -> AnotherStruct { + AnotherStruct { + x: self.x, + y: self.y, + z: self.z.clone(), + } + } +} + +fn main() { + let s1 = SomeStruct {}; + let s2 = s1; + let s3 = &s1; + let mut s4 = s1; + let ref s5 = s1; + + forget(s1); //~ WARN calls to `std::mem::forget` + forget(s2); //~ WARN calls to `std::mem::forget` + forget(s3); //~ WARN calls to `std::mem::forget` + forget(s4); //~ WARN calls to `std::mem::forget` + forget(s5); //~ WARN calls to `std::mem::forget` + + let a1 = AnotherStruct { + x: 255, + y: 0, + z: vec![1, 2, 3], + }; + let a2 = &a1; + let mut a3 = a1.clone(); + let ref a4 = a1; + let a5 = a1.clone(); + + forget(a2); //~ WARN calls to `std::mem::forget` + let a3 = &a1; + forget(a3); //~ WARN calls to `std::mem::forget` + forget(a4); //~ WARN calls to `std::mem::forget` + let a5 = a1.clone(); + forget(a5); +} diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr new file mode 100644 index 000000000000..d33dfa0fd3d1 --- /dev/null +++ b/tests/ui/lint/forget_copy.stderr @@ -0,0 +1,104 @@ +warning: calls to `std::mem::forget` with a value that implements `Copy`. + --> $DIR/forget_copy.rs:34:5 + | +LL | forget(s1); + | ^^^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/forget_copy.rs:34:12 + | +LL | forget(s1); + | ^^ +note: the lint level is defined here + --> $DIR/forget_copy.rs:3:9 + | +LL | #![warn(forget_copy)] + | ^^^^^^^^^^^ + +warning: calls to `std::mem::forget` with a value that implements `Copy`. + --> $DIR/forget_copy.rs:35:5 + | +LL | forget(s2); + | ^^^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/forget_copy.rs:35:12 + | +LL | forget(s2); + | ^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_copy.rs:36:5 + | +LL | forget(s3); + | ^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_copy.rs:36:12 + | +LL | forget(s3); + | ^^ + = note: `#[warn(forget_ref)]` on by default + +warning: calls to `std::mem::forget` with a value that implements `Copy`. + --> $DIR/forget_copy.rs:37:5 + | +LL | forget(s4); + | ^^^^^^^^^^ + | +note: argument has type `SomeStruct` + --> $DIR/forget_copy.rs:37:12 + | +LL | forget(s4); + | ^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_copy.rs:38:5 + | +LL | forget(s5); + | ^^^^^^^^^^ + | +note: argument has type `&SomeStruct` + --> $DIR/forget_copy.rs:38:12 + | +LL | forget(s5); + | ^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_copy.rs:50:5 + | +LL | forget(a2); + | ^^^^^^^^^^ + | +note: argument has type `&AnotherStruct` + --> $DIR/forget_copy.rs:50:12 + | +LL | forget(a2); + | ^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_copy.rs:52:5 + | +LL | forget(a3); + | ^^^^^^^^^^ + | +note: argument has type `&AnotherStruct` + --> $DIR/forget_copy.rs:52:12 + | +LL | forget(a3); + | ^^ + +warning: calls to `std::mem::forget` with a reference instead of an owned value + --> $DIR/forget_copy.rs:53:5 + | +LL | forget(a4); + | ^^^^^^^^^^ + | +note: argument has type `&AnotherStruct` + --> $DIR/forget_copy.rs:53:12 + | +LL | forget(a4); + | ^^ + +warning: 8 warnings emitted + From 3f81b6b8a20378dcb507bf3f6d9afc76494d7933 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 28 Mar 2023 19:26:35 +0200 Subject: [PATCH 13/34] Drop uplifted clippy::forget_copy --- .../clippy/clippy_lints/src/declared_lints.rs | 1 - .../clippy_lints/src/drop_forget_ref.rs | 35 +----- .../clippy/clippy_lints/src/renamed_lints.rs | 1 + src/tools/clippy/tests/ui/drop_forget_copy.rs | 86 -------------- .../clippy/tests/ui/drop_forget_copy.stderr | 112 ------------------ src/tools/clippy/tests/ui/mem_forget.rs | 2 +- src/tools/clippy/tests/ui/rename.fixed | 2 + src/tools/clippy/tests/ui/rename.rs | 2 + src/tools/clippy/tests/ui/rename.stderr | 100 ++++++++-------- 9 files changed, 61 insertions(+), 280 deletions(-) delete mode 100644 src/tools/clippy/tests/ui/drop_forget_copy.rs delete mode 100644 src/tools/clippy/tests/ui/drop_forget_copy.stderr diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index 255df2b7e466..04993e492879 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -133,7 +133,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::doc::UNNECESSARY_SAFETY_DOC_INFO, crate::double_parens::DOUBLE_PARENS_INFO, crate::drop_forget_ref::DROP_NON_DROP_INFO, - crate::drop_forget_ref::FORGET_COPY_INFO, crate::drop_forget_ref::FORGET_NON_DROP_INFO, crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO, crate::duplicate_mod::DUPLICATE_MOD_INFO, diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs index 23ec7f15aaa7..b2f7d026cc8b 100644 --- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs +++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs @@ -7,34 +7,6 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; -declare_clippy_lint! { - /// ### What it does - /// Checks for calls to `std::mem::forget` with a value that - /// derives the Copy trait - /// - /// ### Why is this bad? - /// Calling `std::mem::forget` [does nothing for types that - /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the - /// value will be copied and moved into the function on invocation. - /// - /// An alternative, but also valid, explanation is that Copy types do not - /// implement - /// the Drop trait, which means they have no destructors. Without a destructor, - /// there - /// is nothing for `std::mem::forget` to ignore. - /// - /// ### Example - /// ```rust - /// let x: i32 = 42; // i32 implements Copy - /// std::mem::forget(x) // A copy of x is passed to the function, leaving the - /// // original unaffected - /// ``` - #[clippy::version = "pre 1.29.0"] - pub FORGET_COPY, - correctness, - "calls to `std::mem::forget` with a value that implements Copy" -} - declare_clippy_lint! { /// ### What it does /// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`. @@ -104,15 +76,12 @@ declare_clippy_lint! { "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value" } -const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \ - Forgetting a copy leaves the original intact"; const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \ Dropping such a type only extends its contained lifetimes"; const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \ Forgetting such a type is the same as dropping it"; declare_lint_pass!(DropForgetRef => [ - FORGET_COPY, DROP_NON_DROP, FORGET_NON_DROP, UNDROPPED_MANUALLY_DROPS @@ -129,11 +98,11 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef { let is_copy = is_copy(cx, arg_ty); let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); let (lint, msg) = match fn_name { - // early return for uplifted lints: drop_ref, drop_copy, forget_ref + // early return for uplifted lints: drop_ref, drop_copy, forget_ref, forget_copy sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return, sym::mem_forget if arg_ty.is_ref() => return, sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return, - sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY), + sym::mem_forget if is_copy => return, sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => { span_lint_and_help( cx, diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs index d5b1883e0b27..52e22c0c6303 100644 --- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs +++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs @@ -37,6 +37,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[ ("clippy::for_loop_over_option", "for_loops_over_fallibles"), ("clippy::for_loop_over_result", "for_loops_over_fallibles"), ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"), + ("clippy::forget_copy", "forget_copy"), ("clippy::forget_ref", "forget_ref"), ("clippy::into_iter_on_array", "array_into_iter"), ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"), diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs deleted file mode 100644 index ebe60ebbd304..000000000000 --- a/src/tools/clippy/tests/ui/drop_forget_copy.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![warn(drop_copy, clippy::forget_copy)] -#![allow(clippy::toplevel_ref_arg, drop_ref, forget_ref, unused_mut)] - -use std::mem::{drop, forget}; -use std::vec::Vec; - -#[derive(Copy, Clone)] -struct SomeStruct; - -struct AnotherStruct { - x: u8, - y: u8, - z: Vec, -} - -impl Clone for AnotherStruct { - fn clone(&self) -> AnotherStruct { - AnotherStruct { - x: self.x, - y: self.y, - z: self.z.clone(), - } - } -} - -fn main() { - let s1 = SomeStruct {}; - let s2 = s1; - let s3 = &s1; - let mut s4 = s1; - let ref s5 = s1; - - drop(s1); - drop(s2); - drop(s3); - drop(s4); - drop(s5); - - forget(s1); - forget(s2); - forget(s3); - forget(s4); - forget(s5); - - let a1 = AnotherStruct { - x: 255, - y: 0, - z: vec![1, 2, 3], - }; - let a2 = &a1; - let mut a3 = a1.clone(); - let ref a4 = a1; - let a5 = a1.clone(); - - drop(a2); - drop(a3); - drop(a4); - drop(a5); - - forget(a2); - let a3 = &a1; - forget(a3); - forget(a4); - let a5 = a1.clone(); - forget(a5); -} - -#[allow(unused)] -#[allow(clippy::unit_cmp)] -fn issue9482(x: u8) { - fn println_and(t: T) -> T { - println!("foo"); - t - } - - match x { - 0 => drop(println_and(12)), // Don't lint (copy type), we only care about side-effects - 1 => drop(println_and(String::new())), // Don't lint (no copy type), we only care about side-effects - 2 => { - drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - }, - 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - 4 => drop(2), // Lint, not a fn/method call - _ => (), - } -} diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr deleted file mode 100644 index 3b19cf3968f6..000000000000 --- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr +++ /dev/null @@ -1,112 +0,0 @@ -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:39:5 - | -LL | forget(s1); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:39:12 - | -LL | forget(s1); - | ^^ - = note: `-D clippy::forget-copy` implied by `-D warnings` - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:40:5 - | -LL | forget(s2); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:40:12 - | -LL | forget(s2); - | ^^ - -error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact - --> $DIR/drop_forget_copy.rs:42:5 - | -LL | forget(s4); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:42:12 - | -LL | forget(s4); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:33:5 - | -LL | drop(s1); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:33:10 - | -LL | drop(s1); - | ^^ - = note: `-D drop-copy` implied by `-D warnings` - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:34:5 - | -LL | drop(s2); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:34:10 - | -LL | drop(s2); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:36:5 - | -LL | drop(s4); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_forget_copy.rs:36:10 - | -LL | drop(s4); - | ^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:80:13 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:80:18 - | -LL | drop(println_and(13)); // Lint, even if we only care about the side-effect, it's already in a block - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:82:14 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:82:19 - | -LL | 3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm` - | ^^^^^^^^^^^^^^^ - -error: calls to `std::mem::drop` with a value that implements `Copy`. - --> $DIR/drop_forget_copy.rs:83:14 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_forget_copy.rs:83:19 - | -LL | 4 => drop(2), // Lint, not a fn/method call - | ^ - -error: aborting due to 9 previous errors - diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs index e5b35c098a23..5137448a6d4b 100644 --- a/src/tools/clippy/tests/ui/mem_forget.rs +++ b/src/tools/clippy/tests/ui/mem_forget.rs @@ -5,7 +5,7 @@ use std::mem as memstuff; use std::mem::forget as forgetSomething; #[warn(clippy::mem_forget)] -#[allow(clippy::forget_copy)] +#[allow(forget_copy)] fn main() { let five: i32 = 5; forgetSomething(five); diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 6cb2f82c117a..9036f8926128 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -32,6 +32,7 @@ #![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_copy)] #![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] @@ -79,6 +80,7 @@ #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] #![warn(for_loops_over_fallibles)] +#![warn(forget_copy)] #![warn(forget_ref)] #![warn(array_into_iter)] #![warn(invalid_atomic_ordering)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 72acc312d548..43cabe810f34 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -32,6 +32,7 @@ #![allow(drop_copy)] #![allow(drop_ref)] #![allow(for_loops_over_fallibles)] +#![allow(forget_copy)] #![allow(forget_ref)] #![allow(array_into_iter)] #![allow(invalid_atomic_ordering)] @@ -79,6 +80,7 @@ #![warn(clippy::for_loop_over_option)] #![warn(clippy::for_loop_over_result)] #![warn(clippy::for_loops_over_fallibles)] +#![warn(clippy::forget_copy)] #![warn(clippy::forget_ref)] #![warn(clippy::into_iter_on_array)] #![warn(clippy::invalid_atomic_ordering)] diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr index 2847cdbba5df..1ad7cf412c89 100644 --- a/src/tools/clippy/tests/ui/rename.stderr +++ b/src/tools/clippy/tests/ui/rename.stderr @@ -1,5 +1,5 @@ error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range` - --> $DIR/rename.rs:47:9 + --> $DIR/rename.rs:48:9 | LL | #![warn(clippy::almost_complete_letter_range)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range` @@ -7,274 +7,280 @@ LL | #![warn(clippy::almost_complete_letter_range)] = note: `-D renamed-and-removed-lints` implied by `-D warnings` error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names` - --> $DIR/rename.rs:48:9 + --> $DIR/rename.rs:49:9 | LL | #![warn(clippy::blacklisted_name)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names` error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:49:9 + --> $DIR/rename.rs:50:9 | LL | #![warn(clippy::block_in_if_condition_expr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions` - --> $DIR/rename.rs:50:9 + --> $DIR/rename.rs:51:9 | LL | #![warn(clippy::block_in_if_condition_stmt)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions` error: lint `clippy::box_vec` has been renamed to `clippy::box_collection` - --> $DIR/rename.rs:51:9 + --> $DIR/rename.rs:52:9 | LL | #![warn(clippy::box_vec)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection` error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes` - --> $DIR/rename.rs:52:9 + --> $DIR/rename.rs:53:9 | LL | #![warn(clippy::const_static_lifetime)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes` error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity` - --> $DIR/rename.rs:53:9 + --> $DIR/rename.rs:54:9 | LL | #![warn(clippy::cyclomatic_complexity)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity` error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq` - --> $DIR/rename.rs:54:9 + --> $DIR/rename.rs:55:9 | LL | #![warn(clippy::derive_hash_xor_eq)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq` error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods` - --> $DIR/rename.rs:55:9 + --> $DIR/rename.rs:56:9 | LL | #![warn(clippy::disallowed_method)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods` error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types` - --> $DIR/rename.rs:56:9 + --> $DIR/rename.rs:57:9 | LL | #![warn(clippy::disallowed_type)] | ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types` error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression` - --> $DIR/rename.rs:57:9 + --> $DIR/rename.rs:58:9 | LL | #![warn(clippy::eval_order_dependence)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression` error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion` - --> $DIR/rename.rs:58:9 + --> $DIR/rename.rs:59:9 | LL | #![warn(clippy::identity_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion` error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok` - --> $DIR/rename.rs:59:9 + --> $DIR/rename.rs:60:9 | LL | #![warn(clippy::if_let_some_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok` error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr` - --> $DIR/rename.rs:60:9 + --> $DIR/rename.rs:61:9 | LL | #![warn(clippy::logic_bug)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr` error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default` - --> $DIR/rename.rs:61:9 + --> $DIR/rename.rs:62:9 | LL | #![warn(clippy::new_without_default_derive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default` error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map` - --> $DIR/rename.rs:62:9 + --> $DIR/rename.rs:63:9 | LL | #![warn(clippy::option_and_then_some)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map` error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:63:9 + --> $DIR/rename.rs:64:9 | LL | #![warn(clippy::option_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:64:9 + --> $DIR/rename.rs:65:9 | LL | #![warn(clippy::option_map_unwrap_or)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:65:9 + --> $DIR/rename.rs:66:9 | LL | #![warn(clippy::option_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:66:9 + --> $DIR/rename.rs:67:9 | LL | #![warn(clippy::option_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow` - --> $DIR/rename.rs:67:9 + --> $DIR/rename.rs:68:9 | LL | #![warn(clippy::ref_in_deref)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow` error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used` - --> $DIR/rename.rs:68:9 + --> $DIR/rename.rs:69:9 | LL | #![warn(clippy::result_expect_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used` error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or` - --> $DIR/rename.rs:69:9 + --> $DIR/rename.rs:70:9 | LL | #![warn(clippy::result_map_unwrap_or_else)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or` error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used` - --> $DIR/rename.rs:70:9 + --> $DIR/rename.rs:71:9 | LL | #![warn(clippy::result_unwrap_used)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used` error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str` - --> $DIR/rename.rs:71:9 + --> $DIR/rename.rs:72:9 | LL | #![warn(clippy::single_char_push_str)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str` error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions` - --> $DIR/rename.rs:72:9 + --> $DIR/rename.rs:73:9 | LL | #![warn(clippy::stutter)] | ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions` error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl` - --> $DIR/rename.rs:73:9 + --> $DIR/rename.rs:74:9 | LL | #![warn(clippy::to_string_in_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl` error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters` - --> $DIR/rename.rs:74:9 + --> $DIR/rename.rs:75:9 | LL | #![warn(clippy::zero_width_space)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters` error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op` - --> $DIR/rename.rs:75:9 + --> $DIR/rename.rs:76:9 | LL | #![warn(clippy::clone_double_ref)] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op` error: lint `clippy::drop_bounds` has been renamed to `drop_bounds` - --> $DIR/rename.rs:76:9 + --> $DIR/rename.rs:77:9 | LL | #![warn(clippy::drop_bounds)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds` error: lint `clippy::drop_copy` has been renamed to `drop_copy` - --> $DIR/rename.rs:77:9 + --> $DIR/rename.rs:78:9 | LL | #![warn(clippy::drop_copy)] | ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy` error: lint `clippy::drop_ref` has been renamed to `drop_ref` - --> $DIR/rename.rs:78:9 + --> $DIR/rename.rs:79:9 | LL | #![warn(clippy::drop_ref)] | ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref` error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:79:9 + --> $DIR/rename.rs:80:9 | LL | #![warn(clippy::for_loop_over_option)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:80:9 + --> $DIR/rename.rs:81:9 | LL | #![warn(clippy::for_loop_over_result)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles` - --> $DIR/rename.rs:81:9 + --> $DIR/rename.rs:82:9 | LL | #![warn(clippy::for_loops_over_fallibles)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles` +error: lint `clippy::forget_copy` has been renamed to `forget_copy` + --> $DIR/rename.rs:83:9 + | +LL | #![warn(clippy::forget_copy)] + | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_copy` + error: lint `clippy::forget_ref` has been renamed to `forget_ref` - --> $DIR/rename.rs:82:9 + --> $DIR/rename.rs:84:9 | LL | #![warn(clippy::forget_ref)] | ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref` error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter` - --> $DIR/rename.rs:83:9 + --> $DIR/rename.rs:85:9 | LL | #![warn(clippy::into_iter_on_array)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter` error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering` - --> $DIR/rename.rs:84:9 + --> $DIR/rename.rs:86:9 | LL | #![warn(clippy::invalid_atomic_ordering)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering` error: lint `clippy::invalid_ref` has been renamed to `invalid_value` - --> $DIR/rename.rs:85:9 + --> $DIR/rename.rs:87:9 | LL | #![warn(clippy::invalid_ref)] | ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value` error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop` - --> $DIR/rename.rs:86:9 + --> $DIR/rename.rs:88:9 | LL | #![warn(clippy::let_underscore_drop)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop` error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums` - --> $DIR/rename.rs:87:9 + --> $DIR/rename.rs:89:9 | LL | #![warn(clippy::mem_discriminant_non_enum)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums` error: lint `clippy::panic_params` has been renamed to `non_fmt_panics` - --> $DIR/rename.rs:88:9 + --> $DIR/rename.rs:90:9 | LL | #![warn(clippy::panic_params)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics` error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally` - --> $DIR/rename.rs:89:9 + --> $DIR/rename.rs:91:9 | LL | #![warn(clippy::positional_named_format_parameters)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally` error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr` - --> $DIR/rename.rs:90:9 + --> $DIR/rename.rs:92:9 | LL | #![warn(clippy::temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr` error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints` - --> $DIR/rename.rs:91:9 + --> $DIR/rename.rs:93:9 | LL | #![warn(clippy::unknown_clippy_lints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints` error: lint `clippy::unused_label` has been renamed to `unused_labels` - --> $DIR/rename.rs:92:9 + --> $DIR/rename.rs:94:9 | LL | #![warn(clippy::unused_label)] | ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels` -error: aborting due to 46 previous errors +error: aborting due to 47 previous errors From 61ff2718f76ac1ea0669938a06babfd578fadd46 Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 29 Mar 2023 22:18:20 +0200 Subject: [PATCH 14/34] Adjust tests for new drop and forget lints --- .../fail/stacked_borrows/illegal_write2.rs | 2 + src/tools/miri/tests/fail/uninit_buffer.rs | 2 + .../fail/uninit_buffer_with_provenance.rs | 2 + .../zst-field-retagging-terminates.rs | 3 ++ .../ui/associated-inherent-types/inference.rs | 1 + .../multiple-lifetimes/partial-relation.rs | 2 +- .../borrowck-closures-slice-patterns-ok.rs | 1 + .../borrowck-field-sensitivity-rpass.rs | 1 + .../borrowck/borrowck-use-mut-borrow-rpass.rs | 2 + .../migrations/issue-78720.rs | 1 + .../migrations/issue-78720.stderr | 2 +- .../optimization/edge_case_run_pass.rs | 1 + .../run_pass/drop_then_use_fake_reads.rs | 2 + tests/ui/consts/const_forget.rs | 2 + tests/ui/consts/issue-104155.rs | 3 ++ tests/ui/crate-leading-sep.rs | 2 + tests/ui/drop/repeat-drop.rs | 2 + .../explicit-call-to-supertrait-dtor.fixed | 3 ++ .../explicit-call-to-supertrait-dtor.rs | 3 ++ .../explicit-call-to-supertrait-dtor.stderr | 2 +- .../feature-gate-unsafe_pin_internals.rs | 1 - tests/ui/generator/drop-env.rs | 1 + .../issue-57017.no_drop_tracking.stderr | 42 +++++++++---------- tests/ui/generator/issue-57017.rs | 1 + tests/ui/generator/non-static-is-unpin.rs | 1 + tests/ui/generator/resume-arg-size.rs | 1 + .../stdlib-prelude-from-opaque-late.rs | 1 + tests/ui/illegal-ufcs-drop.fixed | 3 ++ tests/ui/illegal-ufcs-drop.rs | 3 ++ tests/ui/illegal-ufcs-drop.stderr | 2 +- tests/ui/liveness/liveness-unused.rs | 2 +- .../ui/macros/parse-complex-macro-invoc-op.rs | 1 + tests/ui/never_type/never-assign-dead-code.rs | 1 + .../never_type/never-assign-dead-code.stderr | 8 ++-- tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs | 2 + tests/ui/nll/ty-outlives/projection-body.rs | 2 + .../or-patterns-default-binding-modes.rs | 2 + .../borrowck-pat-at-and-box-pass.rs | 3 ++ .../borrowck-pat-by-copy-bindings-in-at.rs | 2 + .../borrowck-move-ref-pattern-pass.rs | 2 + ...move-ref-patterns-closure-captures-pass.rs | 2 + tests/ui/print_type_sizes/async.rs | 2 + tests/ui/print_type_sizes/async.stdout | 8 ++-- .../generator_discr_placement.rs | 1 + .../generator_discr_placement.stdout | 2 +- ...pe-param-outlives-reempty-issue-74429-2.rs | 6 +-- ...type-param-outlives-reempty-issue-74429.rs | 2 + .../borrowck-exhaustive.rs | 2 + .../dbg-macro-expected-behavior.rs | 2 + .../dbg-macro-expected-behavior.run.stderr | 30 ++++++------- tests/ui/rust-2018/remove-extern-crate.fixed | 1 + tests/ui/rust-2018/remove-extern-crate.rs | 1 + tests/ui/rust-2018/remove-extern-crate.stderr | 6 +-- tests/ui/statics/issue-91050-1.rs | 2 + tests/ui/traits/copy-guessing.rs | 3 ++ tests/ui/traits/impl-evaluation-order.rs | 2 + .../auto-with-drop_tracking_mir.fail.stderr | 4 +- .../new-solver/auto-with-drop_tracking_mir.rs | 1 + .../traits/new-solver/temporary-ambiguity.rs | 2 +- .../trivial-bounds-inconsistent-copy.rs | 2 + .../trivial-bounds-inconsistent-copy.stderr | 8 ++-- 61 files changed, 145 insertions(+), 64 deletions(-) diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs index 70c51e671fe8..bf4204c61fd7 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs @@ -1,3 +1,5 @@ +#![allow(drop_ref)] + fn main() { let target = &mut 42; let target2 = target as *mut _; diff --git a/src/tools/miri/tests/fail/uninit_buffer.rs b/src/tools/miri/tests/fail/uninit_buffer.rs index d21371225e57..c084dea20bd8 100644 --- a/src/tools/miri/tests/fail/uninit_buffer.rs +++ b/src/tools/miri/tests/fail/uninit_buffer.rs @@ -1,5 +1,7 @@ //@error-pattern: memory is uninitialized at [0x4..0x10] +#![allow(drop_copy)] + use std::alloc::{alloc, dealloc, Layout}; use std::slice::from_raw_parts; diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs index 170bc6e1ed12..1eccc4836124 100644 --- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs @@ -2,6 +2,8 @@ //@normalize-stderr-test: "a[0-9]+" -> "ALLOC" #![feature(strict_provenance)] +#![allow(drop_copy)] + // Test printing allocations that contain single-byte provenance. use std::alloc::{alloc, dealloc, Layout}; diff --git a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs index ce3c8b7d5f1a..9f743f0b5665 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs @@ -1,5 +1,8 @@ //@compile-flags: -Zmiri-retag-fields // Checks that the test does not run forever (which relies on a fast path). + +#![allow(drop_copy)] + fn main() { let array = [(); usize::MAX]; drop(array); // Pass the array to a function, retagging its fields diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs index 38179214fa12..7d6d26003f60 100644 --- a/tests/ui/associated-inherent-types/inference.rs +++ b/tests/ui/associated-inherent-types/inference.rs @@ -3,6 +3,7 @@ #![feature(inherent_associated_types)] #![allow(incomplete_features)] +#![allow(drop_copy)] use std::convert::identity; diff --git a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs index 02b105999f5b..7375cb6d3a0d 100644 --- a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs +++ b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs @@ -4,7 +4,7 @@ async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32) where 'b: 'a { - drop((a, c)); + let _ = (a, c); (b, b) } diff --git a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs index 0229ca37a692..9163c8ed6fb2 100644 --- a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs +++ b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs @@ -1,6 +1,7 @@ // Check that closure captures for slice patterns are inferred correctly #![allow(unused_variables)] +#![allow(drop_ref)] // run-pass diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs index dd6708582c1b..a88b323e0bf1 100644 --- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs +++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs @@ -1,6 +1,7 @@ // run-pass #![allow(unused_mut)] #![allow(unused_variables)] +#![allow(drop_copy)] // pretty-expanded FIXME #23616 struct A { a: isize, b: Box } diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs index 1cf763f66fd2..40c6bfeeb434 100644 --- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs +++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(drop_copy)] + struct A { a: isize, b: Box } fn field_copy_after_field_borrow() { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs index ff5d284614bf..bc7295a0826f 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs +++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs @@ -1,6 +1,7 @@ // run-pass #![warn(rust_2021_incompatible_closure_captures)] +#![allow(drop_ref, drop_copy)] fn main() { if let a = "" { diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr index 36a80e694e82..2609e2951ec5 100644 --- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr +++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr @@ -1,5 +1,5 @@ warning: irrefutable `if let` pattern - --> $DIR/issue-78720.rs:6:8 + --> $DIR/issue-78720.rs:7:8 | LL | if let a = "" { | ^^^^^^^^^^ diff --git a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs index 033fd6f17753..0f15f664e757 100644 --- a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs +++ b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs @@ -3,6 +3,7 @@ #![allow(unused)] #![allow(dead_code)] +#![allow(drop_ref)] struct Int(i32); struct B<'a>(&'a i32); diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs index 477fdd613f52..a097424a0217 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs +++ b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs @@ -1,6 +1,8 @@ // edition:2021 // check-pass + #![feature(rustc_attrs)] +#![allow(drop_ref)] fn main() { let mut x = 1; diff --git a/tests/ui/consts/const_forget.rs b/tests/ui/consts/const_forget.rs index ec7dde8c9ecd..acdd6a54cf4e 100644 --- a/tests/ui/consts/const_forget.rs +++ b/tests/ui/consts/const_forget.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(forget_copy)] + use std::mem::forget; const _: () = forget(0i32); diff --git a/tests/ui/consts/issue-104155.rs b/tests/ui/consts/issue-104155.rs index 1cc8f81b0d25..b3821f467b61 100644 --- a/tests/ui/consts/issue-104155.rs +++ b/tests/ui/consts/issue-104155.rs @@ -1,4 +1,7 @@ // check-pass + +#![allow(forget_copy)] + const _: () = core::mem::forget(Box::::default); const _: () = core::mem::forget(|| Box::::default()); diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs index ca5905fab41f..8d1d0b4fcdf0 100644 --- a/tests/ui/crate-leading-sep.rs +++ b/tests/ui/crate-leading-sep.rs @@ -1,6 +1,8 @@ // run-pass // pretty-expanded FIXME #23616 +#![allow(drop_copy)] + fn main() { use ::std::mem; mem::drop(2_usize); diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs index 8fd46ecaf442..659d35db6575 100644 --- a/tests/ui/drop/repeat-drop.rs +++ b/tests/ui/drop/repeat-drop.rs @@ -1,6 +1,8 @@ // run-pass // needs-unwind +#![allow(drop_ref, drop_copy)] + static mut CHECK: usize = 0; struct DropChecker(usize); diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed index 47c4c9f67b69..0bc4feed329d 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo { x: isize } diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs index c698de50c75b..26ae6698d669 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo { x: isize } diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr index 7f5106eb57e5..c70671173491 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -1,5 +1,5 @@ error[E0040]: explicit use of destructor method - --> $DIR/explicit-call-to-supertrait-dtor.rs:19:14 + --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14 | LL | self.drop(); | -----^^^^-- diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs index 0680d2344030..dce94c9eab27 100644 --- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs +++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs @@ -13,5 +13,4 @@ fn non_unsafe_pin_new_unchecked(pointer: &mut T) -> Pin<&mut T> { fn main() { let mut self_referential = PhantomPinned; let _: Pin<&mut PhantomPinned> = non_unsafe_pin_new_unchecked(&mut self_referential); - core::mem::forget(self_referential); // move and disable drop glue! } diff --git a/tests/ui/generator/drop-env.rs b/tests/ui/generator/drop-env.rs index 66dfb8c2c098..cb46953dac3c 100644 --- a/tests/ui/generator/drop-env.rs +++ b/tests/ui/generator/drop-env.rs @@ -4,6 +4,7 @@ //[nomiropt]compile-flags: -Z mir-opt-level=0 #![feature(generators, generator_trait)] +#![allow(drop_copy)] use std::ops::Generator; use std::pin::Pin; diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr index 06d2d23b9efb..f7b8e198cc4b 100644 --- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr +++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr @@ -1,5 +1,5 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -15,7 +15,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `copy::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `©::unsync::Client` which is not `Send` @@ -33,14 +33,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -54,9 +54,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `copy::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `copy::unsend::Client` which is not `Send` @@ -74,14 +74,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -97,7 +97,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `&derived_drop::unsync::Client` which is not `Send` @@ -115,14 +115,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -136,9 +136,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `derived_drop::unsend::Client` which is not `Send` @@ -156,14 +156,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:31:25 + --> $DIR/issue-57017.rs:32:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -179,7 +179,7 @@ LL | | ); | = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:29:28 + --> $DIR/issue-57017.rs:30:28 | LL | let g = move || match drop(&$name::unsync::Client::default()) { | --------------------------------- has type `&significant_drop::unsync::Client` which is not `Send` @@ -197,14 +197,14 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info) error: generator cannot be sent between threads safely - --> $DIR/issue-57017.rs:43:25 + --> $DIR/issue-57017.rs:44:25 | LL | assert_send(g); | ^ generator is not `Send` @@ -218,9 +218,9 @@ LL | | } LL | | ); | |_____- in this macro invocation | - = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client` + = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-57017.rs:41:28 + --> $DIR/issue-57017.rs:42:28 | LL | let g = move || match drop($name::unsend::Client::default()) { | -------------------------------- has type `significant_drop::unsend::Client` which is not `Send` @@ -238,7 +238,7 @@ LL | | } LL | | ); | |_____- in this macro invocation note: required by a bound in `assert_send` - --> $DIR/issue-57017.rs:51:19 + --> $DIR/issue-57017.rs:52:19 | LL | fn assert_send(_thing: T) {} | ^^^^ required by this bound in `assert_send` diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs index 03b00ac99ad2..918d233bf4ee 100644 --- a/tests/ui/generator/issue-57017.rs +++ b/tests/ui/generator/issue-57017.rs @@ -5,6 +5,7 @@ // [drop_tracking_mir] build-pass #![feature(generators, negative_impls)] +#![allow(drop_ref, drop_copy)] macro_rules! type_combinations { ( diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs index 17e23f5bcd2f..adba800e25ae 100644 --- a/tests/ui/generator/non-static-is-unpin.rs +++ b/tests/ui/generator/non-static-is-unpin.rs @@ -3,6 +3,7 @@ // run-pass #![feature(generators, generator_trait)] +#![allow(drop_copy)] use std::marker::{PhantomPinned, Unpin}; diff --git a/tests/ui/generator/resume-arg-size.rs b/tests/ui/generator/resume-arg-size.rs index b93dc54f7a97..19618f8d0aa5 100644 --- a/tests/ui/generator/resume-arg-size.rs +++ b/tests/ui/generator/resume-arg-size.rs @@ -1,4 +1,5 @@ #![feature(generators)] +#![allow(drop_copy)] // run-pass diff --git a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs index cf65de2bc239..214267372bf8 100644 --- a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs +++ b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs @@ -1,6 +1,7 @@ // check-pass #![feature(decl_macro)] +#![allow(drop_copy)] macro mac() { mod m { diff --git a/tests/ui/illegal-ufcs-drop.fixed b/tests/ui/illegal-ufcs-drop.fixed index d73b391be062..8783682dec47 100644 --- a/tests/ui/illegal-ufcs-drop.fixed +++ b/tests/ui/illegal-ufcs-drop.fixed @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo; impl Drop for Foo { diff --git a/tests/ui/illegal-ufcs-drop.rs b/tests/ui/illegal-ufcs-drop.rs index 11411f55494c..29774306ec6f 100644 --- a/tests/ui/illegal-ufcs-drop.rs +++ b/tests/ui/illegal-ufcs-drop.rs @@ -1,4 +1,7 @@ // run-rustfix + +#![allow(drop_ref)] + struct Foo; impl Drop for Foo { diff --git a/tests/ui/illegal-ufcs-drop.stderr b/tests/ui/illegal-ufcs-drop.stderr index 91f47d5e456d..7a5c0612c07e 100644 --- a/tests/ui/illegal-ufcs-drop.stderr +++ b/tests/ui/illegal-ufcs-drop.stderr @@ -1,5 +1,5 @@ error[E0040]: explicit use of destructor method - --> $DIR/illegal-ufcs-drop.rs:9:5 + --> $DIR/illegal-ufcs-drop.rs:12:5 | LL | Drop::drop(&mut Foo) | ^^^^^^^^^^ diff --git a/tests/ui/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs index 9c7be15fcc84..8ef6ab1b6ff4 100644 --- a/tests/ui/liveness/liveness-unused.rs +++ b/tests/ui/liveness/liveness-unused.rs @@ -1,7 +1,7 @@ #![warn(unused)] #![deny(unused_variables)] #![deny(unused_assignments)] -#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)] +#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, drop_copy)] use std::ops::AddAssign; diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs index 8fef9b0ed877..c50dfdf0116a 100644 --- a/tests/ui/macros/parse-complex-macro-invoc-op.rs +++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs @@ -4,6 +4,7 @@ #![allow(unused_assignments)] #![allow(unused_variables)] #![allow(stable_features)] +#![allow(drop_copy)] // Test parsing binary operators after macro invocations. diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs index 7bb7c87097c5..e95a992d7804 100644 --- a/tests/ui/never_type/never-assign-dead-code.rs +++ b/tests/ui/never_type/never-assign-dead-code.rs @@ -3,6 +3,7 @@ // check-pass #![feature(never_type)] +#![allow(drop_copy)] #![warn(unused)] fn main() { diff --git a/tests/ui/never_type/never-assign-dead-code.stderr b/tests/ui/never_type/never-assign-dead-code.stderr index 521b82023c93..5660bde5c279 100644 --- a/tests/ui/never_type/never-assign-dead-code.stderr +++ b/tests/ui/never_type/never-assign-dead-code.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/never-assign-dead-code.rs:10:5 + --> $DIR/never-assign-dead-code.rs:11:5 | LL | let x: ! = panic!("aah"); | ------------- any code following this expression is unreachable @@ -7,14 +7,14 @@ LL | drop(x); | ^^^^^^^^ unreachable statement | note: the lint level is defined here - --> $DIR/never-assign-dead-code.rs:6:9 + --> $DIR/never-assign-dead-code.rs:7:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]` warning: unreachable call - --> $DIR/never-assign-dead-code.rs:10:5 + --> $DIR/never-assign-dead-code.rs:11:5 | LL | drop(x); | ^^^^ - any code following this expression is unreachable @@ -22,7 +22,7 @@ LL | drop(x); | unreachable call warning: unused variable: `x` - --> $DIR/never-assign-dead-code.rs:9:9 + --> $DIR/never-assign-dead-code.rs:10:9 | LL | let x: ! = panic!("aah"); | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs index 7cc0acf45f24..73ceaeeb8757 100644 --- a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs +++ b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -5,6 +5,8 @@ // check-pass // compile-flags:-Zno-leak-check +#![allow(drop_copy)] + fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 { panic!() } diff --git a/tests/ui/nll/ty-outlives/projection-body.rs b/tests/ui/nll/ty-outlives/projection-body.rs index b03a539ebdbe..bff9058a507b 100644 --- a/tests/ui/nll/ty-outlives/projection-body.rs +++ b/tests/ui/nll/ty-outlives/projection-body.rs @@ -3,6 +3,8 @@ // // check-pass +#![allow(drop_ref)] + trait MyTrait<'a> { type Output; } diff --git a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs index e56f9ffe23c6..c138d99d3032 100644 --- a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs +++ b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs @@ -3,6 +3,8 @@ // check-pass #![allow(irrefutable_let_patterns)] +#![allow(drop_copy)] +#![allow(drop_ref)] fn main() { // A regression test for a mistake we made at one point: diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index fbdefd9d36c9..965204bf240e 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -2,6 +2,9 @@ // Test `@` patterns combined with `box` patterns. +#![allow(drop_ref)] +#![allow(drop_copy)] + #![feature(box_patterns)] #[derive(Copy, Clone)] diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index 0108861cfce3..3eb5d2cbf546 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -2,6 +2,8 @@ // Test `Copy` bindings in the rhs of `@` patterns. +#![allow(drop_copy)] + #[derive(Copy, Clone)] struct C; diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs index 5445696fdff7..0550238549ef 100644 --- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs +++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(drop_ref)] + fn main() {} struct U; diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs index 583f70f41aa7..788975d960aa 100644 --- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs +++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -1,5 +1,7 @@ // check-pass +#![allow(drop_ref)] + fn main() { struct U; fn accept_fn_once(_: impl FnOnce()) {} diff --git a/tests/ui/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs index 1598b0696913..c73268dc46a7 100644 --- a/tests/ui/print_type_sizes/async.rs +++ b/tests/ui/print_type_sizes/async.rs @@ -3,6 +3,8 @@ // build-pass // ignore-pass +#![allow(drop_copy)] + async fn wait() {} pub async fn test(arg: [u8; 8192]) { diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index 1c6887412be1..873def9031aa 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -1,4 +1,4 @@ -print-type-size type: `[async fn body@$DIR/async.rs:8:36: 11:2]`: 16386 bytes, alignment: 1 bytes +print-type-size type: `[async fn body@$DIR/async.rs:10:36: 13:2]`: 16386 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes @@ -16,14 +16,14 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 8192 bytes -print-type-size type: `[async fn body@$DIR/async.rs:6:17: 6:19]`: 1 bytes, alignment: 1 bytes +print-type-size type: `[async fn body@$DIR/async.rs:8:17: 8:19]`: 1 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes -print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes -print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes +print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes print-type-size field `.value`: 1 bytes diff --git a/tests/ui/print_type_sizes/generator_discr_placement.rs b/tests/ui/print_type_sizes/generator_discr_placement.rs index 1a85fe95bb6f..a77a03f0a8ae 100644 --- a/tests/ui/print_type_sizes/generator_discr_placement.rs +++ b/tests/ui/print_type_sizes/generator_discr_placement.rs @@ -6,6 +6,7 @@ // Avoid emitting panic handlers, like the rest of these tests... #![feature(generators)] +#![allow(drop_copy)] pub fn foo() { let a = || { diff --git a/tests/ui/print_type_sizes/generator_discr_placement.stdout b/tests/ui/print_type_sizes/generator_discr_placement.stdout index f2a11c7a33ba..fe0022cf5f4c 100644 --- a/tests/ui/print_type_sizes/generator_discr_placement.stdout +++ b/tests/ui/print_type_sizes/generator_discr_placement.stdout @@ -1,4 +1,4 @@ -print-type-size type: `[generator@$DIR/generator_discr_placement.rs:11:13: 11:15]`: 8 bytes, alignment: 4 bytes +print-type-size type: `[generator@$DIR/generator_discr_placement.rs:12:13: 12:15]`: 8 bytes, alignment: 4 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Suspend0`: 7 bytes diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs index a65c17e0efc3..5ae5ebb450e8 100644 --- a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs +++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs @@ -55,11 +55,11 @@ where } pub fn x(a: Array) { - // drop just avoids a must_use warning - drop((0..1).filter(|_| true)); + // _ just avoids a must_use warning + let _ = (0..1).filter(|_| true); let y = a.index_axis(); a.axis_iter().for_each(|_| { - drop(y); + let _ = y; }); } diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs index d463f311c34e..af2bb09805ac 100644 --- a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs +++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs @@ -3,6 +3,8 @@ // check-pass +#![allow(drop_copy)] + use std::marker::PhantomData; fn apply(_: T, _: F) {} diff --git a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs index be775b37f7b7..8f45b989f136 100644 --- a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs +++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs @@ -3,6 +3,8 @@ // check-pass +#![allow(drop_ref)] + // aux-build:monovariants.rs extern crate monovariants; diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs index 04d924a9aed2..4c1562790d5f 100644 --- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs +++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs @@ -4,6 +4,8 @@ // Tests ensuring that `dbg!(expr)` has the expected run-time behavior. // as well as some compile time properties we expect. +#![allow(drop_copy)] + #[derive(Copy, Clone, Debug)] struct Unit; diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr index 49d72158e92b..a20a6062c13b 100644 --- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr +++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr @@ -1,28 +1,28 @@ -[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit -[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit -[$DIR/dbg-macro-expected-behavior.rs:27] Point { x: 42, y: 24 } = Point { +[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit +[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit +[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:28] b = Point { +[$DIR/dbg-macro-expected-behavior.rs:30] b = Point { x: 42, y: 24, } -[$DIR/dbg-macro-expected-behavior.rs:36] -[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:38] +[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy( +[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(& a) = NoCopy( 1337, ) -[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42 +[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42 before -[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331 -[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = ( +[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331 +[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = ( "Yeah", ) -[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1 -[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2 -[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1 -[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2 -[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah" +[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1 +[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1 +[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2 +[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah" diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed index 15e0ccc5256a..4ed4d610025f 100644 --- a/tests/ui/rust-2018/remove-extern-crate.fixed +++ b/tests/ui/rust-2018/remove-extern-crate.fixed @@ -5,6 +5,7 @@ // compile-flags:--extern remove_extern_crate #![warn(rust_2018_idioms)] +#![allow(drop_copy)] //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs index aec0bc7c3740..5dafdb2b7b77 100644 --- a/tests/ui/rust-2018/remove-extern-crate.rs +++ b/tests/ui/rust-2018/remove-extern-crate.rs @@ -5,6 +5,7 @@ // compile-flags:--extern remove_extern_crate #![warn(rust_2018_idioms)] +#![allow(drop_copy)] extern crate core; //~ WARNING unused extern crate // Shouldn't suggest changing to `use`, as `another_name` diff --git a/tests/ui/rust-2018/remove-extern-crate.stderr b/tests/ui/rust-2018/remove-extern-crate.stderr index d07358e471bb..f752cac8ed63 100644 --- a/tests/ui/rust-2018/remove-extern-crate.stderr +++ b/tests/ui/rust-2018/remove-extern-crate.stderr @@ -1,5 +1,5 @@ warning: unused extern crate - --> $DIR/remove-extern-crate.rs:9:1 + --> $DIR/remove-extern-crate.rs:10:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ help: remove it @@ -12,7 +12,7 @@ LL | #![warn(rust_2018_idioms)] = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]` warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:33:5 + --> $DIR/remove-extern-crate.rs:34:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | use core; | ~~~ warning: `extern crate` is not idiomatic in the new edition - --> $DIR/remove-extern-crate.rs:43:5 + --> $DIR/remove-extern-crate.rs:44:5 | LL | pub extern crate core; | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/statics/issue-91050-1.rs b/tests/ui/statics/issue-91050-1.rs index 403a41462ef1..f59bcf0b8033 100644 --- a/tests/ui/statics/issue-91050-1.rs +++ b/tests/ui/statics/issue-91050-1.rs @@ -12,6 +12,8 @@ // // In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!" +#![allow(drop_copy)] + pub mod before { #[no_mangle] pub static GLOBAL1: [u8; 1] = [1]; diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs index f031dd9ca48f..558303c2e40b 100644 --- a/tests/ui/traits/copy-guessing.rs +++ b/tests/ui/traits/copy-guessing.rs @@ -1,5 +1,8 @@ // run-pass + #![allow(dead_code)] +#![allow(drop_copy)] + // "guessing" in trait selection can affect `copy_or_move`. Check that this // is correctly handled. I am not sure what is the "correct" behaviour, // but we should at least not ICE. diff --git a/tests/ui/traits/impl-evaluation-order.rs b/tests/ui/traits/impl-evaluation-order.rs index 57809d89aa64..256ce992eefc 100644 --- a/tests/ui/traits/impl-evaluation-order.rs +++ b/tests/ui/traits/impl-evaluation-order.rs @@ -6,6 +6,8 @@ // check-pass +#![allow(drop_copy)] + trait A { type B; } diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr index 6a926534e079..4aefdd6bb073 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr @@ -1,5 +1,5 @@ error[E0277]: `impl Future` cannot be sent between threads safely - --> $DIR/auto-with-drop_tracking_mir.rs:24:13 + --> $DIR/auto-with-drop_tracking_mir.rs:25:13 | LL | is_send(foo()); | ------- ^^^^^ `impl Future` cannot be sent between threads safely @@ -8,7 +8,7 @@ LL | is_send(foo()); | = help: the trait `Send` is not implemented for `impl Future` note: required by a bound in `is_send` - --> $DIR/auto-with-drop_tracking_mir.rs:23:24 + --> $DIR/auto-with-drop_tracking_mir.rs:24:24 | LL | fn is_send(_: impl Send) {} | ^^^^ required by this bound in `is_send` diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs index a5db7c4636b3..f115e1433182 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs @@ -14,6 +14,7 @@ async fn foo() { #[cfg(fail)] let x = &NotSync; bar().await; + #[allow(drop_ref)] drop(x); } diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs index 18ee05457009..c6c11a1a1de1 100644 --- a/tests/ui/traits/new-solver/temporary-ambiguity.rs +++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs @@ -18,5 +18,5 @@ fn main() { let w = Wrapper(x); needs_foo(w); x = 1; - drop(x); + let _ = x; } diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs index 3416503b851f..6ed7667115a0 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs @@ -1,6 +1,8 @@ // check-pass // Check tautalogically false `Copy` bounds + #![feature(trivial_bounds)] +#![allow(drop_ref, drop_copy)] fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds is_copy(&t); diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr index 1e26623899ba..deeb352a2a85 100644 --- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr +++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr @@ -1,5 +1,5 @@ warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51 + --> $DIR/trivial-bounds-inconsistent-copy.rs:7:51 | LL | fn copy_string(t: String) -> String where String: Copy { | ^^^^ @@ -7,19 +7,19 @@ LL | fn copy_string(t: String) -> String where String: Copy { = note: `#[warn(trivial_bounds)]` on by default warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56 + --> $DIR/trivial-bounds-inconsistent-copy.rs:14:56 | LL | fn copy_out_string(t: &String) -> String where String: Copy { | ^^^^ warning: trait bound String: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55 + --> $DIR/trivial-bounds-inconsistent-copy.rs:18:55 | LL | fn copy_string_with_param(x: String) where String: Copy { | ^^^^ warning: trait bound for<'b> &'b mut i32: Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76 + --> $DIR/trivial-bounds-inconsistent-copy.rs:24:76 | LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy { | ^^^^ From 77773ad002f9bd9fc2124b964bebad94b5f5d286 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 30 Mar 2023 09:24:44 +0200 Subject: [PATCH 15/34] Allow the drop_copy lint in some library examples --- library/core/src/mem/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4913a6de9182..289305253ecc 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -968,6 +968,7 @@ pub const fn replace(dest: &mut T, src: T) -> T { /// Integers and other types implementing [`Copy`] are unaffected by `drop`. /// /// ``` +/// # #![cfg_attr(not(bootstrap), allow(drop_copy))] /// #[derive(Copy, Clone)] /// struct Foo(u8); /// From 457fa953a2ed374630e1f5cd0d8c599c2b4b0609 Mon Sep 17 00:00:00 2001 From: Urgau Date: Mon, 10 Apr 2023 11:55:37 +0200 Subject: [PATCH 16/34] Use label instead of note to be more consistent with other lints --- compiler/rustc_lint/messages.ftl | 8 +- .../rustc_lint/src/drop_forget_useless.rs | 8 +- compiler/rustc_lint/src/lints.rs | 16 +-- tests/ui/lint/drop_copy.stderr | 98 +++++---------- tests/ui/lint/drop_ref.stderr | 119 ++++++------------ tests/ui/lint/forget_copy.stderr | 78 ++++-------- tests/ui/lint/forget_ref.stderr | 89 ++++--------- 7 files changed, 133 insertions(+), 283 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 0db4b3160dfb..63424148e4d0 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -522,13 +522,13 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass lint_opaque_hidden_inferred_bound_sugg = add this bound lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value - .note = argument has type `{$arg_ty}` + .label = argument has type `{$arg_ty}` lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy`. - .note = argument has type `{$arg_ty}` + .label = argument has type `{$arg_ty}` lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value - .note = argument has type `{$arg_ty}` + .label = argument has type `{$arg_ty}` lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy`. - .note = argument has type `{$arg_ty}` + .label = argument has type `{$arg_ty}` diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs index e72439439a4b..259abc2af112 100644 --- a/compiler/rustc_lint/src/drop_forget_useless.rs +++ b/compiler/rustc_lint/src/drop_forget_useless.rs @@ -123,16 +123,16 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetUseless { let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr); match fn_name { sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => { - cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, note: arg.span }); + cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, label: arg.span }); }, sym::mem_forget if arg_ty.is_ref() => { - cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, note: arg.span }); + cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, label: arg.span }); }, sym::mem_drop if is_copy && !drop_is_single_call_in_arm => { - cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, note: arg.span }); + cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, label: arg.span }); } sym::mem_forget if is_copy => { - cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, note: arg.span }); + cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, label: arg.span }); } _ => return, }; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 102a149a410c..755b907dfe5c 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -667,32 +667,32 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { #[diag(lint_drop_ref)] pub struct DropRefDiag<'a> { pub arg_ty: Ty<'a>, - #[note] - pub note: Span, + #[label] + pub label: Span, } #[derive(LintDiagnostic)] #[diag(lint_drop_copy)] pub struct DropCopyDiag<'a> { pub arg_ty: Ty<'a>, - #[note] - pub note: Span, + #[label] + pub label: Span, } #[derive(LintDiagnostic)] #[diag(lint_forget_ref)] pub struct ForgetRefDiag<'a> { pub arg_ty: Ty<'a>, - #[note] - pub note: Span, + #[label] + pub label: Span, } #[derive(LintDiagnostic)] #[diag(lint_forget_copy)] pub struct ForgetCopyDiag<'a> { pub arg_ty: Ty<'a>, - #[note] - pub note: Span, + #[label] + pub label: Span, } // hidden_unicode_codepoints.rs diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr index 03d0b392e2b4..a7a3b0e25ec7 100644 --- a/tests/ui/lint/drop_copy.stderr +++ b/tests/ui/lint/drop_copy.stderr @@ -2,13 +2,10 @@ warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:34:5 | LL | drop(s1); - | ^^^^^^^^ + | ^^^^^--^ + | | + | argument has type `SomeStruct` | -note: argument has type `SomeStruct` - --> $DIR/drop_copy.rs:34:10 - | -LL | drop(s1); - | ^^ note: the lint level is defined here --> $DIR/drop_copy.rs:3:9 | @@ -19,110 +16,75 @@ warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:35:5 | LL | drop(s2); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_copy.rs:35:10 - | -LL | drop(s2); - | ^^ + | ^^^^^--^ + | | + | argument has type `SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_copy.rs:36:5 | LL | drop(s3); - | ^^^^^^^^ + | ^^^^^--^ + | | + | argument has type `&SomeStruct` | -note: argument has type `&SomeStruct` - --> $DIR/drop_copy.rs:36:10 - | -LL | drop(s3); - | ^^ = note: `#[warn(drop_ref)]` on by default warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:37:5 | LL | drop(s4); - | ^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/drop_copy.rs:37:10 - | -LL | drop(s4); - | ^^ + | ^^^^^--^ + | | + | argument has type `SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_copy.rs:38:5 | LL | drop(s5); - | ^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_copy.rs:38:10 - | -LL | drop(s5); - | ^^ + | ^^^^^--^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_copy.rs:50:5 | LL | drop(a2); - | ^^^^^^^^ - | -note: argument has type `&AnotherStruct` - --> $DIR/drop_copy.rs:50:10 - | -LL | drop(a2); - | ^^ + | ^^^^^--^ + | | + | argument has type `&AnotherStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_copy.rs:52:5 | LL | drop(a4); - | ^^^^^^^^ - | -note: argument has type `&AnotherStruct` - --> $DIR/drop_copy.rs:52:10 - | -LL | drop(a4); - | ^^ + | ^^^^^--^ + | | + | argument has type `&AnotherStruct` warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:71:13 | LL | drop(println_and(13)); - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_copy.rs:71:18 - | -LL | drop(println_and(13)); - | ^^^^^^^^^^^^^^^ + | ^^^^^---------------^ + | | + | argument has type `i32` warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:74:14 | LL | 3 if drop(println_and(14)) == () => (), - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_copy.rs:74:19 - | -LL | 3 if drop(println_and(14)) == () => (), - | ^^^^^^^^^^^^^^^ + | ^^^^^---------------^ + | | + | argument has type `i32` warning: calls to `std::mem::drop` with a value that implements `Copy`. --> $DIR/drop_copy.rs:76:14 | LL | 4 => drop(2), - | ^^^^^^^ - | -note: argument has type `i32` - --> $DIR/drop_copy.rs:76:19 - | -LL | 4 => drop(2), - | ^ + | ^^^^^-^ + | | + | argument has type `i32` warning: 10 warnings emitted diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr index 34e4050abcf6..c701f99fa901 100644 --- a/tests/ui/lint/drop_ref.stderr +++ b/tests/ui/lint/drop_ref.stderr @@ -2,13 +2,10 @@ warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:8:5 | LL | drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^-----------^ + | | + | argument has type `&SomeStruct` | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:8:10 - | -LL | drop(&SomeStruct); - | ^^^^^^^^^^^ note: the lint level is defined here --> $DIR/drop_ref.rs:3:9 | @@ -19,133 +16,89 @@ warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:11:5 | LL | drop(&owned1); - | ^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:11:10 - | -LL | drop(&owned1); - | ^^^^^^^ + | ^^^^^-------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:12:5 | LL | drop(&&owned1); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/drop_ref.rs:12:10 - | -LL | drop(&&owned1); - | ^^^^^^^^ + | ^^^^^--------^ + | | + | argument has type `&&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:13:5 | LL | drop(&mut owned1); - | ^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:13:10 - | -LL | drop(&mut owned1); - | ^^^^^^^^^^^ + | ^^^^^-----------^ + | | + | argument has type `&mut SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:17:5 | LL | drop(reference1); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:17:10 - | -LL | drop(reference1); - | ^^^^^^^^^^ + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:20:5 | LL | drop(reference2); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/drop_ref.rs:20:10 - | -LL | drop(reference2); - | ^^^^^^^^^^ + | ^^^^^----------^ + | | + | argument has type `&mut SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:23:5 | LL | drop(reference3); - | ^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:23:10 - | -LL | drop(reference3); - | ^^^^^^^^^^ + | ^^^^^----------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:28:5 | LL | drop(&val); - | ^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/drop_ref.rs:28:10 - | -LL | drop(&val); - | ^^^^ + | ^^^^^----^ + | | + | argument has type `&T` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:36:5 | LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/drop_ref.rs:36:20 - | -LL | std::mem::drop(&SomeStruct); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:91:13 | LL | drop(println_and(&13)); - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:91:18 - | -LL | drop(println_and(&13)); - | ^^^^^^^^^^^^^^^^ + | ^^^^^----------------^ + | | + | argument has type `&i32` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:94:14 | LL | 3 if drop(println_and(&14)) == () => (), - | ^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:94:19 - | -LL | 3 if drop(println_and(&14)) == () => (), - | ^^^^^^^^^^^^^^^^ + | ^^^^^----------------^ + | | + | argument has type `&i32` warning: calls to `std::mem::drop` with a reference instead of an owned value --> $DIR/drop_ref.rs:96:14 | LL | 4 => drop(&2), - | ^^^^^^^^ - | -note: argument has type `&i32` - --> $DIR/drop_ref.rs:96:19 - | -LL | 4 => drop(&2), - | ^^ + | ^^^^^--^ + | | + | argument has type `&i32` warning: 12 warnings emitted diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr index d33dfa0fd3d1..e2fc0f8af4fb 100644 --- a/tests/ui/lint/forget_copy.stderr +++ b/tests/ui/lint/forget_copy.stderr @@ -2,13 +2,10 @@ warning: calls to `std::mem::forget` with a value that implements `Copy`. --> $DIR/forget_copy.rs:34:5 | LL | forget(s1); - | ^^^^^^^^^^ + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` | -note: argument has type `SomeStruct` - --> $DIR/forget_copy.rs:34:12 - | -LL | forget(s1); - | ^^ note: the lint level is defined here --> $DIR/forget_copy.rs:3:9 | @@ -19,86 +16,59 @@ warning: calls to `std::mem::forget` with a value that implements `Copy`. --> $DIR/forget_copy.rs:35:5 | LL | forget(s2); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/forget_copy.rs:35:12 - | -LL | forget(s2); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_copy.rs:36:5 | LL | forget(s3); - | ^^^^^^^^^^ + | ^^^^^^^--^ + | | + | argument has type `&SomeStruct` | -note: argument has type `&SomeStruct` - --> $DIR/forget_copy.rs:36:12 - | -LL | forget(s3); - | ^^ = note: `#[warn(forget_ref)]` on by default warning: calls to `std::mem::forget` with a value that implements `Copy`. --> $DIR/forget_copy.rs:37:5 | LL | forget(s4); - | ^^^^^^^^^^ - | -note: argument has type `SomeStruct` - --> $DIR/forget_copy.rs:37:12 - | -LL | forget(s4); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_copy.rs:38:5 | LL | forget(s5); - | ^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_copy.rs:38:12 - | -LL | forget(s5); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_copy.rs:50:5 | LL | forget(a2); - | ^^^^^^^^^^ - | -note: argument has type `&AnotherStruct` - --> $DIR/forget_copy.rs:50:12 - | -LL | forget(a2); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_copy.rs:52:5 | LL | forget(a3); - | ^^^^^^^^^^ - | -note: argument has type `&AnotherStruct` - --> $DIR/forget_copy.rs:52:12 - | -LL | forget(a3); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_copy.rs:53:5 | LL | forget(a4); - | ^^^^^^^^^^ - | -note: argument has type `&AnotherStruct` - --> $DIR/forget_copy.rs:53:12 - | -LL | forget(a4); - | ^^ + | ^^^^^^^--^ + | | + | argument has type `&AnotherStruct` warning: 8 warnings emitted diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr index abb45443e4e9..96fb217215aa 100644 --- a/tests/ui/lint/forget_ref.stderr +++ b/tests/ui/lint/forget_ref.stderr @@ -2,13 +2,10 @@ warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:10:5 | LL | forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:10:12 - | -LL | forget(&SomeStruct); - | ^^^^^^^^^^^ note: the lint level is defined here --> $DIR/forget_ref.rs:3:9 | @@ -19,97 +16,65 @@ warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:13:5 | LL | forget(&owned); - | ^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:13:12 - | -LL | forget(&owned); - | ^^^^^^ + | ^^^^^^^------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:14:5 | LL | forget(&&owned); - | ^^^^^^^^^^^^^^^ - | -note: argument has type `&&SomeStruct` - --> $DIR/forget_ref.rs:14:12 - | -LL | forget(&&owned); - | ^^^^^^^ + | ^^^^^^^-------^ + | | + | argument has type `&&SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:15:5 | LL | forget(&mut owned); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:15:12 - | -LL | forget(&mut owned); - | ^^^^^^^^^^ + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:19:5 | LL | forget(&*reference1); - | ^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:19:12 - | -LL | forget(&*reference1); - | ^^^^^^^^^^^^ + | ^^^^^^^------------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:22:5 | LL | forget(reference2); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&mut SomeStruct` - --> $DIR/forget_ref.rs:22:12 - | -LL | forget(reference2); - | ^^^^^^^^^^ + | ^^^^^^^----------^ + | | + | argument has type `&mut SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:25:5 | LL | forget(reference3); - | ^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:25:12 - | -LL | forget(reference3); - | ^^^^^^^^^^ + | ^^^^^^^----------^ + | | + | argument has type `&SomeStruct` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:30:5 | LL | forget(&val); - | ^^^^^^^^^^^^ - | -note: argument has type `&T` - --> $DIR/forget_ref.rs:30:12 - | -LL | forget(&val); - | ^^^^ + | ^^^^^^^----^ + | | + | argument has type `&T` warning: calls to `std::mem::forget` with a reference instead of an owned value --> $DIR/forget_ref.rs:38:5 | LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: argument has type `&SomeStruct` - --> $DIR/forget_ref.rs:38:22 - | -LL | std::mem::forget(&SomeStruct); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^-----------^ + | | + | argument has type `&SomeStruct` warning: 9 warnings emitted From d23f8957ae9f6a2e3121529422e7883d8bdbcc14 Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 14 Apr 2023 21:49:05 +0200 Subject: [PATCH 17/34] Improve warning message by saying that it "does nothing" --- compiler/rustc_lint/messages.ftl | 8 ++++---- tests/ui/lint/drop_copy.stderr | 20 ++++++++++---------- tests/ui/lint/drop_ref.stderr | 24 ++++++++++++------------ tests/ui/lint/forget_copy.stderr | 16 ++++++++-------- tests/ui/lint/forget_ref.stderr | 18 +++++++++--------- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 63424148e4d0..e323570b5bc0 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -521,14 +521,14 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass lint_opaque_hidden_inferred_bound_sugg = add this bound -lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value +lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` -lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy`. +lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` -lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value +lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` -lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy`. +lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr index a7a3b0e25ec7..2f122ad2aaa4 100644 --- a/tests/ui/lint/drop_copy.stderr +++ b/tests/ui/lint/drop_copy.stderr @@ -1,4 +1,4 @@ -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:34:5 | LL | drop(s1); @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(drop_copy)] | ^^^^^^^^^ -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:35:5 | LL | drop(s2); @@ -20,7 +20,7 @@ LL | drop(s2); | | | argument has type `SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:36:5 | LL | drop(s3); @@ -30,7 +30,7 @@ LL | drop(s3); | = note: `#[warn(drop_ref)]` on by default -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:37:5 | LL | drop(s4); @@ -38,7 +38,7 @@ LL | drop(s4); | | | argument has type `SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:38:5 | LL | drop(s5); @@ -46,7 +46,7 @@ LL | drop(s5); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:50:5 | LL | drop(a2); @@ -54,7 +54,7 @@ LL | drop(a2); | | | argument has type `&AnotherStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:52:5 | LL | drop(a4); @@ -62,7 +62,7 @@ LL | drop(a4); | | | argument has type `&AnotherStruct` -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:71:13 | LL | drop(println_and(13)); @@ -70,7 +70,7 @@ LL | drop(println_and(13)); | | | argument has type `i32` -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:74:14 | LL | 3 if drop(println_and(14)) == () => (), @@ -78,7 +78,7 @@ LL | 3 if drop(println_and(14)) == () => (), | | | argument has type `i32` -warning: calls to `std::mem::drop` with a value that implements `Copy`. +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:76:14 | LL | 4 => drop(2), diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr index c701f99fa901..cd81f72d6e9b 100644 --- a/tests/ui/lint/drop_ref.stderr +++ b/tests/ui/lint/drop_ref.stderr @@ -1,4 +1,4 @@ -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:8:5 | LL | drop(&SomeStruct); @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(drop_ref)] | ^^^^^^^^ -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:11:5 | LL | drop(&owned1); @@ -20,7 +20,7 @@ LL | drop(&owned1); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:12:5 | LL | drop(&&owned1); @@ -28,7 +28,7 @@ LL | drop(&&owned1); | | | argument has type `&&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:13:5 | LL | drop(&mut owned1); @@ -36,7 +36,7 @@ LL | drop(&mut owned1); | | | argument has type `&mut SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:17:5 | LL | drop(reference1); @@ -44,7 +44,7 @@ LL | drop(reference1); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:20:5 | LL | drop(reference2); @@ -52,7 +52,7 @@ LL | drop(reference2); | | | argument has type `&mut SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:23:5 | LL | drop(reference3); @@ -60,7 +60,7 @@ LL | drop(reference3); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:28:5 | LL | drop(&val); @@ -68,7 +68,7 @@ LL | drop(&val); | | | argument has type `&T` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:36:5 | LL | std::mem::drop(&SomeStruct); @@ -76,7 +76,7 @@ LL | std::mem::drop(&SomeStruct); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:91:13 | LL | drop(println_and(&13)); @@ -84,7 +84,7 @@ LL | drop(println_and(&13)); | | | argument has type `&i32` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:94:14 | LL | 3 if drop(println_and(&14)) == () => (), @@ -92,7 +92,7 @@ LL | 3 if drop(println_and(&14)) == () => (), | | | argument has type `&i32` -warning: calls to `std::mem::drop` with a reference instead of an owned value +warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:96:14 | LL | 4 => drop(&2), diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr index e2fc0f8af4fb..b5ce052d3796 100644 --- a/tests/ui/lint/forget_copy.stderr +++ b/tests/ui/lint/forget_copy.stderr @@ -1,4 +1,4 @@ -warning: calls to `std::mem::forget` with a value that implements `Copy`. +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing --> $DIR/forget_copy.rs:34:5 | LL | forget(s1); @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(forget_copy)] | ^^^^^^^^^^^ -warning: calls to `std::mem::forget` with a value that implements `Copy`. +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing --> $DIR/forget_copy.rs:35:5 | LL | forget(s2); @@ -20,7 +20,7 @@ LL | forget(s2); | | | argument has type `SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:36:5 | LL | forget(s3); @@ -30,7 +30,7 @@ LL | forget(s3); | = note: `#[warn(forget_ref)]` on by default -warning: calls to `std::mem::forget` with a value that implements `Copy`. +warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing --> $DIR/forget_copy.rs:37:5 | LL | forget(s4); @@ -38,7 +38,7 @@ LL | forget(s4); | | | argument has type `SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:38:5 | LL | forget(s5); @@ -46,7 +46,7 @@ LL | forget(s5); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:50:5 | LL | forget(a2); @@ -54,7 +54,7 @@ LL | forget(a2); | | | argument has type `&AnotherStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:52:5 | LL | forget(a3); @@ -62,7 +62,7 @@ LL | forget(a3); | | | argument has type `&AnotherStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:53:5 | LL | forget(a4); diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr index 96fb217215aa..f20f5f54b25a 100644 --- a/tests/ui/lint/forget_ref.stderr +++ b/tests/ui/lint/forget_ref.stderr @@ -1,4 +1,4 @@ -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:10:5 | LL | forget(&SomeStruct); @@ -12,7 +12,7 @@ note: the lint level is defined here LL | #![warn(forget_ref)] | ^^^^^^^^^^ -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:13:5 | LL | forget(&owned); @@ -20,7 +20,7 @@ LL | forget(&owned); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:14:5 | LL | forget(&&owned); @@ -28,7 +28,7 @@ LL | forget(&&owned); | | | argument has type `&&SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:15:5 | LL | forget(&mut owned); @@ -36,7 +36,7 @@ LL | forget(&mut owned); | | | argument has type `&mut SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:19:5 | LL | forget(&*reference1); @@ -44,7 +44,7 @@ LL | forget(&*reference1); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:22:5 | LL | forget(reference2); @@ -52,7 +52,7 @@ LL | forget(reference2); | | | argument has type `&mut SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:25:5 | LL | forget(reference3); @@ -60,7 +60,7 @@ LL | forget(reference3); | | | argument has type `&SomeStruct` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:30:5 | LL | forget(&val); @@ -68,7 +68,7 @@ LL | forget(&val); | | | argument has type `&T` -warning: calls to `std::mem::forget` with a reference instead of an owned value +warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:38:5 | LL | std::mem::forget(&SomeStruct); From e280df556dbbe4d25c3a7f29f6e7fee44c543e0b Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 14 Apr 2023 22:20:27 +0200 Subject: [PATCH 18/34] Add note to suggest using `let _ = x` to ignore the value --- compiler/rustc_lint/messages.ftl | 4 ++++ compiler/rustc_lint/src/lints.rs | 4 ++++ tests/ui/lint/drop_copy.stderr | 18 ++++++++++++++++++ tests/ui/lint/drop_ref.stderr | 23 +++++++++++++++++++++++ tests/ui/lint/forget_copy.stderr | 14 ++++++++++++++ tests/ui/lint/forget_ref.stderr | 17 +++++++++++++++++ 6 files changed, 80 insertions(+) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index e323570b5bc0..a5639404fafd 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -523,12 +523,16 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing .label = argument has type `{$arg_ty}` + .note = use `let _ = ...` to ignore the expression or result diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 755b907dfe5c..8e48806b5044 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -665,6 +665,7 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> { // drop_ref.rs #[derive(LintDiagnostic)] #[diag(lint_drop_ref)] +#[note] pub struct DropRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] @@ -673,6 +674,7 @@ pub struct DropRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_drop_copy)] +#[note] pub struct DropCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] @@ -681,6 +683,7 @@ pub struct DropCopyDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forget_ref)] +#[note] pub struct ForgetRefDiag<'a> { pub arg_ty: Ty<'a>, #[label] @@ -689,6 +692,7 @@ pub struct ForgetRefDiag<'a> { #[derive(LintDiagnostic)] #[diag(lint_forget_copy)] +#[note] pub struct ForgetCopyDiag<'a> { pub arg_ty: Ty<'a>, #[label] diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr index 2f122ad2aaa4..db8e89ad295b 100644 --- a/tests/ui/lint/drop_copy.stderr +++ b/tests/ui/lint/drop_copy.stderr @@ -6,6 +6,7 @@ LL | drop(s1); | | | argument has type `SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/drop_copy.rs:3:9 | @@ -19,6 +20,8 @@ LL | drop(s2); | ^^^^^--^ | | | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:36:5 @@ -28,6 +31,7 @@ LL | drop(s3); | | | argument has type `&SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(drop_ref)]` on by default warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing @@ -37,6 +41,8 @@ LL | drop(s4); | ^^^^^--^ | | | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:38:5 @@ -45,6 +51,8 @@ LL | drop(s5); | ^^^^^--^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:50:5 @@ -53,6 +61,8 @@ LL | drop(a2); | ^^^^^--^ | | | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_copy.rs:52:5 @@ -61,6 +71,8 @@ LL | drop(a4); | ^^^^^--^ | | | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:71:13 @@ -69,6 +81,8 @@ LL | drop(println_and(13)); | ^^^^^---------------^ | | | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:74:14 @@ -77,6 +91,8 @@ LL | 3 if drop(println_and(14)) == () => (), | ^^^^^---------------^ | | | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing --> $DIR/drop_copy.rs:76:14 @@ -85,6 +101,8 @@ LL | 4 => drop(2), | ^^^^^-^ | | | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: 10 warnings emitted diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr index cd81f72d6e9b..04c988fe99da 100644 --- a/tests/ui/lint/drop_ref.stderr +++ b/tests/ui/lint/drop_ref.stderr @@ -6,6 +6,7 @@ LL | drop(&SomeStruct); | | | argument has type `&SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/drop_ref.rs:3:9 | @@ -19,6 +20,8 @@ LL | drop(&owned1); | ^^^^^-------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:12:5 @@ -27,6 +30,8 @@ LL | drop(&&owned1); | ^^^^^--------^ | | | argument has type `&&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:13:5 @@ -35,6 +40,8 @@ LL | drop(&mut owned1); | ^^^^^-----------^ | | | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:17:5 @@ -43,6 +50,8 @@ LL | drop(reference1); | ^^^^^----------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:20:5 @@ -51,6 +60,8 @@ LL | drop(reference2); | ^^^^^----------^ | | | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:23:5 @@ -59,6 +70,8 @@ LL | drop(reference3); | ^^^^^----------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:28:5 @@ -67,6 +80,8 @@ LL | drop(&val); | ^^^^^----^ | | | argument has type `&T` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:36:5 @@ -75,6 +90,8 @@ LL | std::mem::drop(&SomeStruct); | ^^^^^^^^^^^^^^^-----------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:91:13 @@ -83,6 +100,8 @@ LL | drop(println_and(&13)); | ^^^^^----------------^ | | | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:94:14 @@ -91,6 +110,8 @@ LL | 3 if drop(println_and(&14)) == () => (), | ^^^^^----------------^ | | | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing --> $DIR/drop_ref.rs:96:14 @@ -99,6 +120,8 @@ LL | 4 => drop(&2), | ^^^^^--^ | | | argument has type `&i32` + | + = note: use `let _ = ...` to ignore the expression or result warning: 12 warnings emitted diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr index b5ce052d3796..37bc8a8854ee 100644 --- a/tests/ui/lint/forget_copy.stderr +++ b/tests/ui/lint/forget_copy.stderr @@ -6,6 +6,7 @@ LL | forget(s1); | | | argument has type `SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/forget_copy.rs:3:9 | @@ -19,6 +20,8 @@ LL | forget(s2); | ^^^^^^^--^ | | | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:36:5 @@ -28,6 +31,7 @@ LL | forget(s3); | | | argument has type `&SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result = note: `#[warn(forget_ref)]` on by default warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing @@ -37,6 +41,8 @@ LL | forget(s4); | ^^^^^^^--^ | | | argument has type `SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:38:5 @@ -45,6 +51,8 @@ LL | forget(s5); | ^^^^^^^--^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:50:5 @@ -53,6 +61,8 @@ LL | forget(a2); | ^^^^^^^--^ | | | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:52:5 @@ -61,6 +71,8 @@ LL | forget(a3); | ^^^^^^^--^ | | | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_copy.rs:53:5 @@ -69,6 +81,8 @@ LL | forget(a4); | ^^^^^^^--^ | | | argument has type `&AnotherStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: 8 warnings emitted diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr index f20f5f54b25a..63fc77919800 100644 --- a/tests/ui/lint/forget_ref.stderr +++ b/tests/ui/lint/forget_ref.stderr @@ -6,6 +6,7 @@ LL | forget(&SomeStruct); | | | argument has type `&SomeStruct` | + = note: use `let _ = ...` to ignore the expression or result note: the lint level is defined here --> $DIR/forget_ref.rs:3:9 | @@ -19,6 +20,8 @@ LL | forget(&owned); | ^^^^^^^------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:14:5 @@ -27,6 +30,8 @@ LL | forget(&&owned); | ^^^^^^^-------^ | | | argument has type `&&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:15:5 @@ -35,6 +40,8 @@ LL | forget(&mut owned); | ^^^^^^^----------^ | | | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:19:5 @@ -43,6 +50,8 @@ LL | forget(&*reference1); | ^^^^^^^------------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:22:5 @@ -51,6 +60,8 @@ LL | forget(reference2); | ^^^^^^^----------^ | | | argument has type `&mut SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:25:5 @@ -59,6 +70,8 @@ LL | forget(reference3); | ^^^^^^^----------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:30:5 @@ -67,6 +80,8 @@ LL | forget(&val); | ^^^^^^^----^ | | | argument has type `&T` + | + = note: use `let _ = ...` to ignore the expression or result warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing --> $DIR/forget_ref.rs:38:5 @@ -75,6 +90,8 @@ LL | std::mem::forget(&SomeStruct); | ^^^^^^^^^^^^^^^^^-----------^ | | | argument has type `&SomeStruct` + | + = note: use `let _ = ...` to ignore the expression or result warning: 9 warnings emitted From f5aede9c822875345eb7eb468ecd9bc4568ed112 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 11 May 2023 10:53:16 +0200 Subject: [PATCH 19/34] Improve code around SGX waitqueue Followed up of d36e390d8176babedcf326581959958d447170cd See https://github.com/rust-lang/rust/pull/109732#issuecomment-1543574908 for more details. Co-authored-by: Jethro Beekman --- library/std/src/sys/sgx/waitqueue/mod.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs index ca649ebd9d5f..5e1d859ee99c 100644 --- a/library/std/src/sys/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/sgx/waitqueue/mod.rs @@ -202,12 +202,18 @@ impl WaitQueue { pub fn notify_one( mut guard: SpinMutexGuard<'_, WaitVariable>, ) -> Result, SpinMutexGuard<'_, WaitVariable>> { + // SAFETY: lifetime of the pop() return value is limited to the map + // closure (The closure return value is 'static). The underlying + // stack frame won't be freed until after the WaitGuard created below + // is dropped. unsafe { - if let Some(entry) = guard.queue.inner.pop() { + let tcs = guard.queue.inner.pop().map(|entry| -> Tcs { let mut entry_guard = entry.lock(); - let tcs = entry_guard.tcs; entry_guard.wake = true; - drop(entry_guard); + entry_guard.tcs + }); + + if let Some(tcs) = tcs { Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::Single(tcs) }) } else { Err(guard) @@ -223,6 +229,9 @@ impl WaitQueue { pub fn notify_all( mut guard: SpinMutexGuard<'_, WaitVariable>, ) -> Result, SpinMutexGuard<'_, WaitVariable>> { + // SAFETY: lifetime of the pop() return values are limited to the + // while loop body. The underlying stack frames won't be freed until + // after the WaitGuard created below is dropped. unsafe { let mut count = 0; while let Some(entry) = guard.queue.inner.pop() { @@ -230,6 +239,7 @@ impl WaitQueue { let mut entry_guard = entry.lock(); entry_guard.wake = true; } + if let Some(count) = NonZeroUsize::new(count) { Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } }) } else { From 7c263adb2afc310b96422bd33317407bc5385bf9 Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Tue, 2 May 2023 17:53:11 +0400 Subject: [PATCH 20/34] Add support for `cfg(overflow_checks)` This PR adds support for detecting if overflow checks are enabled in similar fashion as debug_assertions are detected. Possible use-case of this, for example, if we want to use checked integer casts in builds with overflow checks, e.g. ```rust pub fn cast(val: usize)->u16 { if cfg!(overflow_checks) { val.try_into().unwrap() } else{ vas as _ } } ``` Resolves #91130. Tracking issue: #111466. --- compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_feature/src/builtin_attrs.rs | 1 + compiler/rustc_session/src/config.rs | 4 ++++ compiler/rustc_span/src/symbol.rs | 2 ++ .../feature-gate-cfg_overflow_checks.rs | 6 ++++++ .../feature-gate-cfg_overflow_checks.stderr | 12 ++++++++++++ .../overflow-attribute-works-1.rs | 19 +++++++++++++++++++ .../overflow-attribute-works-2.rs | 19 +++++++++++++++++++ 8 files changed, 65 insertions(+) create mode 100644 tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs create mode 100644 tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr create mode 100644 tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs create mode 100644 tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index f4615445f8e9..fe8c630666bb 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -321,6 +321,8 @@ declare_features! ( (active, c_unwind, "1.52.0", Some(74990), None), /// Allows using C-variadics. (active, c_variadic, "1.34.0", Some(44930), None), + /// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour. + (active, cfg_overflow_checks, "CURRENT_RUSTC_VERSION", Some(111466), None), /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used. (active, cfg_sanitize, "1.41.0", Some(39699), None), /// Allows `cfg(target_abi = "...")`. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fe05d4590e7a..61cfbf5c5e53 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -24,6 +24,7 @@ pub type GatedCfg = (Symbol, Symbol, GateFn); /// `cfg(...)`'s that are feature gated. const GATED_CFGS: &[GatedCfg] = &[ // (name in cfg, feature, function to check if the feature is enabled) + (sym::overflow_checks, sym::cfg_overflow_checks, cfg_fn!(cfg_overflow_checks)), (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)), (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), ( diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index aa3cb03bad89..e2b8d3eea2d4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1060,6 +1060,9 @@ fn default_configuration(sess: &Session) -> CrateConfig { if sess.opts.debug_assertions { ret.insert((sym::debug_assertions, None)); } + if sess.overflow_checks() { + ret.insert((sym::overflow_checks, None)); + } // JUSTIFICATION: before wrapper fn is available #[allow(rustc::bad_opt_access)] if sess.opts.crate_types.contains(&CrateType::ProcMacro) { @@ -1209,6 +1212,7 @@ impl CrateCheckConfig { sym::windows, sym::proc_macro, sym::debug_assertions, + sym::overflow_checks, sym::target_thread_local, ] { self.expecteds.entry(name).or_insert_with(no_values); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 60efcb768cb0..9951d8f4fc15 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -463,6 +463,7 @@ symbols! { cfg_doctest, cfg_eval, cfg_hide, + cfg_overflow_checks, cfg_panic, cfg_sanitize, cfg_target_abi, @@ -1065,6 +1066,7 @@ symbols! { or_patterns, other, out, + overflow_checks, overlapping_marker_traits, owned_box, packed, diff --git a/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs new file mode 100644 index 000000000000..cb265aa7f25b --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +#[cfg(overflow_checks)] //~ ERROR `cfg(overflow_checks)` is experimental +pub fn cast(v: i64)->u32{ + todo!() +} diff --git a/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr new file mode 100644 index 000000000000..79aba7945f6a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-cfg_overflow_checks.stderr @@ -0,0 +1,12 @@ +error[E0658]: `cfg(overflow_checks)` is experimental and subject to change + --> $DIR/feature-gate-cfg_overflow_checks.rs:3:7 + | +LL | #[cfg(overflow_checks)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #111466 for more information + = help: add `#![feature(cfg_overflow_checks)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs new file mode 100644 index 000000000000..318be2a6401b --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -C overflow_checks=true + +#![feature(cfg_overflow_checks)] + +fn main() { + assert!(cfg!(overflow_checks)); + assert!(compiles_differently()); +} + +#[cfg(overflow_checks)] +fn compiles_differently()->bool { + true +} + +#[cfg(not(overflow_checks))] +fn compiles_differently()->bool { + false +} diff --git a/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs new file mode 100644 index 000000000000..0367d980a64c --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -C overflow_checks=false + +#![feature(cfg_overflow_checks)] + +fn main() { + assert!(!cfg!(overflow_checks)); + assert!(!compiles_differently()); +} + +#[cfg(overflow_checks)] +fn compiles_differently()->bool { + true +} + +#[cfg(not(overflow_checks))] +fn compiles_differently()->bool { + false +} From 6b58ff5cdf47da9460871a87cf43e5e8adfab9a8 Mon Sep 17 00:00:00 2001 From: "Evgeniy A. Dushistov" Date: Thu, 11 May 2023 17:35:01 +0300 Subject: [PATCH 21/34] Usage of atomic counters for llvm code coverage --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 3 +++ tests/run-make/coverage-llvmir/filecheck.testprog.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 5ec3b95225d1..7b774d6865c8 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -745,6 +745,9 @@ LLVMRustOptimize( if (InstrProfileOutput) { Options.InstrProfileOutput = InstrProfileOutput; } + // cargo run tests in multhreading mode by default + // so use atomics for coverage counters + Options.Atomic = true; MPM.addPass(InstrProfiling(Options, false)); } ); diff --git a/tests/run-make/coverage-llvmir/filecheck.testprog.txt b/tests/run-make/coverage-llvmir/filecheck.testprog.txt index c943261d799c..b3a8808df052 100644 --- a/tests/run-make/coverage-llvmir/filecheck.testprog.txt +++ b/tests/run-make/coverage-llvmir/filecheck.testprog.txt @@ -36,7 +36,7 @@ CHECK-SAME: section "llvm.metadata" CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} { CHECK-NEXT: start: CHECK-NOT: [[DEFINE_INTERNAL]] -CHECK: %pgocount = load i64, {{i64\*|ptr}} +CHECK: atomicrmw add ptr CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called, CHECK: declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]] From 14bf909e71209fc946f35ffba8ae6572c9575715 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 11 May 2023 02:10:56 +0000 Subject: [PATCH 22/34] Note base types of coercion --- compiler/rustc_middle/src/traits/mod.rs | 3 -- .../src/traits/error_reporting/mod.rs | 16 ++++++--- .../src/traits/error_reporting/suggestions.rs | 28 +++++++-------- .../src/traits/select/confirmation.rs | 36 +++++++------------ .../src/traits/select/mod.rs | 21 ++++++----- .../associated-types-eq-3.stderr | 2 +- ...sociated-types-overridden-binding-2.stderr | 2 +- .../ui/associated-types/issue-65774-1.stderr | 2 +- .../ui/associated-types/issue-65774-2.stderr | 2 +- ...block-control-flow-static-semantics.stderr | 4 +-- .../issue-86507.drop_tracking.stderr | 2 +- .../issue-86507.drop_tracking_mir.stderr | 2 +- .../issue-86507.no_drop_tracking.stderr | 2 +- .../closure_context/issue-26046-fn-mut.stderr | 2 +- .../issue-26046-fn-once.stderr | 2 +- ...-49593-box-never-windows.nofallback.stderr | 4 +-- ...ce-issue-49593-box-never.nofallback.stderr | 4 +-- .../defaults/trait_objects_fail.stderr | 4 +-- .../ui/custom_test_frameworks/mismatch.stderr | 2 +- tests/ui/diagnostic-width/E0271.stderr | 4 +-- tests/ui/dst/dst-bad-coerce1.stderr | 4 +-- .../dst/dst-object-from-unsized-type.stderr | 8 ++--- ...gate-dispatch-from-dyn-missing-impl.stderr | 9 +---- .../issue-76535.base.stderr | 3 +- .../issue-79422.base.stderr | 3 +- .../issue-79422.extended.stderr | 2 +- .../in-trait/object-safety.current.stderr | 3 +- .../in-trait/object-safety.next.stderr | 3 +- tests/ui/issues/issue-14366.stderr | 4 +-- tests/ui/issues/issue-22034.stderr | 2 +- tests/ui/issues/issue-22872.stderr | 2 +- .../ui/kindck/kindck-impl-type-params.stderr | 12 +++---- .../kindck-inherited-copy-bound.curr.stderr | 3 +- ...copy-bound.object_safe_for_dispatch.stderr | 3 +- tests/ui/mismatched_types/cast-rfc0401.stderr | 12 ++----- .../fallback-closure-wrap.fallback.stderr | 2 +- tests/ui/object-safety/issue-19538.stderr | 3 +- ...ted-consts.object_safe_for_dispatch.stderr | 3 +- ...y-generics.object_safe_for_dispatch.stderr | 6 ++-- ...tions-Self.object_safe_for_dispatch.stderr | 6 ++-- ...-no-static.object_safe_for_dispatch.stderr | 3 +- ...ty-sized-2.object_safe_for_dispatch.stderr | 3 +- ...fety-sized.object_safe_for_dispatch.stderr | 3 +- ...ary-self-types-not-object-safe.curr.stderr | 3 +- ...bject-safe.object_safe_for_dispatch.stderr | 3 +- .../derive-macro-missing-bounds.stderr | 8 ++--- .../suggest-borrow-to-dyn-object.rs | 16 --------- .../suggest-borrow-to-dyn-object.stderr | 18 ---------- tests/ui/traits/coercion-generic-bad.stderr | 2 +- tests/ui/traits/issue-20692.stderr | 3 +- tests/ui/traits/issue-38604.stderr | 3 +- tests/ui/traits/issue-7013.stderr | 2 +- tests/ui/traits/map-types.stderr | 2 +- .../supertrait-object-safety.stderr | 3 +- tests/ui/traits/object/safety.stderr | 3 +- tests/ui/traits/test-2.stderr | 3 +- .../type-checking-test-1.stderr | 2 +- .../type-checking-test-2.stderr | 4 +-- .../type-alias-impl-trait/issue-98604.stderr | 2 +- .../type-alias-impl-trait/issue-98608.stderr | 2 +- tests/ui/type/issue-58355.stderr | 2 +- tests/ui/unsized/unsized-fn-param.stderr | 16 ++++----- .../wf/wf-convert-unsafe-trait-obj-box.stderr | 9 ++--- .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 9 ++--- tests/ui/wf/wf-unsafe-trait-obj-match.stderr | 6 ++-- 65 files changed, 142 insertions(+), 225 deletions(-) delete mode 100644 tests/ui/suggestions/suggest-borrow-to-dyn-object.rs delete mode 100644 tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 449c453555e9..2f0b07d4c71b 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -281,9 +281,6 @@ pub enum ObligationCauseCode<'tcx> { /// A type like `Box + 'b>` is WF only if `'b: 'a`. ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>), - /// Obligation incurred due to an object cast. - ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>), - /// Obligation incurred due to a coercion. Coercion { source: Ty<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 983652239237..f5f2fe542178 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -797,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_label(span, explanation); } - if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() && - Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { - self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty); + if let ObligationCauseCode::Coercion { source, target } = + *obligation.cause.code().peel_derives() + { + if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + self.suggest_borrowing_for_object_cast( + &mut err, + &root_obligation, + source, + target, + ); + } } let UnsatisfiedConst(unsatisfied_const) = self @@ -1510,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { | ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ExprItemObligation(..) | ObligationCauseCode::ExprBindingObligation(..) - | ObligationCauseCode::ObjectCastObligation(..) + | ObligationCauseCode::Coercion { .. } | ObligationCauseCode::OpaqueType ); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 53bf38c0a340..49b309abcda3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>, self_ty: Ty<'tcx>, - object_ty: Ty<'tcx>, + target_ty: Ty<'tcx>, ) { + let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else { return; }; let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; }; let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty); @@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_suggestion( obligation.cause.span.shrink_to_lo(), format!( - "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`" + "consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`" ), "&", Applicability::MaybeIncorrect, @@ -2851,30 +2852,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.span_note(tcx.def_span(item_def_id), descr); } } - ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => { - let (concrete_ty, concrete_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty)); - let (object_ty, object_file) = - self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty)); + ObligationCauseCode::Coercion { source, target } => { + let (source, source_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(source)); + let (target, target_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(target)); err.note(with_forced_trimmed_paths!(format!( - "required for the cast from `{concrete_ty}` to the object type `{object_ty}`", + "required for the cast from `{source}` to `{target}`", ))); - if let Some(file) = concrete_file { + if let Some(file) = source_file { err.note(format!( - "the full name for the casted type has been written to '{}'", + "the full name for the source type has been written to '{}'", file.display(), )); } - if let Some(file) = object_file { + if let Some(file) = target_file { err.note(format!( - "the full name for the object type has been written to '{}'", + "the full name for the target type has been written to '{}'", file.display(), )); } } - ObligationCauseCode::Coercion { source: _, target } => { - err.note(format!("required by cast to type `{}`", self.ty_to_string(target))); - } ObligationCauseCode::RepeatElementCopy { is_const_fn } => { err.note( "the `Copy` trait is required because this value will be copied for each element of the array", diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 4dc84e0ad10b..6a648294efd9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -29,9 +29,9 @@ use crate::traits::{ ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData, - ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, - Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, - SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, + ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation, + ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, + TraitNotObjectSafe, TraitObligation, Unimplemented, }; use super::BuiltinImplConditions; @@ -905,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map_err(|_| Unimplemented)?; nested.extend(obligations); - // Register one obligation for 'a: 'b. - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( tcx, - cause, + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, obligation.predicate.rebind(outlives), @@ -1005,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nested.extend(obligations); // Register one obligation for 'a: 'b. - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( tcx, - cause, + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, obligation.predicate.rebind(outlives), @@ -1027,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return Err(TraitNotObjectSafe(did)); } - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObjectCastObligation(source, target), - ); - let predicate_to_obligation = |predicate| { Obligation::with_depth( tcx, - cause.clone(), + obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, predicate, @@ -1056,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]); + let tr = ty::TraitRef::from_lang_item( + tcx, + LangItem::Sized, + obligation.cause.span, + [source], + ); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e4f5a84f4244..b72ff5b78e41 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let predicates = predicates.instantiate_own(tcx, substs); let mut obligations = Vec::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { - let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { - ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_or_alias_def_id: def_id, - impl_def_predicate_index: Some(index), - span, - })) - }); + let cause = + if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() { + cause.clone() + } else { + cause.clone().derived_cause(parent_trait_pred, |derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_or_alias_def_id: def_id, + impl_def_predicate_index: Some(index), + span, + })) + }) + }; let predicate = normalize_with_depth_to( self, param_env, diff --git a/tests/ui/associated-types/associated-types-eq-3.stderr b/tests/ui/associated-types/associated-types-eq-3.stderr index 15ce4fc91cb3..c3377eed20a5 100644 --- a/tests/ui/associated-types/associated-types-eq-3.stderr +++ b/tests/ui/associated-types/associated-types-eq-3.stderr @@ -43,7 +43,7 @@ note: expected this to be `Bar` | LL | type A = usize; | ^^^^^ - = note: required for the cast from `isize` to the object type `dyn Foo` + = note: required for the cast from `&isize` to `&dyn Foo` error: aborting due to 3 previous errors diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index a28a0b74e4ac..fdec01b95e3b 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -4,7 +4,7 @@ error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but LL | let _: &dyn I32Iterator = &vec![42].into_iter(); | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` | - = note: required for the cast from `std::vec::IntoIter` to the object type `dyn Iterator` + = note: required for the cast from `&std::vec::IntoIter` to `&dyn Iterator` error: aborting due to previous error diff --git a/tests/ui/associated-types/issue-65774-1.stderr b/tests/ui/associated-types/issue-65774-1.stderr index 91b557555d58..9c77a25c4320 100644 --- a/tests/ui/associated-types/issue-65774-1.stderr +++ b/tests/ui/associated-types/issue-65774-1.stderr @@ -25,7 +25,7 @@ LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { } | --------- ^^^^^^^^^ ^^^^^^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `&mut T` to the object type `dyn MyDisplay` + = note: required for the cast from `&&mut T` to `&dyn MyDisplay` error: aborting due to 2 previous errors diff --git a/tests/ui/associated-types/issue-65774-2.stderr b/tests/ui/associated-types/issue-65774-2.stderr index c22302cdc262..ca8a727f0fe2 100644 --- a/tests/ui/associated-types/issue-65774-2.stderr +++ b/tests/ui/associated-types/issue-65774-2.stderr @@ -18,7 +18,7 @@ LL | writer.my_write(valref) | ^^^^^^ the trait `MyDisplay` is not implemented for `T` | = help: the trait `MyDisplay` is implemented for `&'a mut T` - = note: required for the cast from `T` to the object type `dyn MyDisplay` + = note: required for the cast from `&mut T` to `&dyn MyDisplay` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr index a6dbb0716143..bbd5a822d8df 100644 --- a/tests/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/tests/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -35,7 +35,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant LL | let _: &dyn Future = █ | ^^^^^^ expected `()`, found `u8` | - = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future` + = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to `&dyn Future` error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:12:43 @@ -51,7 +51,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant LL | let _: &dyn Future = █ | ^^^^^^ expected `()`, found `u8` | - = note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future` + = note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to `&dyn Future` error[E0308]: mismatched types --> $DIR/async-block-control-flow-static-semantics.rs:49:44 diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.drop_tracking.stderr index 5c8b7ef1b713..adb7b9bf4bf8 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future + Send` + = note: required for the cast from `Pin>` to `Pin + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr index 5c8b7ef1b713..adb7b9bf4bf8 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future + Send` + = note: required for the cast from `Pin>` to `Pin + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr index 5c8b7ef1b713..adb7b9bf4bf8 100644 --- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless | LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` - = note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future + Send` + = note: required for the cast from `Pin>` to `Pin + Send + 'async_trait)>>` help: consider further restricting this bound | LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) diff --git a/tests/ui/closure_context/issue-26046-fn-mut.stderr b/tests/ui/closure_context/issue-26046-fn-mut.stderr index f744b71c284b..e468f6be791f 100644 --- a/tests/ui/closure_context/issue-26046-fn-mut.stderr +++ b/tests/ui/closure_context/issue-26046-fn-mut.stderr @@ -9,7 +9,7 @@ LL | num += 1; LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here | - = note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()` + = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]>` to `Box<(dyn Fn() + 'static)>` error: aborting due to previous error diff --git a/tests/ui/closure_context/issue-26046-fn-once.stderr b/tests/ui/closure_context/issue-26046-fn-once.stderr index 34f94f9dca6d..41f60327ce06 100644 --- a/tests/ui/closure_context/issue-26046-fn-once.stderr +++ b/tests/ui/closure_context/issue-26046-fn-once.stderr @@ -9,7 +9,7 @@ LL | vec LL | Box::new(closure) | ----------------- the requirement to implement `Fn` derives from here | - = note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec` + = note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]>` to `Box<(dyn Fn() -> Vec + 'static)>` error: aborting due to previous error diff --git a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr index 980da5360343..b976f70acf76 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr +++ b/tests/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to Box here */ Box::<_ /* ! */>::new(x) | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `dyn std::error::Error` + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` error[E0277]: the trait bound `(): std::error::Error` is not satisfied --> $DIR/coerce-issue-49593-box-never-windows.rs:23:49 @@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)` + = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)` error: aborting due to 2 previous errors diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr index 322681b97bcc..0d98fa93e5a4 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr +++ b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to Box here */ Box::<_ /* ! */>::new(x) | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `dyn std::error::Error` + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` error[E0277]: the trait bound `(): std::error::Error` is not satisfied --> $DIR/coerce-issue-49593-box-never.rs:23:49 @@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | - = note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)` + = note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/defaults/trait_objects_fail.stderr b/tests/ui/const-generics/defaults/trait_objects_fail.stderr index 0e8334d03382..481d77728b9e 100644 --- a/tests/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/tests/ui/const-generics/defaults/trait_objects_fail.stderr @@ -5,7 +5,7 @@ LL | foo(&10_u32); | ^^^^^^^ the trait `Trait` is not implemented for `u32` | = help: the trait `Trait<2>` is implemented for `u32` - = note: required for the cast from `u32` to the object type `dyn Trait` + = note: required for the cast from `&u32` to `&dyn Trait` error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 @@ -14,7 +14,7 @@ LL | bar(&true); | ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | = help: the trait `Traitor<2, 3>` is implemented for `bool` - = note: required for the cast from `bool` to the object type `dyn Traitor<_>` + = note: required for the cast from `&bool` to `&dyn Traitor<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/custom_test_frameworks/mismatch.stderr b/tests/ui/custom_test_frameworks/mismatch.stderr index 61061ae529d1..31b18b2df984 100644 --- a/tests/ui/custom_test_frameworks/mismatch.stderr +++ b/tests/ui/custom_test_frameworks/mismatch.stderr @@ -6,7 +6,7 @@ LL | #[test] LL | fn wrong_kind(){} | ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn` | - = note: required for the cast from `TestDescAndFn` to the object type `dyn Testable` + = note: required for the cast from `&TestDescAndFn` to `&dyn Testable` = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/diagnostic-width/E0271.stderr b/tests/ui/diagnostic-width/E0271.stderr index ed7b6651d018..52f415037d35 100644 --- a/tests/ui/diagnostic-width/E0271.stderr +++ b/tests/ui/diagnostic-width/E0271.stderr @@ -15,8 +15,8 @@ note: expected this to be `Foo` | LL | type Error = E; | ^ - = note: required for the cast from `Result, ...>` to the object type `dyn Future` - = note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt' + = note: required for the cast from `Box>` to `Box<(dyn Future + 'static)>` + = note: the full name for the source type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt' error: aborting due to previous error diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr index ff77bd4cef88..2c75518c298a 100644 --- a/tests/ui/dst/dst-bad-coerce1.stderr +++ b/tests/ui/dst/dst-bad-coerce1.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &Fat = f2; | ^^ the trait `Bar` is not implemented for `Foo` | - = note: required for the cast from `Foo` to the object type `dyn Bar` + = note: required for the cast from `&Fat` to `&Fat` error[E0308]: mismatched types --> $DIR/dst-bad-coerce1.rs:28:27 @@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied LL | let f3: &(dyn Bar,) = f2; | ^^ the trait `Bar` is not implemented for `Foo` | - = note: required for the cast from `Foo` to the object type `dyn Bar` + = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)` error: aborting due to 4 previous errors diff --git a/tests/ui/dst/dst-object-from-unsized-type.stderr b/tests/ui/dst/dst-object-from-unsized-type.stderr index e24c96ebed63..d5e464aed4ba 100644 --- a/tests/ui/dst/dst-object-from-unsized-type.stderr +++ b/tests/ui/dst/dst-object-from-unsized-type.stderr @@ -6,7 +6,7 @@ LL | fn test1(t: &T) { LL | let u: &dyn Foo = t; | ^ doesn't have a size known at compile-time | - = note: required for the cast from `T` to the object type `dyn Foo` + = note: required for the cast from `&T` to `&dyn Foo` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn test1(t: &T) { @@ -21,7 +21,7 @@ LL | fn test2(t: &T) { LL | let v: &dyn Foo = t as &dyn Foo; | ^ doesn't have a size known at compile-time | - = note: required for the cast from `T` to the object type `dyn Foo` + = note: required for the cast from `&T` to `&dyn Foo` help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn test2(t: &T) { @@ -35,7 +35,7 @@ LL | let _: &[&dyn Foo] = &["hi"]; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Foo` + = note: required for the cast from `&'static str` to `&dyn Foo` error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/dst-object-from-unsized-type.rs:23:23 @@ -44,7 +44,7 @@ LL | let _: &dyn Foo = x as &dyn Foo; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: required for the cast from `[u8]` to the object type `dyn Foo` + = note: required for the cast from `&[u8]` to `&dyn Foo` error: aborting due to 4 previous errors diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr index d81eade8e9bf..303700c7ab4f 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr @@ -31,14 +31,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn ptr(self: Ptr); | ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on -note: required for `Ptr<{integer}>` to implement `CoerceUnsized>` - --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:20:40 - | -LL | impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} - | --------- ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ - | | - | unsatisfied trait bound introduced here - = note: required by cast to type `Ptr` + = note: required for the cast from `Ptr<{integer}>` to `Ptr` error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr index 52c6e3eec603..370329b9f837 100644 --- a/tests/ui/generic-associated-types/issue-76535.base.stderr +++ b/tests/ui/generic-associated-types/issue-76535.base.stderr @@ -43,8 +43,7 @@ LL | pub trait SuperTrait { LL | type SubType<'a>: SubTrait where Self: 'a; | ^^^^^^^ ...because it contains the generic associated type `SubType` = help: consider moving `SubType` to another trait - = note: required for `Box` to implement `CoerceUnsized>>>` - = note: required by cast to type `Box>>` + = note: required for the cast from `Box` to `Box>>` error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr index f1de77bc3c0a..ad704f5e9f01 100644 --- a/tests/ui/generic-associated-types/issue-79422.base.stderr +++ b/tests/ui/generic-associated-types/issue-79422.base.stderr @@ -43,8 +43,7 @@ LL | trait MapLike { LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` = help: consider moving `VRefCont` to another trait - = note: required for `Box>` to implement `CoerceUnsized + 'static)>>>` - = note: required by cast to type `Box + 'static)>>` + = note: required for the cast from `Box>` to `Box + 'static)>>` error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr index 04184fce921f..14492266cdaf 100644 --- a/tests/ui/generic-associated-types/issue-79422.extended.stderr +++ b/tests/ui/generic-associated-types/issue-79422.extended.stderr @@ -27,7 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a; | ^^^^^ = note: expected trait object `(dyn RefCont<'_, u8> + 'static)` found reference `&u8` - = note: required for the cast from `BTreeMap` to the object type `dyn MapLike + 'static)>` + = note: required for the cast from `Box>` to `Box + 'static)>>` error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/in-trait/object-safety.current.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr index b7f2b019a776..2c340a02319b 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.current.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.current.stderr @@ -42,8 +42,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box` to `Box` error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr index b7f2b019a776..2c340a02319b 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.next.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.next.stderr @@ -42,8 +42,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box` to `Box` error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-14366.stderr b/tests/ui/issues/issue-14366.stderr index 10a73b245ac5..df61aabf00a7 100644 --- a/tests/ui/issues/issue-14366.stderr +++ b/tests/ui/issues/issue-14366.stderr @@ -5,8 +5,8 @@ LL | let _x = "test" as &dyn (::std::any::Any); | ^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Any` -help: consider borrowing the value, since `&str` can be coerced into `dyn Any` + = note: required for the cast from `&'static str` to `&(dyn Any + 'static)` +help: consider borrowing the value, since `&&'static str` can be coerced into `&(dyn Any + 'static)` | LL | let _x = &"test" as &dyn (::std::any::Any); | + diff --git a/tests/ui/issues/issue-22034.stderr b/tests/ui/issues/issue-22034.stderr index b32de5b24b92..9833e559cbcd 100644 --- a/tests/ui/issues/issue-22034.stderr +++ b/tests/ui/issues/issue-22034.stderr @@ -6,7 +6,7 @@ LL | &mut *(ptr as *mut dyn Fn()) | = help: the trait `Fn<()>` is not implemented for `()` = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }` - = note: required for the cast from `()` to the object type `dyn Fn()` + = note: required for the cast from `*mut ()` to `*mut dyn Fn()` error: aborting due to previous error diff --git a/tests/ui/issues/issue-22872.stderr b/tests/ui/issues/issue-22872.stderr index 9510197197a8..63222d25c017 100644 --- a/tests/ui/issues/issue-22872.stderr +++ b/tests/ui/issues/issue-22872.stderr @@ -13,7 +13,7 @@ LL | impl<'b, P> Wrap<'b> for Wrapper

LL | where P: Process<'b>, LL |

>::Item: Iterator { | -------- unsatisfied trait bound introduced here - = note: required for the cast from `Wrapper

` to the object type `dyn for<'b> Wrap<'b>` + = note: required for the cast from `Box>` to `Box Wrap<'b>>` help: consider further restricting the associated type | LL | fn push_process

(process: P) where P: Process<'static>,

>::Item: Iterator { diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index efb25bf83e1d..53c1940491f8 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -11,7 +11,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `&S` to `&dyn Gettable` help: consider restricting type parameter `T` | LL | fn f(val: T) { @@ -30,7 +30,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `&S` to `&dyn Gettable` help: consider restricting type parameter `T` | LL | fn f(val: T) { @@ -49,7 +49,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `&S` to `&dyn Gettable` help: consider restricting type parameter `T` | LL | fn g(val: T) { @@ -68,7 +68,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `&S` to `&dyn Gettable` help: consider restricting type parameter `T` | LL | fn g(val: T) { @@ -88,7 +88,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `Box>` to `Box>` error[E0277]: the trait bound `Foo: Copy` is not satisfied --> $DIR/kindck-impl-type-params.rs:43:37 @@ -104,7 +104,7 @@ LL | impl Gettable for S {} | ---- ^^^^^^^^^^^ ^^^^ | | | unsatisfied trait bound introduced here - = note: required for the cast from `S` to the object type `dyn Gettable` + = note: required for the cast from `Box>` to `Box>` help: consider annotating `Foo` with `#[derive(Copy)]` | LL + #[derive(Copy)] diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr index 8d45748a6c41..294951765564 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr @@ -46,8 +46,7 @@ LL | trait Foo : Copy { | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&Box<{integer}>` to `&dyn Foo` error: aborting due to 3 previous errors diff --git a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr index 2fbb5a98a8d9..3e164ebf5143 100644 --- a/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr +++ b/tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr @@ -32,8 +32,7 @@ LL | trait Foo : Copy { | --- ^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&Box` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&Box` to `&dyn Foo` error: aborting due to 2 previous errors diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 2a36a352c734..6b9ac3c58523 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -220,11 +220,7 @@ LL | let _ = fat_v as *const dyn Foo; | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` - = note: required for the cast from `[u8]` to the object type `dyn Foo` -help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo` - | -LL | let _ = &fat_v as *const dyn Foo; - | + + = note: required for the cast from `*const [u8]` to `*const dyn Foo` error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/cast-rfc0401.rs:62:13 @@ -233,11 +229,7 @@ LL | let _ = a as *const dyn Foo; | ^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn Foo` -help: consider borrowing the value, since `&str` can be coerced into `dyn Foo` - | -LL | let _ = &a as *const dyn Foo; - | + + = note: required for the cast from `*const str` to `*const dyn Foo` error[E0606]: casting `&{float}` as `f32` is invalid --> $DIR/cast-rfc0401.rs:71:30 diff --git a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr index a0f790dba15e..5b6f02351233 100644 --- a/tests/ui/never_type/fallback-closure-wrap.fallback.stderr +++ b/tests/ui/never_type/fallback-closure-wrap.fallback.stderr @@ -10,7 +10,7 @@ LL | | }) as Box); | = note: expected unit type `()` found type `!` - = note: required for the cast from `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to the object type `dyn FnMut()` + = note: required for the cast from `Box<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]>` to `Box` error: aborting due to previous error diff --git a/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr index 8420637b3dee..183245b23223 100644 --- a/tests/ui/object-safety/issue-19538.stderr +++ b/tests/ui/object-safety/issue-19538.stderr @@ -29,8 +29,7 @@ LL | fn foo(&self, val: T); LL | trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait - = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>` - = note: required by cast to type `&mut dyn Bar` + = note: required for the cast from `&mut Thing` to `&mut dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr index f44de07d5da1..db3e0885a85a 100644 --- a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | const X: usize; | ^ ...because it contains this associated `const` = help: consider moving `X` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr index 9a2d472d5e76..b200b64a1f07 100644 --- a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/object-safety-generics.rs:26:5 @@ -29,8 +28,7 @@ LL | trait Bar { LL | fn bar(&self, t: T); | ^^^ ...because method `bar` has generic type parameters = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr index 40a298bd1a7c..414614d8d0bf 100644 --- a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -12,8 +12,7 @@ LL | trait Bar { LL | fn bar(&self, x: &Self); | ^^^^^ ...because method `bar` references the `Self` type in this parameter = help: consider moving `bar` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error[E0038]: the trait `Baz` cannot be made into an object --> $DIR/object-safety-mentions-Self.rs:30:5 @@ -29,8 +28,7 @@ LL | trait Baz { LL | fn baz(&self) -> Self; | ^^^^ ...because method `baz` references the `Self` type in its return type = help: consider moving `baz` to another trait - = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>` - = note: required by cast to type `&dyn Baz` + = note: required for the cast from `&T` to `&dyn Baz` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr index da87b58c9e29..befcef952a85 100644 --- a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} | ^^^ ...because associated function `foo` has no `self` parameter - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box` to `Box` help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self) {} diff --git a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr index 6c29c8d5f7cd..90e5c59dd027 100644 --- a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Bar | --- this trait cannot be made into an object... LL | where Self : Sized | ^^^^^ ...because it requires `Self: Sized` - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr index 70a44ed61015..a6c22b8747e5 100644 --- a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr +++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -11,8 +11,7 @@ LL | trait Bar : Sized { | --- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>` - = note: required by cast to type `&dyn Bar` + = note: required for the cast from `&T` to `&dyn Bar` error: aborting due to previous error diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 0ec0d4be5f23..13591f5b6351 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -31,8 +31,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = note: required for `Rc` to implement `CoerceUnsized>` - = note: required by cast to type `Rc` + = note: required for the cast from `Rc` to `Rc` error: aborting due to 2 previous errors diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index b494b448e2e7..593f705353a5 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -14,8 +14,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - = note: required for `Rc` to implement `CoerceUnsized>` - = note: required by cast to type `Rc` + = note: required for the cast from `Rc` to `Rc` error: aborting due to previous error diff --git a/tests/ui/suggestions/derive-macro-missing-bounds.stderr b/tests/ui/suggestions/derive-macro-missing-bounds.stderr index c3f305c1770a..bffcb1af487e 100644 --- a/tests/ui/suggestions/derive-macro-missing-bounds.stderr +++ b/tests/ui/suggestions/derive-macro-missing-bounds.stderr @@ -36,7 +36,7 @@ LL | impl Debug for Inner { | unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&c::Inner` to implement `Debug` - = note: required for the cast from `&c::Inner` to the object type `dyn Debug` + = note: required for the cast from `&&c::Inner` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -58,7 +58,7 @@ LL | impl Debug for Inner where T: Debug, T: Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&d::Inner` to implement `Debug` - = note: required for the cast from `&d::Inner` to the object type `dyn Debug` + = note: required for the cast from `&&d::Inner` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -80,7 +80,7 @@ LL | impl Debug for Inner where T: Debug + Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&e::Inner` to implement `Debug` - = note: required for the cast from `&e::Inner` to the object type `dyn Debug` + = note: required for the cast from `&&e::Inner` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -102,7 +102,7 @@ LL | impl Debug for Inner where T: Trait { | ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here = note: 1 redundant requirement hidden = note: required for `&f::Inner` to implement `Debug` - = note: required for the cast from `&f::Inner` to the object type `dyn Debug` + = note: required for the cast from `&&f::Inner` to `&dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs b/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs deleted file mode 100644 index 120fc538307a..000000000000 --- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::ffi::{OsStr, OsString}; -use std::path::Path; - -fn check(p: &dyn AsRef) { - let m = std::fs::metadata(&p); - println!("{:?}", &m); -} - -fn main() { - let s: OsString = ".".into(); - let s: &OsStr = &s; - check(s); - //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time - //~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]` - //~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef` -} diff --git a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr b/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr deleted file mode 100644 index 365c1016eb3d..000000000000 --- a/tests/ui/suggestions/suggest-borrow-to-dyn-object.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/suggest-borrow-to-dyn-object.rs:12:11 - | -LL | check(s); - | ^ doesn't have a size known at compile-time - | - = help: within `OsStr`, the trait `Sized` is not implemented for `[u8]` -note: required because it appears within the type `OsStr` - --> $SRC_DIR/std/src/ffi/os_str.rs:LL:COL - = note: required for the cast from `OsStr` to the object type `dyn AsRef` -help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef` - | -LL | check(&s); - | + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index 93d6770eb47d..e7e8a796796b 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -5,7 +5,7 @@ LL | let s: Box> = Box::new(Struct { person: "Fred" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Struct` | = help: the trait `Trait<&'static str>` is implemented for `Struct` - = note: required for the cast from `Struct` to the object type `dyn Trait` + = note: required for the cast from `Box` to `Box>` error: aborting due to previous error diff --git a/tests/ui/traits/issue-20692.stderr b/tests/ui/traits/issue-20692.stderr index 2028994cdaa0..30e3c9da1a03 100644 --- a/tests/ui/traits/issue-20692.stderr +++ b/tests/ui/traits/issue-20692.stderr @@ -27,8 +27,7 @@ LL | trait Array: Sized + Copy {} | | | | | ...because it requires `Self: Sized` | this trait cannot be made into an object... - = note: required for `&T` to implement `CoerceUnsized<&dyn Array>` - = note: required by cast to type `&dyn Array` + = note: required for the cast from `&T` to `&dyn Array` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr index 50d6fb054654..d53276024306 100644 --- a/tests/ui/traits/issue-38604.stderr +++ b/tests/ui/traits/issue-38604.stderr @@ -25,8 +25,7 @@ LL | trait Foo where u32: Q { | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... - = note: required for `Box<()>` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box<()>` to `Box` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr index 9ac5c4725ab1..1c0e8bcf1851 100644 --- a/tests/ui/traits/issue-7013.stderr +++ b/tests/ui/traits/issue-7013.stderr @@ -12,7 +12,7 @@ note: required because it appears within the type `B` | LL | struct B { | ^ - = note: required for the cast from `B` to the object type `dyn Foo + Send` + = note: required for the cast from `Box` to `Box` error: aborting due to previous error diff --git a/tests/ui/traits/map-types.stderr b/tests/ui/traits/map-types.stderr index f685c50b07d5..4315056f2065 100644 --- a/tests/ui/traits/map-types.stderr +++ b/tests/ui/traits/map-types.stderr @@ -5,7 +5,7 @@ LL | let y: Box> = Box::new(x); | ^^^^^^^^^^^ the trait `Map` is not implemented for `Box>` | = help: the trait `Map` is implemented for `HashMap` - = note: required for the cast from `Box>` to the object type `dyn Map` + = note: required for the cast from `Box>>` to `Box>` error: aborting due to previous error diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr index 47fa29b66488..d56519223f4d 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr @@ -20,8 +20,7 @@ LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables | | | this trait cannot be made into an object... - = note: required for `&()` to implement `CoerceUnsized<&dyn Foo>` - = note: required by cast to type `&dyn Foo` + = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/supertrait-object-safety.rs:19:12 diff --git a/tests/ui/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr index dc18adeafc7f..a51b69759381 100644 --- a/tests/ui/traits/object/safety.stderr +++ b/tests/ui/traits/object/safety.stderr @@ -11,8 +11,7 @@ LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); | ^^^ ...because associated function `foo` has no `self` parameter - = note: required for `&St` to implement `CoerceUnsized<&dyn Tr>` - = note: required by cast to type `&dyn Tr` + = note: required for the cast from `&St` to `&dyn Tr` help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self); diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr index 6c0e8b8af4b7..74a0fc42708e 100644 --- a/tests/ui/traits/test-2.stderr +++ b/tests/ui/traits/test-2.stderr @@ -76,8 +76,7 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | this trait cannot be made into an object... = help: consider moving `dup` to another trait = help: consider moving `blah` to another trait - = note: required for `Box<{integer}>` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box<{integer}>` to `Box` error: aborting due to 5 previous errors diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr index fe269d8e99bf..82b4e9bd72ae 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-1.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied LL | let _ = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` | - = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>` + = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr index ef007d5cb909..856303ef4dd4 100644 --- a/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr +++ b/tests/ui/traits/trait-upcasting/type-checking-test-2.stderr @@ -15,7 +15,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar` is not satisfied LL | let _ = x as &dyn Bar; // Error | ^ the trait `Bar` is not implemented for `&dyn Foo` | - = note: required for the cast from `&dyn Foo` to the object type `dyn Bar` + = note: required for the cast from `&&dyn Foo` to `&dyn Bar` error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>` --> $DIR/type-checking-test-2.rs:25:13 @@ -34,7 +34,7 @@ error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied LL | let a = x as &dyn Bar<_>; // Ambiguous | ^ the trait `Bar<_>` is not implemented for `&dyn Foo` | - = note: required for the cast from `&dyn Foo` to the object type `dyn Bar<_>` + = note: required for the cast from `&&dyn Foo` to `&dyn Bar<_>` error: aborting due to 4 previous errors diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr index fa16d321890c..af758d8099f8 100644 --- a/tests/ui/type-alias-impl-trait/issue-98604.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr @@ -4,7 +4,7 @@ error[E0271]: expected `test` to be a fn item that returns `Pin>>`, found future | - = note: required for the cast from `fn() -> impl Future {test}` to the object type `dyn Fn() -> Pin + 'static)>>` + = note: required for the cast from `Box impl Future {test}>` to `Box<(dyn Fn() -> Pin + 'static)>> + 'static)>` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr index 506d40cb7768..9b651008371f 100644 --- a/tests/ui/type-alias-impl-trait/issue-98608.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr @@ -9,7 +9,7 @@ LL | let b: Box Box> = Box::new(hi); | = note: expected struct `Box` found opaque type `impl Sized` - = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box` + = note: required for the cast from `Box impl Sized {hi}>` to `Box Box>` error: aborting due to previous error diff --git a/tests/ui/type/issue-58355.stderr b/tests/ui/type/issue-58355.stderr index 6f89a7b00499..67078bcfe89a 100644 --- a/tests/ui/type/issue-58355.stderr +++ b/tests/ui/type/issue-58355.stderr @@ -6,7 +6,7 @@ LL | x = Some(Box::new(callback)); | = help: within `fn() -> dyn ToString`, the trait `Sized` is not implemented for `dyn ToString` = note: required because it appears within the type `fn() -> dyn ToString` - = note: required for the cast from `fn() -> dyn ToString` to the object type `dyn Fn() -> (dyn ToString + 'static)` + = note: required for the cast from `Box dyn ToString>` to `Box (dyn ToString + 'static)>` error: aborting due to previous error diff --git a/tests/ui/unsized/unsized-fn-param.stderr b/tests/ui/unsized/unsized-fn-param.stderr index b47726054325..0de3dbbb5572 100644 --- a/tests/ui/unsized/unsized-fn-param.stderr +++ b/tests/ui/unsized/unsized-fn-param.stderr @@ -5,8 +5,8 @@ LL | foo11("bar", &"baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + = note: required for the cast from `&'static str` to `&dyn AsRef` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef` | LL | foo11(&"bar", &"baz"); | + @@ -18,8 +18,8 @@ LL | foo12(&"bar", "baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + = note: required for the cast from `&'static str` to `&dyn AsRef` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef` | LL | foo12(&"bar", &"baz"); | + @@ -31,8 +31,8 @@ LL | foo21("bar", &"baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + = note: required for the cast from `&'static str` to `&dyn AsRef` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef` | LL | foo21(&"bar", &"baz"); | + @@ -44,8 +44,8 @@ LL | foo22(&"bar", "baz"); | ^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `str` to the object type `dyn AsRef` -help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef` + = note: required for the cast from `&'static str` to `&dyn AsRef` +help: consider borrowing the value, since `&&'static str` can be coerced into `&dyn AsRef` | LL | foo22(&"bar", &"baz"); | + diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 6cf4f33f947a..40a25c7df6ba 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -11,8 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box` to `Box` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 @@ -27,8 +26,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box<(dyn Trait + 'static)>` + = note: required for the cast from `Box` to `Box<(dyn Trait + 'static)>` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5 @@ -43,8 +41,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `Box` to implement `CoerceUnsized>` - = note: required by cast to type `Box` + = note: required for the cast from `Box` to `Box` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr index c9bd4549aaff..e2c71df2feb4 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -11,8 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 @@ -27,8 +26,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5 @@ -43,8 +41,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr index d2b41630976a..66504e440600 100644 --- a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -25,8 +25,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&S` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/wf-unsafe-trait-obj-match.rs:25:25 @@ -45,8 +44,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... - = note: required for `&R` to implement `CoerceUnsized<&dyn Trait>` - = note: required by cast to type `&dyn Trait` + = note: required for the cast from `&R` to `&dyn Trait` error: aborting due to 3 previous errors From d58863fe43ee9f0c9a750178950415299e1b8335 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Fri, 12 May 2023 17:22:47 +0800 Subject: [PATCH 23/34] asm: loongarch64: Drop efiapi --- compiler/rustc_target/src/asm/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 705966f52370..e60b8e78e5d5 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -882,8 +882,8 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::LoongArch64 => match name { - "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), - _ => Err(&["C", "system", "efiapi"]), + "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch), + _ => Err(&["C", "system"]), }, _ => Err(&[]), } From f08b51759763e44fc59b56584b640c2d2ccff0a0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Apr 2023 10:19:41 +0000 Subject: [PATCH 24/34] Require `impl Trait` in associated types to appear in method signatures --- compiler/rustc_ast_lowering/src/item.rs | 10 +- compiler/rustc_ast_lowering/src/lib.rs | 36 ++--- .../src/region_infer/opaque_types.rs | 4 +- compiler/rustc_hir/src/hir.rs | 5 +- .../rustc_hir_analysis/src/check/check.rs | 13 +- compiler/rustc_hir_analysis/src/collect.rs | 2 +- .../src/collect/generics_of.rs | 5 +- .../src/collect/predicates_of.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 5 +- .../rustc_hir_analysis/src/collect/type_of.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 13 +- .../rustc_infer/src/infer/opaque_types.rs | 132 ++++++++++++++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- .../src/ty/normalize_erasing_regions.rs | 2 +- src/librustdoc/visit_ast.rs | 3 +- .../associated-type-impl-trait-lifetime.rs | 7 +- .../invalid_impl_trait_in_assoc_ty.rs | 16 +++ .../invalid_impl_trait_in_assoc_ty.stderr | 22 +++ 20 files changed, 242 insertions(+), 53 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs create mode 100644 tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 3d154a93fb2d..08ee3761bac2 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -305,7 +305,10 @@ impl<'hir> LoweringContext<'_, 'hir> { ); this.arena.alloc(this.ty(span, hir::TyKind::Err(guar))) } - Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy), + Some(ty) => this.lower_ty( + ty, + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false }, + ), }, ); hir::ItemKind::TyAlias(ty, generics) @@ -852,7 +855,10 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ImplItemKind::Type(ty) } Some(ty) => { - let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy); + let ty = this.lower_ty( + ty, + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true }, + ); hir::ImplItemKind::Type(ty) } }, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 1fd7cc664703..cd6614a54a4e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -247,7 +247,7 @@ enum ImplTraitContext { in_trait: bool, }, /// Impl trait in type aliases. - TypeAliasesOpaqueTy, + TypeAliasesOpaqueTy { in_assoc_ty: bool }, /// `impl Trait` is unstably accepted in this position. FeatureGated(ImplTraitPosition, Symbol), /// `impl Trait` is not accepted in this position. @@ -1407,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { *in_trait, itctx, ), - ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait( - span, - hir::OpaqueTyOrigin::TyAlias, - *def_node_id, - bounds, - false, - itctx, - ), + &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self + .lower_opaque_impl_trait( + span, + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty }, + *def_node_id, + bounds, + false, + itctx, + ), ImplTraitContext::Universal => { let span = t.span; self.create_def( @@ -1534,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want // to capture the lifetimes that appear in the bounds. So visit the bounds to find out // exactly which ones those are. - let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias { - // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters - Vec::new() - } else { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example, - // we only keep the lifetimes that appear in the `impl Debug` itself: - lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + let lifetimes_to_remap = match origin { + hir::OpaqueTyOrigin::TyAlias { .. } => { + // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters + Vec::new() + } + hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example, + // we only keep the lifetimes that appear in the `impl Debug` itself: + lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds) + } }; debug!(?lifetimes_to_remap); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 4970ece5e7de..309f23d92261 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -265,7 +265,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` // on stable and we'd break that. - let OpaqueTyOrigin::TyAlias = origin else { + let OpaqueTyOrigin::TyAlias { .. } = origin else { return definition_ty; }; let def_id = opaque_type_key.def_id; @@ -360,7 +360,7 @@ fn check_opaque_type_parameter_valid( // which would error here on all of the `'static` args. OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()), // Check these - OpaqueTyOrigin::TyAlias => {} + OpaqueTyOrigin::TyAlias { .. } => {} } let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 38cd5865cc32..932f0396282f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2662,7 +2662,10 @@ pub enum OpaqueTyOrigin { /// `async fn` AsyncFn(LocalDefId), /// type aliases: `type Foo = impl Trait;` - TyAlias, + TyAlias { + /// associated types in impl blocks for traits. + in_assoc_ty: bool, + }, } /// The various kinds of types recognized by the compiler. diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 5187e63f8e3a..b16860907eb2 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -397,7 +397,14 @@ fn check_opaque_meets_bounds<'tcx>( ) { let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, - hir::OpaqueTyOrigin::TyAlias => def_id, + hir::OpaqueTyOrigin::TyAlias { .. } => { + let mut def_id = def_id; + // Find the surrounding item (type alias or assoc type) + while let DefKind::OpaqueTy = tcx.def_kind(def_id) { + def_id = tcx.local_parent(def_id); + } + def_id + } }; let param_env = tcx.param_env(defining_use_anchor); @@ -455,10 +462,10 @@ fn check_opaque_meets_bounds<'tcx>( // They can only be referenced as ` as Trait<&'static T>>::AssocTy`. // We don't have to check them here because their well-formedness follows from the WF of // the projection input types in the defining- and use-sites. - hir::OpaqueTyOrigin::TyAlias + hir::OpaqueTyOrigin::TyAlias { .. } if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {} // Can have different predicates to their defining use - hir::OpaqueTyOrigin::TyAlias => { + hir::OpaqueTyOrigin::TyAlias { .. } => { let wf_tys = ocx.assumed_wf_types(param_env, span, def_id); let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys); let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b65817ee95e9..2f808d4ce738 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1483,7 +1483,7 @@ fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool { match tcx.hir().get_by_def_id(def_id) { Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => { - matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias) + matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }) } _ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id), } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index ab2932bf969a..ed60998ec8dc 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -159,7 +159,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } Some(fn_def_id.to_def_id()) } - ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { + ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. + }) => { let parent_id = tcx.hir().get_parent_item(hir_id); assert_ne!(parent_id, hir::CRATE_OWNER_ID); debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e04658c8e774..a33990813b82 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -721,7 +721,7 @@ pub(super) fn type_param_predicates( | ItemKind::TyAlias(_, generics) | ItemKind::OpaqueTy(OpaqueTy { generics, - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. }) | ItemKind::Enum(_, generics) 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 5c7f7f10b17e..92ae93cf4cc5 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -526,7 +526,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, .. + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. }) => { // Opaque types are visited when we visit the // `TyKind::OpaqueDef`, so that they have the lifetimes from @@ -707,7 +708,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { let opaque_ty = self.tcx.hir().item(item_id); match &opaque_ty.kind { hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, + origin: hir::OpaqueTyOrigin::TyAlias { .. }, .. }) => { intravisit::walk_ty(self, ty); diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 8df0166f76b4..6c7c2b9eea25 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -426,9 +426,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder { - find_opaque_ty_constraints_for_tait(tcx, def_id) - } + ItemKind::OpaqueTy(OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. + }) => find_opaque_ty_constraints_for_tait(tcx, def_id), // Opaque types desugared from `impl Trait`. ItemKind::OpaqueTy(OpaqueTy { origin: diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e78e6acba54..b7253957edcc 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -735,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() && let Some(def_id) = def_id.as_local() - && self.opaque_type_origin(def_id).is_some() { + && self.opaque_type_origin(def_id, self.param_env).is_some() { return None; } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 064811bd29d7..e9c3726f8c3a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -1,8 +1,10 @@ +use crate::infer::opaque_types::may_define_impl_trait_in_assoc_ty_modulo_sig; + use super::TypeErrCtxt; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, Diagnostic, MultiSpan}; use rustc_hir as hir; -use rustc_middle::traits::ObligationCauseCode; +use rustc_middle::traits::ObligationCauseCode::{self, MiscObligation}; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::Printer; use rustc_middle::{ @@ -256,6 +258,15 @@ impl Trait for X { ); } } + (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if matches!(cause.code(), MiscObligation) => { + if let Some(def_id) = alias.def_id.as_local() { + if may_define_impl_trait_in_assoc_ty_modulo_sig(tcx, body_owner_def_id.expect_local(), def_id).is_some() { + diag.span_note(tcx.def_span(body_owner_def_id), "\ + this item must have the opaque type in its signature \ + in order to be able to register hidden types"); + } + } + } (ty::FnPtr(_), ty::FnDef(def, _)) if let hir::def::DefKind::Fn = tcx.def_kind(def) => { diag.note( diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 362b22b23a8d..0b6f51652fd1 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -3,9 +3,10 @@ use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{DefiningAnchor, InferCtxt, InferOk}; use crate::traits; +use hir::def::DefKind; use hir::def_id::{DefId, LocalDefId}; use hir::OpaqueTyOrigin; -use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_middle::traits::ObligationCause; @@ -53,7 +54,9 @@ impl<'tcx> InferCtxt<'tcx> { } let mut obligations = vec![]; let replace_opaque_type = |def_id: DefId| { - def_id.as_local().map_or(false, |def_id| self.opaque_type_origin(def_id).is_some()) + def_id + .as_local() + .map_or(false, |def_id| self.opaque_type_origin(def_id, param_env).is_some()) }; let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, @@ -138,7 +141,7 @@ impl<'tcx> InferCtxt<'tcx> { // let x = || foo(); // returns the Opaque assoc with `foo` // } // ``` - self.opaque_type_origin(def_id)? + self.opaque_type_origin(def_id, param_env)? } DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id), DefiningAnchor::Error => return None, @@ -149,8 +152,9 @@ impl<'tcx> InferCtxt<'tcx> { // no one encounters it in practice. // It does occur however in `fn fut() -> impl Future { async { 42 } }`, // where it is of no concern, so we only check for TAITs. - if let Some(OpaqueTyOrigin::TyAlias) = - b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id)) + if let Some(OpaqueTyOrigin::TyAlias { .. }) = b_def_id + .as_local() + .and_then(|b_def_id| self.opaque_type_origin(b_def_id, param_env)) { self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { span: cause.span, @@ -366,8 +370,12 @@ impl<'tcx> InferCtxt<'tcx> { /// Returns the origin of the opaque type `def_id` if we're currently /// in its defining scope. - #[instrument(skip(self), level = "trace", ret)] - pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option { + #[instrument(skip(self, param_env), level = "trace", ret)] + pub fn opaque_type_origin( + &self, + def_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + ) -> Option { let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); let parent_def_id = match self.defining_use_anchor { DefiningAnchor::Bubble | DefiningAnchor::Error => return None, @@ -381,8 +389,12 @@ impl<'tcx> InferCtxt<'tcx> { // Anonymous `impl Trait` hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id, // Named `type Foo = impl Bar;` - hir::OpaqueTyOrigin::TyAlias => { - may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) + hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { + if in_assoc_ty { + may_define_impl_trait_in_assoc_ty(self.tcx, parent_def_id, def_id, param_env) + } else { + may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) + } } }; in_definition_scope.then_some(origin) @@ -642,3 +654,105 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi ); res } + +#[derive(Debug, TypeVisitable, Clone)] +/// Helper datastructure containing the signature +/// that the opaque type extraction logic uses for determining +/// whether an opaque type may have its hidden types registered +/// by an item. +enum FnSigOrTy<'tcx> { + FnSig(ty::PolyFnSig<'tcx>), + Ty(Ty<'tcx>), +} + +/// Checks that the item may register hidden types for the +/// opaque type, if the opaque type shows up in its signature. +#[instrument(level = "debug", skip(tcx), ret)] +pub fn may_define_impl_trait_in_assoc_ty_modulo_sig<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + opaque_def_id: LocalDefId, +) -> Option>> { + let sig = match tcx.def_kind(def_id) { + DefKind::AssocFn => FnSigOrTy::FnSig(tcx.fn_sig(def_id).subst_identity()), + DefKind::AssocConst | DefKind::AssocTy => { + FnSigOrTy::Ty(tcx.type_of(def_id).subst_identity()) + } + _ => return None, + }; + let impl_id = tcx.local_parent(def_id); + trace!(?impl_id); + let mut assoc_id = opaque_def_id; + // Peel nested opaque types. + while let DefKind::OpaqueTy = tcx.def_kind(assoc_id) { + trace!(?assoc_id); + assoc_id = tcx.local_parent(assoc_id); + } + trace!(?assoc_id); + if !matches!(tcx.def_kind(assoc_id), DefKind::AssocTy) { + tcx.sess + .delay_span_bug(tcx.def_span(opaque_def_id), format!("{:?}", tcx.def_kind(assoc_id))); + } + let assoc_impl_id = tcx.local_parent(assoc_id); + trace!(?assoc_impl_id); + + if impl_id != assoc_impl_id { + return None; + } + + Some(sig) +} + +#[instrument(level = "debug", skip(tcx, param_env), ret)] +fn may_define_impl_trait_in_assoc_ty<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + opaque_def_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, +) -> bool { + let Some(sig) = may_define_impl_trait_in_assoc_ty_modulo_sig(tcx, def_id, opaque_def_id) else { + return false; + }; + + struct Visitor<'tcx> { + opaque_def_id: LocalDefId, + param_env: ty::ParamEnv<'tcx>, + tcx: TyCtxt<'tcx>, + seen: FxHashSet, + } + + impl<'tcx> TypeVisitor> for Visitor<'tcx> { + type BreakTy = (); + #[instrument(level = "trace", skip(self), ret)] + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<()> { + // FIXME(oli-obk): We should be checking if the associated type + // is mentioned instead of normalizing to find the opaque type. + // But that requires a way to figure out that a projection refers + // to a specific opaque type. That is probably doable by checking for + // `Self` as the `substs[0]`. + let normalized_ty = self.tcx.normalize_erasing_regions(self.param_env, ty); + if let ty::Alias(ty::Opaque, alias) = normalized_ty.kind() { + if let Some(def_id) = alias.def_id.as_local() { + trace!(?alias.def_id); + if def_id == self.opaque_def_id { + return ControlFlow::Break(()); + } + + if self.seen.insert(def_id) { + // Look into nested obligations like `impl Trait`. + for (pred, _) in self + .tcx + .explicit_item_bounds(alias.def_id) + .subst_iter_copied(self.tcx, alias.substs) + { + pred.visit_with(self)?; + } + } + } + } + normalized_ty.super_visit_with(self) + } + } + sig.visit_with(&mut Visitor { opaque_def_id, param_env, tcx, seen: Default::default() }) + .is_break() +} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 29cf432b8f91..043410c47e0b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1641,9 +1641,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } hir::ItemKind::OpaqueTy(ref opaque) => { self.encode_explicit_item_bounds(def_id); - self.tables - .is_type_alias_impl_trait - .set(def_id.index, matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias)); + self.tables.is_type_alias_impl_trait.set( + def_id.index, + matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }), + ); } hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { self.tables.impl_defaultness.set_some(def_id.index, *defaultness); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f882f54d6281..2952217f2675 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2520,7 +2520,7 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => { Some(parent) } - hir::OpaqueTyOrigin::TyAlias => None, + hir::OpaqueTyOrigin::TyAlias { .. } => None, }; } } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 9332b0430ffc..a0c8d299f48b 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -32,7 +32,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// This should only be used outside of type inference. For example, /// it assumes that normalization will succeed. - #[tracing::instrument(level = "debug", skip(self, param_env))] + #[tracing::instrument(level = "debug", skip(self, param_env), ret)] pub fn normalize_erasing_regions(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T where T: TypeFoldable>, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index deb29b1e7a91..ff13daa6db45 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -455,7 +455,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { | hir::ItemKind::Union(..) | hir::ItemKind::TyAlias(..) | hir::ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias, .. + origin: hir::OpaqueTyOrigin::TyAlias { .. }, + .. }) | hir::ItemKind::Static(..) | hir::ItemKind::Trait(..) diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 551815d021a0..21c1d8bcc982 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -5,15 +5,14 @@ trait Trait { type Opaque1; type Opaque2; - fn constrain(self); + fn constrain(self) -> (Self::Opaque1, Self::Opaque2); } impl<'a> Trait for &'a () { type Opaque1 = impl Sized; type Opaque2 = impl Sized + 'a; - fn constrain(self) { - let _: Self::Opaque1 = (); - let _: Self::Opaque2 = self; + fn constrain(self) -> (Self::Opaque1, Self::Opaque2) { + ((), self) } } diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs new file mode 100644 index 000000000000..93c52126d69b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs @@ -0,0 +1,16 @@ +#![feature(impl_trait_in_assoc_type)] + +trait Foo { + type Foo; + fn bar(); +} + +impl Foo for () { + type Foo = impl std::fmt::Debug; + fn bar() { + let x: Self::Foo = (); + //~^ ERROR: mismatched types + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr new file mode 100644 index 000000000000..2beed73cb85c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- the expected opaque type +LL | fn bar() { +LL | let x: Self::Foo = (); + | --------- ^^ expected opaque type, found `()` + | | + | expected due to this + | + = note: expected opaque type `<() as Foo>::Foo` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5 + | +LL | fn bar() { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 31ae7c46bddd917886f88bd3ba38f39cd9b51cd0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Apr 2023 07:36:58 +0000 Subject: [PATCH 25/34] Invert `IgnoreRegions` to `CheckRegions` --- compiler/rustc_hir_analysis/src/check/dropck.rs | 4 ++-- compiler/rustc_hir_analysis/src/coherence/orphan.rs | 4 ++-- compiler/rustc_middle/src/ty/util.rs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 5ba1ca1c807b..e0ba255cc069 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, ErrorGuaranteed}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::util::IgnoreRegions; +use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{self, TyCtxt}; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -81,7 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( self_type_did: DefId, adt_to_impl_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { - let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, IgnoreRegions::No) else { + let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound) else { return Ok(()) }; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 272177dfbd0f..23beacd2a8c2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, DelayDm}; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::util::IgnoreRegions; +use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{ self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -507,7 +507,7 @@ fn lint_auto_trait_impl<'tcx>( // Impls which completely cover a given root type are fine as they // disable auto impls entirely. So only lint if the substs // are not a permutation of the identity substs. - let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else { + let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else { // ok return; }; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index bcb51db9bcf9..c2affa244462 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -34,9 +34,9 @@ pub struct Discr<'tcx> { /// Used as an input to [`TyCtxt::uses_unique_generic_params`]. #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum IgnoreRegions { - Yes, +pub enum CheckRegions { No, + OnlyEarlyBound, } #[derive(Copy, Clone, Debug)] @@ -468,13 +468,13 @@ impl<'tcx> TyCtxt<'tcx> { pub fn uses_unique_generic_params( self, substs: SubstsRef<'tcx>, - ignore_regions: IgnoreRegions, + ignore_regions: CheckRegions, ) -> Result<(), NotUniqueParam<'tcx>> { let mut seen = GrowableBitSet::default(); for arg in substs { match arg.unpack() { GenericArgKind::Lifetime(lt) => { - if ignore_regions == IgnoreRegions::No { + if ignore_regions == CheckRegions::OnlyEarlyBound { let ty::ReEarlyBound(p) = lt.kind() else { return Err(NotUniqueParam::NotParam(lt.into())) }; From 84a43f0e3aa9b76bc9cef952d25b41ed1e5e0a94 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Apr 2023 07:42:09 +0000 Subject: [PATCH 26/34] Rewrite nested `if` conditions into a single match --- compiler/rustc_middle/src/ty/util.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c2affa244462..97e1f69057ea 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -473,16 +473,17 @@ impl<'tcx> TyCtxt<'tcx> { let mut seen = GrowableBitSet::default(); for arg in substs { match arg.unpack() { - GenericArgKind::Lifetime(lt) => { - if ignore_regions == CheckRegions::OnlyEarlyBound { - let ty::ReEarlyBound(p) = lt.kind() else { - return Err(NotUniqueParam::NotParam(lt.into())) - }; + GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { + (CheckRegions::OnlyEarlyBound, ty::ReEarlyBound(p)) => { if !seen.insert(p.index) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - } + (CheckRegions::OnlyEarlyBound, _) => { + return Err(NotUniqueParam::NotParam(lt.into())); + } + (CheckRegions::No, _) => {} + }, GenericArgKind::Type(t) => match t.kind() { ty::Param(p) => { if !seen.insert(p.index) { From e2daccc4acbb7a3150e1aef32f8cbe2736e5bd99 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Apr 2023 11:43:08 +0000 Subject: [PATCH 27/34] Add a convenience function --- compiler/rustc_hir_analysis/src/check/check.rs | 9 +-------- compiler/rustc_middle/src/ty/mod.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index b16860907eb2..78ffe59679a0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -397,14 +397,7 @@ fn check_opaque_meets_bounds<'tcx>( ) { let defining_use_anchor = match *origin { hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did, - hir::OpaqueTyOrigin::TyAlias { .. } => { - let mut def_id = def_id; - // Find the surrounding item (type alias or assoc type) - while let DefKind::OpaqueTy = tcx.def_kind(def_id) { - def_id = tcx.local_parent(def_id); - } - def_id - } + hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id), }; let param_env = tcx.param_env(defining_use_anchor); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2952217f2675..b414e1200cdf 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2476,6 +2476,18 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Returns the `DefId` of the item within which the `impl Trait` is declared. + /// For type-alias-impl-trait this is the `type` alias. + /// For impl-trait-in-assoc-type this is the assoc type. + /// For return-position-impl-trait this is the function. + pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId { + // Find the surrounding item (type alias or assoc type) + while let DefKind::OpaqueTy = self.def_kind(def_id) { + def_id = self.local_parent(def_id); + } + def_id + } + pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { if self.def_kind(def_id) != DefKind::AssocFn { return false; From 6ae803eedfeb57944cd0d2930d9a8b7a606baf4a Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 18 Apr 2023 16:09:48 +0200 Subject: [PATCH 28/34] add `query opaque_types_defined_by` --- compiler/rustc_middle/src/query/mod.rs | 9 +++ compiler/rustc_ty_utils/src/lib.rs | 2 + compiler/rustc_ty_utils/src/opaque_types.rs | 80 +++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 compiler/rustc_ty_utils/src/opaque_types.rs diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9fad2816b0d8..5acdd68e60ea 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -236,6 +236,15 @@ rustc_queries! { cache_on_disk_if { key.is_local() } } + query opaque_types_defined_by( + key: LocalDefId + ) -> &'tcx [LocalDefId] { + desc { + |tcx| "computing the opaque types defined by `{}`", + tcx.def_path_str(key.to_def_id()) + } + } + /// Returns the list of bounds that can be used for /// `SelectionCandidate::ProjectionCandidate(_)` and /// `ProjectionTyCandidate::TraitDef`. diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 73a2f6af579a..8306c5ae4936 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -33,6 +33,7 @@ pub mod instance; mod layout; mod layout_sanity_check; mod needs_drop; +mod opaque_types; pub mod representability; mod structural_match; mod ty; @@ -47,6 +48,7 @@ pub fn provide(providers: &mut Providers) { implied_bounds::provide(providers); layout::provide(providers); needs_drop::provide(providers); + opaque_types::provide(providers); representability::provide(providers); ty::provide(providers); instance::provide(providers); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs new file mode 100644 index 000000000000..cdb8e4a439d9 --- /dev/null +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -0,0 +1,80 @@ +use rustc_hir::{def::DefKind, def_id::LocalDefId}; +use rustc_middle::ty::util::CheckRegions; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_type_ir::AliasKind; +use std::ops::ControlFlow; + +struct OpaqueTypeCollector<'tcx> { + tcx: TyCtxt<'tcx>, + opaques: Vec, +} + +impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + match t.kind() { + ty::Alias(AliasKind::Opaque, alias_ty) => { + if let Some(def_id) = alias_ty.def_id.as_local() { + if self + .tcx + .uses_unique_generic_params(alias_ty.substs, CheckRegions::OnlyEarlyBound) + .is_ok() + { + self.opaques.push(def_id); + return ControlFlow::Continue(()); + } else { + warn!(?t, "opaque types with non-unique params in sig: {t:?}"); + } + } + } + _ => {} + } + t.super_visit_with(self) + } +} + +fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { + // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT. + match tcx.def_kind(item) { + DefKind::Fn | DefKind::AssocFn => { + let sig = tcx.fn_sig(item).subst_identity(); + let mut collector = OpaqueTypeCollector { tcx, opaques: Vec::new() }; + sig.visit_with(&mut collector); + tcx.arena.alloc_from_iter(collector.opaques) + } + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(_) + | DefKind::Ctor(_, _) + | DefKind::AssocConst + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Impl { .. } + | DefKind::Closure + | DefKind::Generator => &[], + } +} + +pub(super) fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { opaque_types_defined_by, ..*providers }; +} From 4e92f761fe54fc602ec2bf63819e8c973d1facd5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Apr 2023 08:07:44 +0000 Subject: [PATCH 29/34] Use the opaque_types_defined_by query to cheaply check for whether a hidden type may be registered for an opaque type --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../infer/error_reporting/note_and_explain.rs | 11 +- .../rustc_infer/src/infer/opaque_types.rs | 126 +------------ compiler/rustc_middle/src/query/erase.rs | 4 + compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 15 +- compiler/rustc_ty_utils/messages.ftl | 8 + compiler/rustc_ty_utils/src/errors.rs | 24 ++- compiler/rustc_ty_utils/src/opaque_types.rs | 165 +++++++++++++++--- .../generic-associated-types/issue-88595.rs | 1 + .../issue-88595.stderr | 34 +++- .../impl-trait/in-assoc-type-unconstrained.rs | 27 +++ .../in-assoc-type-unconstrained.stderr | 59 +++++++ tests/ui/impl-trait/in-assoc-type.rs | 21 +++ tests/ui/impl-trait/in-assoc-type.stderr | 22 +++ ...s-impl-trait-declaration-too-subtle.stderr | 5 + .../associated-type-impl-trait-lifetime.rs | 4 +- 17 files changed, 368 insertions(+), 162 deletions(-) create mode 100644 tests/ui/impl-trait/in-assoc-type-unconstrained.rs create mode 100644 tests/ui/impl-trait/in-assoc-type-unconstrained.stderr create mode 100644 tests/ui/impl-trait/in-assoc-type.rs create mode 100644 tests/ui/impl-trait/in-assoc-type.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b7253957edcc..9e78e6acba54 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -735,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind() && let Some(def_id) = def_id.as_local() - && self.opaque_type_origin(def_id, self.param_env).is_some() { + && self.opaque_type_origin(def_id).is_some() { return None; } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index e9c3726f8c3a..421eb807a141 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -1,10 +1,9 @@ -use crate::infer::opaque_types::may_define_impl_trait_in_assoc_ty_modulo_sig; - use super::TypeErrCtxt; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, Diagnostic, MultiSpan}; use rustc_hir as hir; -use rustc_middle::traits::ObligationCauseCode::{self, MiscObligation}; +use rustc_hir::def::DefKind; +use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::Printer; use rustc_middle::{ @@ -258,9 +257,9 @@ impl Trait for X { ); } } - (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if matches!(cause.code(), MiscObligation) => { - if let Some(def_id) = alias.def_id.as_local() { - if may_define_impl_trait_in_assoc_ty_modulo_sig(tcx, body_owner_def_id.expect_local(), def_id).is_some() { + (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => { + if tcx.is_type_alias_impl_trait(alias.def_id) { + if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) { diag.span_note(tcx.def_span(body_owner_def_id), "\ this item must have the opaque type in its signature \ in order to be able to register hidden types"); diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 0b6f51652fd1..545310ad3516 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -3,10 +3,9 @@ use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{DefiningAnchor, InferCtxt, InferOk}; use crate::traits; -use hir::def::DefKind; use hir::def_id::{DefId, LocalDefId}; use hir::OpaqueTyOrigin; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::Lrc; use rustc_hir as hir; use rustc_middle::traits::ObligationCause; @@ -54,9 +53,7 @@ impl<'tcx> InferCtxt<'tcx> { } let mut obligations = vec![]; let replace_opaque_type = |def_id: DefId| { - def_id - .as_local() - .map_or(false, |def_id| self.opaque_type_origin(def_id, param_env).is_some()) + def_id.as_local().map_or(false, |def_id| self.opaque_type_origin(def_id).is_some()) }; let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx, @@ -141,7 +138,7 @@ impl<'tcx> InferCtxt<'tcx> { // let x = || foo(); // returns the Opaque assoc with `foo` // } // ``` - self.opaque_type_origin(def_id, param_env)? + self.opaque_type_origin(def_id)? } DefiningAnchor::Bubble => self.opaque_type_origin_unchecked(def_id), DefiningAnchor::Error => return None, @@ -152,9 +149,8 @@ impl<'tcx> InferCtxt<'tcx> { // no one encounters it in practice. // It does occur however in `fn fut() -> impl Future { async { 42 } }`, // where it is of no concern, so we only check for TAITs. - if let Some(OpaqueTyOrigin::TyAlias { .. }) = b_def_id - .as_local() - .and_then(|b_def_id| self.opaque_type_origin(b_def_id, param_env)) + if let Some(OpaqueTyOrigin::TyAlias { .. }) = + b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id)) { self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { span: cause.span, @@ -370,12 +366,8 @@ impl<'tcx> InferCtxt<'tcx> { /// Returns the origin of the opaque type `def_id` if we're currently /// in its defining scope. - #[instrument(skip(self, param_env), level = "trace", ret)] - pub fn opaque_type_origin( - &self, - def_id: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - ) -> Option { + #[instrument(skip(self), level = "trace", ret)] + pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option { let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); let parent_def_id = match self.defining_use_anchor { DefiningAnchor::Bubble | DefiningAnchor::Error => return None, @@ -391,7 +383,7 @@ impl<'tcx> InferCtxt<'tcx> { // Named `type Foo = impl Bar;` hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { if in_assoc_ty { - may_define_impl_trait_in_assoc_ty(self.tcx, parent_def_id, def_id, param_env) + self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id) } else { may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) } @@ -654,105 +646,3 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi ); res } - -#[derive(Debug, TypeVisitable, Clone)] -/// Helper datastructure containing the signature -/// that the opaque type extraction logic uses for determining -/// whether an opaque type may have its hidden types registered -/// by an item. -enum FnSigOrTy<'tcx> { - FnSig(ty::PolyFnSig<'tcx>), - Ty(Ty<'tcx>), -} - -/// Checks that the item may register hidden types for the -/// opaque type, if the opaque type shows up in its signature. -#[instrument(level = "debug", skip(tcx), ret)] -pub fn may_define_impl_trait_in_assoc_ty_modulo_sig<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - opaque_def_id: LocalDefId, -) -> Option>> { - let sig = match tcx.def_kind(def_id) { - DefKind::AssocFn => FnSigOrTy::FnSig(tcx.fn_sig(def_id).subst_identity()), - DefKind::AssocConst | DefKind::AssocTy => { - FnSigOrTy::Ty(tcx.type_of(def_id).subst_identity()) - } - _ => return None, - }; - let impl_id = tcx.local_parent(def_id); - trace!(?impl_id); - let mut assoc_id = opaque_def_id; - // Peel nested opaque types. - while let DefKind::OpaqueTy = tcx.def_kind(assoc_id) { - trace!(?assoc_id); - assoc_id = tcx.local_parent(assoc_id); - } - trace!(?assoc_id); - if !matches!(tcx.def_kind(assoc_id), DefKind::AssocTy) { - tcx.sess - .delay_span_bug(tcx.def_span(opaque_def_id), format!("{:?}", tcx.def_kind(assoc_id))); - } - let assoc_impl_id = tcx.local_parent(assoc_id); - trace!(?assoc_impl_id); - - if impl_id != assoc_impl_id { - return None; - } - - Some(sig) -} - -#[instrument(level = "debug", skip(tcx, param_env), ret)] -fn may_define_impl_trait_in_assoc_ty<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - opaque_def_id: LocalDefId, - param_env: ty::ParamEnv<'tcx>, -) -> bool { - let Some(sig) = may_define_impl_trait_in_assoc_ty_modulo_sig(tcx, def_id, opaque_def_id) else { - return false; - }; - - struct Visitor<'tcx> { - opaque_def_id: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - tcx: TyCtxt<'tcx>, - seen: FxHashSet, - } - - impl<'tcx> TypeVisitor> for Visitor<'tcx> { - type BreakTy = (); - #[instrument(level = "trace", skip(self), ret)] - fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<()> { - // FIXME(oli-obk): We should be checking if the associated type - // is mentioned instead of normalizing to find the opaque type. - // But that requires a way to figure out that a projection refers - // to a specific opaque type. That is probably doable by checking for - // `Self` as the `substs[0]`. - let normalized_ty = self.tcx.normalize_erasing_regions(self.param_env, ty); - if let ty::Alias(ty::Opaque, alias) = normalized_ty.kind() { - if let Some(def_id) = alias.def_id.as_local() { - trace!(?alias.def_id); - if def_id == self.opaque_def_id { - return ControlFlow::Break(()); - } - - if self.seen.insert(def_id) { - // Look into nested obligations like `impl Trait`. - for (pred, _) in self - .tcx - .explicit_item_bounds(alias.def_id) - .subst_iter_copied(self.tcx, alias.substs) - { - pred.visit_with(self)?; - } - } - } - } - normalized_ty.super_visit_with(self) - } - } - sig.visit_with(&mut Visitor { opaque_def_id, param_env, tcx, seen: Default::default() }) - .is_break() -} diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 28a9c1eef1a6..b45f7caaabe0 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -172,6 +172,10 @@ impl EraseType for ty::Binder<'_, ty::FnSig<'_>> { type Result = [u8; size_of::>>()]; } +impl EraseType for ty::Binder<'_, &'_ ty::List>> { + type Result = [u8; size_of::>>>()]; +} + impl EraseType for (&'_ T0, &'_ T1) { type Result = [u8; size_of::<(&'static (), &'static ())>()]; } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8d0737e1eeee..31929e4f4f62 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1265,7 +1265,7 @@ impl<'tcx> AliasTy<'tcx> { /// Extracts the underlying trait reference and own substs from this projection. /// For example, if this is a projection of `::Item<'a>`, - /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs + /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs pub fn trait_ref_and_own_substs( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 97e1f69057ea..9bab693156b3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -36,7 +36,12 @@ pub struct Discr<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum CheckRegions { No, + /// Only permit early bound regions. This is useful for Adts which + /// can never have late bound regions. OnlyEarlyBound, + /// Permit both late bound and early bound regions. Use this for functions, + /// which frequently have late bound regions. + Bound, } #[derive(Copy, Clone, Debug)] @@ -471,15 +476,21 @@ impl<'tcx> TyCtxt<'tcx> { ignore_regions: CheckRegions, ) -> Result<(), NotUniqueParam<'tcx>> { let mut seen = GrowableBitSet::default(); + let mut seen_late = FxHashSet::default(); for arg in substs { match arg.unpack() { GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) { - (CheckRegions::OnlyEarlyBound, ty::ReEarlyBound(p)) => { + (CheckRegions::Bound, ty::ReLateBound(di, reg)) => { + if !seen_late.insert((di, reg)) { + return Err(NotUniqueParam::DuplicateParam(lt.into())); + } + } + (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => { if !seen.insert(p.index) { return Err(NotUniqueParam::DuplicateParam(lt.into())); } } - (CheckRegions::OnlyEarlyBound, _) => { + (CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => { return Err(NotUniqueParam::NotParam(lt.into())); } (CheckRegions::No, _) => {} diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl index 15a14112f4a2..5bc3e3c00c9a 100644 --- a/compiler/rustc_ty_utils/messages.ftl +++ b/compiler/rustc_ty_utils/messages.ftl @@ -55,3 +55,11 @@ ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes} ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` + +ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope + .label = generic argument `{$arg}` used twice + .note = for this opaque type + +ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope + .label = argument `{$arg}` is not a generic parameter + .note = for this opaque type diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index 3d3fc50e6e59..553bf40ef3a4 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -1,7 +1,7 @@ //! Errors emitted by ty_utils use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{GenericArg, Ty}; use rustc_span::Span; #[derive(Diagnostic)] @@ -100,3 +100,25 @@ pub struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_duplicate_arg)] +pub struct DuplicateArg<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ty_utils_impl_trait_not_param)] +pub struct NotParam<'tcx> { + pub arg: GenericArg<'tcx>, + #[primary_span] + #[label] + pub span: Span, + #[note] + pub opaque_span: Span, +} diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index cdb8e4a439d9..25ebb333bf74 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -1,46 +1,165 @@ +use rustc_data_structures::fx::FxHashSet; +use rustc_errors::ErrorGuaranteed; use rustc_hir::{def::DefKind, def_id::LocalDefId}; -use rustc_middle::ty::util::CheckRegions; +use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_span::Span; use rustc_type_ir::AliasKind; use std::ops::ControlFlow; +use crate::errors::{DuplicateArg, NotParam}; + struct OpaqueTypeCollector<'tcx> { tcx: TyCtxt<'tcx>, opaques: Vec, + /// The `DefId` of the item which we are collecting opaque types for. + item: LocalDefId, + + /// Avoid infinite recursion due to recursive declarations. + seen: FxHashSet, +} + +impl<'tcx> OpaqueTypeCollector<'tcx> { + fn collect( + tcx: TyCtxt<'tcx>, + item: LocalDefId, + val: ty::Binder<'tcx, impl TypeVisitable>>, + ) -> Vec { + let mut collector = Self { tcx, opaques: Vec::new(), item, seen: Default::default() }; + val.skip_binder().visit_with(&mut collector); + collector.opaques + } + + fn span(&self) -> Span { + self.tcx.def_span(self.item) + } + + fn parent(&self) -> Option { + match self.tcx.def_kind(self.item) { + DefKind::Fn => None, + DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + Some(self.tcx.local_parent(self.item)) + } + other => span_bug!( + self.tcx.def_span(self.item), + "unhandled item with opaque types: {other:?}" + ), + } + } } impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + type BreakTy = ErrorGuaranteed; + + #[instrument(skip(self), ret, level = "trace")] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { - ty::Alias(AliasKind::Opaque, alias_ty) => { - if let Some(def_id) = alias_ty.def_id.as_local() { - if self - .tcx - .uses_unique_generic_params(alias_ty.substs, CheckRegions::OnlyEarlyBound) - .is_ok() - { - self.opaques.push(def_id); - return ControlFlow::Continue(()); - } else { - warn!(?t, "opaque types with non-unique params in sig: {t:?}"); + ty::Alias(AliasKind::Opaque, alias_ty) if alias_ty.def_id.is_local() => { + if !self.seen.insert(alias_ty.def_id.expect_local()) { + return ControlFlow::Continue(()); + } + match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) { + Ok(()) => { + // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not + // supported at all, so this is sound to do, but once we want to support them, you'll + // start seeing the error below. + + self.opaques.push(alias_ty.def_id.expect_local()); + + // Collect opaque types nested within the associated type bounds of this opaque type. + for (pred, _span) in self + .tcx + .explicit_item_bounds(alias_ty.def_id) + .subst_iter_copied(self.tcx, alias_ty.substs) + { + trace!(?pred); + pred.visit_with(self)?; + } + + ControlFlow::Continue(()) + } + Err(NotUniqueParam::NotParam(arg)) => { + let err = self.tcx.sess.emit_err(NotParam { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) + } + Err(NotUniqueParam::DuplicateParam(arg)) => { + let err = self.tcx.sess.emit_err(DuplicateArg { + arg, + span: self.span(), + opaque_span: self.tcx.def_span(alias_ty.def_id), + }); + ControlFlow::Break(err) } } } - _ => {} + ty::Alias(AliasKind::Projection, alias_ty) => { + if let Some(parent) = self.parent() { + trace!(?alias_ty); + let (trait_ref, own_substs) = alias_ty.trait_ref_and_own_substs(self.tcx); + + trace!(?trait_ref, ?own_substs); + // This avoids having to do normalization of `Self::AssocTy` by only + // supporting the case of a method defining opaque types from assoc types + // in the same impl block. + if trait_ref.self_ty() == self.tcx.type_of(parent).subst_identity() { + for assoc in self.tcx.associated_items(parent).in_definition_order() { + trace!(?assoc); + if assoc.trait_item_def_id == Some(alias_ty.def_id) { + // We reconstruct the generic args of the associated type within the impl + // from the impl's generics and the generic args passed to the type via the + // projection. + let substs = ty::InternalSubsts::identity_for_item( + self.tcx, + parent.to_def_id(), + ); + trace!(?substs); + let substs: Vec<_> = + substs.iter().chain(own_substs.iter().copied()).collect(); + trace!(?substs); + // Find opaque types in this associated type. + return self + .tcx + .type_of(assoc.def_id) + .subst(self.tcx, &substs) + .visit_with(self); + } + } + } + } + t.super_visit_with(self) + } + _ => t.super_visit_with(self), } - t.super_visit_with(self) } } fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] { - // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT. - match tcx.def_kind(item) { - DefKind::Fn | DefKind::AssocFn => { - let sig = tcx.fn_sig(item).subst_identity(); - let mut collector = OpaqueTypeCollector { tcx, opaques: Vec::new() }; - sig.visit_with(&mut collector); - tcx.arena.alloc_from_iter(collector.opaques) + let kind = tcx.def_kind(item); + trace!(?kind); + // FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types. + match kind { + // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds` + DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => { + let defined_opaques = match kind { + DefKind::Fn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocFn => { + OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity()) + } + DefKind::AssocTy | DefKind::AssocConst => OpaqueTypeCollector::collect( + tcx, + item, + ty::Binder::dummy(tcx.type_of(item).subst_identity()), + ), + _ => unreachable!(), + }; + tcx.arena.alloc_from_iter(defined_opaques) } DefKind::Mod | DefKind::Struct @@ -51,13 +170,11 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [ | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias - | DefKind::AssocTy | DefKind::TyParam | DefKind::Const | DefKind::ConstParam | DefKind::Static(_) | DefKind::Ctor(_, _) - | DefKind::AssocConst | DefKind::Macro(_) | DefKind::ExternCrate | DefKind::Use diff --git a/tests/ui/generic-associated-types/issue-88595.rs b/tests/ui/generic-associated-types/issue-88595.rs index 5a40a6129723..7de906e7ef3f 100644 --- a/tests/ui/generic-associated-types/issue-88595.rs +++ b/tests/ui/generic-associated-types/issue-88595.rs @@ -19,4 +19,5 @@ impl<'a> A<'a> for C { type B<'b> = impl Clone; fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope + //~^ ERROR: mismatched types } diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr index 79d3479af8c8..d6caed854599 100644 --- a/tests/ui/generic-associated-types/issue-88595.stderr +++ b/tests/ui/generic-associated-types/issue-88595.stderr @@ -1,16 +1,34 @@ error: non-defining opaque type use in defining scope - --> $DIR/issue-88595.rs:21:35 + --> $DIR/issue-88595.rs:21:5 | LL | fn a(&'a self) -> Self::B<'a> {} - | ^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice | -note: lifetime used multiple times - --> $DIR/issue-88595.rs:18:6 +note: for this opaque type + --> $DIR/issue-88595.rs:19:18 | -LL | impl<'a> A<'a> for C { - | ^^ LL | type B<'b> = impl Clone; - | ^^ + | ^^^^^^^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-88595.rs:21:23 + | +LL | type B<'b> = impl Clone; + | ---------- the expected opaque type +LL | +LL | fn a(&'a self) -> Self::B<'a> {} + | - ^^^^^^^^^^^ expected opaque type, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected opaque type `>::B<'a>` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/issue-88595.rs:21:5 + | +LL | fn a(&'a self) -> Self::B<'a> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.rs b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs new file mode 100644 index 000000000000..c395b4195a05 --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.rs @@ -0,0 +1,27 @@ +#![feature(impl_trait_in_assoc_type)] + +mod compare_ty { + trait Trait { + type Ty: IntoIterator; + } + impl Trait for () { + type Ty = Option; + //~^ ERROR: unconstrained opaque type + //~| ERROR: type mismatch resolving `::Ty::{opaque#0}> as IntoIterator>::Item == ()` + } +} + +mod compare_method { + trait Trait { + type Ty; + fn method() -> Self::Ty; + } + impl Trait for () { + type Ty = impl Sized; + //~^ ERROR: unconstrained opaque type + fn method() -> () {} + //~^ ERROR: method `method` has an incompatible type for trait + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr new file mode 100644 index 000000000000..1097cd0f452a --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -0,0 +1,59 @@ +error[E0271]: type mismatch resolving `::Ty::{opaque#0}> as IntoIterator>::Item == ()` + --> $DIR/in-assoc-type-unconstrained.rs:8:19 + | +LL | type Ty = Option; + | ^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type + | + = note: expected unit type `()` + found opaque type `<() as compare_ty::Trait>::Ty::{opaque#0}` +note: required by a bound in `compare_ty::Trait::Ty` + --> $DIR/in-assoc-type-unconstrained.rs:5:31 + | +LL | type Ty: IntoIterator; + | ^^^^^^^^^ required by this bound in `Trait::Ty` + +error: unconstrained opaque type + --> $DIR/in-assoc-type-unconstrained.rs:8:26 + | +LL | type Ty = Option; + | ^^^^^^^^^^ + | + = note: `Ty` must be used in combination with a concrete type within the same impl + +error[E0053]: method `method` has an incompatible type for trait + --> $DIR/in-assoc-type-unconstrained.rs:22:24 + | +LL | type Ty = impl Sized; + | ---------- the expected opaque type +LL | +LL | fn method() -> () {} + | ^^ + | | + | expected opaque type, found `()` + | help: change the output type to match the trait: `<() as compare_method::Trait>::Ty` + | +note: type in trait + --> $DIR/in-assoc-type-unconstrained.rs:17:24 + | +LL | fn method() -> Self::Ty; + | ^^^^^^^^ + = note: expected signature `fn() -> <() as compare_method::Trait>::Ty` + found signature `fn()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/in-assoc-type-unconstrained.rs:22:9 + | +LL | fn method() -> () {} + | ^^^^^^^^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/in-assoc-type-unconstrained.rs:20:19 + | +LL | type Ty = impl Sized; + | ^^^^^^^^^^ + | + = note: `Ty` must be used in combination with a concrete type within the same impl + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0053, E0271. +For more information about an error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-assoc-type.rs b/tests/ui/impl-trait/in-assoc-type.rs new file mode 100644 index 000000000000..36c54bdd6de3 --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type.rs @@ -0,0 +1,21 @@ +#![feature(impl_trait_in_assoc_type)] + +trait Foo { + type Bar; + fn foo(&self) -> >::Bar + where + Self: Foo<()>; +} + +impl Foo<()> for () { + type Bar = impl std::fmt::Debug; + fn foo(&self) -> Self::Bar {} +} + +impl Foo for () { + type Bar = u32; + fn foo(&self) -> >::Bar {} + //~^ ERROR: mismatched types +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr new file mode 100644 index 000000000000..f0a272dc2d5d --- /dev/null +++ b/tests/ui/impl-trait/in-assoc-type.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/in-assoc-type.rs:17:22 + | +LL | type Bar = impl std::fmt::Debug; + | -------------------- the expected opaque type +... +LL | fn foo(&self) -> >::Bar {} + | --- ^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + | + = note: expected opaque type `<() as Foo<()>>::Bar` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/in-assoc-type.rs:17:5 + | +LL | fn foo(&self) -> >::Bar {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index f7aff4195444..fe62a8f32888 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -43,6 +43,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | = note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _` found signature `fn(&b::Bar, &(b::Bar, i32)) -> _` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9 + | +LL | fn eq(&self, _other: &(Bar, i32)) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 21c1d8bcc982..58eaa9c2c426 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -12,7 +12,9 @@ impl<'a> Trait for &'a () { type Opaque1 = impl Sized; type Opaque2 = impl Sized + 'a; fn constrain(self) -> (Self::Opaque1, Self::Opaque2) { - ((), self) + let a: Self::Opaque1 = (); + let b: Self::Opaque2 = self; + (a, b) } } From b93fd8355acbe8a4ffd53ad32c3d7f4798c15b98 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 12 May 2023 15:25:24 +0200 Subject: [PATCH 30/34] hedge for future changes Co-authored-by: lcnr --- library/core/src/marker.rs | 8 +++++--- library/core/src/ops/drop.rs | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index de285c99cb1f..2e8cab8601ab 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -668,9 +668,11 @@ impl !Sync for *mut T {} /// /// ## Ownership and the drop check /// -/// Adding a field of type `PhantomData` indicates that your type *owns* data of type `T`. This -/// in turn has effects on the Rust compiler's [drop check] analysis, but that only matters in very -/// specific circumstances. For the exact rules, see the [drop check] documentation. +/// The exact interaction of `PhantomData` with drop check **may change in the future**. +/// +/// Currently, adding a field of type `PhantomData` indicates that your type *owns* data of type +/// `T` in very rare circumstances. This in turn has effects on the Rust compiler's [drop check] +/// analysis. For the exact rules, see the [drop check] documentation. /// /// ## Layout /// diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs index 804d2c775fc0..9ebf426be951 100644 --- a/library/core/src/ops/drop.rs +++ b/library/core/src/ops/drop.rs @@ -168,7 +168,8 @@ /// The Nomicon discusses the need for [drop check in more detail][drop check]. /// /// To reject such code, the "drop check" analysis determines which types and lifetimes need to -/// still be live when `T` gets dropped: +/// still be live when `T` gets dropped. The exact details of this analysis are not yet +/// stably guaranteed and **subject to change**. Currently, the analysis works as follows: /// - If `T` has no drop glue, then trivially nothing is required to be live. This is the case if /// neither `T` nor any of its (recursive) fields have a destructor (`impl Drop`). [`PhantomData`] /// and [`ManuallyDrop`] are considered to never have a destructor, no matter their field type. From ff54c801f0c1552941bda472df992e9f9be25f33 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 May 2023 05:00:59 +0000 Subject: [PATCH 31/34] Encode VariantIdx so we can decode variants in the right order --- compiler/rustc_metadata/src/rmeta/decoder.rs | 57 ++++++++++++------- compiler/rustc_metadata/src/rmeta/encoder.rs | 3 +- compiler/rustc_metadata/src/rmeta/mod.rs | 2 + .../auxiliary/discr-foreign-dep.rs | 7 +++ tests/ui/enum-discriminant/discr-foreign.rs | 11 ++++ 5 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs create mode 100644 tests/ui/enum-discriminant/discr-foreign.rs diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index a310cbb80293..eab32ad8e3f8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -856,7 +856,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ty::EarlyBinder(&*output) } - fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef { + fn get_variant( + self, + kind: DefKind, + index: DefIndex, + parent_did: DefId, + ) -> (VariantIdx, ty::VariantDef) { let adt_kind = match kind { DefKind::Variant => ty::AdtKind::Enum, DefKind::Struct => ty::AdtKind::Struct, @@ -870,22 +875,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index))); - ty::VariantDef::new( - self.item_name(index), - variant_did, - ctor, - data.discr, - self.get_associated_item_or_field_def_ids(index) - .map(|did| ty::FieldDef { - did, - name: self.item_name(did.index), - vis: self.get_visibility(did.index), - }) - .collect(), - adt_kind, - parent_did, - false, - data.is_non_exhaustive, + ( + data.idx, + ty::VariantDef::new( + self.item_name(index), + variant_did, + ctor, + data.discr, + self.get_associated_item_or_field_def_ids(index) + .map(|did| ty::FieldDef { + did, + name: self.item_name(did.index), + vis: self.get_visibility(did.index), + }) + .collect(), + adt_kind, + parent_did, + false, + data.is_non_exhaustive, + ), ) } @@ -901,7 +909,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); - let variants = if let ty::AdtKind::Enum = adt_kind { + let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind { self.root .tables .module_children_non_reexports @@ -912,15 +920,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let kind = self.def_kind(index); match kind { DefKind::Ctor(..) => None, - _ => Some(self.get_variant(&kind, index, did)), + _ => Some(self.get_variant(kind, index, did)), } }) .collect() } else { - std::iter::once(self.get_variant(&kind, item_id, did)).collect() + std::iter::once(self.get_variant(kind, item_id, did)).collect() }; - tcx.mk_adt_def(did, adt_kind, variants, repr) + variants.sort_by_key(|(idx, _)| *idx); + + tcx.mk_adt_def( + did, + adt_kind, + variants.into_iter().map(|(_, variant)| variant).collect(), + repr, + ) } fn get_visibility(self, id: DefIndex) -> Visibility { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 29cf432b8f91..20d94c954ca2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1375,9 +1375,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Therefore, the loop over variants will encode its fields as the adt's children. } - for variant in adt_def.variants().iter() { + for (idx, variant) in adt_def.variants().iter_enumerated() { let data = VariantData { discr: variant.discr, + idx, ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index e2f6acb186b7..1328d7002104 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -31,6 +31,7 @@ use rustc_span::edition::Edition; use rustc_span::hygiene::{ExpnIndex, MacroKind}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span}; +use rustc_target::abi::VariantIdx; use rustc_target::spec::{PanicStrategy, TargetTriple}; use std::marker::PhantomData; @@ -430,6 +431,7 @@ define_tables! { #[derive(TyEncodable, TyDecodable)] struct VariantData { + idx: VariantIdx, discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. ctor: Option<(CtorKind, DefIndex)>, diff --git a/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs new file mode 100644 index 000000000000..a2cc10a4b22c --- /dev/null +++ b/tests/ui/enum-discriminant/auxiliary/discr-foreign-dep.rs @@ -0,0 +1,7 @@ +#[derive(Default)] +pub enum Foo { + A(u32), + #[default] + B, + C(u32), +} diff --git a/tests/ui/enum-discriminant/discr-foreign.rs b/tests/ui/enum-discriminant/discr-foreign.rs new file mode 100644 index 000000000000..e7123b344523 --- /dev/null +++ b/tests/ui/enum-discriminant/discr-foreign.rs @@ -0,0 +1,11 @@ +// aux-build:discr-foreign-dep.rs +// build-pass + +extern crate discr_foreign_dep; + +fn main() { + match Default::default() { + discr_foreign_dep::Foo::A(_) => {} + _ => {} + } +} From c50a2e1d1742ca290aed840fb5273662b209b936 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 10 May 2023 15:23:20 -0700 Subject: [PATCH 32/34] Remove useless `assume`s from `slice::iter(_mut)` --- library/core/src/slice/iter.rs | 4 - tests/codegen/slice-iter-nonnull.rs | 35 ++++ ...ice_iter.forward_loop.PreCodegen.after.mir | 178 ++++++++++++++---- ...ice_iter.reverse_loop.PreCodegen.after.mir | 148 ++++++++++++--- 4 files changed, 301 insertions(+), 64 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 67fcef0f4663..5369fe0a9a9a 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -90,8 +90,6 @@ impl<'a, T> Iter<'a, T> { let ptr = slice.as_ptr(); // SAFETY: Similar to `IterMut::new`. unsafe { - assume(!ptr.is_null()); - let end = if T::IS_ZST { invalid(slice.len()) } else { ptr.add(slice.len()) }; Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData } @@ -228,8 +226,6 @@ impl<'a, T> IterMut<'a, T> { // See the `next_unchecked!` and `is_empty!` macros as well as the // `post_inc_start` method for more information. unsafe { - assume(!ptr.is_null()); - let end = if T::IS_ZST { invalid_mut(slice.len()) } else { ptr.add(slice.len()) }; Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData } diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index 392e43380764..997bdaf56363 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -40,3 +40,38 @@ pub fn slice_iter_next_back<'a>(it: &mut std::slice::Iter<'a, u32>) -> Option<&' it.next_back() } + +// The slice iterator `new` methods used to `assume` that the pointer is non-null, +// but passing slices already requires that, to the extent that LLVM actually +// removed the `call @llvm.assume` anyway. These tests just demonstrate that the +// attribute is there, and confirms adding the assume back doesn't do anything. + +// CHECK-LABEL: @slice_iter_new +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +#[no_mangle] +pub fn slice_iter_new(slice: &[u32]) -> std::slice::Iter<'_, u32> { + // CHECK-NOT: slice + // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %slice.0, 0 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK-NOT: slice + // CHECK: } + slice.iter() +} + +// CHECK-LABEL: @slice_iter_mut_new +// CHECK-SAME: (ptr noalias noundef nonnull {{.+}} %slice.0, {{.+}} noundef %slice.1) +#[no_mangle] +pub fn slice_iter_mut_new(slice: &mut [u32]) -> std::slice::IterMut<'_, u32> { + // CHECK-NOT: slice + // CHECK: %[[END:.+]] = getelementptr inbounds i32{{.+}} %slice.0{{.+}} %slice.1 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %slice.0, 0 + // CHECK-NOT: slice + // CHECK: insertvalue {{.+}} ptr %[[END]], 1 + // CHECK-NOT: slice + // CHECK: } + slice.iter_mut() +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir index f27525bf3d95..0da7e5536ae0 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir @@ -6,58 +6,120 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 let mut _3: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _5: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _8: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 - let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 - let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + let _5: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _6: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _7: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _8: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _10: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _11: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 scope 1 { - debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + debug iter => _4; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + let _9: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 scope 2 { - debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + debug x => _9; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } } scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:28:20: 28:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _12: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _14: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _15: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _17: std::ptr::NonNull; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _18: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _19: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _12; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _13: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _13; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _18; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _21: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _22: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _22; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _22; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _23: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _23; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _23; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _23; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _12; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _16; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _20: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + } } - scope 4 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 - debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + scope 22 (inlined as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 + debug self => _3; // in scope 22 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } bb0: { - StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb10, unwind: bb8]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL - // + user_ty: UserType(0) - // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value() } + StorageLive(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _20 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _12 = move _20 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_20); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _14) -> [0: bb11, otherwise: bb10]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL } bb1: { - StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - _7 = as Iterator>::next(_8) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _7 = &mut _4; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _6 = as Iterator>::next(_7) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 // mir::Constant // + span: $DIR/slice_iter.rs:28:14: 28:26 // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as Iterator>::next}, val: Value() } } bb2: { - _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 - switchInt(move _9) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _8 = discriminant(_6); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + switchInt(move _8) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 } bb3: { - _10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 - StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 - _11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 - StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 - _12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 - _6 = >::call(move _11, move _12) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _9 = ((_6 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_10); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _10 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _11 = (_9,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _5 = >::call(move _10, move _11) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 // mir::Constant // + span: $DIR/slice_iter.rs:29:9: 29:10 // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> >::Output {>::call}, val: Value() } @@ -68,16 +130,15 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb5: { - StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 - StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 - StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 drop(_2) -> bb7; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 } bb6: { - StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 - StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_10); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_6); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } @@ -94,10 +155,49 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb10: { - _3 = move _4; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL - StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:25: +1:26 - StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _15 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = _15 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb11: { + StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _13 = Offset(_12, _16); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb12; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb12: { + StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _18 = _12 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _21 = _18 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _17 = NonNull:: { pointer: _21 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_21); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _19 = _13; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _3 = std::slice::Iter::<'_, T> { ptr: move _17, end: move _19, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value() } + // adt + // + user_ty: UserType(1) + StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_17); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_13); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_12); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _4 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir index 62dd9667d960..45b41b54c8b6 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir @@ -19,39 +19,104 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { scope 2 { debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 } - scope 7 (inlined > as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 - debug self => _8; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - let mut _13: &mut std::slice::Iter<'_, T>; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + scope 25 (inlined > as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _8; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + let mut _25: &mut std::slice::Iter<'_, T>; // in scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL } } scope 3 (inlined core::slice::::iter) { // at $DIR/slice_iter.rs:35:20: 35:26 debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - } - scope 4 (inlined as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 - debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - scope 5 (inlined Rev::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - debug iter => _4; // in scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + scope 4 (inlined std::slice::Iter::<'_, T>::new) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL + debug slice => _1; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let _13: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _15: bool; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _16: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _17: usize; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _18: std::ptr::NonNull; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _19: *mut T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + let mut _20: *const T; // in scope 4 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 5 { + debug ptr => _13; // in scope 5 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 6 { + let _14: *const T; // in scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 7 { + debug end => _14; // in scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + scope 13 (inlined NonNull::::new_unchecked) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug ptr => _19; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _22: *const T; // in scope 13 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + let mut _23: *mut T; // in scope 13 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 14 { + scope 15 (inlined NonNull::::new_unchecked::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug ptr => _23; // in scope 15 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 16 (inlined ptr::mut_ptr::::is_null) { // at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + debug self => _23; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _24: *mut u8; // in scope 16 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 17 { + scope 18 (inlined ptr::mut_ptr::::is_null::runtime_impl) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug ptr => _24; // in scope 18 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 19 (inlined ptr::mut_ptr::::addr) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 19 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + scope 20 { + scope 21 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _24; // in scope 21 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + } + } + } + } + } + } + } + } + } + } + scope 9 (inlined invalid::) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug addr => _16; // in scope 9 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + scope 10 { + } + } + scope 11 (inlined ptr::const_ptr::::add) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _13; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + debug count => _17; // in scope 11 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + scope 12 { + } + } + } + } + scope 8 (inlined core::slice::::as_ptr) { // at $SRC_DIR/core/src/slice/iter.rs:LL:COL + debug self => _1; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _21: *const [T]; // in scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } } } - scope 6 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 - debug self => _3; // in scope 6 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + scope 22 (inlined as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 + debug self => _4; // in scope 22 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + scope 23 (inlined Rev::>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + debug iter => _4; // in scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + } + } + scope 24 (inlined > as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _3; // in scope 24 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL } bb0: { StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 - _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb9, unwind: bb7]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL - // + user_ty: UserType(0) - // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value() } + StorageLive(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _21 = &raw const (*_1); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _13 = move _21 as *const T (PtrToPtr); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_21); // scope 8 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _15 = const _; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + switchInt(move _15) -> [0: bb10, otherwise: bb9]; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL } bb1: { StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 - StorageLive(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - _13 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL - _7 = as DoubleEndedIterator>::next_back(move _13) -> [return: bb10, unwind: bb7]; // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageLive(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _25 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _7 = as DoubleEndedIterator>::next_back(move _25) -> [return: bb12, unwind: bb7]; // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option< as Iterator>::Item> { as DoubleEndedIterator>::next_back}, val: Value() } @@ -99,15 +164,56 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb9: { - _3 = Rev::> { iter: move _4 }; // scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageLive(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _16 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = _16 as *const T (Transmute); // scope 10 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_16); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb10: { + StorageLive(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _17 = Len((*_1)); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _14 = Offset(_13, _17); // scope 12 at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + StorageDead(_17); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + goto -> bb11; // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + } + + bb11: { + StorageDead(_15); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _19 = _13 as *mut T (PtrToPtr); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _22 = _19 as *const T (Pointer(MutToConstPointer)); // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + _18 = NonNull:: { pointer: _22 }; // scope 14 at $SRC_DIR/core/src/ptr/non_null.rs:LL:COL + StorageDead(_24); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_23); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_22); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_19); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageLive(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _20 = _14; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + _4 = std::slice::Iter::<'_, T> { ptr: move _18, end: move _20, _marker: const ZeroSized: PhantomData<&T> }; // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: PhantomData<&T>, val: Value() } + // adt + // + user_ty: UserType(1) + StorageDead(_20); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_18); // scope 7 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_14); // scope 6 at $SRC_DIR/core/src/slice/iter.rs:LL:COL + StorageDead(_13); // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _3 = Rev::> { iter: move _4 }; // scope 23 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32 StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 } - bb10: { - StorageDead(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + bb12: { + StorageDead(_25); // scope 25 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 } From b0a621e62c63e4e768b32f3668881ca9210183ec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 May 2023 10:52:26 +0200 Subject: [PATCH 33/34] 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 42687826b027..b450f9861496 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -0b795044c6f0854445f1f2bb6443e87848e150d1 +69fef92ab2f287f072b66fb7b4f62c8bb4acba43 From 74319707581d99ee6609622aa03f42136cf0c197 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 13 May 2023 10:55:42 +0200 Subject: [PATCH 34/34] fmt and fix lint --- src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs | 2 +- src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs index 064dbe025af9..a1e949183ad4 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs @@ -83,7 +83,7 @@ impl Stack { self.borrows.truncate(write_idx); #[cfg(not(feature = "stack-cache"))] - drop(first_removed); // This is only needed for the stack-cache + let _unused = first_removed; // This is only needed for the stack-cache #[cfg(feature = "stack-cache")] if let Some(first_removed) = first_removed { diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs index e4d9404c2ba5..443f481c0874 100644 --- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs @@ -1,7 +1,6 @@ //@error-in-other-file: memory is uninitialized at [0x4..0x8] //@normalize-stderr-test: "a[0-9]+" -> "ALLOC" #![feature(strict_provenance)] - #![allow(drop_copy)] // Test printing allocations that contain single-byte provenance.