From 4cd2fab8c56b19fa14685a0ceb6d905366913b2c Mon Sep 17 00:00:00 2001 From: Smitty Date: Sun, 20 Jun 2021 13:48:37 -0400 Subject: [PATCH 1/2] Specify if struct/enum in arg mismatch error --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 28 ++++++-- src/test/ui/span/missing-unit-argument.rs | 2 +- src/test/ui/span/missing-unit-argument.stderr | 2 +- src/test/ui/typeck/struct-enum-wrong-args.rs | 13 ++++ .../ui/typeck/struct-enum-wrong-args.stderr | 67 +++++++++++++++++++ 5 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/typeck/struct-enum-wrong-args.rs create mode 100644 src/test/ui/typeck/struct-enum-wrong-args.stderr 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`. From b8a7bfb9f15b26b81f071d8eb1a039489ffce446 Mon Sep 17 00:00:00 2001 From: Smitty Date: Mon, 21 Jun 2021 11:17:30 -0400 Subject: [PATCH 2/2] Reference issue test originated from --- src/test/ui/typeck/struct-enum-wrong-args.rs | 1 + src/test/ui/typeck/struct-enum-wrong-args.stderr | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/test/ui/typeck/struct-enum-wrong-args.rs b/src/test/ui/typeck/struct-enum-wrong-args.rs index 7204caa09d4..19de4d67729 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.rs +++ b/src/test/ui/typeck/struct-enum-wrong-args.rs @@ -1,3 +1,4 @@ +// Regression test of #86481. struct Wrapper(i32); struct DoubleWrapper(i32, i32); diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr index b9c5756d1f9..d77ef73028b 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.stderr +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -1,5 +1,5 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:5:13 + --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); | ^^^^ - - supplied 2 arguments @@ -7,7 +7,7 @@ LL | let _ = Some(3, 2); | expected 1 argument error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:6:13 + --> $DIR/struct-enum-wrong-args.rs:7:13 | LL | let _ = Ok(3, 6, 2); | ^^ - - - supplied 3 arguments @@ -15,7 +15,7 @@ LL | let _ = Ok(3, 6, 2); | expected 1 argument error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:7:13 + --> $DIR/struct-enum-wrong-args.rs:8:13 | LL | let _ = Ok(); | ^^-- supplied 0 arguments @@ -23,7 +23,7 @@ LL | let _ = Ok(); | expected 1 argument error[E0061]: this struct takes 1 argument but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:8:13 + --> $DIR/struct-enum-wrong-args.rs:9:13 | LL | let _ = Wrapper(); | ^^^^^^^-- supplied 0 arguments @@ -31,7 +31,7 @@ LL | let _ = Wrapper(); | expected 1 argument error[E0061]: this struct takes 1 argument but 2 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:9:13 + --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); | ^^^^^^^ - - supplied 2 arguments @@ -39,7 +39,7 @@ LL | let _ = Wrapper(5, 2); | expected 1 argument error[E0061]: this struct takes 2 arguments but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:10:13 + --> $DIR/struct-enum-wrong-args.rs:11:13 | LL | let _ = DoubleWrapper(); | ^^^^^^^^^^^^^-- supplied 0 arguments @@ -47,7 +47,7 @@ LL | let _ = DoubleWrapper(); | expected 2 arguments error[E0061]: this struct takes 2 arguments but 1 argument was supplied - --> $DIR/struct-enum-wrong-args.rs:11:13 + --> $DIR/struct-enum-wrong-args.rs:12:13 | LL | let _ = DoubleWrapper(5); | ^^^^^^^^^^^^^ - supplied 1 argument @@ -55,7 +55,7 @@ LL | let _ = DoubleWrapper(5); | expected 2 arguments error[E0061]: this struct takes 2 arguments but 3 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:12:13 + --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); | ^^^^^^^^^^^^^ - - - supplied 3 arguments