about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-08-28 01:22:51 +0000
committerMichael Goulet <michael@errs.io>2022-08-28 01:24:41 +0000
commit1256530643fdd4762de8de5a47041fc2cf700828 (patch)
tree1a66235680f0f5e882c55c021d95923ae0001ba5
parent18b640aee5b5435491a9db82c08c8fde8b7b62c9 (diff)
downloadrust-1256530643fdd4762de8de5a47041fc2cf700828.tar.gz
rust-1256530643fdd4762de8de5a47041fc2cf700828.zip
More descriptive argument placeholders
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs6
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs69
-rw-r--r--src/test/ui/binop/issue-77910-2.stderr4
-rw-r--r--src/test/ui/fn/fn-trait-formatting.stderr8
-rw-r--r--src/test/ui/issues/issue-35241.stderr4
-rw-r--r--src/test/ui/issues/issue-59488.stderr4
-rw-r--r--src/test/ui/resolve/privacy-enum-ctor.stderr12
-rw-r--r--src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr44
-rw-r--r--src/test/ui/typeck/issue-87181/tuple-field.stderr4
9 files changed, 96 insertions, 59 deletions
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 7660a2f3af6..57555433f55 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -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))
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 96901b53303..d48bdbd7b6d 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -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);
diff --git a/src/test/ui/binop/issue-77910-2.stderr b/src/test/ui/binop/issue-77910-2.stderr
index 74860a93f37..a334bd85625 100644
--- a/src/test/ui/binop/issue-77910-2.stderr
+++ b/src/test/ui/binop/issue-77910-2.stderr
@@ -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
 
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
index 1d5e0a859a6..2a674d3c1d2 100644
--- a/src/test/ui/fn/fn-trait-formatting.stderr
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -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
diff --git a/src/test/ui/issues/issue-35241.stderr b/src/test/ui/issues/issue-35241.stderr
index a66289a1cf8..9ee7654a088 100644
--- a/src/test/ui/issues/issue-35241.stderr
+++ b/src/test/ui/issues/issue-35241.stderr
@@ -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
 
diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr
index df681eb2489..e5368ddf1e5 100644
--- a/src/test/ui/issues/issue-59488.stderr
+++ b/src/test/ui/issues/issue-59488.stderr
@@ -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
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index f885ac2151d..7cf32775a33 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -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
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index ba710bfa746..3c7b895e337 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -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
diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr
index 0e43ace8933..c1ca26ee9af 100644
--- a/src/test/ui/typeck/issue-87181/tuple-field.stderr
+++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr
@@ -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