about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_data_structures/unify/mod.rs20
-rw-r--r--src/librustc_typeck/check/callee.rs1
-rw-r--r--src/librustc_typeck/check/mod.rs34
-rw-r--r--src/test/ui/span/missing-unit-argument.rs19
-rw-r--r--src/test/ui/span/missing-unit-argument.stderr45
5 files changed, 101 insertions, 18 deletions
diff --git a/src/librustc_data_structures/unify/mod.rs b/src/librustc_data_structures/unify/mod.rs
index 7853bf9478a..5411ae0257a 100644
--- a/src/librustc_data_structures/unify/mod.rs
+++ b/src/librustc_data_structures/unify/mod.rs
@@ -119,10 +119,10 @@ impl<K: UnifyKey> VarValue<K> {
     }
 }
 
-// We can't use V:LatticeValue, much as I would like to,
-// because frequently the pattern is that V=Option<U> for some
-// other type parameter U, and we have no way to say
-// Option<U>:LatticeValue.
+/// We can't use V:LatticeValue, much as I would like to,
+/// because frequently the pattern is that V=Option<U> for some
+/// other type parameter U, and we have no way to say
+/// Option<U>:LatticeValue.
 
 impl<K: UnifyKey> UnificationTable<K> {
     pub fn new() -> UnificationTable<K> {
@@ -249,7 +249,7 @@ impl<K: UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
     fn reverse(_: &mut Vec<VarValue<K>>, _: ()) {}
 }
 
-// # Base union-find algorithm, where we are just making sets
+/// # Base union-find algorithm, where we are just making sets
 
 impl<'tcx, K: UnifyKey> UnificationTable<K>
     where K::Value: Combine
@@ -281,11 +281,11 @@ impl<'tcx, K: UnifyKey> UnificationTable<K>
     }
 }
 
-// # Non-subtyping unification
-//
-// Code to handle keys which carry a value, like ints,
-// floats---anything that doesn't have a subtyping relationship we
-// need to worry about.
+/// # Non-subtyping unification
+///
+/// Code to handle keys which carry a value, like ints,
+/// floats---anything that doesn't have a subtyping relationship we
+/// need to worry about.
 
 impl<'tcx, K, V> UnificationTable<K>
     where K: UnifyKey<Value = Option<V>>,
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 460e2858b22..5b9d4af08e0 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -38,6 +38,7 @@ pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefI
 enum CallStep<'tcx> {
     Builtin(Ty<'tcx>),
     DeferredClosure(ty::FnSig<'tcx>),
+    /// e.g. enum variant constructors
     Overloaded(MethodCallee<'tcx>),
 }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3a18eddaad3..04277272696 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2472,7 +2472,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
                                        arg_count: usize, error_code: &str, variadic: bool,
-                                       def_span: Option<Span>) {
+                                       def_span: Option<Span>, sugg_unit: bool) {
             let mut err = sess.struct_span_err_with_code(sp,
                 &format!("this function takes {}{} parameter{} but {} parameter{} supplied",
                     if variadic {"at least "} else {""},
@@ -2482,13 +2482,23 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if arg_count == 1 {" was"} else {"s were"}),
                 error_code);
 
-            err.span_label(sp, format!("expected {}{} parameter{}",
-                                        if variadic {"at least "} else {""},
-                                        expected_count,
-                                        if expected_count == 1 {""} else {"s"}));
             if let Some(def_s) = def_span {
                 err.span_label(def_s, "defined here");
             }
+            if sugg_unit {
+                let mut sugg_span = sp.end_point();
+                // remove closing `)` from the span
+                sugg_span.hi = sugg_span.lo;
+                err.span_suggestion(
+                    sugg_span,
+                    "expected the unit value `()`. You can create one with a pair of parenthesis",
+                    String::from("()"));
+            } else {
+                err.span_label(sp, format!("expected {}{} parameter{}",
+                                            if variadic {"at least "} else {""},
+                                            expected_count,
+                                            if expected_count == 1 {""} else {"s"}));
+            }
             err.emit();
         }
 
@@ -2497,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             match tuple_type.sty {
                 ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
                     parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
-                                          "E0057", false, def_span);
+                                          "E0057", false, def_span, false);
                     expected_arg_tys = &[];
                     self.err_args(args.len())
                 }
@@ -2526,13 +2536,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 fn_inputs.to_vec()
             } else {
                 parameter_count_error(tcx.sess, sp_args, expected_arg_count,
-                                      supplied_arg_count, "E0060", true, def_span);
+                                      supplied_arg_count, "E0060", true, def_span, false);
                 expected_arg_tys = &[];
                 self.err_args(supplied_arg_count)
             }
         } else {
+            // is the missing argument of type `()`?
+            let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
+                self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_nil()
+            } else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
+                self.resolve_type_vars_if_possible(&fn_inputs[0]).is_nil()
+            } else {
+                false
+            };
             parameter_count_error(tcx.sess, sp_args, expected_arg_count,
-                                  supplied_arg_count, "E0061", false, def_span);
+                                  supplied_arg_count, "E0061", false, def_span, sugg_unit);
             expected_arg_tys = &[];
             self.err_args(supplied_arg_count)
         };
diff --git a/src/test/ui/span/missing-unit-argument.rs b/src/test/ui/span/missing-unit-argument.rs
new file mode 100644
index 00000000000..2cdab5bedc4
--- /dev/null
+++ b/src/test/ui/span/missing-unit-argument.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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.
+
+fn foo(():(), ():()) {}
+fn bar(():()) {}
+
+fn main() {
+    let _: Result<(), String> = Ok();
+    foo();
+    foo(());
+    bar();
+}
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
new file mode 100644
index 00000000000..e508a30d182
--- /dev/null
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -0,0 +1,45 @@
+error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+  --> $DIR/missing-unit-argument.rs:15:33
+   |
+15 |     let _: Result<(), String> = Ok();
+   |                                 ^^^^
+   |
+help: expected the unit value `()`. You can create one with a pair of parenthesis
+   |
+15 |     let _: Result<(), String> = Ok(());
+   |                                    ^^
+
+error[E0061]: this function takes 2 parameters but 0 parameters were supplied
+  --> $DIR/missing-unit-argument.rs:16:5
+   |
+11 | fn foo(():(), ():()) {}
+   | ----------------------- defined here
+...
+16 |     foo();
+   |     ^^^^^ expected 2 parameters
+
+error[E0061]: this function takes 2 parameters but 1 parameter was supplied
+  --> $DIR/missing-unit-argument.rs:17:9
+   |
+11 | fn foo(():(), ():()) {}
+   | ----------------------- defined here
+...
+17 |     foo(());
+   |         ^^ expected 2 parameters
+
+error[E0061]: this function takes 1 parameter but 0 parameters were supplied
+  --> $DIR/missing-unit-argument.rs:18:5
+   |
+12 | fn bar(():()) {}
+   | ---------------- defined here
+...
+18 |     bar();
+   |     ^^^^^
+   |
+help: expected the unit value `()`. You can create one with a pair of parenthesis
+   |
+18 |     bar(());
+   |         ^^
+
+error: aborting due to 4 previous errors
+