#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
pub enum StabilityLevel {
- // Reason for the current stability level and the relevant rust-lang issue
- Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
- Stable { since: Symbol, allowed_through_unstable_modules: bool },
+ /// `#[unstable]`
+ Unstable {
+ /// Reason for the current stability level.
+ reason: UnstableReason,
+ /// Relevant `rust-lang/rust` issue.
+ issue: Option<NonZeroU32>,
+ is_soft: bool,
+ /// If part of a feature is stabilized and a new feature is added for the remaining parts,
+ /// then the `implied_by` attribute is used to indicate which now-stable feature previously
+ /// contained a item.
+ ///
+ /// ```pseudo-Rust
+ /// #[unstable(feature = "foo", issue = "...")]
+ /// fn foo() {}
+ /// #[unstable(feature = "foo", issue = "...")]
+ /// fn foobar() {}
+ /// ```
+ ///
+ /// ...becomes...
+ ///
+ /// ```pseudo-Rust
+ /// #[stable(feature = "foo", since = "1.XX.X")]
+ /// fn foo() {}
+ /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
+ /// fn foobar() {}
+ /// ```
+ implied_by: Option<Symbol>,
+ },
+ /// `#[stable]`
+ Stable {
+ /// Rust release which stabilized this feature.
+ since: Symbol,
+ /// Is this item allowed to be referred to on stable, despite being contained in unstable
+ /// modules?
+ allowed_through_unstable_modules: bool,
+ },
}
impl StabilityLevel {
}
}
+#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
+#[derive(HashStable_Generic)]
+pub enum UnstableReason {
+ None,
+ Default,
+ Some(Symbol),
+}
+
+impl UnstableReason {
+ fn from_opt_reason(reason: Option<Symbol>) -> Self {
+ // UnstableReason::Default constructed manually
+ match reason {
+ Some(r) => Self::Some(r),
+ None => Self::None,
+ }
+ }
+
+ pub fn to_opt_reason(&self) -> Option<Symbol> {
+ match self {
+ Self::None => None,
+ Self::Default => Some(sym::unstable_location_reason_default),
+ Self::Some(r) => Some(*r),
+ }
+ }
+}
+
/// Collects stability info from all stability attributes in `attrs`.
/// Returns `None` if no stability attributes are found.
pub fn find_stability(
let mut issue = None;
let mut issue_num = None;
let mut is_soft = false;
+ let mut implied_by = None;
for meta in metas {
let Some(mi) = meta.meta_item() else {
handle_errors(
}
is_soft = true;
}
+ sym::implied_by => {
+ if !get(mi, &mut implied_by) {
+ continue 'outer;
+ }
+ }
_ => {
handle_errors(
&sess.parse_sess,
);
continue;
}
- let level = Unstable { reason, issue: issue_num, is_soft };
+ let level = Unstable {
+ reason: UnstableReason::from_opt_reason(reason),
+ issue: issue_num,
+ is_soft,
+ implied_by,
+ };
if sym::unstable == meta_name {
stab = Some((Stability { level, feature }, attr.span));
} else {
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
- &["since", "note"],
+ &["feature", "since"],
),
);
continue 'outer;