Skip to content

Commit

Permalink
Rollup merge of rust-lang#86493 - Smittyvb:ctor-typeck-error, r=david…
Browse files Browse the repository at this point in the history
…twco

Say "this enum variant takes"/"this struct takes" instead of "this function takes"

This makes error messages for functions with incorrect argument counts adapt if they refer to a struct or enum variant:
```
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
```

Fixes rust-lang#86481.
  • Loading branch information
JohnTitor authored Jun 21, 2021
2 parents fdb1daa + b8a7bfb commit 4495ce7
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 6 deletions.
28 changes: 24 additions & 4 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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`.
Expand All @@ -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),
};
Expand All @@ -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"),
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/span/missing-unit-argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/span/missing-unit-argument.stderr
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/typeck/struct-enum-wrong-args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Regression test of #86481.
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
}
67 changes: 67 additions & 0 deletions src/test/ui/typeck/struct-enum-wrong-args.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
--> $DIR/struct-enum-wrong-args.rs:6: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:7: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:8: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:9: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:10: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:11: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:12: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:13: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`.

0 comments on commit 4495ce7

Please sign in to comment.