Point at closure args too
This commit is contained in:
parent
7bf47bfd32
commit
1549576732
7 changed files with 97 additions and 81 deletions
|
@ -59,7 +59,7 @@ pub fn check_legal_trait_for_method_call(
|
|||
|
||||
enum CallStep<'tcx> {
|
||||
Builtin(Ty<'tcx>),
|
||||
DeferredClosure(ty::FnSig<'tcx>),
|
||||
DeferredClosure(DefId, ty::FnSig<'tcx>),
|
||||
/// E.g., enum variant constructors.
|
||||
Overloaded(MethodCallee<'tcx>),
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected)
|
||||
}
|
||||
|
||||
Some(CallStep::DeferredClosure(fn_sig)) => {
|
||||
self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
|
||||
Some(CallStep::DeferredClosure(def_id, fn_sig)) => {
|
||||
self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, def_id, fn_sig)
|
||||
}
|
||||
|
||||
Some(CallStep::Overloaded(method_callee)) => {
|
||||
|
@ -171,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
closure_substs: substs,
|
||||
},
|
||||
);
|
||||
return Some(CallStep::DeferredClosure(closure_sig));
|
||||
return Some(CallStep::DeferredClosure(def_id, closure_sig));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,6 +533,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
call_expr: &'tcx hir::Expr<'tcx>,
|
||||
arg_exprs: &'tcx [hir::Expr<'tcx>],
|
||||
expected: Expectation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
fn_sig: ty::FnSig<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// `fn_sig` is the *signature* of the closure being called. We
|
||||
|
@ -555,7 +556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
arg_exprs,
|
||||
fn_sig.c_variadic,
|
||||
TupleArgumentsFlag::TupleArguments,
|
||||
None,
|
||||
Some(closure_def_id),
|
||||
);
|
||||
|
||||
fn_sig.output()
|
||||
|
|
|
@ -24,7 +24,7 @@ use rustc_infer::infer::TypeTrace;
|
|||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{self, Span};
|
||||
|
@ -523,24 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
format!("arguments to this {} are incorrect", call_name),
|
||||
);
|
||||
// Call out where the function is defined
|
||||
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.map(|id| tcx.hir().body(id).params)
|
||||
.flatten();
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, String::new());
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
}
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
err.emit();
|
||||
break 'errors;
|
||||
}
|
||||
|
@ -558,24 +541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
DiagnosticId::Error(err_code.to_owned()),
|
||||
);
|
||||
// Call out where the function is defined
|
||||
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.map(|id| tcx.hir().body(id).params)
|
||||
.flatten();
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, String::new());
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
}
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
err.multipart_suggestion(
|
||||
"use parentheses to construct a tuple",
|
||||
vec![(start, '('.to_string()), (end, ')'.to_string())],
|
||||
|
@ -613,24 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
format!("arguments to this {} are incorrect", call_name),
|
||||
);
|
||||
// Call out where the function is defined
|
||||
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.map(|id| tcx.hir().body(id).params)
|
||||
.flatten();
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, String::new());
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
}
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
err.emit();
|
||||
break 'errors;
|
||||
}
|
||||
|
@ -948,24 +897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Call out where the function is defined
|
||||
if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.flat_map(|id| tcx.hir().body(id).params)
|
||||
;
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, String::new());
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
}
|
||||
label_fn_like(tcx, &mut err, fn_def_id);
|
||||
|
||||
// And add a suggestion block for all of the parameters
|
||||
let suggestion_text = match suggestion_text {
|
||||
|
@ -1790,3 +1722,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn label_fn_like<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
err: &mut rustc_errors::DiagnosticBuilder<'tcx, rustc_errors::ErrorGuaranteed>,
|
||||
def_id: Option<DefId>,
|
||||
) {
|
||||
let Some(def_id) = def_id else {
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(def_span) = tcx.def_ident_span(def_id) {
|
||||
let mut spans: MultiSpan = def_span.into();
|
||||
|
||||
let params = tcx
|
||||
.hir()
|
||||
.get_if_local(def_id)
|
||||
.and_then(|node| node.body_id())
|
||||
.into_iter()
|
||||
.map(|id| tcx.hir().body(id).params)
|
||||
.flatten();
|
||||
|
||||
for param in params {
|
||||
spans.push_span_label(param.span, String::new());
|
||||
}
|
||||
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
|
||||
} else {
|
||||
match tcx.hir().get_if_local(def_id) {
|
||||
Some(hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Closure(_, _, _, span, ..),
|
||||
..
|
||||
})) => {
|
||||
let spans: MultiSpan = (*span).into();
|
||||
|
||||
// Note: We don't point to param spans here because they overlap
|
||||
// with the closure span itself
|
||||
|
||||
err.span_note(spans, "closure defined here");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue