about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2016-12-29 16:00:53 -0500
committerFelix S. Klock II <pnkfelix@pnkfx.org>2017-01-03 09:57:49 -0500
commitae13a72ded3e9b42908a62cb23367a0ec337d7c9 (patch)
treede82ed3bbd5074200a5824bc698efce6b30a1f42 /src
parent17f1fba353d2545ee54589350a83681dc3156e70 (diff)
downloadrust-ae13a72ded3e9b42908a62cb23367a0ec337d7c9.tar.gz
rust-ae13a72ded3e9b42908a62cb23367a0ec337d7c9.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')
-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 f45e86f2f4b..e6c9d2c36d0 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};
@@ -432,6 +432,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: \
@@ -492,6 +522,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) {