about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-02-02 12:33:40 +0100
committerRalf Jung <post@ralfj.de>2025-02-02 12:36:12 +0100
commit3320e915757baea34d796feb513e6563c04ad3c3 (patch)
tree0044b3eb4b57ec5bed3833cd8e05bce575e8dc96 /compiler/rustc_passes/src
parent8239a37f9c0951a037cfc51763ea52a20e71e6bd (diff)
downloadrust-3320e915757baea34d796feb513e6563c04ad3c3.tar.gz
rust-3320e915757baea34d796feb513e6563c04ad3c3.zip
rustc_allowed_through_unstable_modules: require deprecation message
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/stability.rs154
1 files changed, 75 insertions, 79 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index a52f080038d..34f1ca55c78 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -5,8 +5,8 @@ use std::mem::replace;
 use std::num::NonZero;
 
 use rustc_attr_parsing::{
-    self as attr, AllowedThroughUnstableModules, ConstStability, DeprecatedSince, Stability,
-    StabilityLevel, StableSince, UnstableReason, VERSION_PLACEHOLDER,
+    self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
+    UnstableReason, VERSION_PLACEHOLDER,
 };
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
@@ -880,7 +880,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
 
             if item_is_allowed {
                 // The item itself is allowed; check whether the path there is also allowed.
-                let is_allowed_through_unstable_modules: Option<AllowedThroughUnstableModules> =
+                let is_allowed_through_unstable_modules: Option<Symbol> =
                     self.tcx.lookup_stability(def_id).and_then(|stab| match stab.level {
                         StabilityLevel::Stable { allowed_through_unstable_modules, .. } => {
                             allowed_through_unstable_modules
@@ -888,83 +888,79 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
                         _ => None,
                     });
 
-                if is_allowed_through_unstable_modules.is_none() {
-                    // Check parent modules stability as well if the item the path refers to is itself
-                    // stable. We only emit warnings for unstable path segments if the item is stable
-                    // or allowed because stability is often inherited, so the most common case is that
-                    // both the segments and the item are unstable behind the same feature flag.
-                    //
-                    // We check here rather than in `visit_path_segment` to prevent visiting the last
-                    // path segment twice
-                    //
-                    // We include special cases via #[rustc_allowed_through_unstable_modules] for items
-                    // that were accidentally stabilized through unstable paths before this check was
-                    // added, such as `core::intrinsics::transmute`
-                    let parents = path.segments.iter().rev().skip(1);
-                    for path_segment in parents {
-                        if let Some(def_id) = path_segment.res.opt_def_id() {
-                            // use `None` for id to prevent deprecation check
-                            self.tcx.check_stability_allow_unstable(
-                                def_id,
-                                None,
-                                path.span,
-                                None,
-                                if is_unstable_reexport(self.tcx, id) {
-                                    AllowUnstable::Yes
-                                } else {
-                                    AllowUnstable::No
-                                },
-                            );
-                        }
-                    }
-                } else if let Some(AllowedThroughUnstableModules::WithDeprecation(deprecation)) =
-                    is_allowed_through_unstable_modules
-                {
-                    // Similar to above, but we cannot use `check_stability_allow_unstable` as that would
-                    // immediately show the stability error. We just want to know the result and disaplay
-                    // our own kind of error.
-                    let parents = path.segments.iter().rev().skip(1);
-                    for path_segment in parents {
-                        if let Some(def_id) = path_segment.res.opt_def_id() {
-                            // use `None` for id to prevent deprecation check
-                            let eval_result = self.tcx.eval_stability_allow_unstable(
-                                def_id,
-                                None,
-                                path.span,
-                                None,
-                                if is_unstable_reexport(self.tcx, id) {
-                                    AllowUnstable::Yes
-                                } else {
-                                    AllowUnstable::No
-                                },
-                            );
-                            let is_allowed = matches!(eval_result, EvalResult::Allow);
-                            if !is_allowed {
-                                // Calculating message for lint involves calling `self.def_path_str`,
-                                // which will by default invoke the expensive `visible_parent_map` query.
-                                // Skip all that work if the lint is allowed anyway.
-                                if self.tcx.lint_level_at_node(DEPRECATED, id).0
-                                    == lint::Level::Allow
-                                {
-                                    return;
-                                }
-                                // Show a deprecation message.
-                                let def_path =
-                                    with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
-                                let def_kind = self.tcx.def_descr(def_id);
-                                let diag = Deprecated {
-                                    sub: None,
-                                    kind: def_kind.to_owned(),
-                                    path: def_path,
-                                    note: Some(deprecation),
-                                    since_kind: lint::DeprecatedSinceKind::InEffect,
-                                };
-                                self.tcx.emit_node_span_lint(
-                                    DEPRECATED,
-                                    id,
-                                    method_span.unwrap_or(path.span),
-                                    diag,
+                // Check parent modules stability as well if the item the path refers to is itself
+                // stable. We only emit errors for unstable path segments if the item is stable
+                // or allowed because stability is often inherited, so the most common case is that
+                // both the segments and the item are unstable behind the same feature flag.
+                //
+                // We check here rather than in `visit_path_segment` to prevent visiting the last
+                // path segment twice
+                //
+                // We include special cases via #[rustc_allowed_through_unstable_modules] for items
+                // that were accidentally stabilized through unstable paths before this check was
+                // added, such as `core::intrinsics::transmute`
+                let parents = path.segments.iter().rev().skip(1);
+                for path_segment in parents {
+                    if let Some(def_id) = path_segment.res.opt_def_id() {
+                        match is_allowed_through_unstable_modules {
+                            None => {
+                                // Emit a hard stability error if this path is not stable.
+
+                                // use `None` for id to prevent deprecation check
+                                self.tcx.check_stability_allow_unstable(
+                                    def_id,
+                                    None,
+                                    path.span,
+                                    None,
+                                    if is_unstable_reexport(self.tcx, id) {
+                                        AllowUnstable::Yes
+                                    } else {
+                                        AllowUnstable::No
+                                    },
+                                );
+                            }
+                            Some(deprecation) => {
+                                // Call the stability check directly so that we can control which
+                                // diagnostic is emitted.
+                                let eval_result = self.tcx.eval_stability_allow_unstable(
+                                    def_id,
+                                    None,
+                                    path.span,
+                                    None,
+                                    if is_unstable_reexport(self.tcx, id) {
+                                        AllowUnstable::Yes
+                                    } else {
+                                        AllowUnstable::No
+                                    },
                                 );
+                                let is_allowed = matches!(eval_result, EvalResult::Allow);
+                                if !is_allowed {
+                                    // Calculating message for lint involves calling `self.def_path_str`,
+                                    // which will by default invoke the expensive `visible_parent_map` query.
+                                    // Skip all that work if the lint is allowed anyway.
+                                    if self.tcx.lint_level_at_node(DEPRECATED, id).0
+                                        == lint::Level::Allow
+                                    {
+                                        return;
+                                    }
+                                    // Show a deprecation message.
+                                    let def_path =
+                                        with_no_trimmed_paths!(self.tcx.def_path_str(def_id));
+                                    let def_kind = self.tcx.def_descr(def_id);
+                                    let diag = Deprecated {
+                                        sub: None,
+                                        kind: def_kind.to_owned(),
+                                        path: def_path,
+                                        note: Some(deprecation),
+                                        since_kind: lint::DeprecatedSinceKind::InEffect,
+                                    };
+                                    self.tcx.emit_node_span_lint(
+                                        DEPRECATED,
+                                        id,
+                                        method_span.unwrap_or(path.span),
+                                        diag,
+                                    );
+                                }
                             }
                         }
                     }