diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-01-20 07:25:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-20 07:25:28 +0100 |
| commit | 5f2ad80e183a629eac81f543cee9a1c054aae3fb (patch) | |
| tree | 905aea07204f944b7695cfeec0f59e55d509b366 /compiler | |
| parent | 720a9f1d9bd2d53beecb3eb847caf14f59bb219e (diff) | |
| parent | 33e11a3b2e2f2ee68fb2cb72e20f84c50c4c15cb (diff) | |
| download | rust-5f2ad80e183a629eac81f543cee9a1c054aae3fb.tar.gz rust-5f2ad80e183a629eac81f543cee9a1c054aae3fb.zip | |
Rollup merge of #106891 - estebank:issue-45727, r=petrochenkov
Tweak "borrow closure argument" suggestion Fix #45727.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 33 |
2 files changed, 26 insertions, 8 deletions
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 434f75de02b..52971486c55 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1350,6 +1350,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { expected_trait_ref, obligation.cause.code(), found_node, + obligation.param_env, ) } else { let (closure_span, closure_arg_span, found) = found_did 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 195bbe92f8b..39e50b2accf 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> { expected: ty::PolyTraitRef<'tcx>, cause: &ObligationCauseCode<'tcx>, found_node: Option<Node<'_>>, + param_env: ty::ParamEnv<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; fn note_conflicting_closure_bounds( @@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { expected: ty::PolyTraitRef<'tcx>, cause: &ObligationCauseCode<'tcx>, found_node: Option<Node<'_>>, + param_env: ty::ParamEnv<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { pub(crate) fn build_fn_sig_ty<'tcx>( infcx: &InferCtxt<'tcx>, @@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.note_conflicting_closure_bounds(cause, &mut err); if let Some(found_node) = found_node { - hint_missing_borrow(span, found, expected, found_node, &mut err); + hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err); } err @@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { /// Add a hint to add a missing borrow or remove an unnecessary one. fn hint_missing_borrow<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span, found: Ty<'tcx>, expected: Ty<'tcx>, @@ -3769,7 +3773,7 @@ fn hint_missing_borrow<'tcx>( // This could be a variant constructor, for example. let Some(fn_decl) = found_node.fn_decl() else { return; }; - let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span); + let args = fn_decl.inputs.iter().map(|ty| ty); fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { let mut refs = 0; @@ -3785,21 +3789,34 @@ fn hint_missing_borrow<'tcx>( let mut to_borrow = Vec::new(); let mut remove_borrow = Vec::new(); - for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) { + for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) { let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg); let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg); - if found_ty == expected_ty { + if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() { if found_refs < expected_refs { - to_borrow.push((arg_span, expected_arg.to_string())); + to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs))); } else if found_refs > expected_refs { - remove_borrow.push((arg_span, expected_arg.to_string())); + let mut span = arg.span.shrink_to_lo(); + let mut left = found_refs - expected_refs; + let mut ty = arg; + while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 { + span = span.with_hi(mut_ty.ty.span.lo()); + ty = mut_ty.ty; + left -= 1; + } + let sugg = if left == 0 { + (span, String::new()) + } else { + (arg.span, expected_arg.to_string()) + }; + remove_borrow.push(sugg); } } } if !to_borrow.is_empty() { - err.multipart_suggestion( + err.multipart_suggestion_verbose( "consider borrowing the argument", to_borrow, Applicability::MaybeIncorrect, @@ -3807,7 +3824,7 @@ fn hint_missing_borrow<'tcx>( } if !remove_borrow.is_empty() { - err.multipart_suggestion( + err.multipart_suggestion_verbose( "do not borrow the argument", remove_borrow, Applicability::MaybeIncorrect, |
