about summary refs log tree commit diff
path: root/src/test/ui/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/parser')
-rw-r--r--src/test/ui/parser/impl-item-const-pass.rs8
-rw-r--r--src/test/ui/parser/impl-item-const-semantic-fail.rs7
-rw-r--r--src/test/ui/parser/impl-item-const-semantic-fail.stderr10
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-pass.rs8
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs7
-rw-r--r--src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr10
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-pass.rs11
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs22
-rw-r--r--src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr73
-rw-r--r--src/test/ui/parser/issue-21153.stderr2
-rw-r--r--src/test/ui/parser/issue-32446.stderr4
-rw-r--r--src/test/ui/parser/macro/trait-non-item-macros.stderr4
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr4
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs12
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr38
-rw-r--r--src/test/ui/parser/trait-item-with-defaultness-pass.rs13
-rw-r--r--src/test/ui/parser/variadic-ffi-3.rs5
-rw-r--r--src/test/ui/parser/variadic-ffi-3.stderr9
-rw-r--r--src/test/ui/parser/variadic-ffi-4.rs5
-rw-r--r--src/test/ui/parser/variadic-ffi-4.stderr9
-rw-r--r--src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs9
-rw-r--r--src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr24
-rw-r--r--src/test/ui/parser/variadic-ffi-semantic-restrictions.rs76
-rw-r--r--src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr206
-rw-r--r--src/test/ui/parser/variadic-ffi-syntactic-pass.rs53
25 files changed, 594 insertions, 35 deletions
diff --git a/src/test/ui/parser/impl-item-const-pass.rs b/src/test/ui/parser/impl-item-const-pass.rs
new file mode 100644
index 00000000000..d1124561374
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-pass.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+    const Y: u8;
+}
diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.rs b/src/test/ui/parser/impl-item-const-semantic-fail.rs
new file mode 100644
index 00000000000..5d4692f9f14
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-semantic-fail.rs
@@ -0,0 +1,7 @@
+fn main() {}
+
+struct X;
+
+impl X {
+    const Y: u8; //~ ERROR associated constant in `impl` without body
+}
diff --git a/src/test/ui/parser/impl-item-const-semantic-fail.stderr b/src/test/ui/parser/impl-item-const-semantic-fail.stderr
new file mode 100644
index 00000000000..ec3bee0ce68
--- /dev/null
+++ b/src/test/ui/parser/impl-item-const-semantic-fail.stderr
@@ -0,0 +1,10 @@
+error: associated constant in `impl` without body
+  --> $DIR/impl-item-const-semantic-fail.rs:6:5
+   |
+LL |     const Y: u8;
+   |     ^^^^^^^^^^^-
+   |                |
+   |                help: provide a definition for the constant: `= <expr>;`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/impl-item-fn-no-body-pass.rs b/src/test/ui/parser/impl-item-fn-no-body-pass.rs
new file mode 100644
index 00000000000..16b09d64e8c
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-pass.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+    fn f();
+}
diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs
new file mode 100644
index 00000000000..cb183db5964
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.rs
@@ -0,0 +1,7 @@
+fn main() {}
+
+struct X;
+
+impl X {
+    fn f(); //~ ERROR associated function in `impl` without body
+}
diff --git a/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr
new file mode 100644
index 00000000000..1acb727368b
--- /dev/null
+++ b/src/test/ui/parser/impl-item-fn-no-body-semantic-fail.stderr
@@ -0,0 +1,10 @@
+error: associated function in `impl` without body
+  --> $DIR/impl-item-fn-no-body-semantic-fail.rs:6:5
+   |
+LL |     fn f();
+   |     ^^^^^^-
+   |           |
+   |           help: provide a definition for the function: `{ <body> }`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/impl-item-type-no-body-pass.rs b/src/test/ui/parser/impl-item-type-no-body-pass.rs
new file mode 100644
index 00000000000..74a9c6ab7e8
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-pass.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl X {
+    type Y;
+    type Z: Ord;
+    type W: Ord where Self: Eq;
+    type W where Self: Eq;
+}
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
new file mode 100644
index 00000000000..71c7d4ba21d
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+//~^ WARN the feature `generic_associated_types` is incomplete
+
+fn main() {}
+
+struct X;
+
+impl X {
+    type Y;
+    //~^ ERROR associated type in `impl` without body
+    //~| ERROR associated types are not yet supported in inherent impls
+    type Z: Ord;
+    //~^ ERROR associated type in `impl` without body
+    //~| ERROR bounds on associated `type`s in `impl`s have no effect
+    //~| ERROR associated types are not yet supported in inherent impls
+    type W: Ord where Self: Eq;
+    //~^ ERROR associated type in `impl` without body
+    //~| ERROR bounds on associated `type`s in `impl`s have no effect
+    //~| ERROR associated types are not yet supported in inherent impls
+    type W where Self: Eq;
+    //~^ ERROR associated type in `impl` without body
+}
diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
new file mode 100644
index 00000000000..6f1439c8f0b
--- /dev/null
+++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr
@@ -0,0 +1,73 @@
+error: associated type in `impl` without body
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
+   |
+LL |     type Y;
+   |     ^^^^^^-
+   |           |
+   |           help: provide a definition for the type: `= <type>;`
+
+error: associated type in `impl` without body
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:12:5
+   |
+LL |     type Z: Ord;
+   |     ^^^^^^^^^^^-
+   |                |
+   |                help: provide a definition for the type: `= <type>;`
+
+error: bounds on associated `type`s in `impl`s have no effect
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:12:13
+   |
+LL |     type Z: Ord;
+   |             ^^^
+
+error: associated type in `impl` without body
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:16:5
+   |
+LL |     type W: Ord where Self: Eq;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |                               |
+   |                               help: provide a definition for the type: `= <type>;`
+
+error: bounds on associated `type`s in `impl`s have no effect
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:16:13
+   |
+LL |     type W: Ord where Self: Eq;
+   |             ^^^
+
+error: associated type in `impl` without body
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:20:5
+   |
+LL |     type W where Self: Eq;
+   |     ^^^^^^^^^^^^^^^^^^^^^-
+   |                          |
+   |                          help: provide a definition for the type: `= <type>;`
+
+warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:1:12
+   |
+LL | #![feature(generic_associated_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0202]: associated types are not yet supported in inherent impls (see #8995)
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:9:5
+   |
+LL |     type Y;
+   |     ^^^^^^^
+
+error[E0202]: associated types are not yet supported in inherent impls (see #8995)
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:12:5
+   |
+LL |     type Z: Ord;
+   |     ^^^^^^^^^^^^
+
+error[E0202]: associated types are not yet supported in inherent impls (see #8995)
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:16:5
+   |
+LL |     type W: Ord where Self: Eq;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0202`.
diff --git a/src/test/ui/parser/issue-21153.stderr b/src/test/ui/parser/issue-21153.stderr
index 70f55f0aeb9..6e20a9ce3c4 100644
--- a/src/test/ui/parser/issue-21153.stderr
+++ b/src/test/ui/parser/issue-21153.stderr
@@ -1,4 +1,4 @@
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-21153.rs:1:29
    |
 LL |   trait MyTrait<T>: Iterator {
diff --git a/src/test/ui/parser/issue-32446.stderr b/src/test/ui/parser/issue-32446.stderr
index 70256a59231..1a97f54160b 100644
--- a/src/test/ui/parser/issue-32446.stderr
+++ b/src/test/ui/parser/issue-32446.stderr
@@ -1,8 +1,8 @@
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
   --> $DIR/issue-32446.rs:4:11
    |
 LL | trait T { ... }
-   |           ^^^ expected one of 9 possible tokens
+   |           ^^^ expected one of 10 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr
index 0a433ab278e..7647ba500e0 100644
--- a/src/test/ui/parser/macro/trait-non-item-macros.stderr
+++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr
@@ -1,8 +1,8 @@
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
   --> $DIR/trait-non-item-macros.rs:2:19
    |
 LL |     ($a:expr) => ($a)
-   |                   ^^ expected one of 8 possible tokens
+   |                   ^^ expected one of 9 possible tokens
 ...
 LL |     bah!(2);
    |     -------- in this macro invocation
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
index cbaf9315e85..7e8abf22d55 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
@@ -7,11 +7,11 @@ LL | trait T {
 LL | fn main() {}
    |                                                                  ^
 
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
+error: expected one of `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
   --> $DIR/missing-close-brace-in-trait.rs:5:12
    |
 LL | pub(crate) struct Bar<T>();
-   |            ^^^^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
+   |            ^^^^^^ expected one of 7 possible tokens
 
 error[E0601]: `main` function not found in crate `missing_close_brace_in_trait`
   --> $DIR/missing-close-brace-in-trait.rs:1:1
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
new file mode 100644
index 00000000000..09f967f161e
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
@@ -0,0 +1,12 @@
+#![feature(specialization)]
+
+fn main() {}
+
+trait X {
+    default const A: u8; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default const B: u8 = 0;  //~ ERROR `default` is only allowed on items in `impl` definitions
+    default type D; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default type C: Ord; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default fn f1(); //~ ERROR `default` is only allowed on items in `impl` definitions
+    default fn f2() {} //~ ERROR `default` is only allowed on items in `impl` definitions
+}
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
new file mode 100644
index 00000000000..54111df3423
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
@@ -0,0 +1,38 @@
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5
+   |
+LL |     default const A: u8;
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5
+   |
+LL |     default const B: u8 = 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5
+   |
+LL |     default type D;
+   |     ^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5
+   |
+LL |     default type C: Ord;
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:10:5
+   |
+LL |     default fn f1();
+   |     ^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:11:5
+   |
+LL |     default fn f2() {}
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/trait-item-with-defaultness-pass.rs b/src/test/ui/parser/trait-item-with-defaultness-pass.rs
new file mode 100644
index 00000000000..a6318bd99e2
--- /dev/null
+++ b/src/test/ui/parser/trait-item-with-defaultness-pass.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+trait X {
+    default const A: u8;
+    default const B: u8 = 0;
+    default type D;
+    default type C: Ord;
+    default fn f1();
+    default fn f2() {}
+}
diff --git a/src/test/ui/parser/variadic-ffi-3.rs b/src/test/ui/parser/variadic-ffi-3.rs
deleted file mode 100644
index ce83cc87abe..00000000000
--- a/src/test/ui/parser/variadic-ffi-3.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn foo(x: isize, ...) {
-    //~^ ERROR: only foreign functions are allowed to be C-variadic
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/variadic-ffi-3.stderr b/src/test/ui/parser/variadic-ffi-3.stderr
deleted file mode 100644
index aeeebdb9914..00000000000
--- a/src/test/ui/parser/variadic-ffi-3.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0743]: only foreign functions are allowed to be C-variadic
-  --> $DIR/variadic-ffi-3.rs:1:18
-   |
-LL | fn foo(x: isize, ...) {
-   |                  ^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0743`.
diff --git a/src/test/ui/parser/variadic-ffi-4.rs b/src/test/ui/parser/variadic-ffi-4.rs
deleted file mode 100644
index 5f8b3f8f539..00000000000
--- a/src/test/ui/parser/variadic-ffi-4.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-extern "C" fn foo(x: isize, ...) {
-    //~^ ERROR: only foreign functions are allowed to be C-variadic
-}
-
-fn main() {}
diff --git a/src/test/ui/parser/variadic-ffi-4.stderr b/src/test/ui/parser/variadic-ffi-4.stderr
deleted file mode 100644
index da83276c72d..00000000000
--- a/src/test/ui/parser/variadic-ffi-4.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0743]: only foreign functions are allowed to be C-variadic
-  --> $DIR/variadic-ffi-4.rs:1:29
-   |
-LL | extern "C" fn foo(x: isize, ...) {
-   |                             ^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0743`.
diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs
new file mode 100644
index 00000000000..9eeee195e56
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.rs
@@ -0,0 +1,9 @@
+fn f1<'a>(x: u8, y: &'a ...) {}
+//~^ ERROR C-variadic type `...` may not be nested inside another type
+
+fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
+//~^ ERROR C-variadic type `...` may not be nested inside another type
+
+fn main() {
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
new file mode 100644
index 00000000000..8b9d676a45d
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-nested-syntactic-fail.stderr
@@ -0,0 +1,24 @@
+error[E0743]: C-variadic type `...` may not be nested inside another type
+  --> $DIR/variadic-ffi-nested-syntactic-fail.rs:1:25
+   |
+LL | fn f1<'a>(x: u8, y: &'a ...) {}
+   |                         ^^^
+
+error[E0743]: C-variadic type `...` may not be nested inside another type
+  --> $DIR/variadic-ffi-nested-syntactic-fail.rs:4:29
+   |
+LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
+   |                             ^^^
+
+error[E0308]: mismatched types
+  --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0743.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs
new file mode 100644
index 00000000000..aa85f6d6b52
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs
@@ -0,0 +1,76 @@
+#![feature(c_variadic)]
+
+fn main() {}
+
+fn f1_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+
+fn f1_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern "C" fn f2_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+
+extern "C" fn f2_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern "C" fn f2_3(..., x: isize) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+//~| ERROR `...` must be the last argument of a C-variadic function
+
+extern fn f3_1(x: isize, ...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+
+extern fn f3_2(...) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+//~| ERROR C-variadic function must be declared with at least one named argument
+
+extern fn f3_3(..., x: isize) {}
+//~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+//~| ERROR `...` must be the last argument of a C-variadic function
+
+extern {
+    fn e_f1(...);
+    //~^ ERROR C-variadic function must be declared with at least one named argument
+    fn e_f2(..., x: isize);
+    //~^ ERROR `...` must be the last argument of a C-variadic function
+}
+
+struct X;
+
+impl X {
+    fn i_f1(x: isize, ...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    fn i_f2(...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR C-variadic function must be declared with at least one named argument
+    fn i_f3(..., x: isize, ...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR `...` must be the last argument of a C-variadic function
+    fn i_f4(..., x: isize, ...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR `...` must be the last argument of a C-variadic function
+}
+
+trait T {
+    fn t_f1(x: isize, ...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    fn t_f2(x: isize, ...);
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    fn t_f3(...) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR C-variadic function must be declared with at least one named argument
+    fn t_f4(...);
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR C-variadic function must be declared with at least one named argument
+    fn t_f5(..., x: isize) {}
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR `...` must be the last argument of a C-variadic function
+    fn t_f6(..., x: isize);
+    //~^ ERROR only foreign or `unsafe extern "C" functions may be C-variadic
+    //~| ERROR `...` must be the last argument of a C-variadic function
+}
diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr
new file mode 100644
index 00000000000..21992a29670
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr
@@ -0,0 +1,206 @@
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:5:19
+   |
+LL | fn f1_1(x: isize, ...) {}
+   |                   ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:8:9
+   |
+LL | fn f1_2(...) {}
+   |         ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:8:9
+   |
+LL | fn f1_2(...) {}
+   |         ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
+   |
+LL | extern "C" fn f2_1(x: isize, ...) {}
+   |                              ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
+   |
+LL | extern "C" fn f2_2(...) {}
+   |                    ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
+   |
+LL | extern "C" fn f2_2(...) {}
+   |                    ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:19:20
+   |
+LL | extern "C" fn f2_3(..., x: isize) {}
+   |                    ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:19:20
+   |
+LL | extern "C" fn f2_3(..., x: isize) {}
+   |                    ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:23:26
+   |
+LL | extern fn f3_1(x: isize, ...) {}
+   |                          ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:26:16
+   |
+LL | extern fn f3_2(...) {}
+   |                ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:26:16
+   |
+LL | extern fn f3_2(...) {}
+   |                ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:30:16
+   |
+LL | extern fn f3_3(..., x: isize) {}
+   |                ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:30:16
+   |
+LL | extern fn f3_3(..., x: isize) {}
+   |                ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:35:13
+   |
+LL |     fn e_f1(...);
+   |             ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:37:13
+   |
+LL |     fn e_f2(..., x: isize);
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:44:23
+   |
+LL |     fn i_f1(x: isize, ...) {}
+   |                       ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:46:13
+   |
+LL |     fn i_f2(...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:46:13
+   |
+LL |     fn i_f2(...) {}
+   |             ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:49:13
+   |
+LL |     fn i_f3(..., x: isize, ...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:49:13
+   |
+LL |     fn i_f3(..., x: isize, ...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:49:28
+   |
+LL |     fn i_f3(..., x: isize, ...) {}
+   |                            ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
+   |
+LL |     fn i_f4(..., x: isize, ...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
+   |
+LL |     fn i_f4(..., x: isize, ...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:53:28
+   |
+LL |     fn i_f4(..., x: isize, ...) {}
+   |                            ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:60:23
+   |
+LL |     fn t_f1(x: isize, ...) {}
+   |                       ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:23
+   |
+LL |     fn t_f2(x: isize, ...);
+   |                       ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
+   |
+LL |     fn t_f3(...) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
+   |
+LL |     fn t_f3(...) {}
+   |             ^^^^
+
+error: C-variadic function must be declared with at least one named argument
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
+   |
+LL |     fn t_f4(...);
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
+   |
+LL |     fn t_f4(...);
+   |             ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:70:13
+   |
+LL |     fn t_f5(..., x: isize) {}
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:70:13
+   |
+LL |     fn t_f5(..., x: isize) {}
+   |             ^^^^
+
+error: `...` must be the last argument of a C-variadic function
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:73:13
+   |
+LL |     fn t_f6(..., x: isize);
+   |             ^^^^
+
+error: only foreign or `unsafe extern "C" functions may be C-variadic
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:73:13
+   |
+LL |     fn t_f6(..., x: isize);
+   |             ^^^^
+
+error: aborting due to 34 previous errors
+
diff --git a/src/test/ui/parser/variadic-ffi-syntactic-pass.rs b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs
new file mode 100644
index 00000000000..3875d6af137
--- /dev/null
+++ b/src/test/ui/parser/variadic-ffi-syntactic-pass.rs
@@ -0,0 +1,53 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn f1_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+fn f1_2(...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_2(...) {}
+
+#[cfg(FALSE)]
+extern "C" fn f2_3(..., x: isize) {}
+
+#[cfg(FALSE)]
+extern fn f3_1(x: isize, ...) {}
+
+#[cfg(FALSE)]
+extern fn f3_2(...) {}
+
+#[cfg(FALSE)]
+extern fn f3_3(..., x: isize) {}
+
+#[cfg(FALSE)]
+extern {
+    fn e_f1(...);
+    fn e_f2(..., x: isize);
+}
+
+struct X;
+
+#[cfg(FALSE)]
+impl X {
+    fn i_f1(x: isize, ...) {}
+    fn i_f2(...) {}
+    fn i_f3(..., x: isize, ...) {}
+    fn i_f4(..., x: isize, ...) {}
+}
+
+#[cfg(FALSE)]
+trait T {
+    fn t_f1(x: isize, ...) {}
+    fn t_f2(x: isize, ...);
+    fn t_f3(...) {}
+    fn t_f4(...);
+    fn t_f5(..., x: isize) {}
+    fn t_f6(..., x: isize);
+}