about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2015-11-20 11:11:08 +0100
committerFlorian Hahn <flo@fhahn.com>2016-01-01 17:50:43 +0100
commit335298e7b606c80cd7218de64856c10acf3855d5 (patch)
tree16771aa8209ab6009c478c0d7e49f2c6f33f9d63 /src
parent88e819f478c530d4e1ca7243e327803771b532af (diff)
downloadrust-335298e7b606c80cd7218de64856c10acf3855d5.tar.gz
rust-335298e7b606c80cd7218de64856c10acf3855d5.zip
Show similar trait implementations if no matching impl is found
closes #21659
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/traits/error_reporting.rs20
-rw-r--r--src/test/compile-fail/issue-21659-show-relevant-trait-impls.rs39
2 files changed, 59 insertions, 0 deletions
diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs
index 9193b1a09f9..94e017a6855 100644
--- a/src/librustc/middle/traits/error_reporting.rs
+++ b/src/librustc/middle/traits/error_reporting.rs
@@ -225,6 +225,26 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                 "the trait `{}` is not implemented for the type `{}`",
                                 trait_ref, trait_ref.self_ty());
 
+                            let mut counter = 1;
+                            infcx.tcx.sess.fileline_help(
+                                obligation.cause.span,
+                                "the following implementations were found:");
+                            infcx.tcx.lookup_trait_def(trait_ref.def_id()).for_each_relevant_impl(
+                                infcx.tcx,
+                                trait_ref.self_ty(),
+                                |impl_def_id| {
+                                    match infcx.tcx.impl_trait_ref(impl_def_id) {
+                                        Some(ref imp) => {
+                                            infcx.tcx.sess.fileline_help(
+                                                obligation.cause.span,
+                                                &format!("implementation {}: `{}`", counter, imp));
+                                            counter += 1;
+                                        },
+                                        None => (),
+                                    }
+                                }
+                            );
+
                             // Check if it has a custom "#[rustc_on_unimplemented]"
                             // error message, report with that message if it does
                             let custom_note = report_on_unimplemented(infcx, &trait_ref.0,
diff --git a/src/test/compile-fail/issue-21659-show-relevant-trait-impls.rs b/src/test/compile-fail/issue-21659-show-relevant-trait-impls.rs
new file mode 100644
index 00000000000..416eef4ad25
--- /dev/null
+++ b/src/test/compile-fail/issue-21659-show-relevant-trait-impls.rs
@@ -0,0 +1,39 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo<A> {
+    fn foo(&self, a: A) -> A {
+        a
+    }
+}
+
+trait NotRelevant<A> {
+    fn nr(&self, a: A) -> A {
+        a
+    }
+}
+
+struct Bar;
+
+impl Foo<i32> for Bar {}
+
+impl Foo<u8> for Bar {}
+
+impl NotRelevant<usize> for Bar {}
+
+fn main() {
+    let f1 = Bar;
+
+    f1.foo(1usize);
+    //~^ error: the trait `Foo<usize>` is not implemented for the type `Bar`
+    // | help: the following implementations were found:
+    // | help: implementation 1: `Foo<i32>`
+    // | help: implementation 2: `Foo<u8>`
+}