about summary refs log tree commit diff
path: root/src/test/ui/parser
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-01-30 00:18:54 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-02-05 01:27:09 +0100
commitb2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684 (patch)
treedb169a7cc1f065c0b2975a1178d3afdef5a172b4 /src/test/ui/parser
parentc0b7b41cff2b40d430befefc8688fb8ad847bcd4 (diff)
downloadrust-b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684.tar.gz
rust-b2c6eeb713d4cf9b35b7dda6ff2b0274e7f24684.zip
parser: merge `fn` grammars wrt. bodies & headers
also refactor `FnKind` and `visit_assoc_item` visitors
Diffstat (limited to 'src/test/ui/parser')
-rw-r--r--src/test/ui/parser/duplicate-visibility.rs2
-rw-r--r--src/test/ui/parser/duplicate-visibility.stderr4
-rw-r--r--src/test/ui/parser/fn-body-optional-semantic-fail.rs27
-rw-r--r--src/test/ui/parser/fn-body-optional-semantic-fail.stderr40
-rw-r--r--src/test/ui/parser/fn-body-optional-syntactic-pass.rs31
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.rs57
-rw-r--r--src/test/ui/parser/fn-header-semantic-fail.stderr136
-rw-r--r--src/test/ui/parser/fn-header-syntactic-pass.rs55
-rw-r--r--src/test/ui/parser/issue-24780.rs2
-rw-r--r--src/test/ui/parser/issue-24780.stderr4
-rw-r--r--src/test/ui/parser/issue-63135.rs2
-rw-r--r--src/test/ui/parser/issue-63135.stderr8
-rw-r--r--src/test/ui/parser/missing_right_paren.rs2
-rw-r--r--src/test/ui/parser/missing_right_paren.stderr8
-rw-r--r--src/test/ui/parser/no-const-fn-in-extern-block.rs4
-rw-r--r--src/test/ui/parser/no-const-fn-in-extern-block.stderr21
-rw-r--r--src/test/ui/parser/not-a-pred.stderr4
17 files changed, 387 insertions, 20 deletions
diff --git a/src/test/ui/parser/duplicate-visibility.rs b/src/test/ui/parser/duplicate-visibility.rs
index bb17e97e950..a8f0b7d61b9 100644
--- a/src/test/ui/parser/duplicate-visibility.rs
+++ b/src/test/ui/parser/duplicate-visibility.rs
@@ -1,4 +1,4 @@
-// error-pattern:expected one of `(`, `fn`, `static`, or `type`
+// error-pattern: expected one of `(`, `async`, `const`, `extern`, `fn`
 extern {
     pub pub fn foo();
 }
diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr
index 313e88e812b..cba4058e482 100644
--- a/src/test/ui/parser/duplicate-visibility.stderr
+++ b/src/test/ui/parser/duplicate-visibility.stderr
@@ -1,8 +1,8 @@
-error: expected one of `(`, `fn`, `static`, or `type`, found keyword `pub`
+error: expected one of `(`, `async`, `const`, `extern`, `fn`, `static`, `type`, or `unsafe`, found keyword `pub`
   --> $DIR/duplicate-visibility.rs:3:9
    |
 LL |     pub pub fn foo();
-   |         ^^^ expected one of `(`, `fn`, `static`, or `type`
+   |         ^^^ expected one of 8 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.rs b/src/test/ui/parser/fn-body-optional-semantic-fail.rs
new file mode 100644
index 00000000000..38def05e8f2
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-semantic-fail.rs
@@ -0,0 +1,27 @@
+// Tests the different rules for `fn` forms requiring the presence or lack of a body.
+
+fn main() {
+    fn f1(); //~ ERROR free function without a body
+    fn f2() {} // OK.
+
+    trait X {
+        fn f1(); // OK.
+        fn f2() {} // OK.
+    }
+
+    struct Y;
+    impl X for Y {
+        fn f1(); //~ ERROR associated function in `impl` without body
+        fn f2() {} // OK.
+    }
+
+    impl Y {
+        fn f3(); //~ ERROR associated function in `impl` without body
+        fn f4() {} // OK.
+    }
+
+    extern {
+        fn f5(); // OK.
+        fn f6() {} //~ ERROR incorrect function inside `extern` block
+    }
+}
diff --git a/src/test/ui/parser/fn-body-optional-semantic-fail.stderr b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr
new file mode 100644
index 00000000000..23ce98fb5d7
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-semantic-fail.stderr
@@ -0,0 +1,40 @@
+error: free function without a body
+  --> $DIR/fn-body-optional-semantic-fail.rs:4:5
+   |
+LL |     fn f1();
+   |     ^^^^^^^-
+   |            |
+   |            help: provide a definition for the function: `{ <body> }`
+
+error: associated function in `impl` without body
+  --> $DIR/fn-body-optional-semantic-fail.rs:14:9
+   |
+LL |         fn f1();
+   |         ^^^^^^^-
+   |                |
+   |                help: provide a definition for the function: `{ <body> }`
+
+error: associated function in `impl` without body
+  --> $DIR/fn-body-optional-semantic-fail.rs:19:9
+   |
+LL |         fn f3();
+   |         ^^^^^^^-
+   |                |
+   |                help: provide a definition for the function: `{ <body> }`
+
+error: incorrect function inside `extern` block
+  --> $DIR/fn-body-optional-semantic-fail.rs:25:12
+   |
+LL |     extern {
+   |     ------ `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL |         fn f5(); // OK.
+LL |         fn f6() {}
+   |            ^^   -- help: remove the invalid body: `;`
+   |            |
+   |            cannot have a body
+   |
+   = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+   = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/fn-body-optional-syntactic-pass.rs b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs
new file mode 100644
index 00000000000..e7991c73b4b
--- /dev/null
+++ b/src/test/ui/parser/fn-body-optional-syntactic-pass.rs
@@ -0,0 +1,31 @@
+// Ensures that all `fn` forms having or lacking a body are syntactically valid.
+
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+    fn f();
+    fn f() {}
+
+    trait X {
+        fn f();
+        fn f() {}
+    }
+
+    impl X for Y {
+        fn f();
+        fn f() {}
+    }
+
+    impl Y {
+        fn f();
+        fn f() {}
+    }
+
+    extern {
+        fn f();
+        fn f() {}
+    }
+}
diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs
new file mode 100644
index 00000000000..c2b7e69c80d
--- /dev/null
+++ b/src/test/ui/parser/fn-header-semantic-fail.rs
@@ -0,0 +1,57 @@
+// Ensures that all `fn` forms can have all the function qualifiers syntactically.
+
+// edition:2018
+
+#![feature(const_extern_fn)]
+#![feature(const_fn)]
+
+fn main() {
+    async fn ff1() {} // OK.
+    unsafe fn ff2() {} // OK.
+    const fn ff3() {} // OK.
+    extern "C" fn ff4() {} // OK.
+    const /* async */ unsafe extern "C" fn ff5() {} // OK.
+    //^ FIXME(Centril): `async` should be legal syntactically, ensure it's illegal semantically.
+
+    trait X {
+        async fn ft1(); //~ ERROR trait fns cannot be declared `async`
+        unsafe fn ft2(); // OK.
+        const fn ft3(); //~ ERROR trait fns cannot be declared const
+        extern "C" fn ft4(); // OK.
+        /* const */ async unsafe extern "C" fn ft5();
+        //~^ ERROR trait fns cannot be declared `async`
+        //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically.
+    }
+
+    struct Y;
+    impl X for Y {
+        async fn ft1() {} //~ ERROR trait fns cannot be declared `async`
+        //~^ ERROR method `ft1` has an incompatible type for trait
+        unsafe fn ft2() {} // OK.
+        const fn ft3() {} //~ ERROR trait fns cannot be declared const
+        extern "C" fn ft4() {}
+        /* const */ async unsafe extern "C" fn ft5() {}
+        //~^ ERROR trait fns cannot be declared `async`
+        //~| ERROR method `ft5` has an incompatible type for trait
+        //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically.
+    }
+
+    impl Y {
+        async fn fi1() {} // OK.
+        unsafe fn fi2() {} // OK.
+        const fn fi3() {} // OK.
+        extern "C" fn fi4() {} // OK.
+        /* const */ async unsafe extern "C" fn fi5() {} // OK.
+        //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically.
+    }
+
+    extern {
+        async fn fe1(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+        unsafe fn fe2(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+        const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+        extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers
+        /* const */ async unsafe extern "C" fn fe5();
+        //~^ ERROR functions in `extern` blocks cannot have qualifiers
+        //^ FIXME(Centril): `const` should be legal syntactically, ensure it's illegal semantically.
+    }
+}
diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr
new file mode 100644
index 00000000000..41d2d9b7faa
--- /dev/null
+++ b/src/test/ui/parser/fn-header-semantic-fail.stderr
@@ -0,0 +1,136 @@
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/fn-header-semantic-fail.rs:17:9
+   |
+LL |         async fn ft1();
+   |         ^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0379]: trait fns cannot be declared const
+  --> $DIR/fn-header-semantic-fail.rs:19:9
+   |
+LL |         const fn ft3();
+   |         ^^^^^ trait fns cannot be const
+
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/fn-header-semantic-fail.rs:21:21
+   |
+LL |         /* const */ async unsafe extern "C" fn ft5();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/fn-header-semantic-fail.rs:28:9
+   |
+LL |         async fn ft1() {}
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0379]: trait fns cannot be declared const
+  --> $DIR/fn-header-semantic-fail.rs:31:9
+   |
+LL |         const fn ft3() {}
+   |         ^^^^^ trait fns cannot be const
+
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/fn-header-semantic-fail.rs:33:21
+   |
+LL |         /* const */ async unsafe extern "C" fn ft5() {}
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:49:18
+   |
+LL |     extern {
+   |     ------ in this `extern` block
+LL |         async fn fe1();
+   |         ---------^^^
+   |         |
+   |         help: remove the qualifiers: `fn`
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:50:19
+   |
+LL |     extern {
+   |     ------ in this `extern` block
+LL |         async fn fe1();
+LL |         unsafe fn fe2();
+   |         ----------^^^
+   |         |
+   |         help: remove the qualifiers: `fn`
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:51:18
+   |
+LL |     extern {
+   |     ------ in this `extern` block
+...
+LL |         const fn fe3();
+   |         ---------^^^
+   |         |
+   |         help: remove the qualifiers: `fn`
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:52:23
+   |
+LL |     extern {
+   |     ------ in this `extern` block
+...
+LL |         extern "C" fn fe4();
+   |         --------------^^^
+   |         |
+   |         help: remove the qualifiers: `fn`
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:53:48
+   |
+LL |     extern {
+   |     ------ in this `extern` block
+...
+LL |         /* const */ async unsafe extern "C" fn fe5();
+   |                     ---------------------------^^^
+   |                     |
+   |                     help: remove the qualifiers: `fn`
+
+error[E0053]: method `ft1` has an incompatible type for trait
+  --> $DIR/fn-header-semantic-fail.rs:28:24
+   |
+LL |         async fn ft1();
+   |                       - type in trait
+...
+LL |         async fn ft1() {}
+   |                        ^
+   |                        |
+   |                        the `Output` of this `async fn`'s found opaque type
+   |                        expected `()`, found opaque type
+   |
+   = note: expected fn pointer `fn()`
+              found fn pointer `fn() -> impl std::future::Future`
+
+error[E0053]: method `ft5` has an incompatible type for trait
+  --> $DIR/fn-header-semantic-fail.rs:33:54
+   |
+LL |         /* const */ async unsafe extern "C" fn ft5();
+   |                                                     - type in trait
+...
+LL |         /* const */ async unsafe extern "C" fn ft5() {}
+   |                                                      ^
+   |                                                      |
+   |                                                      the `Output` of this `async fn`'s found opaque type
+   |                                                      expected `()`, found opaque type
+   |
+   = note: expected fn pointer `unsafe extern "C" fn()`
+              found fn pointer `unsafe extern "C" fn() -> impl std::future::Future`
+
+error: aborting due to 13 previous errors
+
+Some errors have detailed explanations: E0053, E0379, E0706.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/src/test/ui/parser/fn-header-syntactic-pass.rs b/src/test/ui/parser/fn-header-syntactic-pass.rs
new file mode 100644
index 00000000000..145a208cb24
--- /dev/null
+++ b/src/test/ui/parser/fn-header-syntactic-pass.rs
@@ -0,0 +1,55 @@
+// Ensures that all `fn` forms can have all the function qualifiers syntactically.
+
+// check-pass
+// edition:2018
+
+#![feature(const_extern_fn)]
+//^ FIXME(Centril): move check to ast_validation.
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn syntax() {
+    async fn f();
+    unsafe fn f();
+    const fn f();
+    extern "C" fn f();
+    const /* async */ unsafe extern "C" fn f();
+    //^ FIXME(Centril): `async` should be legal syntactically.
+
+    trait X {
+        async fn f();
+        unsafe fn f();
+        const fn f();
+        extern "C" fn f();
+        /* const */ async unsafe extern "C" fn f();
+        //^ FIXME(Centril): `const` should be legal syntactically.
+    }
+
+    impl X for Y {
+        async fn f();
+        unsafe fn f();
+        const fn f();
+        extern "C" fn f();
+        /* const */ async unsafe extern "C" fn f();
+        //^ FIXME(Centril): `const` should be legal syntactically.
+    }
+
+    impl Y {
+        async fn f();
+        unsafe fn f();
+        const fn f();
+        extern "C" fn f();
+        /* const */ async unsafe extern "C" fn f();
+        //^ FIXME(Centril): `const` should be legal syntactically.
+    }
+
+    extern {
+        async fn f();
+        unsafe fn f();
+        const fn f();
+        extern "C" fn f();
+        /* const */ async unsafe extern "C" fn f();
+        //^ FIXME(Centril): `const` should be legal syntactically.
+    }
+}
diff --git a/src/test/ui/parser/issue-24780.rs b/src/test/ui/parser/issue-24780.rs
index 799cdd80222..8b46aa2bf22 100644
--- a/src/test/ui/parser/issue-24780.rs
+++ b/src/test/ui/parser/issue-24780.rs
@@ -3,6 +3,6 @@
 // expected one of ..., `>`, ... found `>`
 
 fn foo() -> Vec<usize>> {
-    //~^ ERROR expected one of `!`, `+`, `::`, `where`, or `{`, found `>`
+    //~^ ERROR expected `;` or `{`, found `>`
     Vec::new()
 }
diff --git a/src/test/ui/parser/issue-24780.stderr b/src/test/ui/parser/issue-24780.stderr
index d9470191b25..d65a5f44873 100644
--- a/src/test/ui/parser/issue-24780.stderr
+++ b/src/test/ui/parser/issue-24780.stderr
@@ -1,8 +1,8 @@
-error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>`
+error: expected `;` or `{`, found `>`
   --> $DIR/issue-24780.rs:5:23
    |
 LL | fn foo() -> Vec<usize>> {
-   |                       ^ expected one of `!`, `+`, `::`, `where`, or `{`
+   |                       ^ expected `;` or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-63135.rs b/src/test/ui/parser/issue-63135.rs
index d5f5f1469f3..7d46b8904f0 100644
--- a/src/test/ui/parser/issue-63135.rs
+++ b/src/test/ui/parser/issue-63135.rs
@@ -1,3 +1,3 @@
-// error-pattern: aborting due to 6 previous errors
+// error-pattern: aborting due to 7 previous errors
 
 fn i(n{...,f #
diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr
index 462fdf11f40..04afae93be0 100644
--- a/src/test/ui/parser/issue-63135.stderr
+++ b/src/test/ui/parser/issue-63135.stderr
@@ -43,5 +43,11 @@ error: expected one of `:` or `|`, found `)`
 LL | fn i(n{...,f #
    |                ^ expected one of `:` or `|`
 
-error: aborting due to 6 previous errors
+error: expected `;` or `{`, found `<eof>`
+  --> $DIR/issue-63135.rs:3:16
+   |
+LL | fn i(n{...,f #
+   |                ^ expected `;` or `{`
+
+error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs
index c35236ce793..810dee9571d 100644
--- a/src/test/ui/parser/missing_right_paren.rs
+++ b/src/test/ui/parser/missing_right_paren.rs
@@ -1,3 +1,3 @@
 // ignore-tidy-trailing-newlines
-// error-pattern: aborting due to 3 previous errors
+// error-pattern: aborting due to 4 previous errors
 fn main((ؼ
\ No newline at end of file
diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr
index d67e7c88912..c1ceb81a07c 100644
--- a/src/test/ui/parser/missing_right_paren.stderr
+++ b/src/test/ui/parser/missing_right_paren.stderr
@@ -22,5 +22,11 @@ error: expected one of `:` or `|`, found `)`
 LL | fn main((ؼ
    |           ^ expected one of `:` or `|`
 
-error: aborting due to 3 previous errors
+error: expected `;` or `{`, found `<eof>`
+  --> $DIR/missing_right_paren.rs:3:11
+   |
+LL | fn main((ؼ
+   |           ^ expected `;` or `{`
+
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.rs b/src/test/ui/parser/no-const-fn-in-extern-block.rs
index 29f26389ded..4cae703a163 100644
--- a/src/test/ui/parser/no-const-fn-in-extern-block.rs
+++ b/src/test/ui/parser/no-const-fn-in-extern-block.rs
@@ -1,8 +1,8 @@
 extern {
     const fn foo();
-    //~^ ERROR extern items cannot be `const`
+    //~^ ERROR functions in `extern` blocks cannot have qualifiers
     const unsafe fn bar();
-    //~^ ERROR extern items cannot be `const`
+    //~^ ERROR functions in `extern` blocks cannot have qualifiers
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/no-const-fn-in-extern-block.stderr b/src/test/ui/parser/no-const-fn-in-extern-block.stderr
index 5b4663a702f..de653987e40 100644
--- a/src/test/ui/parser/no-const-fn-in-extern-block.stderr
+++ b/src/test/ui/parser/no-const-fn-in-extern-block.stderr
@@ -1,14 +1,23 @@
-error: extern items cannot be `const`
-  --> $DIR/no-const-fn-in-extern-block.rs:2:5
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/no-const-fn-in-extern-block.rs:2:14
    |
+LL | extern {
+   | ------ in this `extern` block
 LL |     const fn foo();
-   |     ^^^^^
+   |     ---------^^^
+   |     |
+   |     help: remove the qualifiers: `fn`
 
-error: extern items cannot be `const`
-  --> $DIR/no-const-fn-in-extern-block.rs:4:5
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/no-const-fn-in-extern-block.rs:4:21
    |
+LL | extern {
+   | ------ in this `extern` block
+...
 LL |     const unsafe fn bar();
-   |     ^^^^^
+   |     ----------------^^^
+   |     |
+   |     help: remove the qualifiers: `fn`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr
index 90246b92bf0..dce54655fa0 100644
--- a/src/test/ui/parser/not-a-pred.stderr
+++ b/src/test/ui/parser/not-a-pred.stderr
@@ -1,8 +1,8 @@
-error: expected one of `->`, `where`, or `{`, found `:`
+error: expected `;` or `{`, found `:`
   --> $DIR/not-a-pred.rs:3:26
    |
 LL | fn f(a: isize, b: isize) : lt(a, b) { }
-   |                          ^ expected one of `->`, `where`, or `{`
+   |                          ^ expected `;` or `{`
 
 error: aborting due to previous error