about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr_data_structures/src/stability.rs15
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs18
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs154
-rw-r--r--library/core/src/intrinsics/mod.rs6
-rw-r--r--src/librustdoc/clean/types.rs12
-rw-r--r--tests/rustdoc/inline_local/fully-stable-path-is-better.rs4
-rw-r--r--tests/rustdoc/stability.rs2
-rw-r--r--tests/ui/error-codes/E0789.rs2
-rw-r--r--tests/ui/stability-attribute/allowed-through-unstable.rs3
-rw-r--r--tests/ui/stability-attribute/allowed-through-unstable.stderr8
-rw-r--r--tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs6
12 files changed, 107 insertions, 125 deletions
diff --git a/compiler/rustc_attr_data_structures/src/stability.rs b/compiler/rustc_attr_data_structures/src/stability.rs
index dfda04387ec..c2213fc9ed8 100644
--- a/compiler/rustc_attr_data_structures/src/stability.rs
+++ b/compiler/rustc_attr_data_structures/src/stability.rs
@@ -101,16 +101,6 @@ impl PartialConstStability {
     }
 }
 
-#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
-#[derive(HashStable_Generic)]
-pub enum AllowedThroughUnstableModules {
-    /// This does not get a deprecation warning. We still generally would prefer people to use the
-    /// fully stable path, and a warning will likely be emitted in the future.
-    WithoutDeprecation,
-    /// Emit the given deprecation warning.
-    WithDeprecation(Symbol),
-}
-
 /// The available stability levels.
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
 #[derive(HashStable_Generic)]
@@ -147,8 +137,9 @@ pub enum StabilityLevel {
     Stable {
         /// Rust release which stabilized this feature.
         since: StableSince,
-        /// This is `Some` if this item allowed to be referred to on stable via unstable modules.
-        allowed_through_unstable_modules: Option<AllowedThroughUnstableModules>,
+        /// This is `Some` if this item allowed to be referred to on stable via unstable modules;
+        /// the `Symbol` is the deprecation message printed in that case.
+        allowed_through_unstable_modules: Option<Symbol>,
     },
 }
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index bfbe51b27d8..454b8b5de82 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -6,12 +6,12 @@ use rustc_ast::MetaItem;
 use rustc_ast::attr::AttributeExt;
 use rustc_ast_pretty::pprust;
 use rustc_attr_data_structures::{
-    AllowedThroughUnstableModules, ConstStability, DefaultBodyStability, Stability, StabilityLevel,
-    StableSince, UnstableReason, VERSION_PLACEHOLDER,
+    ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason,
+    VERSION_PLACEHOLDER,
 };
 use rustc_errors::ErrorGuaranteed;
 use rustc_session::Session;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol, kw, sym};
 
 use crate::attributes::util::UnsupportedLiteralReason;
 use crate::{parse_version, session_diagnostics};
@@ -29,10 +29,14 @@ pub fn find_stability(
     for attr in attrs {
         match attr.name_or_empty() {
             sym::rustc_allowed_through_unstable_modules => {
-                allowed_through_unstable_modules = Some(match attr.value_str() {
-                    Some(msg) => AllowedThroughUnstableModules::WithDeprecation(msg),
-                    None => AllowedThroughUnstableModules::WithoutDeprecation,
-                })
+                // The value is mandatory, but avoid ICEs in case such code reaches this function.
+                allowed_through_unstable_modules = Some(attr.value_str().unwrap_or_else(|| {
+                    sess.dcx().span_delayed_bug(
+                        item_sp,
+                        "`#[rustc_allowed_through_unstable_modules]` without deprecation message",
+                    );
+                    kw::Empty
+                }))
             }
             sym::unstable => {
                 if stab.is_some() {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 684fc5e37e0..e0543977e98 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -616,7 +616,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, "allow_internal_unsafe side-steps the unsafe_code lint",
     ),
     rustc_attr!(
-        rustc_allowed_through_unstable_modules, Normal, template!(Word, NameValueStr: "deprecation message"),
+        rustc_allowed_through_unstable_modules, Normal, template!(NameValueStr: "deprecation message"),
         WarnFollowing, EncodeCrossCrate::No,
         "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
         through unstable paths"
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,
+                                    );
+                                }
                             }
                         }
                     }
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index c0d435f99c0..bf07632d992 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -78,7 +78,11 @@ pub mod simd;
 use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
 
 #[stable(feature = "drop_in_place", since = "1.8.0")]
-#[rustc_allowed_through_unstable_modules]
+#[cfg_attr(bootstrap, rustc_allowed_through_unstable_modules)]
+#[cfg_attr(
+    not(bootstrap),
+    rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"
+)]
 #[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
 #[inline]
 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6e817af0d6e..a44d74e6df6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -5,9 +5,7 @@ use std::{fmt, iter};
 
 use arrayvec::ArrayVec;
 use rustc_abi::{ExternAbi, VariantIdx};
-use rustc_attr_parsing::{
-    AllowedThroughUnstableModules, ConstStability, Deprecation, Stability, StableSince,
-};
+use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
@@ -411,15 +409,9 @@ impl Item {
                 ..
             } = stab.level
             {
-                let note = match note {
-                    AllowedThroughUnstableModules::WithDeprecation(note) => Some(note),
-                    // FIXME: Would be better to say *something* here about the *path* being
-                    // deprecated rather than the item.
-                    AllowedThroughUnstableModules::WithoutDeprecation => None,
-                };
                 Some(Deprecation {
                     since: rustc_attr_parsing::DeprecatedSince::Unspecified,
-                    note,
+                    note: Some(note),
                     suggestion: None,
                 })
             } else {
diff --git a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
index 88b0b0d57b0..41bf42d2e7a 100644
--- a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
+++ b/tests/rustdoc/inline_local/fully-stable-path-is-better.rs
@@ -16,10 +16,10 @@ pub mod stb1 {
 #[unstable(feature = "uns", issue = "135003")]
 pub mod uns {
     #[stable(since = "1.0", feature = "stb1")]
-    #[rustc_allowed_through_unstable_modules]
+    #[rustc_allowed_through_unstable_modules = "use stable path instead"]
     pub struct Inside1;
     #[stable(since = "1.0", feature = "stb2")]
-    #[rustc_allowed_through_unstable_modules]
+    #[rustc_allowed_through_unstable_modules = "use stable path instead"]
     pub struct Inside2;
 }
 
diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs
index b74abb0e0ba..22cd4b9cd59 100644
--- a/tests/rustdoc/stability.rs
+++ b/tests/rustdoc/stability.rs
@@ -85,7 +85,7 @@ pub mod stable_later {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_allowed_through_unstable_modules]
+#[rustc_allowed_through_unstable_modules = "use stable path instead"]
 pub mod stable_earlier1 {
     //@ has stability/stable_earlier1/struct.StableInUnstable.html \
     //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
diff --git a/tests/ui/error-codes/E0789.rs b/tests/ui/error-codes/E0789.rs
index 3acc983edc4..08471e1b3f3 100644
--- a/tests/ui/error-codes/E0789.rs
+++ b/tests/ui/error-codes/E0789.rs
@@ -4,7 +4,7 @@
 #![feature(staged_api)]
 #![unstable(feature = "foo_module", reason = "...", issue = "123")]
 
-#[rustc_allowed_through_unstable_modules]
+#[rustc_allowed_through_unstable_modules = "use stable path instead"]
 // #[stable(feature = "foo", since = "1.0")]
 struct Foo;
 //~^ ERROR `rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute
diff --git a/tests/ui/stability-attribute/allowed-through-unstable.rs b/tests/ui/stability-attribute/allowed-through-unstable.rs
index e03417a4dae..5baa0fda940 100644
--- a/tests/ui/stability-attribute/allowed-through-unstable.rs
+++ b/tests/ui/stability-attribute/allowed-through-unstable.rs
@@ -5,6 +5,5 @@
 
 extern crate allowed_through_unstable_core;
 
-use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable;
-use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstableWithDeprecation; //~WARN use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
+use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable; //~WARN use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
 use allowed_through_unstable_core::unstable_module::NewStableTraitNotAllowedThroughUnstable; //~ ERROR use of unstable library feature `unstable_test_feature`
diff --git a/tests/ui/stability-attribute/allowed-through-unstable.stderr b/tests/ui/stability-attribute/allowed-through-unstable.stderr
index 8d07b0cf9e8..bda68045002 100644
--- a/tests/ui/stability-attribute/allowed-through-unstable.stderr
+++ b/tests/ui/stability-attribute/allowed-through-unstable.stderr
@@ -1,13 +1,13 @@
 warning: use of deprecated module `allowed_through_unstable_core::unstable_module`: use the new path instead
-  --> $DIR/allowed-through-unstable.rs:9:53
+  --> $DIR/allowed-through-unstable.rs:8:53
    |
-LL | use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstableWithDeprecation;
-   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | use allowed_through_unstable_core::unstable_module::OldStableTraitAllowedThoughUnstable;
+   |                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[warn(deprecated)]` on by default
 
 error[E0658]: use of unstable library feature `unstable_test_feature`
-  --> $DIR/allowed-through-unstable.rs:10:5
+  --> $DIR/allowed-through-unstable.rs:9:5
    |
 LL | use allowed_through_unstable_core::unstable_module::NewStableTraitNotAllowedThroughUnstable;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs b/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
index 9dfbb451d04..23c722d6e8e 100644
--- a/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
+++ b/tests/ui/stability-attribute/auxiliary/allowed-through-unstable-core.rs
@@ -6,12 +6,8 @@
 #[unstable(feature = "unstable_test_feature", issue = "1")]
 pub mod unstable_module {
     #[stable(feature = "stable_test_feature", since = "1.2.0")]
-    #[rustc_allowed_through_unstable_modules]
-    pub trait OldStableTraitAllowedThoughUnstable {}
-
-    #[stable(feature = "stable_test_feature", since = "1.2.0")]
     #[rustc_allowed_through_unstable_modules = "use the new path instead"]
-    pub trait OldStableTraitAllowedThoughUnstableWithDeprecation {}
+    pub trait OldStableTraitAllowedThoughUnstable {}
 
     #[stable(feature = "stable_test_feature", since = "1.2.0")]
     pub trait NewStableTraitNotAllowedThroughUnstable {}