diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index ff23e3da43800..ad92d58551006 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -139,7 +139,7 @@ pub enum StabilityLevel {
     /// `#[stable]`
     Stable {
         /// Rust release which stabilized this feature.
-        since: Since,
+        since: StableSince,
         /// Is this item allowed to be referred to on stable, despite being contained in unstable
         /// modules?
         allowed_through_unstable_modules: bool,
@@ -149,7 +149,7 @@ pub enum StabilityLevel {
 /// Rust release in which a feature is stabilized.
 #[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
 #[derive(HashStable_Generic)]
-pub enum Since {
+pub enum StableSince {
     Version(RustcVersion),
     /// Stabilized in the upcoming version, whatever number that is.
     Current,
@@ -378,16 +378,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
 
     let since = if let Some(since) = since {
         if since.as_str() == VERSION_PLACEHOLDER {
-            Since::Current
+            StableSince::Current
         } else if let Some(version) = parse_version(since) {
-            Since::Version(version)
+            StableSince::Version(version)
         } else {
             sess.emit_err(session_diagnostics::InvalidSince { span: attr.span });
-            Since::Err
+            StableSince::Err
         }
     } else {
         sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
-        Since::Err
+        StableSince::Err
     };
 
     match feature {
@@ -720,17 +720,49 @@ pub fn eval_condition(
 
 #[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
 pub struct Deprecation {
-    pub since: Option<Symbol>,
+    pub since: DeprecatedSince,
     /// The note to issue a reason.
     pub note: Option<Symbol>,
     /// A text snippet used to completely replace any use of the deprecated item in an expression.
     ///
     /// This is currently unstable.
     pub suggestion: Option<Symbol>,
+}
+
+/// Release in which an API is deprecated.
+#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
+pub enum DeprecatedSince {
+    RustcVersion(RustcVersion),
+    /// Deprecated in the future ("to be determined").
+    Future,
+    /// `feature(staged_api)` is off. Deprecation versions outside the standard
+    /// library are allowed to be arbitrary strings, for better or worse.
+    NonStandard(Symbol),
+    /// Deprecation version is unspecified but optional.
+    Unspecified,
+    /// Failed to parse a deprecation version, or the deprecation version is
+    /// unspecified and required. An error has already been emitted.
+    Err,
+}
+
+impl Deprecation {
+    /// Whether an item marked with #[deprecated(since = "X")] is currently
+    /// deprecated (i.e., whether X is not greater than the current rustc
+    /// version).
+    pub fn is_in_effect(&self) -> bool {
+        match self.since {
+            DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
+            DeprecatedSince::Future => false,
+            // The `since` field doesn't have semantic purpose without `#![staged_api]`.
+            DeprecatedSince::NonStandard(_) => true,
+            // Assume deprecation is in effect if "since" field is absent or invalid.
+            DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
+        }
+    }
 
-    /// Whether to treat the since attribute as being a Rust version identifier
-    /// (rather than an opaque string).
-    pub is_since_rustc_version: bool,
+    pub fn is_since_rustc_version(&self) -> bool {
+        matches!(self.since, DeprecatedSince::RustcVersion(_))
+    }
 }
 
 /// Finds the deprecation attribute. `None` if none exists.
@@ -839,22 +871,30 @@ pub fn find_deprecation(
             }
         }
 
-        if is_rustc {
-            if since.is_none() {
-                sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
-                continue;
+        let since = if let Some(since) = since {
+            if since.as_str() == "TBD" {
+                DeprecatedSince::Future
+            } else if !is_rustc {
+                DeprecatedSince::NonStandard(since)
+            } else if let Some(version) = parse_version(since) {
+                DeprecatedSince::RustcVersion(version)
+            } else {
+                sess.emit_err(session_diagnostics::InvalidSince { span: attr.span });
+                DeprecatedSince::Err
             }
+        } else if is_rustc {
+            sess.emit_err(session_diagnostics::MissingSince { span: attr.span });
+            DeprecatedSince::Err
+        } else {
+            DeprecatedSince::Unspecified
+        };
 
-            if note.is_none() {
-                sess.emit_err(session_diagnostics::MissingNote { span: attr.span });
-                continue;
-            }
+        if is_rustc && note.is_none() {
+            sess.emit_err(session_diagnostics::MissingNote { span: attr.span });
+            continue;
         }
 
-        depr = Some((
-            Deprecation { since, note, suggestion, is_since_rustc_version: is_rustc },
-            attr.span,
-        ));
+        depr = Some((Deprecation { since, note, suggestion }, attr.span));
     }
 
     depr
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 20547696d5a73..f7a55fa95b697 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -5,7 +5,9 @@ pub use self::StabilityLevel::*;
 
 use crate::ty::{self, TyCtxt};
 use rustc_ast::NodeId;
-use rustc_attr::{self as attr, ConstStability, DefaultBodyStability, Deprecation, Stability};
+use rustc_attr::{
+    self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
+};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_feature::GateIssue;
@@ -16,7 +18,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
 use rustc_session::lint::{BuiltinLintDiagnostics, Level, Lint, LintBuffer};
 use rustc_session::parse::feature_err_issue;
-use rustc_session::{RustcVersion, Session};
+use rustc_session::Session;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use std::num::NonZeroU32;
@@ -123,41 +125,6 @@ pub fn report_unstable(
     }
 }
 
-/// Checks whether an item marked with `deprecated(since="X")` is currently
-/// deprecated (i.e., whether X is not greater than the current rustc version).
-pub fn deprecation_in_effect(depr: &Deprecation) -> bool {
-    let is_since_rustc_version = depr.is_since_rustc_version;
-    let since = depr.since.as_ref().map(Symbol::as_str);
-
-    if !is_since_rustc_version {
-        // The `since` field doesn't have semantic purpose without `#![staged_api]`.
-        return true;
-    }
-
-    if let Some(since) = since {
-        if since == "TBD" {
-            return false;
-        }
-
-        // We ignore non-integer components of the version (e.g., "nightly").
-        let since: Vec<u16> =
-            since.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect();
-
-        // We simply treat invalid `since` attributes as relating to a previous
-        // Rust version, thus always displaying the warning.
-        if since.len() != 3 {
-            return true;
-        }
-
-        let rustc = RustcVersion::CURRENT;
-        return since.as_slice() <= &[rustc.major, rustc.minor, rustc.patch];
-    };
-
-    // Assume deprecation is in effect if "since" field is missing
-    // or if we can't determine the current Rust version.
-    true
-}
-
 pub fn deprecation_suggestion(
     diag: &mut Diagnostic,
     kind: &str,
@@ -180,7 +147,7 @@ fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
 
 fn deprecation_message(
     is_in_effect: bool,
-    since: Option<Symbol>,
+    since: DeprecatedSince,
     note: Option<Symbol>,
     kind: &str,
     path: &str,
@@ -188,17 +155,18 @@ fn deprecation_message(
     let message = if is_in_effect {
         format!("use of deprecated {kind} `{path}`")
     } else {
-        let since = since.as_ref().map(Symbol::as_str);
-
-        if since == Some("TBD") {
-            format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
-        } else {
-            format!(
-                "use of {} `{}` that will be deprecated in future version {}",
-                kind,
-                path,
-                since.unwrap()
-            )
+        match since {
+            DeprecatedSince::RustcVersion(version) => format!(
+                "use of {kind} `{path}` that will be deprecated in future version {version}"
+            ),
+            DeprecatedSince::Future => {
+                format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
+            }
+            DeprecatedSince::NonStandard(_)
+            | DeprecatedSince::Unspecified
+            | DeprecatedSince::Err => {
+                unreachable!("this deprecation is always in effect; {since:?}")
+            }
         }
     };
 
@@ -213,7 +181,7 @@ pub fn deprecation_message_and_lint(
     kind: &str,
     path: &str,
 ) -> (String, &'static Lint) {
-    let is_in_effect = deprecation_in_effect(depr);
+    let is_in_effect = depr.is_in_effect();
     (
         deprecation_message(is_in_effect, depr.since, depr.note, kind, path),
         deprecation_lint(is_in_effect),
@@ -381,11 +349,11 @@ impl<'tcx> TyCtxt<'tcx> {
                 // With #![staged_api], we want to emit down the whole
                 // hierarchy.
                 let depr_attr = &depr_entry.attr;
-                if !skip || depr_attr.is_since_rustc_version {
+                if !skip || depr_attr.is_since_rustc_version() {
                     // Calculating message for lint involves calling `self.def_path_str`.
                     // Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
                     // So we skip message calculation altogether, if lint is allowed.
-                    let is_in_effect = deprecation_in_effect(depr_attr);
+                    let is_in_effect = depr_attr.is_in_effect();
                     let lint = deprecation_lint(is_in_effect);
                     if self.lint_level_at_node(lint, id).0 != Level::Allow {
                         let def_path = with_no_trimmed_paths!(self.def_path_str(def_id));
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 026186cbe6cd3..b6661fe721f2d 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -396,11 +396,6 @@ passes_invalid_attr_at_crate_level =
 passes_invalid_attr_at_crate_level_item =
     the inner attribute doesn't annotate this {$kind}
 
-passes_invalid_deprecation_version =
-    invalid deprecation version found
-    .label = invalid deprecation version
-    .item = the stability attribute annotates this item
-
 passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
 
 passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index eca0fb7748b15..e2a61c5941098 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1524,16 +1524,6 @@ pub struct CannotStabilizeDeprecated {
     pub item_sp: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_invalid_deprecation_version)]
-pub struct InvalidDeprecationVersion {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[label(passes_item)]
-    pub item_sp: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(passes_missing_stability_attr)]
 pub struct MissingStabilityAttr<'a> {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 7bfb0742b8be9..6a2498f3f99e9 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -3,8 +3,8 @@
 
 use crate::errors;
 use rustc_attr::{
-    self as attr, ConstStability, Since, Stability, StabilityLevel, Unstable, UnstableReason,
-    VERSION_PLACEHOLDER,
+    self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
+    Unstable, UnstableReason, VERSION_PLACEHOLDER,
 };
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_hir as hir;
@@ -24,8 +24,6 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
-use std::cmp::Ordering;
-use std::iter;
 use std::mem::replace;
 use std::num::NonZeroU32;
 
@@ -198,10 +196,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
         }
 
-        if let Some((rustc_attr::Deprecation { is_since_rustc_version: true, .. }, span)) = &depr {
-            if stab.is_none() {
-                self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
-            }
+        if let Some((depr, span)) = &depr && depr.is_since_rustc_version() && stab.is_none() {
+            self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
         }
 
         if let Some((body_stab, _span)) = body_stab {
@@ -223,44 +219,23 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
 
             // Check if deprecated_since < stable_since. If it is,
             // this is *almost surely* an accident.
-            if let (&Some(dep_since), &attr::Stable { since: stab_since, .. }) =
-                (&depr.as_ref().and_then(|(d, _)| d.since), &stab.level)
+            if let (
+                &Some(DeprecatedSince::RustcVersion(dep_since)),
+                &attr::Stable { since: stab_since, .. },
+            ) = (&depr.as_ref().map(|(d, _)| d.since), &stab.level)
             {
                 match stab_since {
-                    Since::Current => {
+                    StableSince::Current => {
                         self.tcx.sess.emit_err(errors::CannotStabilizeDeprecated { span, item_sp });
                     }
-                    Since::Version(stab_since) => {
-                        // Explicit version of iter::order::lt to handle parse errors properly
-                        for (dep_v, stab_v) in iter::zip(
-                            dep_since.as_str().split('.'),
-                            [stab_since.major, stab_since.minor, stab_since.patch],
-                        ) {
-                            match dep_v.parse::<u64>() {
-                                Ok(dep_vp) => match dep_vp.cmp(&u64::from(stab_v)) {
-                                    Ordering::Less => {
-                                        self.tcx.sess.emit_err(errors::CannotStabilizeDeprecated {
-                                            span,
-                                            item_sp,
-                                        });
-                                        break;
-                                    }
-                                    Ordering::Equal => continue,
-                                    Ordering::Greater => break,
-                                },
-                                Err(_) => {
-                                    if dep_v != "TBD" {
-                                        self.tcx.sess.emit_err(errors::InvalidDeprecationVersion {
-                                            span,
-                                            item_sp,
-                                        });
-                                    }
-                                    break;
-                                }
-                            }
+                    StableSince::Version(stab_since) => {
+                        if dep_since < stab_since {
+                            self.tcx
+                                .sess
+                                .emit_err(errors::CannotStabilizeDeprecated { span, item_sp });
                         }
                     }
-                    Since::Err => {
+                    StableSince::Err => {
                         // An error already reported. Assume the unparseable stabilization
                         // version is older than the deprecation version.
                     }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 455228d04efa7..ba55871c75df3 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -12,7 +12,7 @@ use thin_vec::ThinVec;
 
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
-use rustc_attr::{ConstStability, Deprecation, Since, Stability, StabilityLevel};
+use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel, StableSince};
 use rustc_const_eval::const_eval::is_unstable_const_fn;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -585,14 +585,14 @@ impl Item {
         })
     }
 
-    pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
+    pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<StableSince> {
         match self.stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
+    pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<StableSince> {
         match self.const_stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 0b6079b29334e..c52fa01bdc413 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -48,12 +48,11 @@ use std::str;
 use std::string::ToString;
 
 use askama::Template;
-use rustc_attr::{ConstStability, Deprecation, Since, StabilityLevel};
+use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::Mutability;
-use rustc_middle::middle::stability;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::RustcVersion;
 use rustc_span::{
@@ -617,24 +616,22 @@ fn short_item_info(
 ) -> Vec<ShortItemInfo> {
     let mut extra_info = vec![];
 
-    if let Some(depr @ Deprecation { note, since, is_since_rustc_version: _, suggestion: _ }) =
-        item.deprecation(cx.tcx())
-    {
+    if let Some(depr @ Deprecation { note, since, suggestion: _ }) = item.deprecation(cx.tcx()) {
         // We display deprecation messages for #[deprecated], but only display
         // the future-deprecation messages for rustc versions.
-        let mut message = if let Some(since) = since {
-            let since = since.as_str();
-            if !stability::deprecation_in_effect(&depr) {
-                if since == "TBD" {
-                    String::from("Deprecating in a future Rust version")
+        let mut message = match since {
+            DeprecatedSince::RustcVersion(version) => {
+                if depr.is_in_effect() {
+                    format!("Deprecated since {version}")
                 } else {
-                    format!("Deprecating in {}", Escape(since))
+                    format!("Deprecating in {version}")
                 }
-            } else {
-                format!("Deprecated since {}", Escape(since))
             }
-        } else {
-            String::from("Deprecated")
+            DeprecatedSince::Future => String::from("Deprecating in a future Rust version"),
+            DeprecatedSince::NonStandard(since) => {
+                format!("Deprecated since {}", Escape(since.as_str()))
+            }
+            DeprecatedSince::Unspecified | DeprecatedSince::Err => String::from("Deprecated"),
         };
 
         if let Some(note) = note {
@@ -912,10 +909,10 @@ fn assoc_method(
 /// consequence of the above rules.
 fn render_stability_since_raw_with_extra(
     w: &mut Buffer,
-    ver: Option<Since>,
+    ver: Option<StableSince>,
     const_stability: Option<ConstStability>,
-    containing_ver: Option<Since>,
-    containing_const_ver: Option<Since>,
+    containing_ver: Option<StableSince>,
+    containing_const_ver: Option<StableSince>,
     extra_class: &str,
 ) -> bool {
     let stable_version = if ver != containing_ver && let Some(ver) = &ver {
@@ -977,21 +974,21 @@ fn render_stability_since_raw_with_extra(
     !stability.is_empty()
 }
 
-fn since_to_string(since: &Since) -> Option<String> {
+fn since_to_string(since: &StableSince) -> Option<String> {
     match since {
-        Since::Version(since) => Some(since.to_string()),
-        Since::Current => Some(RustcVersion::CURRENT.to_string()),
-        Since::Err => None,
+        StableSince::Version(since) => Some(since.to_string()),
+        StableSince::Current => Some(RustcVersion::CURRENT.to_string()),
+        StableSince::Err => None,
     }
 }
 
 #[inline]
 fn render_stability_since_raw(
     w: &mut Buffer,
-    ver: Option<Since>,
+    ver: Option<StableSince>,
     const_stability: Option<ConstStability>,
-    containing_ver: Option<Since>,
-    containing_const_ver: Option<Since>,
+    containing_ver: Option<StableSince>,
+    containing_const_ver: Option<StableSince>,
 ) -> bool {
     render_stability_since_raw_with_extra(
         w,
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index fdf4556906172..1c5a1dc99add4 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -6,7 +6,6 @@ use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::DefId;
 use rustc_index::IndexVec;
-use rustc_middle::middle::stability;
 use rustc_middle::query::Key;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
@@ -591,11 +590,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
 
         // The trailing space after each tag is to space it properly against the rest of the docs.
         if let Some(depr) = &item.deprecation(tcx) {
-            let message = if stability::deprecation_in_effect(depr) {
-                "Deprecated"
-            } else {
-                "Deprecation planned"
-            };
+            let message = if depr.is_in_effect() { "Deprecated" } else { "Deprecation planned" };
             write!(f, "{}", tag_html("deprecated", "", message))?;
         }
 
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 563e0cffdddb9..285923251f73f 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -7,6 +7,7 @@
 use std::fmt;
 
 use rustc_ast::ast;
+use rustc_attr::DeprecatedSince;
 use rustc_hir::{def::CtorKind, def::DefKind, def_id::DefId};
 use rustc_metadata::rendered_const;
 use rustc_middle::ty::{self, TyCtxt};
@@ -138,9 +139,14 @@ where
 }
 
 pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
-    #[rustfmt::skip]
-    let rustc_attr::Deprecation { since, note, is_since_rustc_version: _, suggestion: _ } = deprecation;
-    Deprecation { since: since.map(|s| s.to_string()), note: note.map(|s| s.to_string()) }
+    let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation;
+    let since = match since {
+        DeprecatedSince::RustcVersion(version) => Some(version.to_string()),
+        DeprecatedSince::Future => Some("TBD".to_owned()),
+        DeprecatedSince::NonStandard(since) => Some(since.to_string()),
+        DeprecatedSince::Unspecified | DeprecatedSince::Err => None,
+    };
+    Deprecation { since, note: note.map(|s| s.to_string()) }
 }
 
 impl FromWithTcx<clean::GenericArgs> for GenericArgs {
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 31f7b87de635e..ef0e2d3e1b3d1 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -5,7 +5,7 @@
 
 use crate::msrvs::Msrv;
 use hir::LangItem;
-use rustc_attr::Since;
+use rustc_attr::StableSince;
 use rustc_const_eval::transform::check_consts::ConstCx;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -372,9 +372,9 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
                 // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
 
                 let const_stab_rust_version = match since {
-                    Since::Version(version) => version,
-                    Since::Current => rustc_session::RustcVersion::CURRENT,
-                    Since::Err => return false,
+                    StableSince::Version(version) => version,
+                    StableSince::Current => rustc_session::RustcVersion::CURRENT,
+                    StableSince::Err => return false,
                 };
 
                 msrv.meets(RustcVersion::new(
diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-4.rs b/tests/ui/stability-attribute/stability-attribute-sanity-4.rs
index 4fe8e45fd049e..01a46d15c8db5 100644
--- a/tests/ui/stability-attribute/stability-attribute-sanity-4.rs
+++ b/tests/ui/stability-attribute/stability-attribute-sanity-4.rs
@@ -19,6 +19,7 @@ mod bogus_attribute_types_2 {
 
     #[stable(feature = "a", since = "3.3.3")]
     #[deprecated] //~ ERROR missing 'since'
+    //~^ ERROR missing 'note'
     fn f5() { }
 
     #[stable(feature = "a", since = "3.3.3")]
diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
index a76f5be1e3d7c..8ead943ffe3a1 100644
--- a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
+++ b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
@@ -28,12 +28,19 @@ error[E0542]: missing 'since'
 LL |     #[deprecated]
    |     ^^^^^^^^^^^^^
 
+error[E0543]: missing 'note'
+  --> $DIR/stability-attribute-sanity-4.rs:21:5
+   |
+LL |     #[deprecated]
+   |     ^^^^^^^^^^^^^
+
 error[E0542]: missing 'since'
-  --> $DIR/stability-attribute-sanity-4.rs:25:5
+  --> $DIR/stability-attribute-sanity-4.rs:26:5
    |
 LL |     #[deprecated = "a"]
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0542`.
+Some errors have detailed explanations: E0542, E0543.
+For more information about an error, try `rustc --explain E0542`.
diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.rs b/tests/ui/stability-attribute/stability-attribute-sanity.rs
index 8258b6f5ae0ff..7857a0603bd45 100644
--- a/tests/ui/stability-attribute/stability-attribute-sanity.rs
+++ b/tests/ui/stability-attribute/stability-attribute-sanity.rs
@@ -41,7 +41,7 @@ mod missing_version {
     fn f2() { }
 
     #[stable(feature = "a", since = "4.4.4")]
-    #[deprecated(since = "a")] //~ ERROR missing 'note' [E0543]
+    #[deprecated(since = "5.5.5")] //~ ERROR missing 'note' [E0543]
     fn f3() { }
 }
 
@@ -58,18 +58,17 @@ fn multiple2() { }
 fn multiple3() { }
 
 #[stable(feature = "e", since = "b")] //~ ERROR 'since' must be a Rust version number, such as "1.31.0"
-#[deprecated(since = "b", note = "text")]
-#[deprecated(since = "b", note = "text")] //~ ERROR multiple `deprecated` attributes
+#[deprecated(since = "5.5.5", note = "text")]
+#[deprecated(since = "5.5.5", note = "text")] //~ ERROR multiple `deprecated` attributes
 #[rustc_const_unstable(feature = "c", issue = "none")]
 #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
 pub const fn multiple4() { }
 
-#[stable(feature = "a", since = "1.0.0")] //~ ERROR invalid deprecation version found
-//~^ ERROR feature `a` is declared stable since 1.0.0
-#[deprecated(since = "invalid", note = "text")]
+#[stable(feature = "a", since = "1.0.0")] //~ ERROR feature `a` is declared stable since 1.0.0
+#[deprecated(since = "invalid", note = "text")] //~ ERROR 'since' must be a Rust version number, such as "1.31.0"
 fn invalid_deprecation_version() {}
 
-#[deprecated(since = "a", note = "text")]
+#[deprecated(since = "5.5.5", note = "text")]
 fn deprecated_without_unstable_or_stable() { }
 //~^^ ERROR deprecated attribute must be paired with either stable or unstable attribute
 
diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.stderr b/tests/ui/stability-attribute/stability-attribute-sanity.stderr
index 955230742bd15..c614fc2b9f7fa 100644
--- a/tests/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/tests/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -1,14 +1,14 @@
 error: multiple `deprecated` attributes
   --> $DIR/stability-attribute-sanity.rs:62:1
    |
-LL | #[deprecated(since = "b", note = "text")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+LL | #[deprecated(since = "5.5.5", note = "text")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
    |
 note: attribute also specified here
   --> $DIR/stability-attribute-sanity.rs:61:1
    |
-LL | #[deprecated(since = "b", note = "text")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[deprecated(since = "5.5.5", note = "text")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0541]: unknown meta item 'reason'
   --> $DIR/stability-attribute-sanity.rs:8:46
@@ -73,8 +73,8 @@ LL |     #[deprecated(note = "a")]
 error[E0543]: missing 'note'
   --> $DIR/stability-attribute-sanity.rs:44:5
    |
-LL |     #[deprecated(since = "a")]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     #[deprecated(since = "5.5.5")]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0544]: multiple stability levels
   --> $DIR/stability-attribute-sanity.rs:49:1
@@ -106,20 +106,17 @@ error[E0544]: multiple stability levels
 LL | #[rustc_const_unstable(feature = "d", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: invalid deprecation version found
-  --> $DIR/stability-attribute-sanity.rs:67:1
+error: 'since' must be a Rust version number, such as "1.31.0"
+  --> $DIR/stability-attribute-sanity.rs:68:1
    |
-LL | #[stable(feature = "a", since = "1.0.0")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid deprecation version
-...
-LL | fn invalid_deprecation_version() {}
-   | ----------------------------------- the stability attribute annotates this item
+LL | #[deprecated(since = "invalid", note = "text")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0549]: deprecated attribute must be paired with either stable or unstable attribute
-  --> $DIR/stability-attribute-sanity.rs:72:1
+  --> $DIR/stability-attribute-sanity.rs:71:1
    |
-LL | #[deprecated(since = "a", note = "text")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[deprecated(since = "5.5.5", note = "text")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0711]: feature `a` is declared stable since 1.0.0, but was previously declared stable since 4.4.4
   --> $DIR/stability-attribute-sanity.rs:67:1