Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/rustdoc-json-types/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
// will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
// are deliberately not in a doc comment, because they need not be in public docs.)
//
// Latest feature: Add default-body stability metadata.
pub const FORMAT_VERSION: u32 = 60;
// Latest feature: Make `Stability` work with non-self-describing formats
pub const FORMAT_VERSION: u32 = 61;

/// The root of the emitted JSON blob.
///
Expand Down Expand Up @@ -354,14 +354,13 @@ pub struct Stability {
/// For stable items, this is the historical label recorded when the item was stabilized.
pub feature: String,

#[serde(flatten)]
pub level: StabilityLevel,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))]
#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))]
#[serde(tag = "level", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum StabilityLevel {
Stable {
/// The Rust version in which this item became stable, if available.
Expand Down
48 changes: 31 additions & 17 deletions src/rustdoc-json-types/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
use std::fmt::Debug;

use serde::Serialize;
use serde::de::DeserializeOwned;

use super::*;

fn check_roundtrips<T: Serialize + DeserializeOwned + PartialEq + Debug>(t: T) {
let ser_json = serde_json::to_string(&t).expect("should be able to serialize to json");
let de_json: T =
serde_json::from_str(&ser_json).expect("should be able to deserialize from json");
assert_eq!(t, de_json, "value should be the same after json roundtrip");

let ser_postcard =
::postcard::to_allocvec(&t).expect("should be able to serialize to postcard");
let de_postcard: T =
::postcard::from_bytes(&ser_postcard).expect("should be able to deserialze from postcard");
assert_eq!(t, de_postcard, "value should be the same after postcard rountrip");
}

#[test]
fn test_struct_info_roundtrip() {
let s = ItemEnum::Struct(Struct {
Expand All @@ -8,15 +26,7 @@ fn test_struct_info_roundtrip() {
impls: vec![],
});

// JSON
let struct_json = serde_json::to_string(&s).unwrap();
let de_s = serde_json::from_str(&struct_json).unwrap();
assert_eq!(s, de_s);

// Postcard
let encoded: Vec<u8> = postcard::to_allocvec(&s).unwrap();
let decoded: ItemEnum = postcard::from_bytes(&encoded).unwrap();
assert_eq!(s, decoded);
check_roundtrips(s);
}

#[test]
Expand All @@ -28,15 +38,19 @@ fn test_union_info_roundtrip() {
impls: vec![],
});

// JSON
let union_json = serde_json::to_string(&u).unwrap();
let de_u = serde_json::from_str(&union_json).unwrap();
assert_eq!(u, de_u);
check_roundtrips(u);
}

// Postcard
let encoded: Vec<u8> = postcard::to_allocvec(&u).unwrap();
let decoded: ItemEnum = postcard::from_bytes(&encoded).unwrap();
assert_eq!(u, decoded);
#[test]
fn test_stability() {
check_roundtrips(Stability {
feature: "guam_dotcom".to_owned(),
level: StabilityLevel::Stable { since: None },
});
check_roundtrips(Stability {
feature: "bing_mexico".to_owned(),
level: StabilityLevel::Unstable,
});
}

#[cfg(feature = "rkyv_0_8")]
Expand Down
14 changes: 2 additions & 12 deletions tests/rustdoc-json/attrs/stability/associated_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,54 @@
// Trait-associated item declarations only. Items defined inside impl blocks are tested in
// `impls.rs` because they have different parent-item behavior.

//@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.feature" '"stable_trait_with_associated_items"'
//@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.since" '"1.0.0"'
//@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.level.stable.since" '"1.0.0"'
#[stable(feature = "stable_trait_with_associated_items", since = "1.0.0")]
pub trait StableTraitWithAssociatedItems {
// Stable trait-associated items need their own stability attributes in staged API crates.
//@ is "$.index[?(@.name=='StableAssocType')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='StableAssocType')].stability.feature" '"stable_assoc_type_feature"'
//@ is "$.index[?(@.name=='StableAssocType')].stability.since" '"1.1.0"'
//@ is "$.index[?(@.name=='StableAssocType')].stability.level.stable.since" '"1.1.0"'
//@ is "$.index[?(@.name=='StableAssocType')].attrs" []
#[stable(feature = "stable_assoc_type_feature", since = "1.1.0")]
type StableAssocType;

//@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.feature" '"unstable_assoc_const_in_stable_trait"'
//@ !has "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.since"
#[unstable(feature = "unstable_assoc_const_in_stable_trait", issue = "none")]
const UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT: usize = 0;

//@ is "$.index[?(@.name=='unstable_provided_method')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='unstable_provided_method')].stability.feature" '"unstable_provided_method_feature"'
//@ !has "$.index[?(@.name=='unstable_provided_method')].stability.since"
#[unstable(feature = "unstable_provided_method_feature", issue = "none")]
fn unstable_provided_method(&self) {}
}

//@ is "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.feature" '"unstable_trait_with_unannotated_associated_items"'
//@ !has "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.since"
#[unstable(feature = "unstable_trait_with_unannotated_associated_items", issue = "none")]
pub trait UnstableTraitWithUnannotatedAssociatedItems {
// Unannotated associated items in unstable traits inherit the trait's unstable stability.
//@ is "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.feature" '"unstable_trait_with_unannotated_associated_items"'
//@ !has "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.since"
type UnannotatedAssocTypeInUnstableTrait;

//@ is "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.feature" '"unstable_trait_with_unannotated_associated_items"'
//@ !has "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.since"
const UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT: usize;

//@ is "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.feature" '"unstable_trait_with_unannotated_associated_items"'
//@ !has "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.since"
fn unannotated_required_method_in_unstable_trait(&self);
}

//@ is "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.feature" '"unstable_trait_with_explicit_associated_item"'
//@ !has "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.since"
#[unstable(feature = "unstable_trait_with_explicit_associated_item", issue = "none")]
pub trait UnstableTraitWithExplicitAssociatedItem {
// It's possble to override the parent's instability with another `#[unstable]` attribute,
// for example to specify a different feature gate for that item.
//@ is "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.level" '"unstable"'
//@ is "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.feature" '"unstable_assoc_type_in_unstable_trait"'
//@ !has "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.since"
#[unstable(feature = "unstable_assoc_type_in_unstable_trait", issue = "none")]
type UnstableAssocTypeInUnstableTrait;
}
11 changes: 3 additions & 8 deletions tests/rustdoc-json/attrs/stability/const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@
pub fn non_const_function() {}

//@ set stable_const_fn = "$.index[?(@.name=='stable_const_fn')].id"
//@ is "$.index[?(@.name=='stable_const_fn')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='stable_const_fn')].stability.feature" '"stable_const_fn_feature"'
//@ is "$.index[?(@.name=='stable_const_fn')].stability.since" '"1.0.0"'
//@ is "$.index[?(@.name=='stable_const_fn')].const_stability.level" '"stable"'
//@ is "$.index[?(@.name=='stable_const_fn')].stability.level.stable.since" '"1.0.0"'
//@ is "$.index[?(@.name=='stable_const_fn')].const_stability.feature" '"stable_const_fn_const_feature"'
//@ is "$.index[?(@.name=='stable_const_fn')].const_stability.since" '"1.1.0"'
//@ is "$.index[?(@.name=='stable_const_fn')].const_stability.level.stable.since" '"1.1.0"'
//@ is "$.index[?(@.name=='stable_const_fn')].attrs" []
#[stable(feature = "stable_const_fn_feature", since = "1.0.0")]
#[rustc_const_stable(feature = "stable_const_fn_const_feature", since = "1.1.0")]
pub const fn stable_const_fn() {}

//@ is "$.index[?(@.name=='const_unstable_fn')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='const_unstable_fn')].stability.feature" '"const_unstable_fn_feature"'
//@ is "$.index[?(@.name=='const_unstable_fn')].stability.since" '"2.0.0"'
//@ is "$.index[?(@.name=='const_unstable_fn')].stability.level.stable.since" '"2.0.0"'
//@ is "$.index[?(@.name=='const_unstable_fn')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.name=='const_unstable_fn')].const_stability.feature" '"const_unstable_fn_const_feature"'
//@ !has "$.index[?(@.name=='const_unstable_fn')].const_stability.since"
//@ is "$.index[?(@.name=='const_unstable_fn')].attrs" []
#[stable(feature = "const_unstable_fn_feature", since = "2.0.0")]
#[rustc_const_unstable(feature = "const_unstable_fn_const_feature", issue = "none")]
Expand All @@ -35,7 +31,6 @@ pub const fn const_unstable_fn() {}
//@ !has "$.index[?(@.name=='unstable_fn_with_explicit_const_gate')].stability.since"
//@ is "$.index[?(@.name=='unstable_fn_with_explicit_const_gate')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.name=='unstable_fn_with_explicit_const_gate')].const_stability.feature" '"explicit_const_gate_on_unstable_fn"'
//@ !has "$.index[?(@.name=='unstable_fn_with_explicit_const_gate')].const_stability.since"
//@ is "$.index[?(@.name=='unstable_fn_with_explicit_const_gate')].attrs" []
#[unstable(feature = "unstable_fn_with_explicit_const_gate_feature", issue = "none")]
#[rustc_const_unstable(feature = "explicit_const_gate_on_unstable_fn", issue = "none")]
Expand Down
26 changes: 7 additions & 19 deletions tests/rustdoc-json/attrs/stability/const_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,24 @@ impl InherentConstMethodTarget {
pub const fn unstable_inherent_const_method_without_const_gate(&self) {}
}

//@ is "$.index[?(@.name=='ConstTrait')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='ConstTrait')].stability.feature" '"const_trait_feature"'
//@ is "$.index[?(@.name=='ConstTrait')].stability.since" '"2.0.0"'
//@ is "$.index[?(@.name=='ConstTrait')].stability.level.stable.since" '"2.0.0"'
//@ is "$.index[?(@.name=='ConstTrait')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.name=='ConstTrait')].const_stability.feature" '"const_trait_const_feature"'
//@ !has "$.index[?(@.name=='ConstTrait')].const_stability.since"
//@ is "$.index[?(@.name=='ConstTrait')].attrs" []
#[stable(feature = "const_trait_feature", since = "2.0.0")]
#[rustc_const_unstable(feature = "const_trait_const_feature", issue = "none")]
pub const trait ConstTrait {
// This item is *not* usable in a const context, because its parent is const-unstable.
//@ is "$.index[?(@.docs=='assoc type inside const trait')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.docs=='assoc type inside const trait')].const_stability.feature" '"const_trait_const_feature"'
//@ !has "$.index[?(@.docs=='assoc type inside const trait')].const_stability.since"
/// assoc type inside const trait
#[stable(feature = "trait_assoc_type_feature", since = "2.1.0")]
type TraitAssocType;

// This item is also *not* usable in a const context, because its parent is const-unstable.
//@ is "$.index[?(@.docs=='method inside const trait')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.docs=='method inside const trait')].const_stability.feature" '"const_trait_const_feature"'
//@ !has "$.index[?(@.docs=='method inside const trait')].const_stability.since"
/// method inside const trait
#[stable(feature = "trait_method_feature", since = "2.2.0")]
fn trait_method(&self);
Expand All @@ -55,7 +51,7 @@ pub const trait ConstTrait {
const TRAIT_ASSOC_CONST: usize;
}

//@ is "$.index[?(@.name=='ConstTraitWithUnstableMethod')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='ConstTraitWithUnstableMethod')].stability.level.stable.since" '"2.4.0"'
//@ is "$.index[?(@.name=='ConstTraitWithUnstableMethod')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.name=='ConstTraitWithUnstableMethod')].const_stability.feature" '"const_trait_with_unstable_method_const_feature"'
#[stable(feature = "const_trait_with_unstable_method_feature", since = "2.4.0")]
Expand All @@ -72,27 +68,23 @@ pub const trait ConstTraitWithUnstableMethod {
fn unstable_method_without_const_gate(&self);
}

//@ is "$.index[?(@.docs=='const trait impl')].stability.level" '"stable"'
//@ is "$.index[?(@.docs=='const trait impl')].stability.feature" '"const_trait_impl_feature"'
//@ is "$.index[?(@.docs=='const trait impl')].stability.since" '"3.0.0"'
//@ is "$.index[?(@.docs=='const trait impl')].stability.level.stable.since" '"3.0.0"'
//@ is "$.index[?(@.docs=='const trait impl')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.docs=='const trait impl')].const_stability.feature" '"const_trait_impl_const_feature"'
//@ !has "$.index[?(@.docs=='const trait impl')].const_stability.since"
/// const trait impl
#[stable(feature = "const_trait_impl_feature", since = "3.0.0")]
#[rustc_const_unstable(feature = "const_trait_impl_const_feature", issue = "none")]
const impl ConstTrait for ConstTraitTarget {
// This item is *not* usable in a const context, because its parent is const-unstable.
//@ is "$.index[?(@.docs=='assoc type inside const trait impl')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.docs=='assoc type inside const trait impl')].const_stability.feature" '"const_trait_impl_const_feature"'
//@ !has "$.index[?(@.docs=='assoc type inside const trait impl')].const_stability.since"
/// assoc type inside const trait impl
type TraitAssocType = usize;

// This item is also *not* usable in a const context, because its parent is const-unstable.
//@ is "$.index[?(@.docs=='method inside const trait impl')].const_stability.level" '"unstable"'
//@ is "$.index[?(@.docs=='method inside const trait impl')].const_stability.feature" '"const_trait_impl_const_feature"'
//@ !has "$.index[?(@.docs=='method inside const trait impl')].const_stability.since"
/// method inside const trait impl
fn trait_method(&self) {}

Expand All @@ -107,12 +99,10 @@ const impl ConstTrait for ConstTraitTarget {
// The `const trait` is const-stable. We indicate that *once* on the trait, but since
// there are no special cases here (unlike in the const-unstable case with associated consts)
// we do not duplicate the const-stability to all the associated items so as not to bloat the JSON.
//@ is "$.index[?(@.name=='ConstStableTrait')].stability.level" '"stable"'
//@ is "$.index[?(@.name=='ConstStableTrait')].stability.feature" '"const_stable_trait_feature"'
//@ is "$.index[?(@.name=='ConstStableTrait')].stability.since" '"4.0.0"'
//@ is "$.index[?(@.name=='ConstStableTrait')].const_stability.level" '"stable"'
//@ is "$.index[?(@.name=='ConstStableTrait')].const_stability.since" '"4.0.0"'
//@ is "$.index[?(@.name=='ConstStableTrait')].stability.level.stable.since" '"4.0.0"'
//@ is "$.index[?(@.name=='ConstStableTrait')].const_stability.feature" '"const_stable_trait_const_feature"'
//@ is "$.index[?(@.name=='ConstStableTrait')].const_stability.level.stable.since" '"4.0.0"'
#[stable(feature = "const_stable_trait_feature", since = "4.0.0")]
#[rustc_const_stable(feature = "const_stable_trait_const_feature", since = "4.0.0")]
pub const trait ConstStableTrait {
Expand All @@ -135,12 +125,10 @@ pub const trait ConstStableTrait {
// The `const impl` is const-stable. We indicate that *once* on the impl itself, but since
// there are no special cases here (unlike in the const-unstable case with associated consts)
// we do not duplicate the const-stability to all the associated items so as not to bloat the JSON.
//@ is "$.index[?(@.docs=='const-stable trait impl')].stability.level" '"stable"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].stability.feature" '"const_stable_trait_impl_feature"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].stability.since" '"5.0.0"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].const_stability.level" '"stable"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].const_stability.since" '"5.0.0"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].stability.level.stable.since" '"5.0.0"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].const_stability.feature" '"const_stable_trait_impl_const_feature"'
//@ is "$.index[?(@.docs=='const-stable trait impl')].const_stability.level.stable.since" '"5.0.0"'
/// const-stable trait impl
#[stable(feature = "const_stable_trait_impl_feature", since = "5.0.0")]
#[rustc_const_stable(feature = "const_stable_trait_impl_const_feature", since = "5.0.0")]
Expand Down
Loading
Loading