move changes to an extra function
This commit is contained in:
parent
e326e8c885
commit
b1d7430657
1 changed files with 76 additions and 66 deletions
|
@ -1758,73 +1758,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
|
||||
self.note_conflicting_closure_bounds(cause, &mut err);
|
||||
|
||||
let found_args = match found.kind() {
|
||||
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
|
||||
kind => {
|
||||
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
};
|
||||
let expected_args = match expected.kind() {
|
||||
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
|
||||
kind => {
|
||||
span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(found_node) = found_node {
|
||||
let fn_decl = match found_node {
|
||||
Node::Expr(expr) => match &expr.kind {
|
||||
hir::ExprKind::Closure(hir::Closure { fn_decl, .. }) => fn_decl,
|
||||
kind => {
|
||||
span_bug!(found_span, "expression must be a closure but is {:?}", kind)
|
||||
}
|
||||
},
|
||||
Node::Item(item) => match &item.kind {
|
||||
hir::ItemKind::Fn(signature, _generics, _body) => signature.decl,
|
||||
kind => {
|
||||
span_bug!(found_span, "item must be a function but is {:?}", kind)
|
||||
}
|
||||
},
|
||||
node => {
|
||||
span_bug!(found_span, "node must be a expr or item but is {:?}", node)
|
||||
}
|
||||
};
|
||||
|
||||
let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
|
||||
|
||||
fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
|
||||
let mut refs = 0;
|
||||
|
||||
while let ty::Ref(_, new_ty, _) = ty.kind() {
|
||||
ty = *new_ty;
|
||||
refs += 1;
|
||||
}
|
||||
|
||||
(ty, refs)
|
||||
}
|
||||
|
||||
for ((found_arg, expected_arg), arg_span) in
|
||||
found_args.zip(expected_args).zip(arg_spans)
|
||||
{
|
||||
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 {
|
||||
let hint = if found_refs < expected_refs {
|
||||
"consider borrowing here:"
|
||||
} else if found_refs == expected_refs {
|
||||
continue;
|
||||
} else {
|
||||
"consider removing the borrow:"
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
arg_span,
|
||||
hint,
|
||||
expected_arg.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
hint_missing_borrow(span, found_span, found, expected, found_node, &mut err);
|
||||
}
|
||||
|
||||
err
|
||||
|
@ -3455,6 +3390,81 @@ 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>(
|
||||
span: Span,
|
||||
found_span: Span,
|
||||
found: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found_node: Node<'_>,
|
||||
err: &mut Diagnostic,
|
||||
) {
|
||||
let found_args = match found.kind() {
|
||||
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
|
||||
kind => {
|
||||
span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
};
|
||||
let expected_args = match expected.kind() {
|
||||
ty::FnPtr(f) => f.inputs().skip_binder().iter(),
|
||||
kind => {
|
||||
span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
|
||||
}
|
||||
};
|
||||
|
||||
let fn_decl = match found_node {
|
||||
Node::Expr(expr) => match &expr.kind {
|
||||
hir::ExprKind::Closure(hir::Closure { fn_decl, .. }) => fn_decl,
|
||||
kind => {
|
||||
span_bug!(found_span, "expression must be a closure but is {:?}", kind)
|
||||
}
|
||||
},
|
||||
Node::Item(item) => match &item.kind {
|
||||
hir::ItemKind::Fn(signature, _generics, _body) => signature.decl,
|
||||
kind => {
|
||||
span_bug!(found_span, "item must be a function but is {:?}", kind)
|
||||
}
|
||||
},
|
||||
node => {
|
||||
span_bug!(found_span, "node must be a expr or item but is {:?}", node)
|
||||
}
|
||||
};
|
||||
|
||||
let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span);
|
||||
|
||||
fn get_deref_type_and_refs<'tcx>(mut ty: Ty<'tcx>) -> (Ty<'tcx>, usize) {
|
||||
let mut refs = 0;
|
||||
|
||||
while let ty::Ref(_, new_ty, _) = ty.kind() {
|
||||
ty = *new_ty;
|
||||
refs += 1;
|
||||
}
|
||||
|
||||
(ty, refs)
|
||||
}
|
||||
|
||||
for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) {
|
||||
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 {
|
||||
let hint = if found_refs < expected_refs {
|
||||
"consider borrowing here:"
|
||||
} else if found_refs == expected_refs {
|
||||
continue;
|
||||
} else {
|
||||
"consider removing the borrow:"
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
arg_span,
|
||||
hint,
|
||||
expected_arg.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all the returned expressions within the input expression.
|
||||
/// Used to point at the return spans when we want to suggest some change to them.
|
||||
#[derive(Default)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue