rustdoc-search: add index of borrow references

This commit is contained in:
Michael Howell 2024-04-18 18:58:52 -07:00
parent f9b1614920
commit 8b47f67817
4 changed files with 206 additions and 23 deletions

View File

@ -182,6 +182,7 @@ pub(crate) enum RenderTypeId {
Primitive(clean::PrimitiveType), Primitive(clean::PrimitiveType),
AssociatedType(Symbol), AssociatedType(Symbol),
Index(isize), Index(isize),
Mut,
} }
impl RenderTypeId { impl RenderTypeId {

View File

@ -7,7 +7,7 @@
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_span::sym; use rustc_span::sym;
use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, Symbol};
use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer}; use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
use thin_vec::ThinVec; use thin_vec::ThinVec;
@ -163,6 +163,15 @@ fn convert_render_type_id(
) -> Option<RenderTypeId> { ) -> Option<RenderTypeId> {
let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache; let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
match id { match id {
RenderTypeId::Mut => Some(insert_into_map(
primitives,
kw::Mut,
lastpathid,
crate_paths,
ItemType::Keyword,
&[kw::Mut],
None,
)),
RenderTypeId::DefId(defid) => { RenderTypeId::DefId(defid) => {
if let Some(&(ref fqp, item_type)) = if let Some(&(ref fqp, item_type)) =
paths.get(&defid).or_else(|| external_paths.get(&defid)) paths.get(&defid).or_else(|| external_paths.get(&defid))
@ -765,9 +774,8 @@ fn get_index_type_id(
bounds.get(0).map(|b| RenderTypeId::DefId(b.trait_.def_id())) bounds.get(0).map(|b| RenderTypeId::DefId(b.trait_.def_id()))
} }
clean::Primitive(p) => Some(RenderTypeId::Primitive(p)), clean::Primitive(p) => Some(RenderTypeId::Primitive(p)),
clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => { clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)),
get_index_type_id(type_, rgen) clean::RawPointer(_, ref type_) => get_index_type_id(type_, rgen),
}
// The type parameters are converted to generics in `simplify_fn_type` // The type parameters are converted to generics in `simplify_fn_type`
clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)), clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)),
clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)), clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)),
@ -833,28 +841,14 @@ fn simplify_fn_type<'tcx, 'a>(
} }
// First, check if it's "Self". // First, check if it's "Self".
let mut is_self = false; let (is_self, arg) = if let Some(self_) = self_
let mut arg = if let Some(self_) = self_ { && arg.is_self_type()
match &*arg { {
Type::BorrowedRef { type_, .. } if type_.is_self_type() => { (true, self_)
is_self = true;
self_
}
type_ if type_.is_self_type() => {
is_self = true;
self_
}
arg => arg,
}
} else { } else {
arg (false, arg)
}; };
// strip references from the argument type
while let Type::BorrowedRef { type_, .. } = &*arg {
arg = &*type_;
}
// If this argument is a type parameter and not a trait bound or a type, we need to look // If this argument is a type parameter and not a trait bound or a type, we need to look
// for its bounds. // for its bounds.
if let Type::Generic(arg_s) = *arg { if let Type::Generic(arg_s) = *arg {
@ -1027,6 +1021,27 @@ fn simplify_fn_type<'tcx, 'a>(
bindings: Some(ty_bindings), bindings: Some(ty_bindings),
generics: Some(ty_generics), generics: Some(ty_generics),
}); });
} else if let Type::BorrowedRef { lifetime: _, mutability, ref type_ } = *arg {
let mut ty_generics = Vec::new();
if mutability.is_mut() {
ty_generics.push(RenderType {
id: Some(RenderTypeId::Mut),
generics: None,
bindings: None,
});
}
simplify_fn_type(
self_,
generics,
&type_,
tcx,
recurse + 1,
&mut ty_generics,
rgen,
is_return,
cache,
);
res.push(get_index_type(arg, ty_generics, rgen));
} else { } else {
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
// looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't.

View File

@ -0,0 +1,135 @@
// exact-check
const EXPECTED = [
// pinkie with explicit names
{
'query': 'usize, usize -> ()',
'others': [
{ 'path': 'reference', 'name': 'pinky' },
],
},
{
'query': 'reference<usize>, usize -> ()',
'others': [
{ 'path': 'reference', 'name': 'pinky' },
],
},
{
'query': 'reference<usize>, reference<usize> -> ()',
'others': [],
},
{
'query': 'reference<mut, usize>, usize -> ()',
'others': [],
},
// thumb with explicit names
{
'query': 'thumb, thumb -> ()',
'others': [
{ 'path': 'reference::Thumb', 'name': 'up' },
],
},
{
'query': 'reference<thumb>, thumb -> ()',
'others': [
{ 'path': 'reference::Thumb', 'name': 'up' },
],
},
{
'query': 'reference<thumb>, reference<thumb> -> ()',
'others': [],
},
{
'query': 'reference<mut, thumb>, thumb -> ()',
'others': [],
},
// index with explicit names
{
'query': 'index, index -> ()',
'others': [
{ 'path': 'reference::Index', 'name': 'point' },
],
},
{
'query': 'reference<index>, index -> ()',
'others': [
{ 'path': 'reference::Index', 'name': 'point' },
],
},
{
'query': 'reference<index>, reference<index> -> ()',
'others': [],
},
{
'query': 'reference<mut, index>, index -> ()',
'others': [],
},
// ring with explicit names
{
'query': 'ring, ring -> ()',
'others': [
{ 'path': 'reference::Ring', 'name': 'wear' },
],
},
{
'query': 'reference<ring>, ring -> ()',
'others': [
{ 'path': 'reference::Ring', 'name': 'wear' },
],
},
{
'query': 'reference<ring>, reference<ring> -> ()',
'others': [
{ 'path': 'reference::Ring', 'name': 'wear' },
],
},
{
'query': 'reference<mut, ring>, reference<ring> -> ()',
'others': [
{ 'path': 'reference::Ring', 'name': 'wear' },
],
},
{
'query': 'reference<mut, ring>, reference<mut, ring> -> ()',
'others': [],
},
// middle with explicit names
{
'query': 'middle, middle -> ()',
'others': [
{ 'path': 'reference', 'name': 'show' },
],
},
{
'query': 'reference<middle>, reference<middle> -> ()',
'others': [
{ 'path': 'reference', 'name': 'show' },
],
},
{
'query': 'reference<mut, middle>, reference<mut, middle> -> ()',
'others': [
{ 'path': 'reference', 'name': 'show' },
],
},
{
'query': 'reference<reference<mut, middle>>, reference<mut, reference<middle>> -> ()',
'others': [
{ 'path': 'reference', 'name': 'show' },
],
},
{
'query': 'reference<mut, reference<middle>>, reference<reference<mut, middle>> -> ()',
'others': [
{ 'path': 'reference', 'name': 'show' },
],
},
{
'query': 'reference<reference<mut, middle>>, reference<reference<mut, middle>> -> ()',
'others': [],
},
{
'query': 'reference<mut, reference<middle>>, reference<mut, reference<middle>> -> ()',
'others': [],
},
];

View File

@ -0,0 +1,32 @@
#![feature(extern_types)]
pub fn pinky(input: &usize, manage: usize) {
unimplemented!()
}
pub struct Thumb;
impl Thumb {
pub fn up(&self, finger: Thumb) { unimplemented!() }
}
pub enum Index {}
impl Index {
pub fn point(self, data: &Index) { unimplemented!() }
}
pub union Ring {
magic: u32,
marriage: f32,
}
impl Ring {
pub fn wear(&mut self, extra: &Ring) { unimplemented!() }
}
extern "C" {
pub type Middle;
}
pub fn show(left: &&mut Middle, right: &mut &Middle) { unimplemented!() }