about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-10-27 09:08:06 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-10-27 15:12:47 -0700
commit15547e1d72105165d448b9ef4b4dc11932f67a74 (patch)
tree5844becf99a85a47b94d900895288d3bc76478c6
parentcfeff3e1c7e52ad2d6f364a53b8066c734dc4d83 (diff)
parent2ce77b33b04c64d57bef696d88605d08dff72775 (diff)
downloadrust-15547e1d72105165d448b9ef4b4dc11932f67a74.tar.gz
rust-15547e1d72105165d448b9ef4b4dc11932f67a74.zip
rollup merge of #18346 : aochagavia/closure-fields
-rw-r--r--src/librustc/middle/typeck/check/method.rs22
-rw-r--r--src/test/compile-fail/issue-18343.rs19
2 files changed, 40 insertions, 1 deletions
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index b1684cae95d..66693224c87 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -223,17 +223,37 @@ pub fn report_error(fcx: &FnCtxt,
 {
     match error {
         NoMatch(static_sources) => {
+            let cx = fcx.tcx();
+            let method_ustring = method_name.user_string(cx);
+
+            // True if the type is a struct and contains a field with
+            // the same name as the not-found method
+            let is_field = match ty::get(rcvr_ty).sty {
+                ty_struct(did, _) =>
+                    ty::lookup_struct_fields(cx, did)
+                        .iter()
+                        .any(|f| f.name.user_string(cx) == method_ustring),
+                _ => false
+            };
+
             fcx.type_error_message(
                 span,
                 |actual| {
                     format!("type `{}` does not implement any \
                              method in scope named `{}`",
                             actual,
-                            method_name.user_string(fcx.tcx()))
+                            method_ustring)
                 },
                 rcvr_ty,
                 None);
 
+            // If the method has the name of a field, give a help note
+            if is_field {
+                cx.sess.span_note(span,
+                    format!("use `(s.{0})(...)` if you meant to call the \
+                            function stored in the `{0}` field", method_ustring).as_slice());
+            }
+
             if static_sources.len() > 0 {
                 fcx.tcx().sess.fileline_note(
                     span,
diff --git a/src/test/compile-fail/issue-18343.rs b/src/test/compile-fail/issue-18343.rs
new file mode 100644
index 00000000000..1608d2137fc
--- /dev/null
+++ b/src/test/compile-fail/issue-18343.rs
@@ -0,0 +1,19 @@
+// Copyright 2014 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.
+
+struct Obj<'a> {
+    closure: ||: 'a -> u32
+}
+
+fn main() {
+    let o = Obj { closure: || 42 };
+    o.closure(); //~ ERROR type `Obj<'_>` does not implement any method in scope named `closure`
+    //~^ NOTE use `(s.closure)(...)` if you meant to call the function stored in the `closure` field
+}