parent
19423b5944
commit
33e11a3b2e
9 changed files with 127 additions and 47 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue