]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_privacy/lib.rs
introduce PredicateAtom
[rust.git] / src / librustc_privacy / lib.rs
index 2c5cbed2192ef35b1a38f8e418bd66b9101845ae..9c5fb4ce73450198d6ac4de1c29acc0b811da637 100644 (file)
@@ -2,7 +2,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(or_patterns)]
-#![cfg_attr(bootstrap, feature(track_caller))]
 #![recursion_limit = "256"]
 
 use rustc_attr as attr;
@@ -69,10 +68,7 @@ fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool
     }
 }
 
-struct DefIdVisitorSkeleton<'v, 'tcx, V>
-where
-    V: DefIdVisitor<'tcx> + ?Sized,
-{
+struct DefIdVisitorSkeleton<'v, 'tcx, V: ?Sized> {
     def_id_visitor: &'v mut V,
     visited_opaque_tys: FxHashSet<DefId>,
     dummy: PhantomData<TyCtxt<'tcx>>,
@@ -88,34 +84,28 @@ fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
             || (!self.def_id_visitor.shallow() && substs.visit_with(self))
     }
 
+    fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
+        match predicate.skip_binders() {
+            ty::PredicateAtom::Trait(ty::TraitPredicate { trait_ref }, _) => {
+                self.visit_trait(trait_ref)
+            }
+            ty::PredicateAtom::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
+                ty.visit_with(self)
+                    || self.visit_trait(projection_ty.trait_ref(self.def_id_visitor.tcx()))
+            }
+            ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
+                ty.visit_with(self)
+            }
+            ty::PredicateAtom::RegionOutlives(..) => false,
+            _ => bug!("unexpected predicate: {:?}", predicate),
+        }
+    }
+
     fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
         let ty::GenericPredicates { parent: _, predicates } = predicates;
-        for (predicate, _span) in predicates {
-            match predicate.kind() {
-                ty::PredicateKind::Trait(poly_predicate, _) => {
-                    let ty::TraitPredicate { trait_ref } = poly_predicate.skip_binder();
-                    if self.visit_trait(trait_ref) {
-                        return true;
-                    }
-                }
-                ty::PredicateKind::Projection(poly_predicate) => {
-                    let ty::ProjectionPredicate { projection_ty, ty } =
-                        poly_predicate.skip_binder();
-                    if ty.visit_with(self) {
-                        return true;
-                    }
-                    if self.visit_trait(projection_ty.trait_ref(self.def_id_visitor.tcx())) {
-                        return true;
-                    }
-                }
-                ty::PredicateKind::TypeOutlives(poly_predicate) => {
-                    let ty::OutlivesPredicate(ty, _region) = poly_predicate.skip_binder();
-                    if ty.visit_with(self) {
-                        return true;
-                    }
-                }
-                ty::PredicateKind::RegionOutlives(..) => {}
-                _ => bug!("unexpected predicate: {:?}", predicate),
+        for &(predicate, _span) in predicates {
+            if self.visit_predicate(predicate) {
+                return true;
             }
         }
         false
@@ -1021,17 +1011,18 @@ fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display
 
 struct NamePrivacyVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    maybe_typeck_tables: Option<&'tcx ty::TypeckTables<'tcx>>,
+    maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
     current_item: Option<hir::HirId>,
 }
 
 impl<'tcx> NamePrivacyVisitor<'tcx> {
-    /// Gets the type-checking side-tables for the current body.
+    /// Gets the type-checking results for the current body.
     /// As this will ICE if called outside bodies, only call when working with
     /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
     #[track_caller]
-    fn tables(&self) -> &'tcx ty::TypeckTables<'tcx> {
-        self.maybe_typeck_tables.expect("`NamePrivacyVisitor::tables` called outside of body")
+    fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
+        self.maybe_typeck_results
+            .expect("`NamePrivacyVisitor::typeck_results` called outside of body")
     }
 
     // Checks that a field in a struct constructor (expression or pattern) is accessible.
@@ -1084,10 +1075,11 @@ fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
-        let old_maybe_typeck_tables = self.maybe_typeck_tables.replace(self.tcx.body_tables(body));
+        let old_maybe_typeck_results =
+            self.maybe_typeck_results.replace(self.tcx.typeck_body(body));
         let body = self.tcx.hir().body(body);
         self.visit_body(body);
-        self.maybe_typeck_tables = old_maybe_typeck_tables;
+        self.maybe_typeck_results = old_maybe_typeck_results;
     }
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
@@ -1098,17 +1090,17 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
 
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if let hir::ExprKind::Struct(ref qpath, fields, ref base) = expr.kind {
-            let res = self.tables().qpath_res(qpath, expr.hir_id);
-            let adt = self.tables().expr_ty(expr).ty_adt_def().unwrap();
+            let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
+            let adt = self.typeck_results().expr_ty(expr).ty_adt_def().unwrap();
             let variant = adt.variant_of_res(res);
             if let Some(ref base) = *base {
                 // If the expression uses FRU we need to make sure all the unmentioned fields
                 // are checked for privacy (RFC 736). Rather than computing the set of
                 // unmentioned fields, just check them all.
                 for (vf_index, variant_field) in variant.fields.iter().enumerate() {
-                    let field = fields
-                        .iter()
-                        .find(|f| self.tcx.field_index(f.hir_id, self.tables()) == vf_index);
+                    let field = fields.iter().find(|f| {
+                        self.tcx.field_index(f.hir_id, self.typeck_results()) == vf_index
+                    });
                     let (use_ctxt, span) = match field {
                         Some(field) => (field.ident.span, field.span),
                         None => (base.span, base.span),
@@ -1118,7 +1110,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
             } else {
                 for field in fields {
                     let use_ctxt = field.ident.span;
-                    let index = self.tcx.field_index(field.hir_id, self.tables());
+                    let index = self.tcx.field_index(field.hir_id, self.typeck_results());
                     self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
                 }
             }
@@ -1129,12 +1121,12 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
 
     fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
         if let PatKind::Struct(ref qpath, fields, _) = pat.kind {
-            let res = self.tables().qpath_res(qpath, pat.hir_id);
-            let adt = self.tables().pat_ty(pat).ty_adt_def().unwrap();
+            let res = self.typeck_results().qpath_res(qpath, pat.hir_id);
+            let adt = self.typeck_results().pat_ty(pat).ty_adt_def().unwrap();
             let variant = adt.variant_of_res(res);
             for field in fields {
                 let use_ctxt = field.ident.span;
-                let index = self.tcx.field_index(field.hir_id, self.tables());
+                let index = self.tcx.field_index(field.hir_id, self.typeck_results());
                 self.check_field(use_ctxt, field.span, adt, &variant.fields[index], false);
             }
         }
@@ -1151,18 +1143,19 @@ fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
 
 struct TypePrivacyVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    maybe_typeck_tables: Option<&'tcx ty::TypeckTables<'tcx>>,
+    maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
     current_item: LocalDefId,
     span: Span,
 }
 
 impl<'tcx> TypePrivacyVisitor<'tcx> {
-    /// Gets the type-checking side-tables for the current body.
+    /// Gets the type-checking results for the current body.
     /// As this will ICE if called outside bodies, only call when working with
     /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
     #[track_caller]
-    fn tables(&self) -> &'tcx ty::TypeckTables<'tcx> {
-        self.maybe_typeck_tables.expect("`TypePrivacyVisitor::tables` called outside of body")
+    fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
+        self.maybe_typeck_results
+            .expect("`TypePrivacyVisitor::typeck_results` called outside of body")
     }
 
     fn item_is_accessible(&self, did: DefId) -> bool {
@@ -1174,11 +1167,11 @@ fn item_is_accessible(&self, did: DefId) -> bool {
     // Take node-id of an expression or pattern and check its type for privacy.
     fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
         self.span = span;
-        let tables = self.tables();
-        if self.visit(tables.node_type(id)) || self.visit(tables.node_substs(id)) {
+        let typeck_results = self.typeck_results();
+        if self.visit(typeck_results.node_type(id)) || self.visit(typeck_results.node_substs(id)) {
             return true;
         }
-        if let Some(adjustments) = tables.adjustments().get(id) {
+        if let Some(adjustments) = typeck_results.adjustments().get(id) {
             for adjustment in adjustments {
                 if self.visit(adjustment.target) {
                     return true;
@@ -1216,17 +1209,18 @@ fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
     }
 
     fn visit_nested_body(&mut self, body: hir::BodyId) {
-        let old_maybe_typeck_tables = self.maybe_typeck_tables.replace(self.tcx.body_tables(body));
+        let old_maybe_typeck_results =
+            self.maybe_typeck_results.replace(self.tcx.typeck_body(body));
         let body = self.tcx.hir().body(body);
         self.visit_body(body);
-        self.maybe_typeck_tables = old_maybe_typeck_tables;
+        self.maybe_typeck_results = old_maybe_typeck_results;
     }
 
     fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
         self.span = hir_ty.span;
-        if let Some(tables) = self.maybe_typeck_tables {
+        if let Some(typeck_results) = self.maybe_typeck_results {
             // Types in bodies.
-            if self.visit(tables.node_type(hir_ty.hir_id)) {
+            if self.visit(typeck_results.node_type(hir_ty.hir_id)) {
                 return;
             }
         } else {
@@ -1243,7 +1237,7 @@ fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
 
     fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
         self.span = trait_ref.path.span;
-        if self.maybe_typeck_tables.is_none() {
+        if self.maybe_typeck_results.is_none() {
             // Avoid calling `hir_trait_to_predicates` in bodies, it will ICE.
             // The traits' privacy in bodies is already checked as a part of trait object types.
             let bounds = rustc_typeck::hir_trait_to_predicates(
@@ -1289,7 +1283,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
             hir::ExprKind::MethodCall(_, span, _, _) => {
                 // Method calls have to be checked specially.
                 self.span = span;
-                if let Some(def_id) = self.tables().type_dependent_def_id(expr.hir_id) {
+                if let Some(def_id) = self.typeck_results().type_dependent_def_id(expr.hir_id) {
                     if self.visit(self.tcx.type_of(def_id)) {
                         return;
                     }
@@ -1317,9 +1311,9 @@ fn visit_qpath(&mut self, qpath: &'tcx hir::QPath<'tcx>, id: hir::HirId, span: S
                 Res::Def(kind, def_id) => Some((kind, def_id)),
                 _ => None,
             },
-            hir::QPath::TypeRelative(..) => {
-                self.maybe_typeck_tables.and_then(|tables| tables.type_dependent_def(id))
-            }
+            hir::QPath::TypeRelative(..) => self
+                .maybe_typeck_results
+                .and_then(|typeck_results| typeck_results.type_dependent_def(id)),
         };
         let def = def.filter(|(kind, _)| match kind {
             DefKind::AssocFn | DefKind::AssocConst | DefKind::AssocTy | DefKind::Static => true,
@@ -1375,9 +1369,9 @@ fn visit_local(&mut self, local: &'tcx hir::Local<'tcx>) {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         let orig_current_item =
             mem::replace(&mut self.current_item, self.tcx.hir().local_def_id(item.hir_id));
-        let old_maybe_typeck_tables = self.maybe_typeck_tables.take();
+        let old_maybe_typeck_results = self.maybe_typeck_results.take();
         intravisit::walk_item(self, item);
-        self.maybe_typeck_tables = old_maybe_typeck_tables;
+        self.maybe_typeck_results = old_maybe_typeck_results;
         self.current_item = orig_current_item;
     }
 }
@@ -2040,7 +2034,7 @@ pub fn provide(providers: &mut Providers) {
 
 fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     // Check privacy of names not checked in previous compilation stages.
-    let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_tables: None, current_item: None };
+    let mut visitor = NamePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: None };
     let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
 
     intravisit::walk_mod(&mut visitor, module, hir_id);
@@ -2048,7 +2042,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     // Check privacy of explicitly written types and traits as well as
     // inferred types of expressions and patterns.
     let mut visitor =
-        TypePrivacyVisitor { tcx, maybe_typeck_tables: None, current_item: module_def_id, span };
+        TypePrivacyVisitor { tcx, maybe_typeck_results: None, current_item: module_def_id, span };
     intravisit::walk_mod(&mut visitor, module, hir_id);
 }