From 8b47f6781792606fcf49724155bce4228e87be36 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 18 Apr 2024 18:58:52 -0700 Subject: [PATCH] rustdoc-search: add index of borrow references --- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/render/search_index.rs | 61 ++++++---- tests/rustdoc-js/reference.js | 135 +++++++++++++++++++++ tests/rustdoc-js/reference.rs | 32 +++++ 4 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 tests/rustdoc-js/reference.js create mode 100644 tests/rustdoc-js/reference.rs diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 09a53affb14..075d94bd337 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -182,6 +182,7 @@ pub(crate) enum RenderTypeId { Primitive(clean::PrimitiveType), AssociatedType(Symbol), Index(isize), + Mut, } impl RenderTypeId { diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 6d2bb31ee13..e635c1e611d 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; use rustc_span::sym; -use rustc_span::symbol::Symbol; +use rustc_span::symbol::{kw, Symbol}; use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer}; use thin_vec::ThinVec; @@ -163,6 +163,15 @@ pub(crate) fn build_index<'tcx>( ) -> Option { let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache; match id { + RenderTypeId::Mut => Some(insert_into_map( + primitives, + kw::Mut, + lastpathid, + crate_paths, + ItemType::Keyword, + &[kw::Mut], + None, + )), RenderTypeId::DefId(defid) => { if let Some(&(ref fqp, item_type)) = 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())) } clean::Primitive(p) => Some(RenderTypeId::Primitive(p)), - clean::BorrowedRef { ref type_, .. } | clean::RawPointer(_, ref type_) => { - get_index_type_id(type_, rgen) - } + clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)), + clean::RawPointer(_, ref type_) => get_index_type_id(type_, rgen), // The type parameters are converted to generics in `simplify_fn_type` clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)), clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)), @@ -833,28 +841,14 @@ fn simplify_fn_type<'tcx, 'a>( } // First, check if it's "Self". - let mut is_self = false; - let mut arg = if let Some(self_) = self_ { - match &*arg { - Type::BorrowedRef { type_, .. } if type_.is_self_type() => { - is_self = true; - self_ - } - type_ if type_.is_self_type() => { - is_self = true; - self_ - } - arg => arg, - } + let (is_self, arg) = if let Some(self_) = self_ + && arg.is_self_type() + { + (true, self_) } 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 // for its bounds. if let Type::Generic(arg_s) = *arg { @@ -1027,6 +1021,27 @@ fn simplify_fn_type<'tcx, 'a>( bindings: Some(ty_bindings), 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 { // This is not a type parameter. So for example if we have `T, U: Option`, and we're // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. diff --git a/tests/rustdoc-js/reference.js b/tests/rustdoc-js/reference.js new file mode 100644 index 00000000000..dc40eee5687 --- /dev/null +++ b/tests/rustdoc-js/reference.js @@ -0,0 +1,135 @@ +// exact-check + +const EXPECTED = [ + // pinkie with explicit names + { + 'query': 'usize, usize -> ()', + 'others': [ + { 'path': 'reference', 'name': 'pinky' }, + ], + }, + { + 'query': 'reference, usize -> ()', + 'others': [ + { 'path': 'reference', 'name': 'pinky' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [], + }, + { + 'query': 'reference, usize -> ()', + 'others': [], + }, + // thumb with explicit names + { + 'query': 'thumb, thumb -> ()', + 'others': [ + { 'path': 'reference::Thumb', 'name': 'up' }, + ], + }, + { + 'query': 'reference, thumb -> ()', + 'others': [ + { 'path': 'reference::Thumb', 'name': 'up' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [], + }, + { + 'query': 'reference, thumb -> ()', + 'others': [], + }, + // index with explicit names + { + 'query': 'index, index -> ()', + 'others': [ + { 'path': 'reference::Index', 'name': 'point' }, + ], + }, + { + 'query': 'reference, index -> ()', + 'others': [ + { 'path': 'reference::Index', 'name': 'point' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [], + }, + { + 'query': 'reference, index -> ()', + 'others': [], + }, + // ring with explicit names + { + 'query': 'ring, ring -> ()', + 'others': [ + { 'path': 'reference::Ring', 'name': 'wear' }, + ], + }, + { + 'query': 'reference, ring -> ()', + 'others': [ + { 'path': 'reference::Ring', 'name': 'wear' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [ + { 'path': 'reference::Ring', 'name': 'wear' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [ + { 'path': 'reference::Ring', 'name': 'wear' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [], + }, + // middle with explicit names + { + 'query': 'middle, middle -> ()', + 'others': [ + { 'path': 'reference', 'name': 'show' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [ + { 'path': 'reference', 'name': 'show' }, + ], + }, + { + 'query': 'reference, reference -> ()', + 'others': [ + { 'path': 'reference', 'name': 'show' }, + ], + }, + { + 'query': 'reference>, reference> -> ()', + 'others': [ + { 'path': 'reference', 'name': 'show' }, + ], + }, + { + 'query': 'reference>, reference> -> ()', + 'others': [ + { 'path': 'reference', 'name': 'show' }, + ], + }, + { + 'query': 'reference>, reference> -> ()', + 'others': [], + }, + { + 'query': 'reference>, reference> -> ()', + 'others': [], + }, +]; diff --git a/tests/rustdoc-js/reference.rs b/tests/rustdoc-js/reference.rs new file mode 100644 index 00000000000..3a0a23c65d5 --- /dev/null +++ b/tests/rustdoc-js/reference.rs @@ -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!() }