about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-10-31 00:22:19 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-11-25 16:40:03 +0300
commitd4a78da543fd8959edf386602537bece057a3918 (patch)
tree12a0041c26c27bf65f0801bef1982fa7fffe2951 /src
parentabe19a730576cf7ead1bf7995271b53d551ea37f (diff)
downloadrust-d4a78da543fd8959edf386602537bece057a3918.tar.gz
rust-d4a78da543fd8959edf386602537bece057a3918.zip
resolve: Prohibit relative paths in visibilities on 2018 edition
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/lib.rs13
-rw-r--r--src/test/ui/privacy/restricted/relative-2018.rs13
-rw-r--r--src/test/ui/privacy/restricted/relative-2018.stderr16
3 files changed, 41 insertions, 1 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 12dabd2a31d..a392ab717c0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -4710,7 +4710,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
             }
             ast::VisibilityKind::Restricted { ref path, id, .. } => {
-                // Visibilities are resolved as global by default, add starting root segment.
+                // For visibilities we are not ready to provide correct implementation of "uniform
+                // paths" right now, so on 2018 edition we only allow module-relative paths for now.
+                let first_ident = path.segments[0].ident;
+                if self.session.rust_2018() && !first_ident.is_path_segment_keyword() {
+                    let msg = "relative paths are not supported in visibilities on 2018 edition";
+                    self.session.struct_span_err(first_ident.span, msg)
+                                .span_suggestion(path.span, "try", format!("crate::{}", path))
+                                .emit();
+                    return ty::Visibility::Public;
+                }
+                // On 2015 visibilities are resolved as crate-relative by default,
+                // add starting root segment if necessary.
                 let segments = path.make_root().iter().chain(path.segments.iter())
                     .map(|seg| Segment { ident: seg.ident, id: Some(seg.id) })
                     .collect::<Vec<_>>();
diff --git a/src/test/ui/privacy/restricted/relative-2018.rs b/src/test/ui/privacy/restricted/relative-2018.rs
new file mode 100644
index 00000000000..69b7c1e4d4f
--- /dev/null
+++ b/src/test/ui/privacy/restricted/relative-2018.rs
@@ -0,0 +1,13 @@
+// edition:2018
+
+mod m {
+    pub(in crate) struct S1; // OK
+    pub(in super) struct S2; // OK
+    pub(in self) struct S3; // OK
+    pub(in ::core) struct S4;
+    //~^ ERROR visibilities can only be restricted to ancestor modules
+    pub(in a::b) struct S5;
+    //~^ ERROR relative paths are not supported in visibilities on 2018 edition
+}
+
+fn main() {}
diff --git a/src/test/ui/privacy/restricted/relative-2018.stderr b/src/test/ui/privacy/restricted/relative-2018.stderr
new file mode 100644
index 00000000000..61effc463e9
--- /dev/null
+++ b/src/test/ui/privacy/restricted/relative-2018.stderr
@@ -0,0 +1,16 @@
+error: visibilities can only be restricted to ancestor modules
+  --> $DIR/relative-2018.rs:7:12
+   |
+LL |     pub(in ::core) struct S4;
+   |            ^^^^^^
+
+error: relative paths are not supported in visibilities on 2018 edition
+  --> $DIR/relative-2018.rs:9:12
+   |
+LL |     pub(in a::b) struct S5;
+   |            ^---
+   |            |
+   |            help: try: `crate::a::b`
+
+error: aborting due to 2 previous errors
+