]> git.lizzy.rs Git - rust.git/commitdiff
Suggest calling function on type error when finding bare fn
authorEsteban Küber <esteban@kuber.com.ar>
Wed, 7 Aug 2019 05:29:10 +0000 (22:29 -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/substs-ppaux.normal.stderr
src/test/ui/substs-ppaux.verbose.stderr

index da9b02fcf513a1c91f90cd63081f45a5fdfc016a..6600f83393857f55084bb3640a81a3f433dd16bb 100644 (file)
@@ -3819,6 +3819,41 @@ pub fn suggest_mismatched_types_on_tail(
         pointing_at_return_type
     }
 
+    fn suggest_fn_call(
+        &self,
+        err: &mut DiagnosticBuilder<'tcx>,
+        expr: &hir::Expr,
+        expected: Ty<'tcx>,
+        found: Ty<'tcx>,
+    ) -> bool {
+        if let ty::FnDef(..) | ty::FnPtr(_) = &found.sty {
+            let sig = found.fn_sig(self.tcx);
+            let sig = self
+                .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
+                .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
+                        }
+                    );
+                    return true;
+                }
+            }
+        }
+        false
+    }
+
     pub fn suggest_ref_or_into(
         &self,
         err: &mut DiagnosticBuilder<'tcx>,
@@ -3833,6 +3868,14 @@ pub fn suggest_ref_or_into(
                 suggestion,
                 Applicability::MachineApplicable,
             );
+        } else if let (ty::FnDef(def_id, ..), true) = (
+            &found.sty,
+            self.suggest_fn_call(err, expr, expected, found),
+        ) {
+            if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
+                let sp = self.sess().source_map().def_span(sp);
+                err.span_label(sp, &format!("{} defined here", found));
+            }
         } else if !self.check_for_cast(err, expr, found, expected) {
             let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
                 expr.hir_id,
index 8fda58abadb6ee26c015c56c723c0e76a877f6d4..248e6f0f46b19f90549185f50b8e7bd553a06e0d 100644 (file)
@@ -1,11 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/issue-35241.rs:3:20
    |
+LL | struct Foo(u32);
+   | ---------------- fn(u32) -> Foo {Foo} defined here
+LL | 
 LL | fn test() -> Foo { Foo }
    |              ---   ^^^
    |              |     |
    |              |     expected struct `Foo`, found fn item
-   |              |     did you mean `Foo(/* fields */)`?
+   |              |     help: use parentheses to call this function: `Foo(...)`
    |              expected `Foo` because of return type
    |
    = note: expected type `Foo`
index a1a8714ab3f3837281131647908a6c75bc103716..07cbffb009406fe4810a4dca49656ffb2beabeec 100644 (file)
@@ -195,8 +195,14 @@ LL |     let _: Z = m::n::Z::Unit {};
 error[E0308]: mismatched types
   --> $DIR/privacy-enum-ctor.rs:27:20
    |
+LL |             Fn(u8),
+   |             ------ fn(u8) -> m::n::Z {m::n::Z::Fn} defined here
+...
 LL |         let _: Z = Z::Fn;
-   |                    ^^^^^ expected enum `m::n::Z`, found fn item
+   |                    ^^^^^
+   |                    |
+   |                    expected enum `m::n::Z`, found fn item
+   |                    help: use parentheses to call this function: `Z::Fn(...)`
    |
    = note: expected type `m::n::Z`
               found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
@@ -219,8 +225,14 @@ LL |         let _ = Z::Unit;
 error[E0308]: mismatched types
   --> $DIR/privacy-enum-ctor.rs:43:16
    |
+LL |         Fn(u8),
+   |         ------ fn(u8) -> m::E {m::E::Fn} defined here
+...
 LL |     let _: E = m::E::Fn;
-   |                ^^^^^^^^ expected enum `m::E`, found fn item
+   |                ^^^^^^^^
+   |                |
+   |                expected enum `m::E`, found fn item
+   |                help: use parentheses to call this function: `m::E::Fn(...)`
    |
    = note: expected type `m::E`
               found type `fn(u8) -> m::E {m::E::Fn}`
@@ -243,8 +255,14 @@ LL |     let _: E = m::E::Unit;
 error[E0308]: mismatched types
   --> $DIR/privacy-enum-ctor.rs:51:16
    |
+LL |         Fn(u8),
+   |         ------ fn(u8) -> m::E {m::E::Fn} defined here
+...
 LL |     let _: E = E::Fn;
-   |                ^^^^^ expected enum `m::E`, found fn item
+   |                ^^^^^
+   |                |
+   |                expected enum `m::E`, found fn item
+   |                help: use parentheses to call this function: `E::Fn(...)`
    |
    = note: expected type `m::E`
               found type `fn(u8) -> m::E {m::E::Fn}`
index 123dd86b9054933408fe154262ffbb4175006e03..b3b879ef9acbef79523669ae7a2b9cef2422480a 100644 (file)
@@ -1,8 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:16:17
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
@@ -10,8 +16,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:25:17
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
@@ -19,8 +31,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:33:17
    |
+LL |     fn baz() {}
+   |     -------- fn() {<i8 as Foo<'static, 'static, u8>>::baz} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::baz;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u8>>::baz()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
@@ -28,8 +46,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::baz;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:41:17
    |
+LL | fn foo<'z>() where &'z (): Sized {
+   | -------------------------------- fn() {foo::<'static>} defined here
+...
 LL |     let x: () = foo::<'static>;
-   |                 ^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `foo::<'static>()`
    |
    = note: expected type `()`
               found type `fn() {foo::<'static>}`
index 9167346282baba52aedd73d1e7d4b4f44a290aa8..363018db232d88858766fc437c0e4d427b732071 100644 (file)
@@ -1,8 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:16:17
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
@@ -10,8 +16,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::bar::<'static, char>;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:25:17
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
@@ -19,8 +31,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u32>>::bar::<'static, char>;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:33:17
    |
+LL |     fn baz() {}
+   |     -------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz} defined here
+...
 LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::baz;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `<i8 as Foo<'static, 'static,  u8>>::baz()`
    |
    = note: expected type `()`
               found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
@@ -28,8 +46,14 @@ LL |     let x: () = <i8 as Foo<'static, 'static,  u8>>::baz;
 error[E0308]: mismatched types
   --> $DIR/substs-ppaux.rs:41:17
    |
+LL | fn foo<'z>() where &'z (): Sized {
+   | -------------------------------- fn() {foo::<ReStatic>} defined here
+...
 LL |     let x: () = foo::<'static>;
-   |                 ^^^^^^^^^^^^^^ expected (), found fn item
+   |                 ^^^^^^^^^^^^^^
+   |                 |
+   |                 expected (), found fn item
+   |                 help: use parentheses to call this function: `foo::<'static>()`
    |
    = note: expected type `()`
               found type `fn() {foo::<ReStatic>}`