1
Fork 0

move changes to an extra function

This commit is contained in:
akida31 2022-10-11 16:20:52 +02:00
parent e326e8c885
commit b1d7430657
No known key found for this signature in database
GPG key ID: 02E1AF2C3D9FB7C9

View file

@ -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)]