mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 17:33:07 +00:00
Point at closure args too
This commit is contained in:
parent
7bf47bfd32
commit
1549576732
@ -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");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,4 +22,7 @@ fn main() {
|
||||
missing(); //~ ERROR this function takes
|
||||
swapped("", 1); //~ ERROR arguments to this function are incorrect
|
||||
permuted(Y {}, Z {}, X {}); //~ ERROR arguments to this function are incorrect
|
||||
|
||||
let closure = |x| x;
|
||||
closure(); //~ ERROR this function takes
|
||||
}
|
||||
|
@ -81,7 +81,23 @@ help: reorder these arguments
|
||||
LL | permuted(X {}, Y {}, Z {});
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error[E0057]: this function takes 1 argument but 0 arguments were supplied
|
||||
--> $DIR/basic.rs:27:5
|
||||
|
|
||||
LL | closure();
|
||||
| ^^^^^^^-- an argument is missing
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/basic.rs:26:19
|
||||
|
|
||||
LL | let closure = |x| x;
|
||||
| ^^^
|
||||
help: provide the argument
|
||||
|
|
||||
LL | closure({_});
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
Some errors have detailed explanations: E0061, E0308.
|
||||
For more information about an error, try `rustc --explain E0061`.
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0057, E0061, E0308.
|
||||
For more information about an error, try `rustc --explain E0057`.
|
||||
|
@ -4,6 +4,11 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied
|
||||
LL | let a = f();
|
||||
| ^-- an argument is missing
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/E0057.rs:2:13
|
||||
|
|
||||
LL | let f = |x| x * 3;
|
||||
| ^^^
|
||||
help: provide the argument
|
||||
|
|
||||
LL | let a = f({_});
|
||||
@ -15,6 +20,11 @@ error[E0057]: this function takes 1 argument but 2 arguments were supplied
|
||||
LL | let c = f(2, 3);
|
||||
| ^ - argument unexpected
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/E0057.rs:2:13
|
||||
|
|
||||
LL | let f = |x| x * 3;
|
||||
| ^^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | let c = f(2);
|
||||
|
@ -8,6 +8,11 @@ LL | | let b = 1;
|
||||
LL | | });
|
||||
| |_____- argument unexpected
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/wrong_argument_ice-4.rs:2:6
|
||||
|
|
||||
LL | (|| {})(|| {
|
||||
| ^^
|
||||
help: remove the extra argument
|
||||
|
|
||||
LL | (|| {})();
|
||||
|
@ -6,6 +6,11 @@ LL | let z = f(1_usize, 2);
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: closure defined here
|
||||
--> $DIR/unboxed-closures-type-mismatch.rs:4:17
|
||||
|
|
||||
LL | let mut f = |x: isize, y: isize| -> isize { x + y };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: change the type of the numeric literal from `usize` to `isize`
|
||||
|
|
||||
LL | let z = f(1_isize, 2);
|
||||
|
Loading…
Reference in New Issue
Block a user