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 418eae9b0e8d..4561ab0bfe40 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -671,11 +671,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { trait_pred: ty::PolyTraitPredicate<'tcx>, ) -> bool { // It only make sense when suggesting dereferences for arguments - let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { - return false; - }; - let param_env = obligation.param_env; - let body_id = obligation.cause.body_id; + let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() + else { return false; }; + let Some(typeck_results) = self.in_progress_typeck_results + else { return false; }; + let typeck_results = typeck_results.borrow(); + let hir::Node::Expr(expr) = self.tcx.hir().get(*arg_hir_id) + else { return false; }; + let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr) + else { return false; }; + let span = obligation.cause.span; let mut real_trait_pred = trait_pred; let mut code = obligation.cause.code(); @@ -687,9 +692,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Skipping binder here, remapping below let real_ty = real_trait_pred.self_ty().skip_binder(); + if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() { + continue; + } if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { - let mut autoderef = Autoderef::new(self, param_env, body_id, span, base_ty, span); + let mut autoderef = Autoderef::new( + self, + obligation.param_env, + obligation.cause.body_id, + span, + base_ty, + span, + ); if let Some(steps) = autoderef.find_map(|(ty, steps)| { // Re-add the `&` let ty = self.tcx.mk_ref(region, TypeAndMut { ty, mutbl }); @@ -697,8 +712,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Remapping bound vars here let real_trait_pred_and_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, ty)); - let obligation = self - .mk_trait_obligation_with_new_self_ty(param_env, real_trait_pred_and_ty); + let obligation = self.mk_trait_obligation_with_new_self_ty( + obligation.param_env, + real_trait_pred_and_ty, + ); Some(steps).filter(|_| self.predicate_may_hold(&obligation)) }) { if steps > 0 { @@ -727,7 +744,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let real_trait_pred_and_base_ty = real_trait_pred.map_bound(|inner_trait_pred| (inner_trait_pred, base_ty)); let obligation = self.mk_trait_obligation_with_new_self_ty( - param_env, + obligation.param_env, real_trait_pred_and_base_ty, ); if self.predicate_may_hold(&obligation) { @@ -855,6 +872,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => return false, }; if matches!(obligation.cause.code(), ObligationCauseCode::FunctionArgumentObligation { .. }) + && obligation.cause.span.can_be_used_for_suggestions() { // When the obligation error has been ensured to have been caused by // an argument, the `obligation.cause.span` points at the expression diff --git a/src/test/ui/binop/issue-77910-1.stderr b/src/test/ui/binop/issue-77910-1.stderr index 7ff5752fc358..68303b842088 100644 --- a/src/test/ui/binop/issue-77910-1.stderr +++ b/src/test/ui/binop/issue-77910-1.stderr @@ -19,12 +19,8 @@ LL | assert_eq!(foo, y); | ^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r i32) -> &'r i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `for<'r> fn(&'r i32) -> &'r i32 {foo}` + = help: use parentheses to call the function: `foo(s)` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use parentheses to call the function - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $crate::panicking::assert_failed(kind, &*left_val(s), &*right_val, $crate::option::Option::None); - | +++ error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr index 7b9f59fcc67d..a2ca06b4e6e1 100644 --- a/src/test/ui/closures/closure-move-sync.stderr +++ b/src/test/ui/closures/closure-move-sync.stderr @@ -22,10 +22,6 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` -help: consider dereferencing here - | -LL | let t = thread::spawn(*|| { - | + error[E0277]: `Sender<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:18:19 @@ -47,10 +43,6 @@ note: required by a bound in `spawn` | LL | F: Send + 'static, | ^^^^ required by this bound in `spawn` -help: consider dereferencing here - | -LL | thread::spawn(*|| tx.send(()).unwrap()); - | + error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 97dbaf73ade6..a821c57b923a 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -23,10 +23,6 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` -help: consider dereferencing here - | -LL | assert_send(*|| { - | + error: generator cannot be shared between threads safely --> $DIR/not-send-sync.rs:9:17 diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr index 14e058189781..909e49c38b8d 100644 --- a/src/test/ui/generator/print/generator-print-verbose-2.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -23,10 +23,6 @@ note: required by a bound in `assert_send` | LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` -help: consider dereferencing here - | -LL | assert_send(*|| { - | + error: generator cannot be shared between threads safely --> $DIR/generator-print-verbose-2.rs:12:17 diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index ee476e7aa384..94f41c925988 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -19,10 +19,6 @@ note: required by a bound in `catch_unwind` | LL | pub fn catch_unwind R + UnwindSafe, R>(f: F) -> Result { | ^^^^^^^^^^ required by this bound in `catch_unwind` -help: consider dereferencing here - | -LL | catch_unwind(*|| { x.set(23); }); - | + error: aborting due to previous error diff --git a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr index b834920b0d04..c6e6ea1e096a 100644 --- a/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr +++ b/src/test/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr @@ -34,12 +34,8 @@ LL | assert_eq!(a, 0); | ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `fn() -> i32 {a}` + = help: use parentheses to call the function: `a()` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: use parentheses to call the function - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $crate::panicking::assert_failed(kind, &*left_val(), &*right_val, $crate::option::Option::None); - | ++ error: aborting due to 3 previous errors