diff options
| author | Jubilee <workingjubilee@gmail.com> | 2024-09-26 22:20:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-26 22:20:56 -0700 |
| commit | 6b0c897499202997f84ee71860c3f974aeed7ba8 (patch) | |
| tree | e9de311ec30335fd1d04b996014af93ae81a40dc /compiler/rustc_trait_selection/src | |
| parent | 081b9469d8565c2fc6f76b0a853000683e7840d4 (diff) | |
| parent | c48b0d4eb404f856f8bf1d305818ce21cc125fc5 (diff) | |
| download | rust-6b0c897499202997f84ee71860c3f974aeed7ba8.tar.gz rust-6b0c897499202997f84ee71860c3f974aeed7ba8.zip | |
Rollup merge of #130911 - notriddle:notriddle/suggest-wrap-parens-fn-pointer, r=compiler-errors
diagnostics: wrap fn cast suggestions in parens when needed Fixes #121632
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 969f2528836..9cd2b1e7bfb 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -33,7 +33,8 @@ use tracing::{debug, instrument}; use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote}; use super::suggestions::get_explanation_based_on_obligation; use super::{ - ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate, UnsatisfiedConst, + ArgKind, CandidateSimilarity, FindExprBySpan, GetSafeTransmuteErrorAndReason, ImplCandidate, + UnsatisfiedConst, }; use crate::error_reporting::TypeErrCtxt; use crate::error_reporting::infer::TyCategory; @@ -378,14 +379,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if let (ty::FnPtr(..), ty::FnDef(..)) = (cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind()) { - err.span_suggestion( - span.shrink_to_hi(), + // Wrap method receivers and `&`-references in parens + let suggestion = if self.tcx.sess.source_map().span_look_ahead(span, ".", Some(50)).is_some() { + vec![ + (span.shrink_to_lo(), format!("(")), + (span.shrink_to_hi(), format!(" as {})", cand.self_ty())), + ] + } else if let Some(body) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { + let mut expr_finder = FindExprBySpan::new(span, self.tcx); + expr_finder.visit_expr(body.value); + if let Some(expr) = expr_finder.result && + let hir::ExprKind::AddrOf(_, _, expr) = expr.kind { + vec![ + (expr.span.shrink_to_lo(), format!("(")), + (expr.span.shrink_to_hi(), format!(" as {})", cand.self_ty())), + ] + } else { + vec![(span.shrink_to_hi(), format!(" as {}", cand.self_ty()))] + } + } else { + vec![(span.shrink_to_hi(), format!(" as {}", cand.self_ty()))] + }; + err.multipart_suggestion( format!( "the trait `{}` is implemented for fn pointer `{}`, try casting using `as`", cand.print_trait_sugared(), cand.self_ty(), ), - format!(" as {}", cand.self_ty()), + suggestion, Applicability::MaybeIncorrect, ); true |
