about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs28
-rw-r--r--src/test/ui/span/missing-unit-argument.rs2
-rw-r--r--src/test/ui/span/missing-unit-argument.stderr2
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.rs13
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.stderr67
5 files changed, 106 insertions, 6 deletions
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index d6989b866c1..f65cc429fbd 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -11,7 +11,7 @@ use crate::check::{
 use rustc_ast as ast;
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_middle::ty::adjustment::AllowTwoPhase;
@@ -120,8 +120,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                  error_code: &str,
                                  c_variadic: bool,
                                  sugg_unit: bool| {
-            let (span, start_span, args) = match &expr.kind {
-                hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]),
+            let (span, start_span, args, ctor_of) = match &expr.kind {
+                hir::ExprKind::Call(
+                    hir::Expr {
+                        span,
+                        kind:
+                            hir::ExprKind::Path(hir::QPath::Resolved(
+                                _,
+                                hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
+                            )),
+                        ..
+                    },
+                    args,
+                ) => (*span, *span, &args[..], Some(of)),
+                hir::ExprKind::Call(hir::Expr { span, .. }, args) => {
+                    (*span, *span, &args[..], None)
+                }
                 hir::ExprKind::MethodCall(path_segment, span, args, _) => (
                     *span,
                     // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
@@ -137,6 +151,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         })
                         .unwrap_or(*span),
                     &args[1..], // Skip the receiver.
+                    None,       // methods are never ctors
                 ),
                 k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k),
             };
@@ -157,7 +172,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut err = tcx.sess.struct_span_err_with_code(
                 span,
                 &format!(
-                    "this function takes {}{} but {} {} supplied",
+                    "this {} takes {}{} but {} {} supplied",
+                    match ctor_of {
+                        Some(CtorOf::Struct) => "struct",
+                        Some(CtorOf::Variant) => "enum variant",
+                        None => "function",
+                    },
                     if c_variadic { "at least " } else { "" },
                     potentially_plural_count(expected_count, "argument"),
                     potentially_plural_count(arg_count, "argument"),
diff --git a/src/test/ui/span/missing-unit-argument.rs b/src/test/ui/span/missing-unit-argument.rs
index b8fb332120a..5b9861da6e8 100644
--- a/src/test/ui/span/missing-unit-argument.rs
+++ b/src/test/ui/span/missing-unit-argument.rs
@@ -8,7 +8,7 @@ impl S {
 }
 
 fn main() {
-    let _: Result<(), String> = Ok(); //~ ERROR this function takes
+    let _: Result<(), String> = Ok(); //~ ERROR this enum variant takes
     foo(); //~ ERROR this function takes
     foo(()); //~ ERROR this function takes
     bar(); //~ ERROR this function takes
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
index b15da2cb479..7a24ffbd81c 100644
--- a/src/test/ui/span/missing-unit-argument.stderr
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -1,4 +1,4 @@
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
+error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:11:33
    |
 LL |     let _: Result<(), String> = Ok();
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.rs b/src/test/ui/typeck/struct-enum-wrong-args.rs
new file mode 100644
index 00000000000..7204caa09d4
--- /dev/null
+++ b/src/test/ui/typeck/struct-enum-wrong-args.rs
@@ -0,0 +1,13 @@
+struct Wrapper(i32);
+struct DoubleWrapper(i32, i32);
+
+fn main() {
+    let _ = Some(3, 2); //~ ERROR this enum variant takes
+    let _ = Ok(3, 6, 2); //~ ERROR this enum variant takes
+    let _ = Ok(); //~ ERROR this enum variant takes
+    let _ = Wrapper(); //~ ERROR this struct takes
+    let _ = Wrapper(5, 2); //~ ERROR this struct takes
+    let _ = DoubleWrapper(); //~ ERROR this struct takes
+    let _ = DoubleWrapper(5); //~ ERROR this struct takes
+    let _ = DoubleWrapper(5, 2, 7); //~ ERROR this struct takes
+}
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
new file mode 100644
index 00000000000..b9c5756d1f9
--- /dev/null
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -0,0 +1,67 @@
+error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:5:13
+   |
+LL |     let _ = Some(3, 2);
+   |             ^^^^ -  - supplied 2 arguments
+   |             |
+   |             expected 1 argument
+
+error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:6:13
+   |
+LL |     let _ = Ok(3, 6, 2);
+   |             ^^ -  -  - supplied 3 arguments
+   |             |
+   |             expected 1 argument
+
+error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:7:13
+   |
+LL |     let _ = Ok();
+   |             ^^-- supplied 0 arguments
+   |             |
+   |             expected 1 argument
+
+error[E0061]: this struct takes 1 argument but 0 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:8:13
+   |
+LL |     let _ = Wrapper();
+   |             ^^^^^^^-- supplied 0 arguments
+   |             |
+   |             expected 1 argument
+
+error[E0061]: this struct takes 1 argument but 2 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:9:13
+   |
+LL |     let _ = Wrapper(5, 2);
+   |             ^^^^^^^ -  - supplied 2 arguments
+   |             |
+   |             expected 1 argument
+
+error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:10:13
+   |
+LL |     let _ = DoubleWrapper();
+   |             ^^^^^^^^^^^^^-- supplied 0 arguments
+   |             |
+   |             expected 2 arguments
+
+error[E0061]: this struct takes 2 arguments but 1 argument was supplied
+  --> $DIR/struct-enum-wrong-args.rs:11:13
+   |
+LL |     let _ = DoubleWrapper(5);
+   |             ^^^^^^^^^^^^^ - supplied 1 argument
+   |             |
+   |             expected 2 arguments
+
+error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
+  --> $DIR/struct-enum-wrong-args.rs:12:13
+   |
+LL |     let _ = DoubleWrapper(5, 2, 7);
+   |             ^^^^^^^^^^^^^ -  -  - supplied 3 arguments
+   |             |
+   |             expected 2 arguments
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0061`.