about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-12-10 11:50:18 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-12-10 12:02:18 -0800
commitcc1ab3db8ba655508a6c8f649b2de32161a29f06 (patch)
tree156c23f1773bdd3c513eb4208d8188c81a28e143
parent2924d38dd9ba0502264d5b8652ffd65f3f43f0df (diff)
downloadrust-cc1ab3db8ba655508a6c8f649b2de32161a29f06.tar.gz
rust-cc1ab3db8ba655508a6c8f649b2de32161a29f06.zip
Suggest setting type param on function call
-rw-r--r--src/librustc/traits/error_reporting.rs24
-rw-r--r--src/test/ui/type/type-annotation-needed.stderr5
2 files changed, 28 insertions, 1 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 963da858803..b8200a8e173 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1994,6 +1994,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
                 err.note(&format!("cannot resolve `{}`", predicate));
+                if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) = (
+                    self.tcx.sess.source_map().span_to_snippet(span),
+                    &obligation.cause.code,
+                ) {
+                    let generics = self.tcx.generics_of(*def_id);
+                    if !generics.params.is_empty() {
+                        err.span_suggestion(
+                            span,
+                            &format!(
+                                "consider specifying the type argument{} in the function call",
+                                if generics.params.len() > 1 {
+                                    "s"
+                                } else {
+                                    ""
+                                },
+                            ),
+                            format!("{}::<{}>", snippet, generics.params.iter()
+                                .map(|p| p.name.to_string())
+                                .collect::<Vec<String>>()
+                                .join(", ")),
+                            Applicability::HasPlaceholders,
+                        );
+                    }
+                }
                 err
             }
 
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index f30bbf6b7db..5b7d6ba16d0 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -5,7 +5,10 @@ LL | fn foo<T: Into<String>>(x: i32) {}
    |    ---    ------------ required by this bound in `foo`
 ...
 LL |     foo(42);
-   |     ^^^ cannot infer type for `T`
+   |     ^^^
+   |     |
+   |     cannot infer type for `T`
+   |     help: consider specifying the type argument in the function call: `foo::<T>`
    |
    = note: cannot resolve `_: std::convert::Into<std::string::String>`