summary refs log tree commit diff
path: root/src/librustc/middle/stability.rs
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2016-12-29 16:00:53 -0500
committerNiko Matsakis <niko@alum.mit.edu>2017-01-06 13:47:21 -0500
commit7bb20bcfedba996bec708108ca57fec0043ee72a (patch)
tree8357ccdbc1e90725b7fd3ca237986dc2e690ebb9 /src/librustc/middle/stability.rs
parentd86ed7896218134b23a208b5496da066c200538d (diff)
downloadrust-7bb20bcfedba996bec708108ca57fec0043ee72a.tar.gz
rust-7bb20bcfedba996bec708108ca57fec0043ee72a.zip
Dont check stability for items that are not pub to universe.
Includes special case handling for trait methods.

Fix #38412.
Diffstat (limited to 'src/librustc/middle/stability.rs')
-rw-r--r--src/librustc/middle/stability.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 3e32957aecf..5cd82bd363b 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -18,7 +18,7 @@ use hir::map as hir_map;
 use lint;
 use hir::def::Def;
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, DefIndex, LOCAL_CRATE};
-use ty::TyCtxt;
+use ty::{self, TyCtxt};
 use middle::privacy::AccessLevels;
 use syntax::symbol::Symbol;
 use syntax_pos::{Span, DUMMY_SP};
@@ -436,6 +436,36 @@ struct Checker<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
+    // (See issue #38412)
+    fn skip_stability_check_due_to_privacy(self, def_id: DefId) -> bool {
+        let visibility = {
+            // Check if `def_id` is a trait method.
+            match self.sess.cstore.associated_item(def_id) {
+                Some(ty::AssociatedItem { container: ty::TraitContainer(trait_def_id), .. }) => {
+                    // Trait methods do not declare visibility (even
+                    // for visibility info in cstore). Use containing
+                    // trait instead, so methods of pub traits are
+                    // themselves considered pub.
+                    self.sess.cstore.visibility(trait_def_id)
+                }
+                _ => {
+                    // Otherwise, cstore info works directly.
+                    self.sess.cstore.visibility(def_id)
+                }
+            }
+        };
+
+        match visibility {
+            // must check stability for pub items.
+            ty::Visibility::Public => false,
+
+            // these are not visible outside crate; therefore
+            // stability markers are irrelevant, if even present.
+            ty::Visibility::Restricted(..) |
+            ty::Visibility::Invisible => true,
+        }
+    }
+
     pub fn check_stability(self, def_id: DefId, id: NodeId, span: Span) {
         if self.sess.codemap().span_allows_unstable(span) {
             debug!("stability: \
@@ -496,6 +526,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             self.stability.borrow_mut().used_features.insert(feature.clone(), level.clone());
         }
 
+        // Issue 38412: private items lack stability markers.
+        if self.skip_stability_check_due_to_privacy(def_id) {
+            return
+        }
+
         match stability {
             Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
                 if !self.stability.borrow().active_features.contains(feature) {