]> git.lizzy.rs Git - rust.git/commitdiff
When suggesting fn call use an appropriate number of placeholder arguments
authorEsteban Küber <esteban@kuber.com.ar>
Thu, 8 Aug 2019 19:01:22 +0000 (12:01 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Fri, 9 Aug 2019 14:18:05 +0000 (07:18 -0700)
src/librustc_typeck/check/mod.rs
src/test/ui/issues/issue-35241.stderr
src/test/ui/resolve/privacy-enum-ctor.stderr
src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs [new file with mode: 0644]
src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr [new file with mode: 0644]

index 6600f83393857f55084bb3640a81a3f433dd16bb..130cc8f3a60509b9c8287eccc018ed0f038c9d19 100644 (file)
@@ -3833,19 +3833,38 @@ fn suggest_fn_call(
                 .0;
             let sig = self.normalize_associated_types_in(expr.span, &sig);
             if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
-                if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
-                    err.span_suggestion(expr.span, "use parentheses to call this function", format!(
-                        "{}({})",
-                        code,
-                        if sig.inputs().len() > 0 {
-                            "..."
-                        } else {
-                            ""
-                        }), if sig.inputs().len() > 0 {
-                            Applicability::MachineApplicable
-                        } else {
-                            Applicability::HasPlaceholders
+                let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
+                    (String::new(), Applicability::MachineApplicable)
+                } else {
+                    ("...".to_owned(), Applicability::HasPlaceholders)
+                };
+                let mut msg = "call this function";
+                if let ty::FnDef(def_id, ..) = found.sty {
+                    match self.tcx.hir().get_if_local(def_id) {
+                        Some(Node::Item(hir::Item {
+                            node: ItemKind::Fn(.., body_id),
+                            ..
+                        })) => {
+                            let body = self.tcx.hir().body(*body_id);
+                            sugg_call = body.arguments.iter()
+                                .map(|arg| hir::print::to_string(
+                                    hir::print::NO_ANN,
+                                    |s| s.print_pat(&arg.pat),
+                                )).collect::<Vec<_>>().join(", ");
+                        }
+                        Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
+                            sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
+                            msg = "instatiate this tuple struct";
                         }
+                        _ => {}
+                    }
+                };
+                if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
+                    err.span_suggestion(
+                        expr.span,
+                        &format!("use parentheses to {}", msg),
+                        format!("{}({})", code, sugg_call),
+                        applicability,
                     );
                     return true;
                 }
index 248e6f0f46b19f90549185f50b8e7bd553a06e0d..8befc6873857ee011b12fa179851c7f380c6fa42 100644 (file)
@@ -8,7 +8,7 @@ LL | fn test() -> Foo { Foo }
    |              ---   ^^^
    |              |     |
    |              |     expected struct `Foo`, found fn item
-   |              |     help: use parentheses to call this function: `Foo(...)`
+   |              |     help: use parentheses to instatiate this tuple struct: `Foo(_)`
    |              expected `Foo` because of return type
    |
    = note: expected type `Foo`
index 07cbffb009406fe4810a4dca49656ffb2beabeec..49092562feebaf67f0d1e4a9725629e473c6e9bd 100644 (file)
@@ -202,7 +202,7 @@ LL |         let _: Z = Z::Fn;
    |                    ^^^^^
    |                    |
    |                    expected enum `m::n::Z`, found fn item
-   |                    help: use parentheses to call this function: `Z::Fn(...)`
+   |                    help: use parentheses to instatiate this tuple struct: `Z::Fn(_)`
    |
    = note: expected type `m::n::Z`
               found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
@@ -232,7 +232,7 @@ LL |     let _: E = m::E::Fn;
    |                ^^^^^^^^
    |                |
    |                expected enum `m::E`, found fn item
-   |                help: use parentheses to call this function: `m::E::Fn(...)`
+   |                help: use parentheses to instatiate this tuple struct: `m::E::Fn(_)`
    |
    = note: expected type `m::E`
               found type `fn(u8) -> m::E {m::E::Fn}`
@@ -262,7 +262,7 @@ LL |     let _: E = E::Fn;
    |                ^^^^^
    |                |
    |                expected enum `m::E`, found fn item
-   |                help: use parentheses to call this function: `E::Fn(...)`
+   |                help: use parentheses to instatiate this tuple struct: `E::Fn(_)`
    |
    = note: expected type `m::E`
               found type `fn(u8) -> m::E {m::E::Fn}`
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
new file mode 100644 (file)
index 0000000..6758c1d
--- /dev/null
@@ -0,0 +1,20 @@
+fn foo(a: usize, b: usize) -> usize { a }
+
+fn bar() -> usize { 42 }
+
+struct S(usize, usize);
+struct V();
+
+trait T {
+    fn baz(x: usize, y: usize) -> usize { x }
+    fn bat() -> usize { 42 }
+}
+
+fn main() {
+    let _: usize = foo; //~ ERROR mismatched types
+    let _: S = S; //~ ERROR mismatched types
+    let _: usize = bar; //~ ERROR mismatched types
+    let _: V = V; //~ ERROR mismatched types
+    let _: usize = T::baz; //~ ERROR mismatched types
+    let _: usize = T::bat; //~ ERROR mismatched types
+}
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
new file mode 100644 (file)
index 0000000..524c779
--- /dev/null
@@ -0,0 +1,93 @@
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:14:20
+   |
+LL | fn foo(a: usize, b: usize) -> usize { a }
+   | ----------------------------------- fn(usize, usize) -> usize {foo} defined here
+...
+LL |     let _: usize = foo;
+   |                    ^^^
+   |                    |
+   |                    expected usize, found fn item
+   |                    help: use parentheses to call this function: `foo(a, b)`
+   |
+   = note: expected type `usize`
+              found type `fn(usize, usize) -> usize {foo}`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:15:16
+   |
+LL | struct S(usize, usize);
+   | ----------------------- fn(usize, usize) -> S {S} defined here
+...
+LL |     let _: S = S;
+   |                ^
+   |                |
+   |                expected struct `S`, found fn item
+   |                help: use parentheses to instatiate this tuple struct: `S(_, _)`
+   |
+   = note: expected type `S`
+              found type `fn(usize, usize) -> S {S}`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:16:20
+   |
+LL | fn bar() -> usize { 42 }
+   | ----------------- fn() -> usize {bar} defined here
+...
+LL |     let _: usize = bar;
+   |                    ^^^
+   |                    |
+   |                    expected usize, found fn item
+   |                    help: use parentheses to call this function: `bar()`
+   |
+   = note: expected type `usize`
+              found type `fn() -> usize {bar}`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:17:16
+   |
+LL | struct V();
+   | ----------- fn() -> V {V} defined here
+...
+LL |     let _: V = V;
+   |                ^
+   |                |
+   |                expected struct `V`, found fn item
+   |                help: use parentheses to instatiate this tuple struct: `V()`
+   |
+   = note: expected type `V`
+              found type `fn() -> V {V}`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:18:20
+   |
+LL |     fn baz(x: usize, y: usize) -> usize { x }
+   |     ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here
+...
+LL |     let _: usize = T::baz;
+   |                    ^^^^^^
+   |                    |
+   |                    expected usize, found fn item
+   |                    help: use parentheses to call this function: `T::baz(...)`
+   |
+   = note: expected type `usize`
+              found type `fn(usize, usize) -> usize {<_ as T>::baz}`
+
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:19:20
+   |
+LL |     fn bat() -> usize { 42 }
+   |     ----------------- fn() -> usize {<_ as T>::bat} defined here
+...
+LL |     let _: usize = T::bat;
+   |                    ^^^^^^
+   |                    |
+   |                    expected usize, found fn item
+   |                    help: use parentheses to call this function: `T::bat()`
+   |
+   = note: expected type `usize`
+              found type `fn() -> usize {<_ as T>::bat}`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.