about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorcole <cole@swift-mail.com>2022-06-04 17:05:33 -0500
committercole <cole@swift-mail.com>2022-06-04 17:05:33 -0500
commitf3d93b6c625a0837cd6f2bedc713436e56856b5d (patch)
tree6c70a63b336294ef2621b5befbba23265b6efe48 /compiler/rustc_passes/src
parent0a437b2ca081bc12425a3318cb66aade9824cbae (diff)
downloadrust-f3d93b6c625a0837cd6f2bedc713436e56856b5d.tar.gz
rust-f3d93b6c625a0837cd6f2bedc713436e56856b5d.zip
Allow unstable items to be re-exported unstably without requiring the feature be enabled
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/stability.rs40
1 files changed, 37 insertions, 3 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 70cb1f2a281..144a60faad2 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -9,10 +9,10 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
+use rustc_hir::{FieldDef, Generics, HirId, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::privacy::AccessLevels;
-use rustc_middle::middle::stability::{DeprecationEntry, Index};
+use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
 use rustc_middle::ty::{self, query::Providers, TyCtxt};
 use rustc_session::lint;
 use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
@@ -807,12 +807,46 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
     fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
         if let Some(def_id) = path.res.opt_def_id() {
             let method_span = path.segments.last().map(|s| s.ident.span);
-            self.tcx.check_stability(def_id, Some(id), path.span, method_span)
+            self.tcx.check_stability_allow_unstable(
+                def_id,
+                Some(id),
+                path.span,
+                method_span,
+                if is_unstable_reexport(self.tcx, id) {
+                    AllowUnstable::Yes
+                } else {
+                    AllowUnstable::No
+                },
+            )
         }
         intravisit::walk_path(self, path)
     }
 }
 
+/// Check whether a path is a `use` item that has been marked as unstable.
+///
+/// See issue #94972 for details on why this is a special case
+fn is_unstable_reexport<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId) -> bool {
+    // Get the LocalDefId so we can lookup the item to check the kind.
+    let Some(def_id) = tcx.hir().opt_local_def_id(id) else { return false; };
+
+    let Some(stab) = tcx.stability().local_stability(def_id) else {
+        return false;
+    };
+
+    if stab.level.is_stable() {
+        // The re-export is not marked as unstable, don't override
+        return false;
+    }
+
+    // If this is a path that isn't a use, we don't need to do anything special
+    if !matches!(tcx.hir().item(hir::ItemId { def_id }).kind, ItemKind::Use(..)) {
+        return false;
+    }
+
+    true
+}
+
 struct CheckTraitImplStable<'tcx> {
     tcx: TyCtxt<'tcx>,
     fully_stable: bool,