]> git.lizzy.rs Git - rust.git/commitdiff
Use recorded types in rustc_privacy
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 16 Sep 2017 13:45:49 +0000 (16:45 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Fri, 22 Sep 2017 21:50:46 +0000 (00:50 +0300)
src/Cargo.lock
src/librustc_privacy/Cargo.toml
src/librustc_privacy/lib.rs
src/test/compile-fail/lint-stability-deprecated.rs
src/test/compile-fail/private-inferred-type.rs
src/test/compile-fail/private-type-in-interface.rs

index 3a9d9ad9c5456c2c97bfb022d184054d0ba88541..807375e00afdbe58a9fac223154c477aaab35317 100644 (file)
@@ -1715,6 +1715,7 @@ name = "rustc_privacy"
 version = "0.0.0"
 dependencies = [
  "rustc 0.0.0",
+ "rustc_typeck 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
index 439fa661e0ab52dfc117c8dc48c749d43b4295b3..c65312e9a8337e8fd48f3d290d91926bb97956d6 100644 (file)
@@ -10,5 +10,6 @@ crate-type = ["dylib"]
 
 [dependencies]
 rustc = { path = "../librustc" }
+rustc_typeck = { path = "../librustc_typeck" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
index 0d5ad6f47c9ad8a927685e14768649031b239f9e..e7a1dd6b043b173b51022a94877f785c0a301d35 100644 (file)
@@ -17,6 +17,7 @@
 
 #[macro_use] extern crate rustc;
 #[macro_use] extern crate syntax;
+extern crate rustc_typeck;
 extern crate syntax_pos;
 
 use rustc::hir::{self, PatKind};
@@ -658,65 +659,6 @@ fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
         }
         false
     }
-
-    fn check_item(&mut self, item_id: ast::NodeId) -> &mut Self {
-        self.current_item = self.tcx.hir.local_def_id(item_id);
-        self.span = self.tcx.hir.span(item_id);
-        self
-    }
-
-    // Convenience methods for checking item interfaces
-    fn ty(&mut self) -> &mut Self {
-        self.tcx.type_of(self.current_item).visit_with(self);
-        self
-    }
-
-    fn generics(&mut self) -> &mut Self {
-        for def in &self.tcx.generics_of(self.current_item).types {
-            if def.has_default {
-                self.tcx.type_of(def.def_id).visit_with(self);
-            }
-        }
-        self
-    }
-
-    fn predicates(&mut self) -> &mut Self {
-        let predicates = self.tcx.predicates_of(self.current_item);
-        for predicate in &predicates.predicates {
-            predicate.visit_with(self);
-            match predicate {
-                &ty::Predicate::Trait(poly_predicate) => {
-                    self.check_trait_ref(poly_predicate.skip_binder().trait_ref);
-                },
-                &ty::Predicate::Projection(poly_predicate) => {
-                    let tcx = self.tcx;
-                    self.check_trait_ref(
-                        poly_predicate.skip_binder().projection_ty.trait_ref(tcx)
-                    );
-                },
-                _ => (),
-            };
-        }
-        self
-    }
-
-    fn impl_trait_ref(&mut self) -> &mut Self {
-        if let Some(impl_trait_ref) = self.tcx.impl_trait_ref(self.current_item) {
-            self.check_trait_ref(impl_trait_ref);
-        }
-        self.tcx.predicates_of(self.current_item).visit_with(self);
-        self
-    }
-
-    fn check_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
-        if !self.item_is_accessible(trait_ref.def_id) {
-            let msg = format!("trait `{}` is private", trait_ref);
-            self.tcx.sess.span_err(self.span, &msg);
-            return true;
-        }
-
-        trait_ref.super_visit_with(self)
-    }
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
@@ -733,6 +675,35 @@ fn visit_nested_body(&mut self, body: hir::BodyId) {
         self.tables = orig_tables;
     }
 
+    fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty) {
+        self.span = hir_ty.span;
+        if let Some(ty) = self.tables.node_id_to_type_opt(hir_ty.hir_id) {
+            // Types in bodies.
+            if ty.visit_with(self) {
+                return;
+            }
+        } else {
+            // Types in signatures.
+            // FIXME: This is very ineffective. Ideally each HIR type should be converted
+            // into a semantic type only once and the result should be cached somehow.
+            if rustc_typeck::hir_ty_to_ty(self.tcx, hir_ty).visit_with(self) {
+                return;
+            }
+        }
+
+        intravisit::walk_ty(self, hir_ty);
+    }
+
+    fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef) {
+        if !self.item_is_accessible(trait_ref.path.def.def_id()) {
+            let msg = format!("trait `{:?}` is private", trait_ref.path);
+            self.tcx.sess.span_err(self.span, &msg);
+            return;
+        }
+
+        intravisit::walk_trait_ref(self, trait_ref);
+    }
+
     // Check types of expressions
     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         if self.check_expr_pat_type(expr.hir_id, expr.span) {
@@ -807,63 +778,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
                                         item.id,
                                         &mut self.tables,
                                         self.empty_tables);
-
-        match item.node {
-            hir::ItemExternCrate(..) | hir::ItemMod(..) |
-            hir::ItemUse(..) | hir::ItemGlobalAsm(..) => {}
-            hir::ItemConst(..) | hir::ItemStatic(..) |
-            hir::ItemTy(..) | hir::ItemFn(..) => {
-                self.check_item(item.id).generics().predicates().ty();
-            }
-            hir::ItemTrait(.., ref trait_item_refs) => {
-                self.check_item(item.id).generics().predicates();
-                for trait_item_ref in trait_item_refs {
-                    let check = self.check_item(trait_item_ref.id.node_id);
-                    check.generics().predicates();
-                    if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
-                       trait_item_ref.defaultness.has_value() {
-                        check.ty();
-                    }
-                }
-            }
-            hir::ItemEnum(ref def, _) => {
-                self.check_item(item.id).generics().predicates();
-                for variant in &def.variants {
-                    for field in variant.node.data.fields() {
-                        self.check_item(field.id).ty();
-                    }
-                }
-            }
-            hir::ItemForeignMod(ref foreign_mod) => {
-                for foreign_item in &foreign_mod.items {
-                    self.check_item(foreign_item.id).generics().predicates().ty();
-                }
-            }
-            hir::ItemStruct(ref struct_def, _) |
-            hir::ItemUnion(ref struct_def, _) => {
-                self.check_item(item.id).generics().predicates();
-                for field in struct_def.fields() {
-                    self.check_item(field.id).ty();
-                }
-            }
-            hir::ItemDefaultImpl(..) => {
-                self.check_item(item.id).impl_trait_ref();
-            }
-            hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
-                {
-                    let check = self.check_item(item.id);
-                    check.ty().generics().predicates();
-                    if trait_ref.is_some() {
-                        check.impl_trait_ref();
-                    }
-                }
-                for impl_item_ref in impl_item_refs {
-                    let impl_item = self.tcx.hir.impl_item(impl_item_ref.id);
-                    self.check_item(impl_item.id).generics().predicates().ty();
-                }
-            }
-        }
-
         self.current_item = self.tcx.hir.local_def_id(item.id);
         intravisit::walk_item(self, item);
         self.tables = orig_tables;
@@ -924,8 +838,13 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
                 }
             }
             ty::TyProjection(ref proj) => {
-                let tcx = self.tcx;
-                if self.check_trait_ref(proj.trait_ref(tcx)) {
+                let trait_ref = proj.trait_ref(self.tcx);
+                if !self.item_is_accessible(trait_ref.def_id) {
+                    let msg = format!("trait `{}` is private", trait_ref);
+                    self.tcx.sess.span_err(self.span, &msg);
+                    return true;
+                }
+                if trait_ref.super_visit_with(self) {
                     return true;
                 }
             }
index 9bc2c021904aad24dee2886f8a9cf2b8db797e5a..de455afbd6629d73b4cc9fa265dc43528b800d07 100644 (file)
@@ -107,6 +107,7 @@ fn test() {
         struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
         //~^ WARN use of deprecated item
+        //~| WARN use of deprecated item
 
         let _ = DeprecatedStruct { //~ WARN use of deprecated item
             i: 0 //~ WARN use of deprecated item
index 4d41f8ba47d014334ed82e4e7e3ba01024df2bb8..973d467b1122670184cbee8cf5e345b6ac899b22 100644 (file)
@@ -103,10 +103,11 @@ pub fn method_s3(&self) {}
 
 fn main() {
     let _: m::Alias; //~ ERROR type `m::Priv` is private
-    let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; // FIXME
+                     //~^ ERROR type `m::Priv` is private
+    let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; //~ ERROR type `m::Priv` is private
     m::Alias {}; //~ ERROR type `m::Priv` is private
     m::Pub { 0: m::Alias {} }; //~ ERROR type `m::Priv` is private
-    m::Pub { 0: loop {} }; // FIXME
+    m::Pub { 0: loop {} }; // OK, `m::Pub` is in value context, so it means Pub<_>, not Pub<Priv>
     m::Pub::static_method; //~ ERROR type `m::Priv` is private
     m::Pub::INHERENT_ASSOC_CONST; //~ ERROR type `m::Priv` is private
     m::Pub(0u8).method_with_substs::<m::Alias>(); //~ ERROR type `m::Priv` is private
index a5581664f741859baa603fd7c7b140a73f850d60..eb8c40a7dd5e821b0436334be6a073b900dfd1b6 100644 (file)
@@ -31,7 +31,6 @@ fn f_ext(_: ext::Alias) {} //~ ERROR type `ext::Priv` is private
 trait Tr1 {}
 impl m::Alias {} //~ ERROR type `m::Priv` is private
 impl Tr1 for ext::Alias {} //~ ERROR type `ext::Priv` is private
-                           //~^ ERROR type `ext::Priv` is private
 type A = <m::Alias as m::Trait>::X; //~ ERROR type `m::Priv` is private
 
 trait Tr2<T> {}