]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / compiler / rustc_typeck / src / check / fn_ctxt / checks.rs
index 49aea19c8d099970e72e2ec57fb5ddbc58478f0c..f65cc429fbd48241fdb5423ee8fa47fde73a1d38 100644 (file)
@@ -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"),
@@ -291,7 +311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // that are not closures, then we type-check the closures. This is so
         // that we have more information about the types of arguments when we
         // type-check the functions. This isn't really the right way to do this.
-        for &check_closures in &[false, true] {
+        for check_closures in [false, true] {
             debug!("check_closures={}", check_closures);
 
             // More awful hacks: before we check argument types, try to do