]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_privacy/lib.rs
Auto merge of #28504 - Eljay:fix-trait-privacy, r=nrc
[rust.git] / src / librustc_privacy / lib.rs
index 7f72ccb51e60db41da7bf83ee68cefda2a871fa6..710341952a7e8e718e459752591e16e5748d96dd 100644 (file)
@@ -50,6 +50,8 @@
 use syntax::ast;
 use syntax::codemap::Span;
 
+pub mod diagnostics;
+
 type Context<'a, 'tcx> = (&'a ty::MethodMap<'tcx>, &'a def::ExportMap);
 
 /// Result of a checking operation - None => no errors were found. Some => an
@@ -715,7 +717,8 @@ fn check_field(&mut self,
             UnnamedField(idx) => format!("field #{} of {} is private",
                                          idx + 1, struct_desc),
         };
-        self.tcx.sess.span_err(span, &msg[..]);
+        span_err!(self.tcx.sess, span, E0451,
+                  "{}", &msg[..]);
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
@@ -844,35 +847,14 @@ fn check_method(&mut self, span: Span, method_def_id: DefId,
             ty::ImplContainer(_) => {
                 self.check_static_method(span, method_def_id, name)
             }
-            // Trait methods are always all public. The only controlling factor
-            // is whether the trait itself is accessible or not.
-            ty::TraitContainer(trait_def_id) => {
-                self.report_error(self.ensure_public(span, trait_def_id,
-                                                     None, "source trait"));
-            }
+            // Trait methods are always accessible if the trait is in scope.
+            ty::TraitContainer(_) => {}
         }
     }
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
-        if let hir::ItemUse(ref vpath) = item.node {
-            if let hir::ViewPathList(ref prefix, ref list) = vpath.node {
-                for pid in list {
-                    match pid.node {
-                        hir::PathListIdent { id, name, .. } => {
-                            debug!("privacy - ident item {}", id);
-                            self.check_path(pid.span, id, name.name);
-                        }
-                        hir::PathListMod { id, .. } => {
-                            debug!("privacy - mod item {}", id);
-                            let name = prefix.segments.last().unwrap().identifier.name;
-                            self.check_path(pid.span, id, name);
-                        }
-                    }
-                }
-            }
-        }
         let orig_curitem = replace(&mut self.curitem, item.id);
         visit::walk_item(self, item);
         self.curitem = orig_curitem;
@@ -929,9 +911,9 @@ fn visit_expr(&mut self, expr: &hir::Expr) {
                         });
 
                     if any_priv {
-                        self.tcx.sess.span_err(expr.span,
-                                               "cannot invoke tuple struct constructor \
-                                                with private fields");
+                        span_err!(self.tcx.sess, expr.span, E0450,
+                                  "cannot invoke tuple struct constructor with private \
+                                   fields");
                     }
                 }
             }
@@ -994,8 +976,22 @@ fn visit_foreign_item(&mut self, fi: &hir::ForeignItem) {
     }
 
     fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
-        self.check_path(path.span, id, path.segments.last().unwrap().identifier.name);
-        visit::walk_path(self, path);
+        if !path.segments.is_empty() {
+            self.check_path(path.span, id, path.segments.last().unwrap().identifier.name);
+            visit::walk_path(self, path);
+        }
+    }
+
+    fn visit_path_list_item(&mut self, prefix: &hir::Path, item: &hir::PathListItem) {
+        let name = if let hir::PathListIdent { name, .. } = item.node {
+            name.name
+        } else if !prefix.segments.is_empty() {
+            prefix.segments.last().unwrap().identifier.name
+        } else {
+            self.tcx.sess.bug("`self` import in an import list with empty prefix");
+        };
+        self.check_path(item.span, item.node.id(), name);
+        visit::walk_path_list_item(self, prefix, item);
     }
 }
 
@@ -1043,7 +1039,8 @@ fn check_sane_privacy(&self, item: &hir::Item) {
         let tcx = self.tcx;
         let check_inherited = |sp: Span, vis: hir::Visibility, note: &str| {
             if vis != hir::Inherited {
-                tcx.sess.span_err(sp, "unnecessary visibility qualifier");
+                span_err!(tcx.sess, sp, E0449,
+                          "unnecessary visibility qualifier");
                 if !note.is_empty() {
                     tcx.sess.span_note(sp, note);
                 }
@@ -1071,20 +1068,7 @@ fn check_sane_privacy(&self, item: &hir::Item) {
                                  instead");
             }
 
-            hir::ItemEnum(ref def, _) => {
-                for v in &def.variants {
-                    match v.node.vis {
-                        hir::Public => {
-                            if item.vis == hir::Public {
-                                tcx.sess.span_err(v.span, "unnecessary `pub` \
-                                                           visibility");
-                            }
-                        }
-                        hir::Inherited => {}
-                    }
-                }
-            }
-
+            hir::ItemEnum(..) |
             hir::ItemTrait(..) | hir::ItemDefaultImpl(..) |
             hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemStruct(..) |
             hir::ItemFn(..) | hir::ItemMod(..) | hir::ItemTy(..) |
@@ -1098,7 +1082,8 @@ fn check_all_inherited(&self, item: &hir::Item) {
         let tcx = self.tcx;
         fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) {
             if vis != hir::Inherited {
-                tcx.sess.span_err(sp, "visibility has no effect inside functions");
+                span_err!(tcx.sess, sp, E0447,
+                          "visibility has no effect inside functions");
             }
         }
         let check_struct = |def: &hir::StructDef| {
@@ -1126,14 +1111,10 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: hir::Visibility) {
                     check_inherited(tcx, i.span, i.vis);
                 }
             }
-            hir::ItemEnum(ref def, _) => {
-                for v in &def.variants {
-                    check_inherited(tcx, v.span, v.node.vis);
-                }
-            }
 
             hir::ItemStruct(ref def, _) => check_struct(&**def),
 
+            hir::ItemEnum(..) |
             hir::ItemExternCrate(_) | hir::ItemUse(_) |
             hir::ItemTrait(..) | hir::ItemDefaultImpl(..) |
             hir::ItemStatic(..) | hir::ItemConst(..) |
@@ -1193,8 +1174,8 @@ fn check_ty_param_bound(&self,
             if !self.tcx.sess.features.borrow().visible_private_types &&
                 self.path_is_private_type(trait_ref.trait_ref.ref_id) {
                     let span = trait_ref.trait_ref.path.span;
-                    self.tcx.sess.span_err(span, "private trait in exported type \
-                                                  parameter bound");
+                    span_err!(self.tcx.sess, span, E0445,
+                              "private trait in exported type parameter bound");
             }
         }
     }
@@ -1435,7 +1416,8 @@ fn visit_ty(&mut self, t: &hir::Ty) {
         if let hir::TyPath(_, ref p) = t.node {
             if !self.tcx.sess.features.borrow().visible_private_types &&
                 self.path_is_private_type(t.id) {
-                self.tcx.sess.span_err(p.span, "private type in exported type signature");
+                span_err!(self.tcx.sess, p.span, E0446,
+                          "private type in exported type signature");
             }
         }
         visit::walk_ty(self, t)