Skip to content

Commit 8b47f67

Browse files
committed
rustdoc-search: add index of borrow references
1 parent f9b1614 commit 8b47f67

File tree

4 files changed

+206
-23
lines changed

4 files changed

+206
-23
lines changed

src/librustdoc/html/render/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ pub(crate) enum RenderTypeId {
182182
Primitive(clean::PrimitiveType),
183183
AssociatedType(Symbol),
184184
Index(isize),
185+
Mut,
185186
}
186187

187188
impl RenderTypeId {

src/librustdoc/html/render/search_index.rs

+38-23
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
77
use rustc_middle::ty::TyCtxt;
88
use rustc_span::def_id::DefId;
99
use rustc_span::sym;
10-
use rustc_span::symbol::Symbol;
10+
use rustc_span::symbol::{kw, Symbol};
1111
use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
1212
use thin_vec::ThinVec;
1313

@@ -163,6 +163,15 @@ pub(crate) fn build_index<'tcx>(
163163
) -> Option<RenderTypeId> {
164164
let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
165165
match id {
166+
RenderTypeId::Mut => Some(insert_into_map(
167+
primitives,
168+
kw::Mut,
169+
lastpathid,
170+
crate_paths,
171+
ItemType::Keyword,
172+
&[kw::Mut],
173+
None,
174+
)),
166175
RenderTypeId::DefId(defid) => {
167176
if let Some(&(ref fqp, item_type)) =
168177
paths.get(&defid).or_else(|| external_paths.get(&defid))
@@ -765,9 +774,8 @@ fn get_index_type_id(
765774
bounds.get(0).map(|b| RenderTypeId::DefId(b.trait_.def_id()))
766775
}
767776
clean::Primitive(p) => Some(RenderTypeId::Primitive(p)),
768-
clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => {
769-
get_index_type_id(type_, rgen)
770-
}
777+
clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)),
778+
clean::RawPointer(_, ref type_) => get_index_type_id(type_, rgen),
771779
// The type parameters are converted to generics in `simplify_fn_type`
772780
clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)),
773781
clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)),
@@ -833,28 +841,14 @@ fn simplify_fn_type<'tcx, 'a>(
833841
}
834842

835843
// First, check if it's "Self".
836-
let mut is_self = false;
837-
let mut arg = if let Some(self_) = self_ {
838-
match &*arg {
839-
Type::BorrowedRef { type_, .. } if type_.is_self_type() => {
840-
is_self = true;
841-
self_
842-
}
843-
type_ if type_.is_self_type() => {
844-
is_self = true;
845-
self_
846-
}
847-
arg => arg,
848-
}
844+
let (is_self, arg) = if let Some(self_) = self_
845+
&& arg.is_self_type()
846+
{
847+
(true, self_)
849848
} else {
850-
arg
849+
(false, arg)
851850
};
852851

853-
// strip references from the argument type
854-
while let Type::BorrowedRef { type_, .. } = &*arg {
855-
arg = &*type_;
856-
}
857-
858852
// If this argument is a type parameter and not a trait bound or a type, we need to look
859853
// for its bounds.
860854
if let Type::Generic(arg_s) = *arg {
@@ -1027,6 +1021,27 @@ fn simplify_fn_type<'tcx, 'a>(
10271021
bindings: Some(ty_bindings),
10281022
generics: Some(ty_generics),
10291023
});
1024+
} else if let Type::BorrowedRef { lifetime: _, mutability, ref type_ } = *arg {
1025+
let mut ty_generics = Vec::new();
1026+
if mutability.is_mut() {
1027+
ty_generics.push(RenderType {
1028+
id: Some(RenderTypeId::Mut),
1029+
generics: None,
1030+
bindings: None,
1031+
});
1032+
}
1033+
simplify_fn_type(
1034+
self_,
1035+
generics,
1036+
&type_,
1037+
tcx,
1038+
recurse + 1,
1039+
&mut ty_generics,
1040+
rgen,
1041+
is_return,
1042+
cache,
1043+
);
1044+
res.push(get_index_type(arg, ty_generics, rgen));
10301045
} else {
10311046
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
10321047
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.

tests/rustdoc-js/reference.js

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// exact-check
2+
3+
const EXPECTED = [
4+
// pinkie with explicit names
5+
{
6+
'query': 'usize, usize -> ()',
7+
'others': [
8+
{ 'path': 'reference', 'name': 'pinky' },
9+
],
10+
},
11+
{
12+
'query': 'reference<usize>, usize -> ()',
13+
'others': [
14+
{ 'path': 'reference', 'name': 'pinky' },
15+
],
16+
},
17+
{
18+
'query': 'reference<usize>, reference<usize> -> ()',
19+
'others': [],
20+
},
21+
{
22+
'query': 'reference<mut, usize>, usize -> ()',
23+
'others': [],
24+
},
25+
// thumb with explicit names
26+
{
27+
'query': 'thumb, thumb -> ()',
28+
'others': [
29+
{ 'path': 'reference::Thumb', 'name': 'up' },
30+
],
31+
},
32+
{
33+
'query': 'reference<thumb>, thumb -> ()',
34+
'others': [
35+
{ 'path': 'reference::Thumb', 'name': 'up' },
36+
],
37+
},
38+
{
39+
'query': 'reference<thumb>, reference<thumb> -> ()',
40+
'others': [],
41+
},
42+
{
43+
'query': 'reference<mut, thumb>, thumb -> ()',
44+
'others': [],
45+
},
46+
// index with explicit names
47+
{
48+
'query': 'index, index -> ()',
49+
'others': [
50+
{ 'path': 'reference::Index', 'name': 'point' },
51+
],
52+
},
53+
{
54+
'query': 'reference<index>, index -> ()',
55+
'others': [
56+
{ 'path': 'reference::Index', 'name': 'point' },
57+
],
58+
},
59+
{
60+
'query': 'reference<index>, reference<index> -> ()',
61+
'others': [],
62+
},
63+
{
64+
'query': 'reference<mut, index>, index -> ()',
65+
'others': [],
66+
},
67+
// ring with explicit names
68+
{
69+
'query': 'ring, ring -> ()',
70+
'others': [
71+
{ 'path': 'reference::Ring', 'name': 'wear' },
72+
],
73+
},
74+
{
75+
'query': 'reference<ring>, ring -> ()',
76+
'others': [
77+
{ 'path': 'reference::Ring', 'name': 'wear' },
78+
],
79+
},
80+
{
81+
'query': 'reference<ring>, reference<ring> -> ()',
82+
'others': [
83+
{ 'path': 'reference::Ring', 'name': 'wear' },
84+
],
85+
},
86+
{
87+
'query': 'reference<mut, ring>, reference<ring> -> ()',
88+
'others': [
89+
{ 'path': 'reference::Ring', 'name': 'wear' },
90+
],
91+
},
92+
{
93+
'query': 'reference<mut, ring>, reference<mut, ring> -> ()',
94+
'others': [],
95+
},
96+
// middle with explicit names
97+
{
98+
'query': 'middle, middle -> ()',
99+
'others': [
100+
{ 'path': 'reference', 'name': 'show' },
101+
],
102+
},
103+
{
104+
'query': 'reference<middle>, reference<middle> -> ()',
105+
'others': [
106+
{ 'path': 'reference', 'name': 'show' },
107+
],
108+
},
109+
{
110+
'query': 'reference<mut, middle>, reference<mut, middle> -> ()',
111+
'others': [
112+
{ 'path': 'reference', 'name': 'show' },
113+
],
114+
},
115+
{
116+
'query': 'reference<reference<mut, middle>>, reference<mut, reference<middle>> -> ()',
117+
'others': [
118+
{ 'path': 'reference', 'name': 'show' },
119+
],
120+
},
121+
{
122+
'query': 'reference<mut, reference<middle>>, reference<reference<mut, middle>> -> ()',
123+
'others': [
124+
{ 'path': 'reference', 'name': 'show' },
125+
],
126+
},
127+
{
128+
'query': 'reference<reference<mut, middle>>, reference<reference<mut, middle>> -> ()',
129+
'others': [],
130+
},
131+
{
132+
'query': 'reference<mut, reference<middle>>, reference<mut, reference<middle>> -> ()',
133+
'others': [],
134+
},
135+
];

tests/rustdoc-js/reference.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#![feature(extern_types)]
2+
3+
pub fn pinky(input: &usize, manage: usize) {
4+
unimplemented!()
5+
}
6+
7+
pub struct Thumb;
8+
9+
impl Thumb {
10+
pub fn up(&self, finger: Thumb) { unimplemented!() }
11+
}
12+
13+
pub enum Index {}
14+
15+
impl Index {
16+
pub fn point(self, data: &Index) { unimplemented!() }
17+
}
18+
19+
pub union Ring {
20+
magic: u32,
21+
marriage: f32,
22+
}
23+
24+
impl Ring {
25+
pub fn wear(&mut self, extra: &Ring) { unimplemented!() }
26+
}
27+
28+
extern "C" {
29+
pub type Middle;
30+
}
31+
32+
pub fn show(left: &&mut Middle, right: &mut &Middle) { unimplemented!() }

0 commit comments

Comments
 (0)