Skip to content

Commit d35829b

Browse files
committed
rustdoc search: prefer stable items in search results
fixes #138067
1 parent 642e49b commit d35829b

File tree

10 files changed

+67
-6
lines changed

10 files changed

+67
-6
lines changed

src/librustdoc/formats/cache.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
586586
search_type,
587587
aliases,
588588
deprecation,
589+
stability: item.stability(tcx),
589590
};
590591
cache.search_index.push(index_item);
591592
}

src/librustdoc/html/render/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ use std::{fs, str};
5050
use askama::Template;
5151
use itertools::Either;
5252
use rustc_attr_data_structures::{
53-
ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
53+
ConstStability, DeprecatedSince, Deprecation, RustcVersion, Stability, StabilityLevel,
54+
StableSince,
5455
};
5556
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
5657
use rustc_hir::Mutability;
@@ -140,6 +141,12 @@ pub(crate) struct IndexItem {
140141
pub(crate) search_type: Option<IndexItemFunctionType>,
141142
pub(crate) aliases: Box<[Symbol]>,
142143
pub(crate) deprecation: Option<Deprecation>,
144+
pub(crate) stability: Option<Stability>,
145+
}
146+
impl IndexItem {
147+
fn is_unstable(&self) -> bool {
148+
matches!(&self.stability, Some(Stability { level: StabilityLevel::Unstable { .. }, .. }))
149+
}
143150
}
144151

145152
/// A type used for the search index.

src/librustdoc/html/render/search_index.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub(crate) fn build_index(
9393
),
9494
aliases: item.attrs.get_doc_aliases(),
9595
deprecation: item.deprecation(tcx),
96+
stability: item.stability(tcx),
9697
});
9798
}
9899
}
@@ -642,6 +643,7 @@ pub(crate) fn build_index(
642643
let mut parents_backref_queue = VecDeque::new();
643644
let mut functions = String::with_capacity(self.items.len());
644645
let mut deprecated = Vec::with_capacity(self.items.len());
646+
let mut unstable = Vec::with_capacity(self.items.len());
645647

646648
let mut type_backref_queue = VecDeque::new();
647649

@@ -698,6 +700,9 @@ pub(crate) fn build_index(
698700
// bitmasks always use 1-indexing for items, with 0 as the crate itself
699701
deprecated.push(u32::try_from(index + 1).unwrap());
700702
}
703+
if item.is_unstable() {
704+
unstable.push(u32::try_from(index + 1).unwrap());
705+
}
701706
}
702707

703708
for (index, path) in &revert_extra_paths {
@@ -736,6 +741,7 @@ pub(crate) fn build_index(
736741
crate_data.serialize_field("r", &re_exports)?;
737742
crate_data.serialize_field("b", &self.associated_item_disambiguators)?;
738743
crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?;
744+
crate_data.serialize_field("u", &bitmap_to_string(&unstable))?;
739745
crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?;
740746
crate_data.serialize_field("P", &param_names)?;
741747
if has_aliases {

src/librustdoc/html/static/js/rustdoc.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ declare namespace rustdoc {
129129

130130
/**
131131
* A single parsed "atom" in a search query. For example,
132-
*
132+
*
133133
* std::fmt::Formatter, Write -> Result<()>
134134
* ┏━━━━━━━━━━━━━━━━━━ ┌──── ┏━━━━━┅┅┅┅┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
135135
* ┃ │ ┗ QueryElement { ┊
@@ -442,6 +442,8 @@ declare namespace rustdoc {
442442
* of `p`) but is used for modules items like free functions.
443443
*
444444
* `c` is an array of item indices that are deprecated.
445+
*
446+
* `u` is an array of item indices that are unstable.
445447
*/
446448
type RawSearchIndexCrate = {
447449
doc: string,
@@ -456,6 +458,7 @@ declare namespace rustdoc {
456458
p: Array<[number, string] | [number, string, number] | [number, string, number, number] | [number, string, number, number, string]>,
457459
b: Array<[number, String]>,
458460
c: string,
461+
u: string,
459462
r: Array<[number, number]>,
460463
P: Array<[number, string]>,
461464
};

src/librustdoc/html/static/js/search.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,11 @@ class DocSearch {
14631463
* @type {Map<String, RoaringBitmap>}
14641464
*/
14651465
this.searchIndexEmptyDesc = new Map();
1466+
/**
1467+
* @type {Map<String, RoaringBitmap>}
1468+
*/
1469+
this.searchIndexUnstable = new Map();
1470+
14661471
/**
14671472
* @type {Uint32Array}
14681473
*/
@@ -2048,9 +2053,10 @@ class DocSearch {
20482053
};
20492054
const descShardList = [descShard];
20502055

2051-
// Deprecated items and items with no description
2056+
// Deprecated and unstable items and items with no description
20522057
this.searchIndexDeprecated.set(crate, new RoaringBitmap(crateCorpus.c));
20532058
this.searchIndexEmptyDesc.set(crate, new RoaringBitmap(crateCorpus.e));
2059+
this.searchIndexUnstable.set(crate, new RoaringBitmap(crateCorpus.u));
20542060
let descIndex = 0;
20552061

20562062
/**
@@ -3284,6 +3290,19 @@ class DocSearch {
32843290
return a - b;
32853291
}
32863292

3293+
// sort unstable items later
3294+
a = Number(
3295+
// @ts-expect-error
3296+
this.searchIndexUnstable.get(aaa.item.crate).contains(aaa.item.bitIndex),
3297+
);
3298+
b = Number(
3299+
// @ts-expect-error
3300+
this.searchIndexUnstable.get(bbb.item.crate).contains(bbb.item.bitIndex),
3301+
);
3302+
if (a !== b) {
3303+
return a - b;
3304+
}
3305+
32873306
// sort by crate (current crate comes first)
32883307
a = Number(aaa.item.crate !== preferredCrate);
32893308
b = Number(bbb.item.crate !== preferredCrate);

tests/rustdoc-js-std/core-transmute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ const EXPECTED = [
33
{
44
'query': 'generic:T -> generic:U',
55
'others': [
6+
{ 'path': 'core::mem', 'name': 'transmute' },
67
{ 'path': 'core::intrinsics::simd', 'name': 'simd_as' },
78
{ 'path': 'core::intrinsics::simd', 'name': 'simd_cast' },
8-
{ 'path': 'core::mem', 'name': 'transmute' },
99
],
1010
},
1111
];

tests/rustdoc-js-std/transmute-fail.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ const EXPECTED = [
66
// should-fail tag and the search query below:
77
'query': 'generic:T -> generic:T',
88
'others': [
9+
{ 'path': 'std::mem', 'name': 'transmute' },
910
{ 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
1011
{ 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
11-
{ 'path': 'std::mem', 'name': 'transmute' },
1212
],
1313
},
1414
];

tests/rustdoc-js-std/transmute.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ const EXPECTED = [
55
// should-fail tag and the search query below:
66
'query': 'generic:T -> generic:U',
77
'others': [
8+
{ 'path': 'std::mem', 'name': 'transmute' },
89
{ 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
910
{ 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
10-
{ 'path': 'std::mem', 'name': 'transmute' },
1111
],
1212
},
1313
];

tests/rustdoc-js/sort-stability.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const EXPECTED = [
2+
{
3+
'query': 'foo',
4+
'others': [
5+
{"path": "sort_stability::old", "name": "foo"},
6+
{"path": "sort_stability::new", "name": "foo"},
7+
],
8+
},
9+
];

tests/rustdoc-js/sort-stability.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(staged_api)]
2+
#![stable(feature = "foo_lib", since = "1.0.0")]
3+
4+
#[stable(feature = "old_foo", since = "1.0.1")]
5+
pub mod old {
6+
/// Old, stable foo
7+
#[stable(feature = "old_foo", since = "1.0.1")]
8+
pub fn foo() {}
9+
}
10+
11+
#[unstable(feature = "new_foo", issue = "none")]
12+
pub mod new {
13+
/// New, unstable foo
14+
#[unstable(feature = "new_foo", issue = "none")]
15+
pub fn foo() {}
16+
}

0 commit comments

Comments
 (0)