diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c145929534d97..9687d014c8727 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -431,6 +431,10 @@ impl Item { self.deprecation(tcx).is_some_and(|deprecation| deprecation.is_in_effect()) } + pub(crate) fn is_unstable(&self) -> bool { + self.stability.is_some_and(|x| x.is_unstable()) + } + pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { self.item_id.as_def_id().map(|did| inner_docs(tcx.get_all_attrs(did))).unwrap_or(false) } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 64e361d566c32..5a97d8e5b5f42 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -594,6 +594,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It ); let aliases = item.attrs.get_doc_aliases(); let is_deprecated = item.is_deprecated(tcx); + let is_unstable = item.is_unstable(); let index_item = IndexItem { ty: item.type_(), defid: Some(defid), @@ -609,6 +610,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It search_type, aliases, is_deprecated, + is_unstable, }; cache.search_index.push(index_item); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 86e8167dc3cda..57428b6f481e8 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -142,6 +142,7 @@ pub(crate) struct IndexItem { pub(crate) search_type: Option, pub(crate) aliases: Box<[Symbol]>, pub(crate) is_deprecated: bool, + pub(crate) is_unstable: bool, } /// A type used for the search index. diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 30b534003da17..7c493653e77c0 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -616,6 +616,7 @@ impl SerializedSearchIndex { parent, trait_parent, deprecated, + unstable, associated_item_disambiguator, }| EntryData { krate: *map.get(krate).unwrap(), @@ -626,6 +627,7 @@ impl SerializedSearchIndex { parent: parent.and_then(|path_id| map.get(&path_id).copied()), trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()), deprecated: *deprecated, + unstable: *unstable, associated_item_disambiguator: associated_item_disambiguator.clone(), }, ), @@ -896,6 +898,7 @@ struct EntryData { parent: Option, trait_parent: Option, deprecated: bool, + unstable: bool, associated_item_disambiguator: Option, } @@ -912,6 +915,7 @@ impl Serialize for EntryData { seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?; seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?; seq.serialize_element(&if self.deprecated { 1 } else { 0 })?; + seq.serialize_element(&if self.unstable { 1 } else { 0 })?; if let Some(disambig) = &self.associated_item_disambiguator { seq.serialize_element(&disambig)?; } @@ -946,6 +950,7 @@ impl<'de> Deserialize<'de> for EntryData { v.next_element()?.ok_or_else(|| A::Error::missing_field("trait_parent"))?; let deprecated: u32 = v.next_element()?.unwrap_or(0); + let unstable: u32 = v.next_element()?.unwrap_or(0); let associated_item_disambiguator: Option = v.next_element()?; Ok(EntryData { krate, @@ -956,6 +961,7 @@ impl<'de> Deserialize<'de> for EntryData { parent: Option::::from(parent).map(|path| path as usize), trait_parent: Option::::from(trait_parent).map(|path| path as usize), deprecated: deprecated != 0, + unstable: unstable != 0, associated_item_disambiguator, }) } @@ -1283,6 +1289,7 @@ pub(crate) fn build_index( ), aliases: item.attrs.get_doc_aliases(), is_deprecated: item.is_deprecated(tcx), + is_unstable: item.is_unstable(), }); } } @@ -1382,6 +1389,7 @@ pub(crate) fn build_index( parent: None, trait_parent: None, deprecated: false, + unstable: false, associated_item_disambiguator: None, }), crate_doc, @@ -1520,6 +1528,7 @@ pub(crate) fn build_index( module_path, exact_module_path, deprecated: item.is_deprecated, + unstable: item.is_unstable, associated_item_disambiguator: if let Some(impl_id) = item.impl_id && let Some(parent_idx) = item.parent_idx && associated_item_duplicates diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 60df4fc10b8c5..555324c16f71a 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -243,6 +243,7 @@ declare namespace rustdoc { parent: number?, traitParent: number?, deprecated: boolean, + unstable: boolean, associatedItemDisambiguator: string?, } @@ -292,6 +293,7 @@ declare namespace rustdoc { path: PathData?, functionData: FunctionData?, deprecated: boolean, + unstable: boolean, parent: RowParent, traitParent: RowParent, } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 9961c1447ec2a..ab7350c8c0e4d 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1633,6 +1633,7 @@ class DocSearch { * parent, * trait_parent, * deprecated, + * unstable, * associated_item_disambiguator * @type {rustdoc.ArrayWithOptionals<[ * number, @@ -1642,6 +1643,7 @@ class DocSearch { * number, * number, * number, + * number, * ], [string]>} */ const raw = JSON.parse(encoded); @@ -1653,7 +1655,8 @@ class DocSearch { parent: raw[4] === 0 ? null : raw[4] - 1, traitParent: raw[5] === 0 ? null : raw[5] - 1, deprecated: raw[6] === 1 ? true : false, - associatedItemDisambiguator: raw.length === 7 ? null : raw[7], + unstable: raw[7] === 1 ? true : false, + associatedItemDisambiguator: raw.length === 8 ? null : raw[8], }; } @@ -1946,6 +1949,7 @@ class DocSearch { path, functionData, deprecated: entry ? entry.deprecated : false, + unstable: entry ? entry.unstable : false, parent, traitParent, }; @@ -2858,6 +2862,13 @@ class DocSearch { return a - b; } + // sort unstable items later + a = Number(aai.unstable); + b = Number(bbi.unstable); + if (a !== b) { + return a - b; + } + // sort by crate (current crate comes first) a = Number(aai.crate !== preferredCrate); b = Number(bbi.crate !== preferredCrate); diff --git a/tests/rustdoc-js-std/core-transmute.js b/tests/rustdoc-js-std/core-transmute.js index 8c9910a32d7f1..b15f398902c31 100644 --- a/tests/rustdoc-js-std/core-transmute.js +++ b/tests/rustdoc-js-std/core-transmute.js @@ -3,9 +3,9 @@ const EXPECTED = [ { 'query': 'generic:T -> generic:U', 'others': [ + { 'path': 'core::mem', 'name': 'transmute' }, { 'path': 'core::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'core::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'core::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/transmute-fail.js b/tests/rustdoc-js-std/transmute-fail.js index ddfb276194818..459e8dc3f0029 100644 --- a/tests/rustdoc-js-std/transmute-fail.js +++ b/tests/rustdoc-js-std/transmute-fail.js @@ -6,9 +6,9 @@ const EXPECTED = [ // should-fail tag and the search query below: 'query': 'generic:T -> generic:T', 'others': [ + { 'path': 'std::mem', 'name': 'transmute' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/transmute.js b/tests/rustdoc-js-std/transmute.js index f52e0ab14362d..a85b02e29947e 100644 --- a/tests/rustdoc-js-std/transmute.js +++ b/tests/rustdoc-js-std/transmute.js @@ -5,9 +5,9 @@ const EXPECTED = [ // should-fail tag and the search query below: 'query': 'generic:T -> generic:U', 'others': [ + { 'path': 'std::mem', 'name': 'transmute' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js/sort-stability.js b/tests/rustdoc-js/sort-stability.js new file mode 100644 index 0000000000000..8c095619a0866 --- /dev/null +++ b/tests/rustdoc-js/sort-stability.js @@ -0,0 +1,9 @@ +const EXPECTED = [ + { + 'query': 'foo', + 'others': [ + {"path": "sort_stability::old", "name": "foo"}, + {"path": "sort_stability::new", "name": "foo"}, + ], + }, +]; diff --git a/tests/rustdoc-js/sort-stability.rs b/tests/rustdoc-js/sort-stability.rs new file mode 100644 index 0000000000000..68662bb3aab6c --- /dev/null +++ b/tests/rustdoc-js/sort-stability.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] +#![stable(feature = "foo_lib", since = "1.0.0")] + +#[stable(feature = "old_foo", since = "1.0.1")] +pub mod old { + /// Old, stable foo + #[stable(feature = "old_foo", since = "1.0.1")] + pub fn foo() {} +} + +#[unstable(feature = "new_foo", issue = "none")] +pub mod new { + /// New, unstable foo + #[unstable(feature = "new_foo", issue = "none")] + pub fn foo() {} +}