about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/traits/error_reporting.rs90
-rw-r--r--src/test/ui/issue-47706.rs24
-rw-r--r--src/test/ui/issue-47706.stderr13
3 files changed, 86 insertions, 41 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 067340ecacc..42200a3a447 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -794,48 +794,56 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec<ArgKind>) {
-        if let hir::map::NodeExpr(&hir::Expr {
-            node: hir::ExprClosure(_, ref _decl, id, span, _),
-            ..
-        }) = node {
-            (self.tcx.sess.codemap().def_span(span), self.tcx.hir.body(id).arguments.iter()
-                .map(|arg| {
-                    if let hir::Pat {
-                        node: hir::PatKind::Tuple(args, _),
-                        span,
-                        ..
-                    } = arg.pat.clone().into_inner() {
-                        ArgKind::Tuple(
+        match node {
+            hir::map::NodeExpr(&hir::Expr {
+                node: hir::ExprClosure(_, ref _decl, id, span, _),
+                ..
+            }) => {
+                (self.tcx.sess.codemap().def_span(span), self.tcx.hir.body(id).arguments.iter()
+                    .map(|arg| {
+                        if let hir::Pat {
+                            node: hir::PatKind::Tuple(args, _),
                             span,
-                            args.iter().map(|pat| {
-                                let snippet = self.tcx.sess.codemap()
-                                    .span_to_snippet(pat.span).unwrap();
-                                (snippet, "_".to_owned())
-                            }).collect::<Vec<_>>(),
-                        )
-                    } else {
-                        let name = self.tcx.sess.codemap().span_to_snippet(arg.pat.span).unwrap();
-                        ArgKind::Arg(name, "_".to_owned())
-                    }
-                })
-                .collect::<Vec<ArgKind>>())
-        } else if let hir::map::NodeItem(&hir::Item {
-            span,
-            node: hir::ItemFn(ref decl, ..),
-            ..
-        }) = node {
-            (self.tcx.sess.codemap().def_span(span), decl.inputs.iter()
-                    .map(|arg| match arg.clone().into_inner().node {
-                hir::TyTup(ref tys) => ArgKind::Tuple(
-                    arg.span,
-                    tys.iter()
-                        .map(|_| ("_".to_owned(), "_".to_owned()))
-                        .collect::<Vec<_>>(),
-                ),
-                _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
-            }).collect::<Vec<ArgKind>>())
-        } else {
-            panic!("non-FnLike node found: {:?}", node);
+                            ..
+                        } = arg.pat.clone().into_inner() {
+                            ArgKind::Tuple(
+                                span,
+                                args.iter().map(|pat| {
+                                    let snippet = self.tcx.sess.codemap()
+                                        .span_to_snippet(pat.span).unwrap();
+                                    (snippet, "_".to_owned())
+                                }).collect::<Vec<_>>(),
+                            )
+                        } else {
+                            let name = self.tcx.sess.codemap()
+                                .span_to_snippet(arg.pat.span).unwrap();
+                            ArgKind::Arg(name, "_".to_owned())
+                        }
+                    })
+                    .collect::<Vec<ArgKind>>())
+            }
+            hir::map::NodeItem(&hir::Item {
+                span,
+                node: hir::ItemFn(ref decl, ..),
+                ..
+            }) |
+            hir::map::NodeImplItem(&hir::ImplItem {
+                span,
+                node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _),
+                ..
+            }) => {
+                (self.tcx.sess.codemap().def_span(span), decl.inputs.iter()
+                        .map(|arg| match arg.clone().into_inner().node {
+                    hir::TyTup(ref tys) => ArgKind::Tuple(
+                        arg.span,
+                        tys.iter()
+                            .map(|_| ("_".to_owned(), "_".to_owned()))
+                            .collect::<Vec<_>>(),
+                    ),
+                    _ => ArgKind::Arg("_".to_owned(), "_".to_owned())
+                }).collect::<Vec<ArgKind>>())
+            }
+            _ => panic!("non-FnLike node found: {:?}", node),
         }
     }
 
diff --git a/src/test/ui/issue-47706.rs b/src/test/ui/issue-47706.rs
new file mode 100644
index 00000000000..24a0f66f5b1
--- /dev/null
+++ b/src/test/ui/issue-47706.rs
@@ -0,0 +1,24 @@
+// Copyright 2018 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.
+
+pub struct Foo {
+    foo: Option<i32>,
+}
+
+impl Foo {
+    pub fn new(foo: Option<i32>, _: ()) -> Foo {
+        Foo { foo }
+    }
+
+    pub fn map(self) -> Option<Foo> {
+        self.foo.map(Foo::new)
+    }
+    //~^^ ERROR function is expected to take 1 argument, but it takes 2 arguments [E0593]
+}
diff --git a/src/test/ui/issue-47706.stderr b/src/test/ui/issue-47706.stderr
new file mode 100644
index 00000000000..0916dc64292
--- /dev/null
+++ b/src/test/ui/issue-47706.stderr
@@ -0,0 +1,13 @@
+error[E0601]: main function not found
+
+error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
+  --> $DIR/issue-47706.rs:21:18
+   |
+16 |     pub fn new(foo: Option<i32>, _: ()) -> Foo {
+   |     ------------------------------------------ takes 2 arguments
+...
+21 |         self.foo.map(Foo::new)
+   |                  ^^^ expected function that takes 1 argument
+
+error: aborting due to 2 previous errors
+