diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b60d466c3a7..f61a32a0f79 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1469,6 +1469,10 @@ impl Symbol { self.0.as_u32() } + pub fn is_empty(self) -> bool { + self == kw::Invalid + } + /// This method is supposed to be used in error messages, so it's expected to be /// identical to printing the original identifier token written in source code /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f7b6553a935..d358a7a369d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -124,7 +124,7 @@ crate fn try_inline( let attrs = merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone); cx.renderinfo.borrow_mut().inlined.insert(did); - let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name.clean(cx)), kind, cx); + let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx); ret.push(clean::Item { attrs, ..what_rustc_thinks }); Some(ret) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a63a5092ca..2d2465e56f3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -169,7 +169,7 @@ impl Clean for CrateNum { for attr in attrs.lists(sym::doc) { if attr.has_name(sym::keyword) { if let Some(v) = attr.value_str() { - keyword = Some(v.to_string()); + keyword = Some(v); break; } } @@ -253,12 +253,7 @@ impl Clean for doctree::Module<'_> { ModuleItem(Module { is_crate: self.is_crate, items }), cx, ); - Item { - name: Some(what_rustc_thinks.name.unwrap_or_default()), - attrs, - source: span.clean(cx), - ..what_rustc_thinks - } + Item { attrs, source: span.clean(cx), ..what_rustc_thinks } } } @@ -1096,7 +1091,7 @@ impl Clean for hir::TraitItem<'_> { AssocTypeItem(bounds.clean(cx), default.clean(cx)) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx) + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) }) } } @@ -1124,7 +1119,7 @@ impl Clean for hir::ImplItem<'_> { TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } }; - Item::from_def_id_and_parts(local_did, Some(self.ident.name.clean(cx)), inner, cx) + Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx) }) } } @@ -1281,7 +1276,7 @@ impl Clean for ty::AssocItem { } }; - Item::from_def_id_and_parts(self.def_id, Some(self.ident.name.clean(cx)), kind, cx) + Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), kind, cx) } } @@ -1771,7 +1766,7 @@ impl Clean for ty::FieldDef { fn clean(&self, cx: &DocContext<'_>) -> Item { let what_rustc_thinks = Item::from_def_id_and_parts( self.did, - Some(self.ident.name.clean(cx)), + Some(self.ident.name), StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), cx, ); @@ -1847,7 +1842,7 @@ impl Clean for ty::VariantDef { .fields .iter() .map(|field| { - let name = Some(field.ident.name.clean(cx)); + let name = Some(field.ident.name); let kind = StructFieldItem(cx.tcx.type_of(field.did).clean(cx)); let what_rustc_thinks = Item::from_def_id_and_parts(field.did, name, kind, cx); @@ -1859,7 +1854,7 @@ impl Clean for ty::VariantDef { }; let what_rustc_thinks = Item::from_def_id_and_parts( self.def_id, - Some(self.ident.name.clean(cx)), + Some(self.ident.name), VariantItem(Variant { kind }), cx, ); @@ -2033,7 +2028,7 @@ impl Clean> for (&hir::Item<'_>, Option) { _ => unreachable!("not yet converted"), }; - vec![Item::from_def_id_and_parts(def_id, Some(name.clean(cx)), kind, cx)] + vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)] }) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0228d63ac00..2c353a1e081 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -70,7 +70,7 @@ crate struct ExternalCrate { crate src: FileName, crate attrs: Attributes, crate primitives: Vec<(DefId, PrimitiveType)>, - crate keywords: Vec<(DefId, String)>, + crate keywords: Vec<(DefId, Symbol)>, } /// Anything with a source location and set of attributes and, optionally, a @@ -81,7 +81,7 @@ crate struct Item { /// Stringified span crate source: Span, /// Not everything has a name. E.g., impls - crate name: Option, + crate name: Option, crate attrs: Attributes, crate visibility: Visibility, crate kind: ItemKind, @@ -123,17 +123,12 @@ impl Item { kind: ItemKind, cx: &DocContext<'_>, ) -> Item { - Item::from_def_id_and_parts( - cx.tcx.hir().local_def_id(hir_id).to_def_id(), - name.clean(cx), - kind, - cx, - ) + Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx) } pub fn from_def_id_and_parts( def_id: DefId, - name: Option, + name: Option, kind: ItemKind, cx: &DocContext<'_>, ) -> Item { @@ -334,7 +329,7 @@ crate enum ItemKind { AssocTypeItem(Vec, Option), /// An item that has been stripped by a rustdoc pass StrippedItem(Box), - KeywordItem(String), + KeywordItem(Symbol), } impl ItemKind { @@ -1163,6 +1158,8 @@ crate enum Type { } #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)] +/// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't +/// paths, like `Unit`. crate enum PrimitiveType { Isize, I8, @@ -1502,6 +1499,37 @@ impl PrimitiveType { crate fn to_url_str(&self) -> &'static str { self.as_str() } + + crate fn as_sym(&self) -> Symbol { + use PrimitiveType::*; + match self { + Isize => sym::isize, + I8 => sym::i8, + I16 => sym::i16, + I32 => sym::i32, + I64 => sym::i64, + I128 => sym::i128, + Usize => sym::usize, + U8 => sym::u8, + U16 => sym::u16, + U32 => sym::u32, + U64 => sym::u64, + U128 => sym::u128, + F32 => sym::f32, + F64 => sym::f64, + Str => sym::str, + Bool => sym::bool, + Char => sym::char, + Array => sym::array, + Slice => sym::slice, + Tuple => sym::tuple, + Unit => sym::unit, + RawPointer => sym::pointer, + Reference => sym::reference, + Fn => kw::Fn, + Never => sym::never, + } + } } impl From for PrimitiveType { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 1b22d26f49b..f8743a4c42e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -68,7 +68,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { m.items.extend(primitives.iter().map(|&(def_id, prim)| { Item::from_def_id_and_parts( def_id, - Some(prim.to_url_str().to_owned()), + Some(prim.as_sym()), ItemKind::PrimitiveItem(prim), cx, ) diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 6334524eb1c..c332da4db4e 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use rustc_data_structures::sync::Lrc; use rustc_session::Session; use rustc_span::edition::Edition; +use rustc_span::Symbol; use crate::clean; use crate::config::{RenderInfo, RenderOptions}; @@ -75,7 +76,7 @@ crate fn run_format( None => return Ok(()), }; - item.name = Some(krate.name.clone()); + item.name = Some(Symbol::intern(&krate.name)); // Render the crate documentation let mut work = vec![(format_renderer.clone(), item)]; diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 97f764517fa..91037bc160a 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -76,7 +76,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { if let Some(&(ref fqp, _)) = paths.get(&did) { search_index.push(IndexItem { ty: item.type_(), - name: item.name.clone().unwrap(), + name: item.name.unwrap().to_string(), path: fqp[..fqp.len() - 1].join("::"), desc: item.doc_value().map_or_else(|| String::new(), short_markdown_summary), parent: Some(did), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index db04624dca8..00f3723ce23 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -61,7 +61,7 @@ use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::FileName; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; @@ -665,7 +665,7 @@ impl FormatRenderer for Context { if !buf.is_empty() { let name = item.name.as_ref().unwrap(); let item_type = item.type_(); - let file_name = &item_path(item_type, name); + let file_name = &item_path(item_type, &name.as_str()); self.shared.ensure_dir(&self.dst)?; let joint_dst = self.dst.join(file_name); self.shared.fs.write(&joint_dst, buf.as_bytes())?; @@ -1543,7 +1543,7 @@ impl Context { if !title.is_empty() { title.push_str("::"); } - title.push_str(it.name.as_ref().unwrap()); + title.push_str(&it.name.unwrap().as_str()); } title.push_str(" - Rust"); let tyname = it.type_(); @@ -1815,7 +1815,7 @@ fn item_path(ty: ItemType, name: &str) -> String { fn full_path(cx: &Context, item: &clean::Item) -> String { let mut s = cx.current.join("::"); s.push_str("::"); - s.push_str(item.name.as_ref().unwrap()); + s.push_str(&item.name.unwrap().as_str()); s } @@ -2065,9 +2065,9 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: (true, false) => return Ordering::Greater, } } - let lhs = i1.name.as_ref().map_or("", |s| &**s); - let rhs = i2.name.as_ref().map_or("", |s| &**s); - compare_names(lhs, rhs) + let lhs = i1.name.unwrap_or(kw::Invalid).as_str(); + let rhs = i2.name.unwrap_or(kw::Invalid).as_str(); + compare_names(&lhs, &rhs) } if cx.shared.sort_modules_alphabetically { @@ -2191,7 +2191,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: add = add, stab = stab.unwrap_or_else(String::new), unsafety_flag = unsafety_flag, - href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()), + href = item_path(myitem.type_(), &myitem.name.unwrap().as_str()), title = [full_path(cx, myitem), myitem.type_().to_string()] .iter() .filter_map(|s| if !s.is_empty() { Some(s.as_str()) } else { None }) @@ -2623,7 +2623,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait, fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item, cache: &Cache) { let name = m.name.as_ref().unwrap(); - info!("Documenting {} on {}", name, t.name.as_deref().unwrap_or_default()); + info!("Documenting {} on {:?}", name, t.name); let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); write!(w, "

", id = id,); @@ -2951,7 +2951,7 @@ fn render_assoc_item( AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from an impl-item to the corresponding // trait-item and need to map the anchored type accordingly. - let ty = if provided_methods.contains(name) { + let ty = if provided_methods.contains(&*name.as_str()) { ItemType::Method } else { ItemType::TyMethod @@ -3434,10 +3434,7 @@ fn render_assoc_items( what: AssocItemRender<'_>, cache: &Cache, ) { - info!( - "Documenting associated items of {}", - containing_item.name.as_deref().unwrap_or_default() - ); + info!("Documenting associated items of {:?}", containing_item.name); let v = match cache.impls.get(&it) { Some(v) => v, None => return, @@ -4139,7 +4136,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca ty: \"{ty}\", \ relpath: \"{path}\"\ }};", - name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""), + name = it.name.unwrap_or(kw::Invalid), ty = it.type_(), path = relpath ); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index c463481db86..49de4c6d2e7 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -33,7 +33,7 @@ impl JsonRenderer { _ => Some(Item { id: def_id.into(), crate_id: def_id.krate.as_u32(), - name, + name: name.map(|sym| sym.to_string()), source: self.convert_span(source), visibility: visibility.into(), docs: attrs.collapsed_doc_value().unwrap_or_default(), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 167eb07a690..dc6f8ed6cbb 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -696,7 +696,7 @@ fn resolve_associated_trait_item( // Give precedence to methods that were overridden if !impl_.provided_trait_methods.contains(&*item_name.as_str()) { let mut items = impl_.items.into_iter().filter_map(|assoc| { - if assoc.name.as_deref() != Some(&*item_name.as_str()) { + if assoc.name != Some(item_name) { return None; } let kind = assoc @@ -2015,7 +2015,14 @@ fn privacy_error( dox: &str, link_range: Option>, ) { - let item_name = item.name.as_deref().unwrap_or(""); + let sym; + let item_name = match item.name { + Some(name) => { + sym = name.as_str(); + &*sym + } + None => "", + }; let msg = format!("public documentation for `{}` links to private item `{}`", item_name, path_str);