Skip to content

Commit 1256530

Browse files
More descriptive argument placeholders
1 parent 18b640a commit 1256530

File tree

9 files changed

+96
-59
lines changed

9 files changed

+96
-59
lines changed

compiler/rustc_middle/src/ty/structural_impls.rs

+6
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,12 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
844844
}
845845
}
846846

847+
impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
848+
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
849+
self.iter().try_for_each(|t| t.visit_with(visitor))
850+
}
851+
}
852+
847853
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
848854
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
849855
self.try_map_id(|t| t.try_fold_with(folder))

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+50-19
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7676
found: Ty<'tcx>,
7777
can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
7878
) -> bool {
79-
let Some((def_id_or_name, output, num_inputs)) = self.extract_callable_info(expr, found)
79+
let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(expr, found)
8080
else { return false; };
8181
if can_satisfy(output) {
82-
let (sugg_call, mut applicability) = match num_inputs {
82+
let (sugg_call, mut applicability) = match inputs.len() {
8383
0 => ("".to_string(), Applicability::MachineApplicable),
8484
1..=4 => (
85-
(0..num_inputs).map(|_| "_").collect::<Vec<_>>().join(", "),
86-
Applicability::MachineApplicable,
85+
inputs
86+
.iter()
87+
.map(|ty| {
88+
if ty.is_suggestable(self.tcx, false) {
89+
format!("/* {ty} */")
90+
} else {
91+
"".to_string()
92+
}
93+
})
94+
.collect::<Vec<_>>()
95+
.join(", "),
96+
Applicability::HasPlaceholders,
8797
),
88-
_ => ("...".to_string(), Applicability::HasPlaceholders),
98+
_ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
8999
};
90100

91101
let msg = match def_id_or_name {
@@ -137,19 +147,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
137147
&self,
138148
expr: &Expr<'_>,
139149
found: Ty<'tcx>,
140-
) -> Option<(DefIdOrName, Ty<'tcx>, usize)> {
150+
) -> Option<(DefIdOrName, Ty<'tcx>, Vec<Ty<'tcx>>)> {
141151
// Autoderef is useful here because sometimes we box callables, etc.
142152
let Some((def_id_or_name, output, inputs)) = self.autoderef(expr.span, found).silence_errors().find_map(|(found, _)| {
143153
match *found.kind() {
144154
ty::FnPtr(fn_sig) =>
145-
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs().skip_binder().len())),
155+
Some((DefIdOrName::Name("function pointer"), fn_sig.output(), fn_sig.inputs())),
146156
ty::FnDef(def_id, _) => {
147157
let fn_sig = found.fn_sig(self.tcx);
148-
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().skip_binder().len()))
158+
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
149159
}
150160
ty::Closure(def_id, substs) => {
151161
let fn_sig = substs.as_closure().sig();
152-
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().skip_binder().len() - 1))
162+
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..])))
153163
}
154164
ty::Opaque(def_id, substs) => {
155165
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> {
161171
Some((
162172
DefIdOrName::DefId(def_id),
163173
pred.kind().rebind(proj.term.ty().unwrap()),
164-
args.len(),
174+
pred.kind().rebind(args.as_slice()),
165175
))
166176
} else {
167177
None
@@ -178,7 +188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
178188
Some((
179189
DefIdOrName::Name("trait object"),
180190
pred.rebind(proj.term.ty().unwrap()),
181-
args.len(),
191+
pred.rebind(args.as_slice()),
182192
))
183193
} else {
184194
None
@@ -197,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
197207
Some((
198208
DefIdOrName::DefId(def_id),
199209
pred.kind().rebind(proj.term.ty().unwrap()),
200-
args.len(),
210+
pred.kind().rebind(args.as_slice()),
201211
))
202212
} else {
203213
None
@@ -209,6 +219,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
209219
}) else { return None; };
210220

211221
let output = self.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, output);
222+
let inputs = inputs
223+
.skip_binder()
224+
.iter()
225+
.map(|ty| {
226+
self.replace_bound_vars_with_fresh_vars(
227+
expr.span,
228+
infer::FnCall,
229+
inputs.rebind(*ty),
230+
)
231+
})
232+
.collect();
212233

213234
// We don't want to register any extra obligations, which should be
214235
// implied by wf, but also because that would possibly result in
@@ -228,23 +249,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
228249
rhs_ty: Ty<'tcx>,
229250
can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
230251
) -> bool {
231-
let Some((_, lhs_output_ty, num_lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
252+
let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_expr, lhs_ty)
232253
else { return false; };
233-
let Some((_, rhs_output_ty, num_rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
254+
let Some((_, rhs_output_ty, rhs_inputs)) = self.extract_callable_info(rhs_expr, rhs_ty)
234255
else { return false; };
235256

236257
if can_satisfy(lhs_output_ty, rhs_output_ty) {
237258
let mut sugg = vec![];
238259
let mut applicability = Applicability::MachineApplicable;
239260

240-
for (expr, num_inputs) in [(lhs_expr, num_lhs_inputs), (rhs_expr, num_rhs_inputs)] {
241-
let (sugg_call, this_applicability) = match num_inputs {
261+
for (expr, inputs) in [(lhs_expr, lhs_inputs), (rhs_expr, rhs_inputs)] {
262+
let (sugg_call, this_applicability) = match inputs.len() {
242263
0 => ("".to_string(), Applicability::MachineApplicable),
243264
1..=4 => (
244-
(0..num_inputs).map(|_| "_").collect::<Vec<_>>().join(", "),
245-
Applicability::MachineApplicable,
265+
inputs
266+
.iter()
267+
.map(|ty| {
268+
if ty.is_suggestable(self.tcx, false) {
269+
format!("/* {ty} */")
270+
} else {
271+
"/* value */".to_string()
272+
}
273+
})
274+
.collect::<Vec<_>>()
275+
.join(", "),
276+
Applicability::HasPlaceholders,
246277
),
247-
_ => ("...".to_string(), Applicability::HasPlaceholders),
278+
_ => ("/* ... */".to_string(), Applicability::HasPlaceholders),
248279
};
249280

250281
applicability = applicability.max(this_applicability);

src/test/ui/binop/issue-77910-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ LL | if foo == y {}
88
|
99
help: use parentheses to call this function
1010
|
11-
LL | if foo(_) == y {}
12-
| +++
11+
LL | if foo(/* &i32 */) == y {}
12+
| ++++++++++++
1313

1414
error: aborting due to previous error
1515

src/test/ui/fn/fn-trait-formatting.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ LL | let _: () = Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>;
1010
found struct `Box<dyn FnOnce(isize)>`
1111
help: use parentheses to call this trait object
1212
|
13-
LL | let _: () = (Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>)(_);
14-
| + ++++
13+
LL | let _: () = (Box::new(|_: isize| {}) as Box<dyn FnOnce(isize)>)(/* isize */);
14+
| + ++++++++++++++
1515

1616
error[E0308]: mismatched types
1717
--> $DIR/fn-trait-formatting.rs:10:17
@@ -25,8 +25,8 @@ LL | let _: () = Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>
2525
found struct `Box<dyn Fn(isize, isize)>`
2626
help: use parentheses to call this trait object
2727
|
28-
LL | let _: () = (Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>)(_, _);
29-
| + +++++++
28+
LL | let _: () = (Box::new(|_: isize, isize| {}) as Box<dyn Fn(isize, isize)>)(/* isize */, /* isize */);
29+
| + +++++++++++++++++++++++++++
3030

3131
error[E0308]: mismatched types
3232
--> $DIR/fn-trait-formatting.rs:14:17

src/test/ui/issues/issue-35241.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ LL | fn test() -> Foo { Foo }
1313
found fn item `fn(u32) -> Foo {Foo}`
1414
help: use parentheses to instantiate this tuple struct
1515
|
16-
LL | fn test() -> Foo { Foo(_) }
17-
| +++
16+
LL | fn test() -> Foo { Foo(/* u32 */) }
17+
| +++++++++++
1818

1919
error: aborting due to previous error
2020

src/test/ui/issues/issue-59488.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ LL | bar > 13;
3030
|
3131
help: use parentheses to call this function
3232
|
33-
LL | bar(_) > 13;
34-
| +++
33+
LL | bar(/* i64 */) > 13;
34+
| +++++++++++
3535

3636
error[E0308]: mismatched types
3737
--> $DIR/issue-59488.rs:18:11

src/test/ui/resolve/privacy-enum-ctor.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,8 @@ LL | let _: Z = Z::Fn;
329329
found fn item `fn(u8) -> Z {Z::Fn}`
330330
help: use parentheses to instantiate this tuple variant
331331
|
332-
LL | let _: Z = Z::Fn(_);
333-
| +++
332+
LL | let _: Z = Z::Fn(/* u8 */);
333+
| ++++++++++
334334

335335
error[E0618]: expected function, found enum variant `Z::Unit`
336336
--> $DIR/privacy-enum-ctor.rs:31:17
@@ -364,8 +364,8 @@ LL | let _: E = m::E::Fn;
364364
found fn item `fn(u8) -> E {E::Fn}`
365365
help: use parentheses to instantiate this tuple variant
366366
|
367-
LL | let _: E = m::E::Fn(_);
368-
| +++
367+
LL | let _: E = m::E::Fn(/* u8 */);
368+
| ++++++++++
369369

370370
error[E0618]: expected function, found enum variant `m::E::Unit`
371371
--> $DIR/privacy-enum-ctor.rs:47:16
@@ -399,8 +399,8 @@ LL | let _: E = E::Fn;
399399
found fn item `fn(u8) -> E {E::Fn}`
400400
help: use parentheses to instantiate this tuple variant
401401
|
402-
LL | let _: E = E::Fn(_);
403-
| +++
402+
LL | let _: E = E::Fn(/* u8 */);
403+
| ++++++++++
404404

405405
error[E0618]: expected function, found enum variant `E::Unit`
406406
--> $DIR/privacy-enum-ctor.rs:55:16

src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr

+22-22
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ LL | let _: usize = foo;
3333
found fn item `fn(usize, usize) -> usize {foo}`
3434
help: use parentheses to call this function
3535
|
36-
LL | let _: usize = foo(_, _);
37-
| ++++++
36+
LL | let _: usize = foo(/* usize */, /* usize */);
37+
| ++++++++++++++++++++++++++
3838

3939
error[E0308]: mismatched types
4040
--> $DIR/fn-or-tuple-struct-without-args.rs:30:16
@@ -51,8 +51,8 @@ LL | let _: S = S;
5151
found fn item `fn(usize, usize) -> S {S}`
5252
help: use parentheses to instantiate this tuple struct
5353
|
54-
LL | let _: S = S(_, _);
55-
| ++++++
54+
LL | let _: S = S(/* usize */, /* usize */);
55+
| ++++++++++++++++++++++++++
5656

5757
error[E0308]: mismatched types
5858
--> $DIR/fn-or-tuple-struct-without-args.rs:31:20
@@ -105,8 +105,8 @@ LL | let _: usize = T::baz;
105105
found fn item `fn(usize, usize) -> usize {<_ as T>::baz}`
106106
help: use parentheses to call this associated function
107107
|
108-
LL | let _: usize = T::baz(_, _);
109-
| ++++++
108+
LL | let _: usize = T::baz(/* usize */, /* usize */);
109+
| ++++++++++++++++++++++++++
110110

111111
error[E0308]: mismatched types
112112
--> $DIR/fn-or-tuple-struct-without-args.rs:34:20
@@ -123,8 +123,8 @@ LL | let _: usize = T::bat;
123123
found fn item `fn(usize) -> usize {<_ as T>::bat}`
124124
help: use parentheses to call this associated function
125125
|
126-
LL | let _: usize = T::bat(_);
127-
| +++
126+
LL | let _: usize = T::bat(/* usize */);
127+
| +++++++++++++
128128

129129
error[E0308]: mismatched types
130130
--> $DIR/fn-or-tuple-struct-without-args.rs:35:16
@@ -141,8 +141,8 @@ LL | let _: E = E::A;
141141
found fn item `fn(usize) -> E {E::A}`
142142
help: use parentheses to instantiate this tuple variant
143143
|
144-
LL | let _: E = E::A(_);
145-
| +++
144+
LL | let _: E = E::A(/* usize */);
145+
| +++++++++++++
146146

147147
error[E0308]: mismatched types
148148
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20
@@ -159,8 +159,8 @@ LL | let _: usize = X::baz;
159159
found fn item `fn(usize, usize) -> usize {<X as T>::baz}`
160160
help: use parentheses to call this associated function
161161
|
162-
LL | let _: usize = X::baz(_, _);
163-
| ++++++
162+
LL | let _: usize = X::baz(/* usize */, /* usize */);
163+
| ++++++++++++++++++++++++++
164164

165165
error[E0308]: mismatched types
166166
--> $DIR/fn-or-tuple-struct-without-args.rs:38:20
@@ -177,8 +177,8 @@ LL | let _: usize = X::bat;
177177
found fn item `fn(usize) -> usize {<X as T>::bat}`
178178
help: use parentheses to call this associated function
179179
|
180-
LL | let _: usize = X::bat(_);
181-
| +++
180+
LL | let _: usize = X::bat(/* usize */);
181+
| +++++++++++++
182182

183183
error[E0308]: mismatched types
184184
--> $DIR/fn-or-tuple-struct-without-args.rs:39:20
@@ -195,8 +195,8 @@ LL | let _: usize = X::bax;
195195
found fn item `fn(usize) -> usize {<X as T>::bax}`
196196
help: use parentheses to call this associated function
197197
|
198-
LL | let _: usize = X::bax(_);
199-
| +++
198+
LL | let _: usize = X::bax(/* usize */);
199+
| +++++++++++++
200200

201201
error[E0308]: mismatched types
202202
--> $DIR/fn-or-tuple-struct-without-args.rs:40:20
@@ -213,8 +213,8 @@ LL | let _: usize = X::bach;
213213
found fn item `fn(usize) -> usize {<X as T>::bach}`
214214
help: use parentheses to call this associated function
215215
|
216-
LL | let _: usize = X::bach(_);
217-
| +++
216+
LL | let _: usize = X::bach(/* usize */);
217+
| +++++++++++++
218218

219219
error[E0308]: mismatched types
220220
--> $DIR/fn-or-tuple-struct-without-args.rs:41:20
@@ -231,8 +231,8 @@ LL | let _: usize = X::ban;
231231
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::ban}`
232232
help: use parentheses to call this associated function
233233
|
234-
LL | let _: usize = X::ban(_);
235-
| +++
234+
LL | let _: usize = X::ban(/* &X */);
235+
| ++++++++++
236236

237237
error[E0308]: mismatched types
238238
--> $DIR/fn-or-tuple-struct-without-args.rs:42:20
@@ -249,8 +249,8 @@ LL | let _: usize = X::bal;
249249
found fn item `for<'r> fn(&'r X) -> usize {<X as T>::bal}`
250250
help: use parentheses to call this associated function
251251
|
252-
LL | let _: usize = X::bal(_);
253-
| +++
252+
LL | let _: usize = X::bal(/* &X */);
253+
| ++++++++++
254254

255255
error[E0615]: attempted to take value of method `ban` on type `X`
256256
--> $DIR/fn-or-tuple-struct-without-args.rs:43:22

src/test/ui/typeck/issue-87181/tuple-field.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ LL | thing.bar.0;
66
|
77
help: use parentheses to instantiate this tuple struct
88
|
9-
LL | (thing.bar)(_, _).0;
10-
| + +++++++
9+
LL | (thing.bar)(/* char */, /* u16 */).0;
10+
| + ++++++++++++++++++++++++
1111

1212
error: aborting due to previous error
1313

0 commit comments

Comments
 (0)