mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
More descriptive argument placeholders
This commit is contained in:
parent
18b640aee5
commit
1256530643
@ -844,6 +844,12 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_id(|t| t.try_fold_with(folder))
|
||||
|
@ -76,16 +76,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
found: Ty<'tcx>,
|
||||
can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
|
||||
) -> bool {
|
||||
let Some((def_id_or_name, output, num_inputs)) = self.extract_callable_info(expr, found)
|
||||
let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(expr, found)
|
||||
else { return false; };
|
||||
if can_satisfy(output) {
|
||||
let (sugg_call, mut applicability) = match num_inputs {
|
||||
let (sugg_call, mut applicability) = match inputs.len() {
|
||||
0 => ("".to_string(), Applicability::MachineApplicable),
|
||||
1..=4 => (
|
||||
(0..num_inputs).map(|_| "_").collect::<Vec<_>>().join(", "),
|
||||
Applicability::MachineApplicable,
|
||||
inputs
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
if ty.is_suggestable(self.tcx, false) {
|
||||
format!("/* {ty} */")
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Applicability::HasPlaceholders,
|
||||
),
|
||||
_ => ("...".to_string(), Applicability::HasPlaceholders),
|
||||
_ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
|
||||
let msg = match def_id_or_name {
|
||||
@ -137,19 +147,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
expr: &Expr<'_>,
|
||||
found: Ty<'tcx>,
|
||||
) -> Option<(DefIdOrName, Ty<'tcx>, usize)> {
|
||||
) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
|
||||
// Autoderef is useful here because sometimes we box callables, etc.
|
||||
let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| {
|
||||
match *found.kind() {
|
||||
ty::FnPtr(fn_sig) =>
|
||||
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs().skip_binder().len())),
|
||||
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
|
||||
ty::FnDef(def_id, _) => {
|
||||
let fn_sig = found.fn_sig(self.tcx);
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().skip_binder().len()))
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
|
||||
}
|
||||
ty::Closure(def_id, substs) => {
|
||||
let fn_sig = substs.as_closure().sig();
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().skip_binder().len() - 1))
|
||||
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
|
||||
}
|
||||
ty::Opaque(def_id, substs) => {
|
||||
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
|
||||
@ -161,7 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
pred.kind().rebind(proj.term.ty().unwrap()),
|
||||
args.len(),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@ -178,7 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Some((
|
||||
DefIdOrName::Name("trait object"),
|
||||
pred.rebind(proj.term.ty().unwrap()),
|
||||
args.len(),
|
||||
pred.rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@ -197,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Some((
|
||||
DefIdOrName::DefId(def_id),
|
||||
pred.kind().rebind(proj.term.ty().unwrap()),
|
||||
args.len(),
|
||||
pred.kind().rebind(args.as_slice()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@ -209,6 +219,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}) else { return None; };
|
||||
|
||||
let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
|
||||
let inputs = inputs
|
||||
.skip_binder()
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
self.replace_bound_vars_with_fresh_vars(
|
||||
expr.span,
|
||||
infer::FnCall,
|
||||
inputs.rebind(*ty),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// We don't want to register any extra obligations, which should be
|
||||
// implied by wf, but also because that would possibly result in
|
||||
@ -228,23 +249,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
rhs_ty: Ty<'tcx>,
|
||||
can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
|
||||
) -> bool {
|
||||
let Some((_, lhs_output_ty, num_lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
|
||||
let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
|
||||
else { return false; };
|
||||
let Some((_, rhs_output_ty, num_rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
|
||||
let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
|
||||
else { return false; };
|
||||
|
||||
if can_satisfy(lhs_output_ty, rhs_output_ty) {
|
||||
let mut sugg = vec![];
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
||||
for (expr, num_inputs) in [(lhs_expr, num_lhs_inputs), (rhs_expr, num_rhs_inputs)] {
|
||||
let (sugg_call, this_applicability) = match num_inputs {
|
||||
for (expr, inputs) in [(lhs_expr, lhs_inputs), (rhs_expr, rhs_inputs)] {
|
||||
let (sugg_call, this_applicability) = match inputs.len() {
|
||||
0 => ("".to_string(), Applicability::MachineApplicable),
|
||||
1..=4 => (
|
||||
(0..num_inputs).map(|_| "_").collect::<Vec<_>>().join(", "),
|
||||
Applicability::MachineApplicable,
|
||||
inputs
|
||||
.iter()
|
||||
.map(|ty| {
|
||||
if ty.is_suggestable(self.tcx, false) {
|
||||
format!("/* {ty} */")
|
||||
} else {
|
||||
"/* value */".to_string()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
Applicability::HasPlaceholders,
|
||||
),
|
||||
_ => ("...".to_string(), Applicability::HasPlaceholders),
|
||||
_ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
|
||||
};
|
||||
|
||||
applicability = applicability.max(this_applicability);
|
||||
|
@ -8,8 +8,8 @@ LL | if foo == y {}
|
||||
|
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | if foo(_) == y {}
|
||||
| +++
|
||||
LL | if foo(/* &i32 */) == y {}
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,8 +10,8 @@ LL | let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
|
||||
found struct `Box<dyn FnOnce(isize)>`
|
||||
help: use parentheses to call this trait object
|
||||
|
|
||||
LL | let _: () = (Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>)(_);
|
||||
| + ++++
|
||||
LL | let _: () = (Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>)(/* isize */);
|
||||
| + ++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-trait-formatting.rs:10:17
|
||||
@ -25,8 +25,8 @@ LL | let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>
|
||||
found struct `Box<dyn Fn(isize, isize)>`
|
||||
help: use parentheses to call this trait object
|
||||
|
|
||||
LL | let _: () = (Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>)(_, _);
|
||||
| + +++++++
|
||||
LL | let _: () = (Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>)(/* isize */, /* isize */);
|
||||
| + +++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-trait-formatting.rs:14:17
|
||||
|
@ -13,8 +13,8 @@ LL | fn test() -> Foo { Foo }
|
||||
found fn item `fn(u32) -> Foo {Foo}`
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
|
|
||||
LL | fn test() -> Foo { Foo(_) }
|
||||
| +++
|
||||
LL | fn test() -> Foo { Foo(/* u32 */) }
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -30,8 +30,8 @@ LL | bar > 13;
|
||||
|
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | bar(_) > 13;
|
||||
| +++
|
||||
LL | bar(/* i64 */) > 13;
|
||||
| +++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-59488.rs:18:11
|
||||
|
@ -329,8 +329,8 @@ LL | let _: Z = Z::Fn;
|
||||
found fn item `fn(u8) -> Z {Z::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
|
|
||||
LL | let _: Z = Z::Fn(_);
|
||||
| +++
|
||||
LL | let _: Z = Z::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
|
||||
error[E0618]: expected function, found enum variant `Z::Unit`
|
||||
--> $DIR/privacy-enum-ctor.rs:31:17
|
||||
@ -364,8 +364,8 @@ LL | let _: E = m::E::Fn;
|
||||
found fn item `fn(u8) -> E {E::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
|
|
||||
LL | let _: E = m::E::Fn(_);
|
||||
| +++
|
||||
LL | let _: E = m::E::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
|
||||
error[E0618]: expected function, found enum variant `m::E::Unit`
|
||||
--> $DIR/privacy-enum-ctor.rs:47:16
|
||||
@ -399,8 +399,8 @@ LL | let _: E = E::Fn;
|
||||
found fn item `fn(u8) -> E {E::Fn}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
|
|
||||
LL | let _: E = E::Fn(_);
|
||||
| +++
|
||||
LL | let _: E = E::Fn(/* u8 */);
|
||||
| ++++++++++
|
||||
|
||||
error[E0618]: expected function, found enum variant `E::Unit`
|
||||
--> $DIR/privacy-enum-ctor.rs:55:16
|
||||
|
@ -33,8 +33,8 @@ LL | let _: usize = foo;
|
||||
found fn item `fn(usize, usize) -> usize {foo}`
|
||||
help: use parentheses to call this function
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ++++++
|
||||
LL | let _: usize = foo(/* usize */, /* usize */);
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:30:16
|
||||
@ -51,8 +51,8 @@ LL | let _: S = S;
|
||||
found fn item `fn(usize, usize) -> S {S}`
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ++++++
|
||||
LL | let _: S = S(/* usize */, /* usize */);
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:31:20
|
||||
@ -105,8 +105,8 @@ LL | let _: usize = T::baz;
|
||||
found fn item `fn(usize, usize) -> usize {<_ as T>::baz}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ++++++
|
||||
LL | let _: usize = T::baz(/* usize */, /* usize */);
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:34:20
|
||||
@ -123,8 +123,8 @@ LL | let _: usize = T::bat;
|
||||
found fn item `fn(usize) -> usize {<_ as T>::bat}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = T::bat(_);
|
||||
| +++
|
||||
LL | let _: usize = T::bat(/* usize */);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:35:16
|
||||
@ -141,8 +141,8 @@ LL | let _: E = E::A;
|
||||
found fn item `fn(usize) -> E {E::A}`
|
||||
help: use parentheses to instantiate this tuple variant
|
||||
|
|
||||
LL | let _: E = E::A(_);
|
||||
| +++
|
||||
LL | let _: E = E::A(/* usize */);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20
|
||||
@ -159,8 +159,8 @@ LL | let _: usize = X::baz;
|
||||
found fn item `fn(usize, usize) -> usize {<X as T>::baz}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::baz(_, _);
|
||||
| ++++++
|
||||
LL | let _: usize = X::baz(/* usize */, /* usize */);
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:38:20
|
||||
@ -177,8 +177,8 @@ LL | let _: usize = X::bat;
|
||||
found fn item `fn(usize) -> usize {<X as T>::bat}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::bat(_);
|
||||
| +++
|
||||
LL | let _: usize = X::bat(/* usize */);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:39:20
|
||||
@ -195,8 +195,8 @@ LL | let _: usize = X::bax;
|
||||
found fn item `fn(usize) -> usize {<X as T>::bax}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::bax(_);
|
||||
| +++
|
||||
LL | let _: usize = X::bax(/* usize */);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:40:20
|
||||
@ -213,8 +213,8 @@ LL | let _: usize = X::bach;
|
||||
found fn item `fn(usize) -> usize {<X as T>::bach}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::bach(_);
|
||||
| +++
|
||||
LL | let _: usize = X::bach(/* usize */);
|
||||
| +++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:41:20
|
||||
@ -231,8 +231,8 @@ LL | let _: usize = X::ban;
|
||||
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::ban}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::ban(_);
|
||||
| +++
|
||||
LL | let _: usize = X::ban(/* &X */);
|
||||
| ++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:42:20
|
||||
@ -249,8 +249,8 @@ LL | let _: usize = X::bal;
|
||||
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::bal}`
|
||||
help: use parentheses to call this associated function
|
||||
|
|
||||
LL | let _: usize = X::bal(_);
|
||||
| +++
|
||||
LL | let _: usize = X::bal(/* &X */);
|
||||
| ++++++++++
|
||||
|
||||
error[E0615]: attempted to take value of method `ban` on type `X`
|
||||
--> $DIR/fn-or-tuple-struct-without-args.rs:43:22
|
||||
|
@ -6,8 +6,8 @@ LL | thing.bar.0;
|
||||
|
|
||||
help: use parentheses to instantiate this tuple struct
|
||||
|
|
||||
LL | (thing.bar)(_, _).0;
|
||||
| + +++++++
|
||||
LL | (thing.bar)(/* char */, /* u16 */).0;
|
||||
| + ++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user