Skip to content

Commit 2257ba9

Browse files
Adjust diagnostics, bless tests
1 parent 99b3454 commit 2257ba9

31 files changed

+279
-157
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1557,11 +1557,17 @@ fn check_fn_or_method<'tcx>(
15571557
tcx.require_lang_item(hir::LangItem::Tuple, Some(span)),
15581558
);
15591559
} else {
1560-
tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple");
1560+
tcx.sess.span_err(
1561+
hir_decl.inputs.last().map_or(span, |input| input.span),
1562+
"functions with the \"rust-call\" ABI must take a single non-self tuple argument",
1563+
);
15611564
}
15621565
// No more inputs other than the `self` type and the tuple type
15631566
if inputs.next().is_some() {
1564-
tcx.sess.span_err(span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple");
1567+
tcx.sess.span_err(
1568+
hir_decl.inputs.last().map_or(span, |input| input.span),
1569+
"functions with the \"rust-call\" ABI must take a single non-self tuple argument",
1570+
);
15651571
}
15661572
}
15671573
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
215215
"cannot use call notation; the first type parameter \
216216
for the function trait is neither a tuple nor unit"
217217
)
218-
.emit();
218+
.delay_as_bug();
219219
(self.err_args(provided_args.len()), None)
220220
}
221221
}

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
700700
}
701701
}
702702

703+
if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
704+
match obligation.cause.code().peel_derives() {
705+
ObligationCauseCode::RustCall => {
706+
err.set_primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument");
707+
}
708+
ObligationCauseCode::BindingObligation(def_id, _)
709+
| ObligationCauseCode::ItemObligation(def_id)
710+
if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() =>
711+
{
712+
err.code(rustc_errors::error_code!(E0059));
713+
err.set_primary_message(format!(
714+
"type parameter to bare `{}` trait must be a tuple",
715+
tcx.def_path_str(*def_id)
716+
));
717+
}
718+
_ => {}
719+
}
720+
}
721+
703722
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
704723
&& predicate_is_const
705724
{
@@ -848,12 +867,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
848867
);
849868
}
850869

851-
let is_fn_trait = [
852-
self.tcx.lang_items().fn_trait(),
853-
self.tcx.lang_items().fn_mut_trait(),
854-
self.tcx.lang_items().fn_once_trait(),
855-
]
856-
.contains(&Some(trait_ref.def_id()));
870+
let is_fn_trait = ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some();
857871
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
858872
*trait_ref.skip_binder().self_ty().kind()
859873
{
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
#![feature(unboxed_closures)]
22

33
extern "rust-call" fn b(_i: i32) {}
4-
//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument that is a tuple
4+
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
55

66
trait Tr {
77
extern "rust-call" fn a();
8+
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
89

910
extern "rust-call" fn b() {}
10-
//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
11+
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
1112
}
1213

1314
struct Foo;
1415

1516
impl Foo {
1617
extern "rust-call" fn bar() {}
17-
//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
18+
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
1819
}
1920

2021
impl Tr for Foo {
2122
extern "rust-call" fn a() {}
22-
//~^ ERROR functions with the "rust-call" ABI must take a single non-self argument
23+
//~^ ERROR functions with the "rust-call" ABI must take a single non-self tuple argument
2324
}
2425

25-
fn main () {
26+
fn main() {
2627
b(10);
27-
2828
Foo::bar();
29-
3029
<Foo as Tr>::a();
3130
<Foo as Tr>::b();
3231
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
1-
error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
1+
error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument
22
--> $DIR/issue-22565-rust-call.rs:3:1
33
|
44
LL | extern "rust-call" fn b(_i: i32) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32`
66

7-
error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
8-
--> $DIR/issue-22565-rust-call.rs:9:5
9-
|
10-
LL | extern "rust-call" fn b() {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12-
13-
error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
14-
--> $DIR/issue-22565-rust-call.rs:16:5
7+
error: functions with the "rust-call" ABI must take a single non-self tuple argument
8+
--> $DIR/issue-22565-rust-call.rs:17:5
159
|
1610
LL | extern "rust-call" fn bar() {}
1711
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1812

19-
error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple
20-
--> $DIR/issue-22565-rust-call.rs:21:5
13+
error: functions with the "rust-call" ABI must take a single non-self tuple argument
14+
--> $DIR/issue-22565-rust-call.rs:22:5
2115
|
2216
LL | extern "rust-call" fn a() {}
2317
| ^^^^^^^^^^^^^^^^^^^^^^^^^
2418

25-
error: aborting due to 4 previous errors
19+
error: functions with the "rust-call" ABI must take a single non-self tuple argument
20+
--> $DIR/issue-22565-rust-call.rs:7:5
21+
|
22+
LL | extern "rust-call" fn a();
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error: functions with the "rust-call" ABI must take a single non-self tuple argument
26+
--> $DIR/issue-22565-rust-call.rs:10:5
27+
|
28+
LL | extern "rust-call" fn b() {}
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 5 previous errors
2632

33+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/abi/rustcall-generic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// check-pass
33
//[opt] compile-flags: -Zmir-opt-level=3
44

5-
#![feature(unboxed_closures)]
5+
#![feature(unboxed_closures, tuple_trait)]
66

7-
extern "rust-call" fn foo<T>(_: T) {}
7+
extern "rust-call" fn foo<T: std::marker::Tuple>(_: T) {}
88

99
fn main() {
1010
foo(());

src/test/ui/borrowck/borrow-immutable-upvar-mutation.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(unboxed_closures)]
1+
#![feature(unboxed_closures, tuple_trait)]
22

33
// Tests that we can't assign to or mutably borrow upvars from `Fn`
44
// closures (issue #17780)
@@ -7,10 +7,10 @@ fn set(x: &mut usize) {
77
*x = 5;
88
}
99

10-
fn to_fn<A, F: Fn<A>>(f: F) -> F {
10+
fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
1111
f
1212
}
13-
fn to_fn_mut<A, F: FnMut<A>>(f: F) -> F {
13+
fn to_fn_mut<A: std::marker::Tuple, F: FnMut<A>>(f: F) -> F {
1414
f
1515
}
1616

src/test/ui/borrowck/borrow-immutable-upvar-mutation.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
22
--> $DIR/borrow-immutable-upvar-mutation.rs:21:27
33
|
4-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
5-
| - change this to accept `FnMut` instead of `Fn`
4+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
5+
| - change this to accept `FnMut` instead of `Fn`
66
...
77
LL | let _f = to_fn(|| x = 42);
88
| ----- -- ^^^^^^ cannot assign
@@ -13,8 +13,8 @@ LL | let _f = to_fn(|| x = 42);
1313
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
1414
--> $DIR/borrow-immutable-upvar-mutation.rs:24:31
1515
|
16-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
17-
| - change this to accept `FnMut` instead of `Fn`
16+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
17+
| - change this to accept `FnMut` instead of `Fn`
1818
...
1919
LL | let _g = to_fn(|| set(&mut y));
2020
| ----- -- ^^^^^^ cannot borrow as mutable
@@ -25,8 +25,8 @@ LL | let _g = to_fn(|| set(&mut y));
2525
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
2626
--> $DIR/borrow-immutable-upvar-mutation.rs:29:22
2727
|
28-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
29-
| - change this to accept `FnMut` instead of `Fn`
28+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
29+
| - change this to accept `FnMut` instead of `Fn`
3030
...
3131
LL | to_fn(|| z = 42);
3232
| ----- -- ^^^^^^ cannot assign
@@ -37,8 +37,8 @@ LL | to_fn(|| z = 42);
3737
error[E0594]: cannot assign to `x`, as it is a captured variable in a `Fn` closure
3838
--> $DIR/borrow-immutable-upvar-mutation.rs:36:32
3939
|
40-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
41-
| - change this to accept `FnMut` instead of `Fn`
40+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
41+
| - change this to accept `FnMut` instead of `Fn`
4242
...
4343
LL | let _f = to_fn(move || x = 42);
4444
| ----- ------- ^^^^^^ cannot assign
@@ -49,8 +49,8 @@ LL | let _f = to_fn(move || x = 42);
4949
error[E0596]: cannot borrow `y` as mutable, as it is a captured variable in a `Fn` closure
5050
--> $DIR/borrow-immutable-upvar-mutation.rs:39:36
5151
|
52-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
53-
| - change this to accept `FnMut` instead of `Fn`
52+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
53+
| - change this to accept `FnMut` instead of `Fn`
5454
...
5555
LL | let _g = to_fn(move || set(&mut y));
5656
| ----- ------- ^^^^^^ cannot borrow as mutable
@@ -61,8 +61,8 @@ LL | let _g = to_fn(move || set(&mut y));
6161
error[E0594]: cannot assign to `z`, as it is a captured variable in a `Fn` closure
6262
--> $DIR/borrow-immutable-upvar-mutation.rs:44:27
6363
|
64-
LL | fn to_fn<A, F: Fn<A>>(f: F) -> F {
65-
| - change this to accept `FnMut` instead of `Fn`
64+
LL | fn to_fn<A: std::marker::Tuple, F: Fn<A>>(f: F) -> F {
65+
| - change this to accept `FnMut` instead of `Fn`
6666
...
6767
LL | to_fn(move || z = 42);
6868
| ----- ------- ^^^^^^ cannot assign

src/test/ui/borrowck/borrowck-move-by-capture.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#![feature(unboxed_closures)]
1+
#![feature(unboxed_closures, tuple_trait)]
22

3-
fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
4-
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
3+
fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f }
4+
fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
55

66
pub fn main() {
77
let bar: Box<_> = Box::new(3);

src/test/ui/c-variadic/issue-86053-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize
6666
|
6767
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
6868
|
69-
LL | pub trait Fn<Args>: FnMut<Args> {
70-
| ------------------------------- similarly named trait `Fn` defined here
69+
LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
70+
| -------------------------------------- similarly named trait `Fn` defined here
7171
|
7272
help: a trait with a similar name exists
7373
|

src/test/ui/cannot-mutate-captured-non-mut-var.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#![feature(unboxed_closures)]
1+
#![feature(unboxed_closures, tuple_trait)]
22

33
use std::io::Read;
44

5-
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
5+
fn to_fn_once<A:std::marker::Tuple,F:FnOnce<A>>(f: F) -> F { f }
66

77
fn main() {
88
let x = 1;

src/test/ui/chalkify/closure.stderr

+73-15
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,80 @@
1-
error[E0382]: borrow of moved value: `b`
2-
--> $DIR/closure.rs:28:5
1+
error[E0277]: `()` is not a tuple
2+
--> $DIR/closure.rs:6:5
3+
|
4+
LL | t();
5+
| ^^^ the trait `Tuple` is not implemented for `()`
6+
|
7+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
8+
|
9+
LL | fn main() -> () where (): Tuple {
10+
| +++++++++++++++
11+
12+
error[E0277]: `()` is not a tuple
13+
--> $DIR/closure.rs:12:5
14+
|
15+
LL | b();
16+
| ^^^ the trait `Tuple` is not implemented for `()`
17+
|
18+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
19+
|
20+
LL | fn main() -> () where (): Tuple {
21+
| +++++++++++++++
22+
23+
error[E0277]: `()` is not a tuple
24+
--> $DIR/closure.rs:16:5
25+
|
26+
LL | c();
27+
| ^^^ the trait `Tuple` is not implemented for `()`
28+
|
29+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
30+
|
31+
LL | fn main() -> () where (): Tuple {
32+
| +++++++++++++++
33+
34+
error[E0277]: `()` is not a tuple
35+
--> $DIR/closure.rs:17:5
336
|
4-
LL | let mut c = b;
5-
| - value moved here
6-
...
737
LL | b();
8-
| ^ value borrowed here after move
38+
| ^^^ the trait `Tuple` is not implemented for `()`
939
|
10-
note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
11-
--> $DIR/closure.rs:21:9
40+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
41+
|
42+
LL | fn main() -> () where (): Tuple {
43+
| +++++++++++++++
44+
45+
error[E0277]: `()` is not a tuple
46+
--> $DIR/closure.rs:23:5
47+
|
48+
LL | b();
49+
| ^^^ the trait `Tuple` is not implemented for `()`
50+
|
51+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
52+
|
53+
LL | fn main() -> () where (): Tuple {
54+
| +++++++++++++++
55+
56+
error[E0277]: `()` is not a tuple
57+
--> $DIR/closure.rs:27:5
58+
|
59+
LL | c();
60+
| ^^^ the trait `Tuple` is not implemented for `()`
61+
|
62+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
63+
|
64+
LL | fn main() -> () where (): Tuple {
65+
| +++++++++++++++
66+
67+
error[E0277]: `()` is not a tuple
68+
--> $DIR/closure.rs:28:5
69+
|
70+
LL | b();
71+
| ^^^ `()` is not a tuple
1272
|
13-
LL | a = 1;
14-
| ^
15-
help: consider mutably borrowing `b`
73+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
1674
|
17-
LL | let mut c = &mut b;
18-
| ++++
75+
LL | fn main() -> () where (): Tuple {
76+
| +++++++++++++++
1977

20-
error: aborting due to previous error
78+
error: aborting due to 7 previous errors
2179

22-
For more information about this error, try `rustc --explain E0382`.
80+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/closures/issue-78720.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ LL | _func: F,
1212
|
1313
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
1414
|
15-
LL | pub trait Fn<Args>: FnMut<Args> {
16-
| ------------------------------- similarly named trait `Fn` defined here
15+
LL | pub trait Fn<Args: Tuple>: FnMut<Args> {
16+
| -------------------------------------- similarly named trait `Fn` defined here
1717
|
1818
help: a trait with a similar name exists
1919
|

0 commit comments

Comments
 (0)