Skip to content

Commit e3bc06f

Browse files
authored
Unrolled build for #160165
Rollup merge of #160165 - folkertdev:reject-dotdotdot-post-expansion, r=oli-obk reject `...` without pattern post-expansion tracking issue: #44930 fixes #160109 Discussed in today's lang meeting ([notes](https://hackmd.io/TiPFDCs4SD26EKTu12NNsg#C-variadic-function-definitions-stabilization-allows--without-pattern-with-immediate-FCW-rust160109)). We already emit the `varargs_without_pattern` FCW for `...` without a pattern in function definitions and trait method declarations. This PR adds a hard error if this makes it past macro expansion.
2 parents c9ff496 + 1d77f8a commit e3bc06f

7 files changed

Lines changed: 273 additions & 22 deletions

File tree

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,13 @@ impl<'a> AstValidator<'a> {
935935
match fn_ctxt {
936936
FnCtxt::Foreign => return,
937937
FnCtxt::Free | FnCtxt::Assoc(_) => {
938+
// Reject `...` without a pattern post-expansion. The varargs_without_pattern
939+
// FCW is already triggered pre-expansion.
940+
if let PatKind::Missing = variadic_param.pat.kind {
941+
self.dcx()
942+
.emit_err(diagnostics::VarargsWithoutPattern { span: variadic_param.span });
943+
}
944+
938945
match self.sess.target.supports_c_variadic_definitions() {
939946
CVariadicStatus::NotSupported => {
940947
self.dcx().emit_err(diagnostics::CVariadicNotSupported {

compiler/rustc_ast_passes/src/diagnostics.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,3 +1245,15 @@ pub(crate) enum DeprecatedWhereClauseLocationSugg {
12451245
span: Span,
12461246
},
12471247
}
1248+
1249+
#[derive(Diagnostic)]
1250+
#[diag("missing pattern for `...` argument")]
1251+
pub(crate) struct VarargsWithoutPattern {
1252+
#[suggestion(
1253+
"add a pattern for this argument",
1254+
applicability = "machine-applicable",
1255+
code = "_: ..."
1256+
)]
1257+
#[primary_span]
1258+
pub span: Span,
1259+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#![crate_type = "lib"]
2+
#![warn(varargs_without_pattern)]
3+
4+
// Test that we reject a bare `...` without a pattern post-expansion in function definitons and
5+
// trait method declarations. On foreign function declarations it is allowed.
6+
//
7+
// We have the `varargs_without_pattern` FCW for this idiom, with the intent to eventually also
8+
// reject this idiom pre-expansion.
9+
10+
// Bare `...` is allowed in extern blocks.
11+
extern "C" {
12+
fn g(...);
13+
}
14+
15+
// When the `...` argument does not make it past expansion, that only lints.
16+
macro_rules! discard_item {
17+
($item:item) => {};
18+
}
19+
20+
discard_item! {
21+
unsafe extern "C" fn f(...) -> i32 {
22+
//~^ WARN missing pattern for `...` argument
23+
//~| WARN this was previously accepted by the compiler but is being phased out
24+
0
25+
}
26+
}
27+
28+
// But when it does make it post-expansion, that is a hard error.
29+
macro_rules! identity_item {
30+
($item:item) => {
31+
$item
32+
};
33+
}
34+
35+
identity_item! {
36+
unsafe extern "C" fn f(...) {}
37+
//~^ ERROR missing pattern for `...` argument
38+
//~| WARN missing pattern for `...` argument
39+
//~| WARN this was previously accepted by the compiler but is being phased out
40+
//~| WARN missing pattern for `...` argument
41+
//~| WARN this was previously accepted by the compiler but is being phased out
42+
}
43+
44+
trait T {
45+
identity_item! {
46+
unsafe extern "C" fn f(...);
47+
//~^ ERROR missing pattern for `...` argument
48+
//~| WARN missing pattern for `...` argument
49+
//~| WARN this was previously accepted by the compiler but is being phased out
50+
//~| WARN missing pattern for `...` argument
51+
//~| WARN this was previously accepted by the compiler but is being phased out
52+
//~| WARN anonymous_parameters
53+
//~| WARN this is accepted in the current edition (Rust 2015)
54+
}
55+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
error: missing pattern for `...` argument
2+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:36:28
3+
|
4+
LL | unsafe extern "C" fn f(...) {}
5+
| ^^^ help: add a pattern for this argument: `_: ...`
6+
7+
error: missing pattern for `...` argument
8+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
9+
|
10+
LL | unsafe extern "C" fn f(...);
11+
| ^^^ help: add a pattern for this argument: `_: ...`
12+
13+
warning: missing pattern for `...` argument
14+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:21:28
15+
|
16+
LL | unsafe extern "C" fn f(...) -> i32 {
17+
| ^^^
18+
|
19+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
20+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
21+
note: the lint level is defined here
22+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
23+
|
24+
LL | #![warn(varargs_without_pattern)]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^
26+
help: name the argument, or use `_` to continue ignoring it
27+
|
28+
LL | unsafe extern "C" fn f(_: ...) -> i32 {
29+
| ++
30+
31+
warning: missing pattern for `...` argument
32+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:36:28
33+
|
34+
LL | unsafe extern "C" fn f(...) {}
35+
| ^^^
36+
|
37+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
38+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
39+
help: name the argument, or use `_` to continue ignoring it
40+
|
41+
LL | unsafe extern "C" fn f(_: ...) {}
42+
| ++
43+
44+
warning: missing pattern for `...` argument
45+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:36:28
46+
|
47+
LL | unsafe extern "C" fn f(...) {}
48+
| ^^^
49+
|
50+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
51+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
52+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
53+
help: name the argument, or use `_` to continue ignoring it
54+
|
55+
LL | unsafe extern "C" fn f(_: ...) {}
56+
| ++
57+
58+
warning: missing pattern for `...` argument
59+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
60+
|
61+
LL | unsafe extern "C" fn f(...);
62+
| ^^^
63+
|
64+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
65+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
66+
help: name the argument, or use `_` to continue ignoring it
67+
|
68+
LL | unsafe extern "C" fn f(_: ...);
69+
| ++
70+
71+
warning: missing pattern for `...` argument
72+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
73+
|
74+
LL | unsafe extern "C" fn f(...);
75+
| ^^^
76+
|
77+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
78+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
79+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
80+
help: name the argument, or use `_` to continue ignoring it
81+
|
82+
LL | unsafe extern "C" fn f(_: ...);
83+
| ++
84+
85+
warning: anonymous parameters are deprecated and will be removed in the next edition
86+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
87+
|
88+
LL | unsafe extern "C" fn f(...);
89+
| ^^^ help: try naming the parameter or explicitly ignoring it: `_: ...`
90+
|
91+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
92+
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2018/trait-fn-parameters.html>
93+
= note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default
94+
95+
error: aborting due to 2 previous errors; 6 warnings emitted
96+
97+
Future incompatibility report: Future breakage diagnostic:
98+
warning: missing pattern for `...` argument
99+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:21:28
100+
|
101+
LL | unsafe extern "C" fn f(...) -> i32 {
102+
| ^^^
103+
|
104+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
105+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
106+
note: the lint level is defined here
107+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
108+
|
109+
LL | #![warn(varargs_without_pattern)]
110+
| ^^^^^^^^^^^^^^^^^^^^^^^
111+
help: name the argument, or use `_` to continue ignoring it
112+
|
113+
LL | unsafe extern "C" fn f(_: ...) -> i32 {
114+
| ++
115+
116+
Future breakage diagnostic:
117+
warning: missing pattern for `...` argument
118+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:36:28
119+
|
120+
LL | unsafe extern "C" fn f(...) {}
121+
| ^^^
122+
|
123+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
124+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
125+
note: the lint level is defined here
126+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
127+
|
128+
LL | #![warn(varargs_without_pattern)]
129+
| ^^^^^^^^^^^^^^^^^^^^^^^
130+
help: name the argument, or use `_` to continue ignoring it
131+
|
132+
LL | unsafe extern "C" fn f(_: ...) {}
133+
| ++
134+
135+
Future breakage diagnostic:
136+
warning: missing pattern for `...` argument
137+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:36:28
138+
|
139+
LL | unsafe extern "C" fn f(...) {}
140+
| ^^^
141+
|
142+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
143+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
144+
note: the lint level is defined here
145+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
146+
|
147+
LL | #![warn(varargs_without_pattern)]
148+
| ^^^^^^^^^^^^^^^^^^^^^^^
149+
help: name the argument, or use `_` to continue ignoring it
150+
|
151+
LL | unsafe extern "C" fn f(_: ...) {}
152+
| ++
153+
154+
Future breakage diagnostic:
155+
warning: missing pattern for `...` argument
156+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
157+
|
158+
LL | unsafe extern "C" fn f(...);
159+
| ^^^
160+
|
161+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
162+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
163+
note: the lint level is defined here
164+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
165+
|
166+
LL | #![warn(varargs_without_pattern)]
167+
| ^^^^^^^^^^^^^^^^^^^^^^^
168+
help: name the argument, or use `_` to continue ignoring it
169+
|
170+
LL | unsafe extern "C" fn f(_: ...);
171+
| ++
172+
173+
Future breakage diagnostic:
174+
warning: missing pattern for `...` argument
175+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:46:32
176+
|
177+
LL | unsafe extern "C" fn f(...);
178+
| ^^^
179+
|
180+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
181+
= note: for more information, see issue #145544 <https://github.com/rust-lang/rust/issues/145544>
182+
note: the lint level is defined here
183+
--> $DIR/reject-varargs-without-pattern-post-expansion.rs:2:9
184+
|
185+
LL | #![warn(varargs_without_pattern)]
186+
| ^^^^^^^^^^^^^^^^^^^^^^^
187+
help: name the argument, or use `_` to continue ignoring it
188+
|
189+
LL | unsafe extern "C" fn f(_: ...);
190+
| ++
191+

tests/ui/thir-print/c-variadic.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
//@ compile-flags: -Zunpretty=thir-tree --crate-type=lib
22
//@ check-pass
3-
#![expect(varargs_without_pattern)]
43

5-
// The `...` argument uses `PatKind::Missing`.
6-
unsafe extern "C" fn foo(_: i32, ...) {}
4+
unsafe extern "C" fn foo(_: i32, _: ...) {}

tests/ui/thir-print/c-variadic.stderr

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/ui/thir-print/c-variadic.stdout

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ DefId(0:3 ~ c_variadic[a5de]::foo):
22
params: [
33
Param {
44
ty: i32
5-
ty_span: Some($DIR/c-variadic.rs:6:29: 6:32 (#0))
5+
ty_span: Some($DIR/c-variadic.rs:4:29: 4:32 (#0))
66
self_kind: None
77
hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).1))
88
param: Some(
99
Pat {
1010
ty: i32
11-
span: $DIR/c-variadic.rs:6:26: 6:27 (#0)
11+
span: $DIR/c-variadic.rs:4:26: 4:27 (#0)
1212
kind: PatKind {
1313
Wild
1414
}
@@ -23,9 +23,9 @@ params: [
2323
param: Some(
2424
Pat {
2525
ty: std::ffi::VaList<'{erased}>
26-
span: $DIR/c-variadic.rs:6:34: 6:37 (#0)
26+
span: $DIR/c-variadic.rs:4:34: 4:35 (#0)
2727
kind: PatKind {
28-
Missing
28+
Wild
2929
}
3030
}
3131
)
@@ -35,7 +35,7 @@ body:
3535
Expr {
3636
ty: ()
3737
temp_scope_id: 6
38-
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
38+
span: $DIR/c-variadic.rs:4:42: 4:44 (#0)
3939
kind:
4040
Scope {
4141
region_scope: Node(6)
@@ -44,11 +44,11 @@ body:
4444
Expr {
4545
ty: ()
4646
temp_scope_id: 6
47-
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
47+
span: $DIR/c-variadic.rs:4:42: 4:44 (#0)
4848
kind:
4949
Block {
5050
targeted_by_break: false
51-
span: $DIR/c-variadic.rs:6:39: 6:41 (#0)
51+
span: $DIR/c-variadic.rs:4:42: 4:44 (#0)
5252
region_scope: Node(5)
5353
safety_mode: Safe
5454
stmts: []

0 commit comments

Comments
 (0)