Split out the error reporting logic into a separate function
This commit is contained in:
parent
c5bbf36a31
commit
aa3fbf8795
1 changed files with 140 additions and 134 deletions
|
@ -394,6 +394,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ty::FnPtr(sig) => (sig, None),
|
ty::FnPtr(sig) => (sig, None),
|
||||||
_ => {
|
_ => {
|
||||||
|
self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs);
|
||||||
|
|
||||||
|
// This is the "default" function signature, used in case of error.
|
||||||
|
// In that case, we check each argument against "error" in order to
|
||||||
|
// set up all the node type bindings.
|
||||||
|
(
|
||||||
|
ty::Binder::dummy(self.tcx.mk_fn_sig(
|
||||||
|
self.err_args(arg_exprs.len()).into_iter(),
|
||||||
|
self.tcx.ty_error(),
|
||||||
|
false,
|
||||||
|
hir::Unsafety::Normal,
|
||||||
|
abi::Abi::Rust,
|
||||||
|
)),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Replace any late-bound regions that appear in the function
|
||||||
|
// signature with region variables. We also have to
|
||||||
|
// renormalize the associated types at this point, since they
|
||||||
|
// previously appeared within a `Binder<>` and hence would not
|
||||||
|
// have been normalized before.
|
||||||
|
let fn_sig = self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig);
|
||||||
|
let fn_sig = self.normalize_associated_types_in(call_expr.span, fn_sig);
|
||||||
|
|
||||||
|
// Call the generic checker.
|
||||||
|
let expected_arg_tys = self.expected_inputs_for_expected_output(
|
||||||
|
call_expr.span,
|
||||||
|
expected,
|
||||||
|
fn_sig.output(),
|
||||||
|
fn_sig.inputs(),
|
||||||
|
);
|
||||||
|
self.check_argument_types(
|
||||||
|
call_expr.span,
|
||||||
|
call_expr,
|
||||||
|
fn_sig.inputs(),
|
||||||
|
expected_arg_tys,
|
||||||
|
arg_exprs,
|
||||||
|
fn_sig.c_variadic,
|
||||||
|
TupleArgumentsFlag::DontTupleArguments,
|
||||||
|
def_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn_sig.output()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_invalid_callee(
|
||||||
|
&self,
|
||||||
|
call_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
callee_expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
callee_ty: Ty<'tcx>,
|
||||||
|
arg_exprs: &'tcx [hir::Expr<'tcx>],
|
||||||
|
) {
|
||||||
let mut unit_variant = None;
|
let mut unit_variant = None;
|
||||||
if let hir::ExprKind::Path(qpath) = &callee_expr.kind
|
if let hir::ExprKind::Path(qpath) = &callee_expr.kind
|
||||||
&& let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
|
&& let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _)
|
||||||
|
@ -451,8 +505,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// If the call spans more than one line and the callee kind is
|
// If the call spans more than one line and the callee kind is
|
||||||
// itself another `ExprCall`, that's a clue that we might just be
|
// itself another `ExprCall`, that's a clue that we might just be
|
||||||
// missing a semicolon (Issue #51055)
|
// missing a semicolon (Issue #51055)
|
||||||
let call_is_multiline =
|
let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span);
|
||||||
self.tcx.sess.source_map().is_multiline(call_expr.span);
|
|
||||||
if call_is_multiline {
|
if call_is_multiline {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
callee_expr.span.shrink_to_hi(),
|
callee_expr.span.shrink_to_hi(),
|
||||||
|
@ -514,10 +567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
callee_ty
|
callee_ty
|
||||||
)),
|
)),
|
||||||
Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
|
Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
|
||||||
Some(format!(
|
Some(format!("`{}` defined here", self.tcx.def_path_str(def_id),))
|
||||||
"`{}` defined here",
|
|
||||||
self.tcx.def_path_str(def_id),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
_ => Some(format!("`{callee_ty}` defined here")),
|
_ => Some(format!("`{callee_ty}` defined here")),
|
||||||
}
|
}
|
||||||
|
@ -528,50 +578,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
|
|
||||||
// This is the "default" function signature, used in case of error.
|
|
||||||
// In that case, we check each argument against "error" in order to
|
|
||||||
// set up all the node type bindings.
|
|
||||||
(
|
|
||||||
ty::Binder::dummy(self.tcx.mk_fn_sig(
|
|
||||||
self.err_args(arg_exprs.len()).into_iter(),
|
|
||||||
self.tcx.ty_error(),
|
|
||||||
false,
|
|
||||||
hir::Unsafety::Normal,
|
|
||||||
abi::Abi::Rust,
|
|
||||||
)),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Replace any late-bound regions that appear in the function
|
|
||||||
// signature with region variables. We also have to
|
|
||||||
// renormalize the associated types at this point, since they
|
|
||||||
// previously appeared within a `Binder<>` and hence would not
|
|
||||||
// have been normalized before.
|
|
||||||
let fn_sig = self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig);
|
|
||||||
let fn_sig = self.normalize_associated_types_in(call_expr.span, fn_sig);
|
|
||||||
|
|
||||||
// Call the generic checker.
|
|
||||||
let expected_arg_tys = self.expected_inputs_for_expected_output(
|
|
||||||
call_expr.span,
|
|
||||||
expected,
|
|
||||||
fn_sig.output(),
|
|
||||||
fn_sig.inputs(),
|
|
||||||
);
|
|
||||||
self.check_argument_types(
|
|
||||||
call_expr.span,
|
|
||||||
call_expr,
|
|
||||||
fn_sig.inputs(),
|
|
||||||
expected_arg_tys,
|
|
||||||
arg_exprs,
|
|
||||||
fn_sig.c_variadic,
|
|
||||||
TupleArgumentsFlag::DontTupleArguments,
|
|
||||||
def_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
fn_sig.output()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_deferred_closure_call(
|
fn confirm_deferred_closure_call(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue