about summary refs log tree commit diff
path: root/tests/ui/pub
diff options
context:
space:
mode:
authorAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-05 09:13:28 +0100
committerAlbert Larsan <74931857+albertlarsan68@users.noreply.github.com>2023-01-11 09:32:08 +0000
commitcf2dff2b1e3fa55fa5415d524200070d0d7aacfe (patch)
tree40a88d9a46aaf3e8870676eb2538378b75a263eb /tests/ui/pub
parentca855e6e42787ecd062d81d53336fe6788ef51a9 (diff)
downloadrust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.tar.gz
rust-cf2dff2b1e3fa55fa5415d524200070d0d7aacfe.zip
Move /src/test to /tests
Diffstat (limited to 'tests/ui/pub')
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs28
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr30
-rw-r--r--tests/ui/pub/pub-ident-fn-2.fixed10
-rw-r--r--tests/ui/pub/pub-ident-fn-2.rs10
-rw-r--r--tests/ui/pub/pub-ident-fn-2.stderr13
-rw-r--r--tests/ui/pub/pub-ident-fn-3.rs8
-rw-r--r--tests/ui/pub/pub-ident-fn-3.stderr8
-rw-r--r--tests/ui/pub/pub-ident-fn-or-struct-2.rs4
-rw-r--r--tests/ui/pub/pub-ident-fn-or-struct-2.stderr8
-rw-r--r--tests/ui/pub/pub-ident-fn-or-struct.rs4
-rw-r--r--tests/ui/pub/pub-ident-fn-or-struct.stderr8
-rw-r--r--tests/ui/pub/pub-ident-fn-with-lifetime-2.rs6
-rw-r--r--tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr13
-rw-r--r--tests/ui/pub/pub-ident-fn-with-lifetime.fixed8
-rw-r--r--tests/ui/pub/pub-ident-fn-with-lifetime.rs8
-rw-r--r--tests/ui/pub/pub-ident-fn-with-lifetime.stderr13
-rw-r--r--tests/ui/pub/pub-ident-fn.fixed8
-rw-r--r--tests/ui/pub/pub-ident-fn.rs8
-rw-r--r--tests/ui/pub/pub-ident-fn.stderr13
-rw-r--r--tests/ui/pub/pub-ident-struct-with-lifetime.rs4
-rw-r--r--tests/ui/pub/pub-ident-struct-with-lifetime.stderr13
-rw-r--r--tests/ui/pub/pub-ident-struct.fixed6
-rw-r--r--tests/ui/pub/pub-ident-struct.rs6
-rw-r--r--tests/ui/pub/pub-ident-struct.stderr13
-rw-r--r--tests/ui/pub/pub-ident-with-lifetime-incomplete.rs5
-rw-r--r--tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr8
-rw-r--r--tests/ui/pub/pub-reexport-priv-extern-crate.rs20
-rw-r--r--tests/ui/pub/pub-reexport-priv-extern-crate.stderr37
-rw-r--r--tests/ui/pub/pub-restricted-error-fn.rs2
-rw-r--r--tests/ui/pub/pub-restricted-error-fn.stderr16
-rw-r--r--tests/ui/pub/pub-restricted-error.rs7
-rw-r--r--tests/ui/pub/pub-restricted-error.stderr10
-rw-r--r--tests/ui/pub/pub-restricted-non-path.rs5
-rw-r--r--tests/ui/pub/pub-restricted-non-path.stderr8
-rw-r--r--tests/ui/pub/pub-restricted.rs31
-rw-r--r--tests/ui/pub/pub-restricted.stderr65
36 files changed, 464 insertions, 0 deletions
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
new file mode 100644
index 00000000000..67f888c5e94
--- /dev/null
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
@@ -0,0 +1,28 @@
+#![allow(non_camel_case_types)] // genus is always capitalized
+
+pub(crate) struct Snail;
+//~^ NOTE `Snail` declared as private
+
+mod sea {
+    pub(super) struct Turtle;
+    //~^ NOTE `Turtle` declared as crate-private
+}
+
+struct Tortoise;
+//~^ NOTE `Tortoise` declared as private
+
+pub struct Shell<T> {
+    pub(crate) creature: T,
+}
+
+pub type Helix_pomatia = Shell<Snail>;
+//~^ ERROR private type `Snail` in public interface
+//~| NOTE can't leak private type
+pub type Dermochelys_coriacea = Shell<sea::Turtle>;
+//~^ ERROR crate-private type `Turtle` in public interface
+//~| NOTE can't leak crate-private type
+pub type Testudo_graeca = Shell<Tortoise>;
+//~^ ERROR private type `Tortoise` in public interface
+//~| NOTE can't leak private type
+
+fn main() {}
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
new file mode 100644
index 00000000000..39d4f5ac8d3
--- /dev/null
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
@@ -0,0 +1,30 @@
+error[E0446]: private type `Snail` in public interface
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:18:1
+   |
+LL | pub(crate) struct Snail;
+   | ----------------------- `Snail` declared as private
+...
+LL | pub type Helix_pomatia = Shell<Snail>;
+   | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+
+error[E0446]: crate-private type `Turtle` in public interface
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:21:1
+   |
+LL |     pub(super) struct Turtle;
+   |     ------------------------ `Turtle` declared as crate-private
+...
+LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
+
+error[E0446]: private type `Tortoise` in public interface
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:24:1
+   |
+LL | struct Tortoise;
+   | --------------- `Tortoise` declared as private
+...
+LL | pub type Testudo_graeca = Shell<Tortoise>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/pub/pub-ident-fn-2.fixed b/tests/ui/pub/pub-ident-fn-2.fixed
new file mode 100644
index 00000000000..afd75a41f7b
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-2.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+pub fn foo(_s: usize) { bar() }
+//~^ ERROR missing `fn` for function definition
+
+fn bar() {}
+
+fn main() {
+    foo(2);
+}
diff --git a/tests/ui/pub/pub-ident-fn-2.rs b/tests/ui/pub/pub-ident-fn-2.rs
new file mode 100644
index 00000000000..e7b86a9098d
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-2.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+
+pub foo(_s: usize) { bar() }
+//~^ ERROR missing `fn` for function definition
+
+fn bar() {}
+
+fn main() {
+    foo(2);
+}
diff --git a/tests/ui/pub/pub-ident-fn-2.stderr b/tests/ui/pub/pub-ident-fn-2.stderr
new file mode 100644
index 00000000000..b5b667b41b6
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-2.stderr
@@ -0,0 +1,13 @@
+error: missing `fn` for function definition
+  --> $DIR/pub-ident-fn-2.rs:3:4
+   |
+LL | pub foo(_s: usize) { bar() }
+   |    ^
+   |
+help: add `fn` here to parse `foo` as a public function
+   |
+LL | pub fn foo(_s: usize) { bar() }
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn-3.rs b/tests/ui/pub/pub-ident-fn-3.rs
new file mode 100644
index 00000000000..fdbea7cf487
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-3.rs
@@ -0,0 +1,8 @@
+// #60115
+
+mod foo {
+    pub bar();
+    //~^ ERROR missing `fn` or `struct` for function or struct definition
+}
+
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-fn-3.stderr b/tests/ui/pub/pub-ident-fn-3.stderr
new file mode 100644
index 00000000000..6d3d4e592c8
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-3.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/pub-ident-fn-3.rs:4:8
+   |
+LL |     pub bar();
+   |     ---^--- help: if you meant to call a macro, try: `bar!`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn-or-struct-2.rs b/tests/ui/pub/pub-ident-fn-or-struct-2.rs
new file mode 100644
index 00000000000..8f67cdd2933
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-or-struct-2.rs
@@ -0,0 +1,4 @@
+pub S();
+//~^ ERROR missing `fn` or `struct` for function or struct definition
+
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-fn-or-struct-2.stderr b/tests/ui/pub/pub-ident-fn-or-struct-2.stderr
new file mode 100644
index 00000000000..047e66b18d8
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-or-struct-2.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/pub-ident-fn-or-struct-2.rs:1:4
+   |
+LL | pub S();
+   | ---^- help: if you meant to call a macro, try: `S!`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn-or-struct.rs b/tests/ui/pub/pub-ident-fn-or-struct.rs
new file mode 100644
index 00000000000..832831d2920
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-or-struct.rs
@@ -0,0 +1,4 @@
+pub S (foo) bar
+//~^ ERROR missing `fn` or `struct` for function or struct definition
+
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-fn-or-struct.stderr b/tests/ui/pub/pub-ident-fn-or-struct.stderr
new file mode 100644
index 00000000000..c4a196eb2c2
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-or-struct.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/pub-ident-fn-or-struct.rs:1:4
+   |
+LL | pub S (foo) bar
+   | ---^- help: if you meant to call a macro, try: `S!`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs b/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs
new file mode 100644
index 00000000000..1ee8c84f13b
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-with-lifetime-2.rs
@@ -0,0 +1,6 @@
+pub   bar<'a>(&self, _s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for method definition
+
+fn main() {
+    bar(2);
+}
diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr b/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr
new file mode 100644
index 00000000000..6a9aeaf4a56
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-with-lifetime-2.stderr
@@ -0,0 +1,13 @@
+error: missing `fn` for method definition
+  --> $DIR/pub-ident-fn-with-lifetime-2.rs:1:4
+   |
+LL | pub   bar<'a>(&self, _s: &'a usize) -> bool { true }
+   |    ^^^
+   |
+help: add `fn` here to parse `bar` as a public method
+   |
+LL | pub fn bar<'a>(&self, _s: &'a usize) -> bool { true }
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime.fixed b/tests/ui/pub/pub-ident-fn-with-lifetime.fixed
new file mode 100644
index 00000000000..e510ace5fc1
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-with-lifetime.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub fn foo<'a>(_s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(&2);
+}
diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime.rs b/tests/ui/pub/pub-ident-fn-with-lifetime.rs
new file mode 100644
index 00000000000..63e6eca1516
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-with-lifetime.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub   foo<'a>(_s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(&2);
+}
diff --git a/tests/ui/pub/pub-ident-fn-with-lifetime.stderr b/tests/ui/pub/pub-ident-fn-with-lifetime.stderr
new file mode 100644
index 00000000000..c1ca0136b18
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn-with-lifetime.stderr
@@ -0,0 +1,13 @@
+error: missing `fn` for function definition
+  --> $DIR/pub-ident-fn-with-lifetime.rs:3:4
+   |
+LL | pub   foo<'a>(_s: &'a usize) -> bool { true }
+   |    ^^^
+   |
+help: add `fn` here to parse `foo` as a public function
+   |
+LL | pub fn foo<'a>(_s: &'a usize) -> bool { true }
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-fn.fixed b/tests/ui/pub/pub-ident-fn.fixed
new file mode 100644
index 00000000000..65ed8c7b4dd
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub fn foo(_s: usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(2);
+}
diff --git a/tests/ui/pub/pub-ident-fn.rs b/tests/ui/pub/pub-ident-fn.rs
new file mode 100644
index 00000000000..2fe4d34fb22
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub   foo(_s: usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(2);
+}
diff --git a/tests/ui/pub/pub-ident-fn.stderr b/tests/ui/pub/pub-ident-fn.stderr
new file mode 100644
index 00000000000..cb94c48add4
--- /dev/null
+++ b/tests/ui/pub/pub-ident-fn.stderr
@@ -0,0 +1,13 @@
+error: missing `fn` for function definition
+  --> $DIR/pub-ident-fn.rs:3:4
+   |
+LL | pub   foo(_s: usize) -> bool { true }
+   |    ^^^
+   |
+help: add `fn` here to parse `foo` as a public function
+   |
+LL | pub fn foo(_s: usize) -> bool { true }
+   |     ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-struct-with-lifetime.rs b/tests/ui/pub/pub-ident-struct-with-lifetime.rs
new file mode 100644
index 00000000000..2feb0266070
--- /dev/null
+++ b/tests/ui/pub/pub-ident-struct-with-lifetime.rs
@@ -0,0 +1,4 @@
+pub S<'a> {
+//~^ ERROR missing `struct` for struct definition
+}
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-struct-with-lifetime.stderr b/tests/ui/pub/pub-ident-struct-with-lifetime.stderr
new file mode 100644
index 00000000000..562b68e3542
--- /dev/null
+++ b/tests/ui/pub/pub-ident-struct-with-lifetime.stderr
@@ -0,0 +1,13 @@
+error: missing `struct` for struct definition
+  --> $DIR/pub-ident-struct-with-lifetime.rs:1:4
+   |
+LL | pub S<'a> {
+   |    ^
+   |
+help: add `struct` here to parse `S` as a public struct
+   |
+LL | pub struct S<'a> {
+   |     ++++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-struct.fixed b/tests/ui/pub/pub-ident-struct.fixed
new file mode 100644
index 00000000000..58cde8fd6e0
--- /dev/null
+++ b/tests/ui/pub/pub-ident-struct.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+pub struct S {
+//~^ ERROR missing `struct` for struct definition
+}
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-struct.rs b/tests/ui/pub/pub-ident-struct.rs
new file mode 100644
index 00000000000..3930e556e9a
--- /dev/null
+++ b/tests/ui/pub/pub-ident-struct.rs
@@ -0,0 +1,6 @@
+// run-rustfix
+
+pub S {
+//~^ ERROR missing `struct` for struct definition
+}
+fn main() {}
diff --git a/tests/ui/pub/pub-ident-struct.stderr b/tests/ui/pub/pub-ident-struct.stderr
new file mode 100644
index 00000000000..d3a378786e4
--- /dev/null
+++ b/tests/ui/pub/pub-ident-struct.stderr
@@ -0,0 +1,13 @@
+error: missing `struct` for struct definition
+  --> $DIR/pub-ident-struct.rs:3:4
+   |
+LL | pub S {
+   |    ^
+   |
+help: add `struct` here to parse `S` as a public struct
+   |
+LL | pub struct S {
+   |     ++++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs b/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs
new file mode 100644
index 00000000000..c86a9f2fdd6
--- /dev/null
+++ b/tests/ui/pub/pub-ident-with-lifetime-incomplete.rs
@@ -0,0 +1,5 @@
+fn main() {
+}
+
+pub   foo<'a>
+//~^ ERROR missing `fn` or `struct` for function or struct definition
diff --git a/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr b/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr
new file mode 100644
index 00000000000..0e0b127054d
--- /dev/null
+++ b/tests/ui/pub/pub-ident-with-lifetime-incomplete.stderr
@@ -0,0 +1,8 @@
+error: missing `fn` or `struct` for function or struct definition
+  --> $DIR/pub-ident-with-lifetime-incomplete.rs:4:4
+   |
+LL | pub   foo<'a>
+   |    ^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-reexport-priv-extern-crate.rs b/tests/ui/pub/pub-reexport-priv-extern-crate.rs
new file mode 100644
index 00000000000..dd5cd420fa5
--- /dev/null
+++ b/tests/ui/pub/pub-reexport-priv-extern-crate.rs
@@ -0,0 +1,20 @@
+extern crate core;
+pub use core as reexported_core; //~ ERROR `core` is private, and cannot be re-exported
+                                 //~^ WARN this was previously accepted
+
+mod foo1 {
+    extern crate core;
+}
+
+mod foo2 {
+    use foo1::core; //~ ERROR crate import `core` is private
+    pub mod bar {
+        extern crate core;
+    }
+}
+
+mod baz {
+    pub use foo2::bar::core; //~ ERROR crate import `core` is private
+}
+
+fn main() {}
diff --git a/tests/ui/pub/pub-reexport-priv-extern-crate.stderr b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr
new file mode 100644
index 00000000000..c7fadc6f929
--- /dev/null
+++ b/tests/ui/pub/pub-reexport-priv-extern-crate.stderr
@@ -0,0 +1,37 @@
+error[E0603]: crate import `core` is private
+  --> $DIR/pub-reexport-priv-extern-crate.rs:10:15
+   |
+LL |     use foo1::core;
+   |               ^^^^ private crate import
+   |
+note: the crate import `core` is defined here
+  --> $DIR/pub-reexport-priv-extern-crate.rs:6:5
+   |
+LL |     extern crate core;
+   |     ^^^^^^^^^^^^^^^^^^
+
+error[E0603]: crate import `core` is private
+  --> $DIR/pub-reexport-priv-extern-crate.rs:17:24
+   |
+LL |     pub use foo2::bar::core;
+   |                        ^^^^ private crate import
+   |
+note: the crate import `core` is defined here
+  --> $DIR/pub-reexport-priv-extern-crate.rs:12:9
+   |
+LL |         extern crate core;
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: extern crate `core` is private, and cannot be re-exported (error E0365), consider declaring with `pub`
+  --> $DIR/pub-reexport-priv-extern-crate.rs:2:9
+   |
+LL | pub use core as reexported_core;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
+   = note: `#[deny(pub_use_of_private_extern_crate)]` on by default
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/tests/ui/pub/pub-restricted-error-fn.rs b/tests/ui/pub/pub-restricted-error-fn.rs
new file mode 100644
index 00000000000..fc1aeae2b0c
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-error-fn.rs
@@ -0,0 +1,2 @@
+pub(crate) () fn foo() {} //~ ERROR visibility `pub(crate)` is not followed by an item
+//~^ ERROR expected item, found `(`
diff --git a/tests/ui/pub/pub-restricted-error-fn.stderr b/tests/ui/pub/pub-restricted-error-fn.stderr
new file mode 100644
index 00000000000..0511a821a7a
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-error-fn.stderr
@@ -0,0 +1,16 @@
+error: visibility `pub(crate)` is not followed by an item
+  --> $DIR/pub-restricted-error-fn.rs:1:1
+   |
+LL | pub(crate) () fn foo() {}
+   | ^^^^^^^^^^ the visibility
+   |
+   = help: you likely meant to define an item, e.g., `pub(crate) fn foo() {}`
+
+error: expected item, found `(`
+  --> $DIR/pub-restricted-error-fn.rs:1:12
+   |
+LL | pub(crate) () fn foo() {}
+   |            ^ expected item
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/pub/pub-restricted-error.rs b/tests/ui/pub/pub-restricted-error.rs
new file mode 100644
index 00000000000..60fce3f51b8
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-error.rs
@@ -0,0 +1,7 @@
+struct Bar(pub(()));
+
+struct Foo {
+    pub(crate) () foo: usize, //~ ERROR expected identifier
+}
+
+fn main() {}
diff --git a/tests/ui/pub/pub-restricted-error.stderr b/tests/ui/pub/pub-restricted-error.stderr
new file mode 100644
index 00000000000..b47328f34e6
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-error.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `(`
+  --> $DIR/pub-restricted-error.rs:4:16
+   |
+LL | struct Foo {
+   |        --- while parsing this struct
+LL |     pub(crate) () foo: usize,
+   |                ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-restricted-non-path.rs b/tests/ui/pub/pub-restricted-non-path.rs
new file mode 100644
index 00000000000..bdad18dbe65
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-non-path.rs
@@ -0,0 +1,5 @@
+#![feature(pub_restricted)]
+
+pub (.) fn afn() {} //~ ERROR expected identifier
+
+fn main() {}
diff --git a/tests/ui/pub/pub-restricted-non-path.stderr b/tests/ui/pub/pub-restricted-non-path.stderr
new file mode 100644
index 00000000000..e0ea50621f7
--- /dev/null
+++ b/tests/ui/pub/pub-restricted-non-path.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `.`
+  --> $DIR/pub-restricted-non-path.rs:3:6
+   |
+LL | pub (.) fn afn() {}
+   |      ^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/pub/pub-restricted.rs b/tests/ui/pub/pub-restricted.rs
new file mode 100644
index 00000000000..bcd21082f75
--- /dev/null
+++ b/tests/ui/pub/pub-restricted.rs
@@ -0,0 +1,31 @@
+mod a {}
+
+pub (a) fn afn() {} //~ incorrect visibility restriction
+pub (b) fn bfn() {} //~ incorrect visibility restriction
+pub (crate::a) fn cfn() {} //~ incorrect visibility restriction
+
+pub fn privfn() {}
+mod x {
+    mod y {
+        pub (in x) fn foo() {}
+        pub (super) fn bar() {}
+        pub (crate) fn qux() {}
+    }
+}
+
+mod y {
+    struct Foo {
+        pub (crate) c: usize,
+        pub (super) s: usize,
+        valid_private: usize,
+        pub (in y) valid_in_x: usize,
+        pub (a) invalid: usize, //~ incorrect visibility restriction
+        pub (in x) non_parent_invalid: usize, //~ ERROR visibilities can only be restricted
+    }
+}
+
+fn main() {}
+
+// test multichar names
+mod xyz {}
+pub (xyz) fn xyz() {} //~ incorrect visibility restriction
diff --git a/tests/ui/pub/pub-restricted.stderr b/tests/ui/pub/pub-restricted.stderr
new file mode 100644
index 00000000000..4694530e548
--- /dev/null
+++ b/tests/ui/pub/pub-restricted.stderr
@@ -0,0 +1,65 @@
+error[E0704]: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:3:6
+   |
+LL | pub (a) fn afn() {}
+   |      ^ help: make this visible only to module `a` with `in`: `in a`
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+
+error[E0704]: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:4:6
+   |
+LL | pub (b) fn bfn() {}
+   |      ^ help: make this visible only to module `b` with `in`: `in b`
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+
+error[E0704]: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:5:6
+   |
+LL | pub (crate::a) fn cfn() {}
+   |      ^^^^^^^^ help: make this visible only to module `crate::a` with `in`: `in crate::a`
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+
+error[E0704]: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:22:14
+   |
+LL |         pub (a) invalid: usize,
+   |              ^ help: make this visible only to module `a` with `in`: `in a`
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+
+error[E0704]: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:31:6
+   |
+LL | pub (xyz) fn xyz() {}
+   |      ^^^ help: make this visible only to module `xyz` with `in`: `in xyz`
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+
+error[E0742]: visibilities can only be restricted to ancestor modules
+  --> $DIR/pub-restricted.rs:23:17
+   |
+LL |         pub (in x) non_parent_invalid: usize,
+   |                 ^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0704, E0742.
+For more information about an error, try `rustc --explain E0704`.