diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 45a915719e9f2..1bba43cc45fd2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -117,7 +117,14 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< hir::ItemKind::Use(path, kind) => { let hir::UsePath { segments, span, .. } = *path; let path = hir::Path { segments, res: *res, span }; - clean_use_statement_inner(import, name, &path, kind, cx, &mut Default::default()) + clean_use_statement_inner( + import, + Some(name), + &path, + kind, + cx, + &mut Default::default(), + ) } _ => unreachable!(), } @@ -125,8 +132,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { - let name = renamed.unwrap_or(kw::Empty); // using kw::Empty is a bit of a hack - clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted) + clean_use_statement(item, *renamed, path, hir::UseKind::Glob, cx, &mut inserted) } else { // skip everything else Vec::new() @@ -1072,10 +1078,10 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib .. } = param { - func.decl - .inputs - .values - .insert(a.get() as _, Argument { name, type_: *ty, is_const: true }); + func.decl.inputs.values.insert( + a.get() as _, + Argument { name: Some(name), type_: *ty, is_const: true }, + ); } else { panic!("unexpected non const in position {pos}"); } @@ -1132,9 +1138,9 @@ fn clean_args_from_types_and_names<'tcx>( // If at least one argument has a name, use `_` as the name of unnamed // arguments. Otherwise omit argument names. let default_name = if idents.iter().any(|ident| nonempty_name(ident).is_some()) { - kw::Underscore + Some(kw::Underscore) } else { - kw::Empty + None }; Arguments { @@ -1143,7 +1149,7 @@ fn clean_args_from_types_and_names<'tcx>( .enumerate() .map(|(i, ty)| Argument { type_: clean_ty(ty, cx), - name: idents.get(i).and_then(nonempty_name).unwrap_or(default_name), + name: idents.get(i).and_then(nonempty_name).or(default_name), is_const: false, }) .collect(), @@ -1162,7 +1168,7 @@ fn clean_args_from_types_and_body_id<'tcx>( .iter() .zip(body.params) .map(|(ty, param)| Argument { - name: name_from_pat(param.pat), + name: Some(name_from_pat(param.pat)), type_: clean_ty(ty, cx), is_const: false, }) @@ -1218,11 +1224,11 @@ fn clean_poly_fn_sig<'tcx>( .iter() .map(|t| Argument { type_: clean_middle_ty(t.map_bound(|t| *t), cx, None, None), - name: if let Some(Some(ident)) = names.next() { + name: Some(if let Some(Some(ident)) = names.next() { ident.name } else { kw::Underscore - }, + }), is_const: false, }) .collect(), @@ -2792,10 +2798,7 @@ fn clean_maybe_renamed_item<'tcx>( use hir::ItemKind; let def_id = item.owner_id.to_def_id(); - let mut name = renamed.unwrap_or_else(|| { - // FIXME: using kw::Empty is a bit of a hack - cx.tcx.hir_opt_name(item.hir_id()).unwrap_or(kw::Empty) - }); + let mut name = if renamed.is_some() { renamed } else { cx.tcx.hir_opt_name(item.hir_id()) }; cx.with_param_env(def_id, |cx| { let kind = match item.kind { @@ -2836,7 +2839,7 @@ fn clean_maybe_renamed_item<'tcx>( item_type: Some(type_), })), item.owner_id.def_id.to_def_id(), - name, + name.unwrap(), import_id, renamed, )); @@ -2861,13 +2864,15 @@ fn clean_maybe_renamed_item<'tcx>( }), ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx), ItemKind::Macro(_, macro_def, MacroKind::Bang) => MacroItem(Macro { - source: display_macro_source(cx, name, macro_def), + source: display_macro_source(cx, name.unwrap(), macro_def), macro_rules: macro_def.macro_rules, }), - ItemKind::Macro(_, _, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx), + ItemKind::Macro(_, _, macro_kind) => { + clean_proc_macro(item, name.as_mut().unwrap(), macro_kind, cx) + } // proc macros can have a name set by attributes ItemKind::Fn { ref sig, generics, body: body_id, .. } => { - clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) + clean_fn_or_proc_macro(item, sig, generics, body_id, name.as_mut().unwrap(), cx) } ItemKind::Trait(_, _, _, generics, bounds, item_ids) => { let items = item_ids @@ -2883,7 +2888,7 @@ fn clean_maybe_renamed_item<'tcx>( })) } ItemKind::ExternCrate(orig_name, _) => { - return clean_extern_crate(item, name, orig_name, cx); + return clean_extern_crate(item, name.unwrap(), orig_name, cx); } ItemKind::Use(path, kind) => { return clean_use_statement(item, name, path, kind, cx, &mut FxHashSet::default()); @@ -2895,7 +2900,7 @@ fn clean_maybe_renamed_item<'tcx>( cx, kind, item.owner_id.def_id.to_def_id(), - name, + name.unwrap(), import_id, renamed, )] @@ -3006,7 +3011,7 @@ fn clean_extern_crate<'tcx>( fn clean_use_statement<'tcx>( import: &hir::Item<'tcx>, - name: Symbol, + name: Option, path: &hir::UsePath<'tcx>, kind: hir::UseKind, cx: &mut DocContext<'tcx>, @@ -3023,7 +3028,7 @@ fn clean_use_statement<'tcx>( fn clean_use_statement_inner<'tcx>( import: &hir::Item<'tcx>, - name: Symbol, + name: Option, path: &hir::Path<'tcx>, kind: hir::UseKind, cx: &mut DocContext<'tcx>, @@ -3042,7 +3047,7 @@ fn clean_use_statement_inner<'tcx>( let visibility = cx.tcx.visibility(import.owner_id); let attrs = cx.tcx.hir_attrs(import.hir_id()); let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline); - let pub_underscore = visibility.is_public() && name == kw::Underscore; + let pub_underscore = visibility.is_public() && name == Some(kw::Underscore); let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id); let import_def_id = import.owner_id.def_id; @@ -3108,6 +3113,7 @@ fn clean_use_statement_inner<'tcx>( } Import::new_glob(resolve_use_source(cx, path), true) } else { + let name = name.unwrap(); if inline_attr.is_none() && let Res::Def(DefKind::Mod, did) = path.res && !did.is_local() diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 06e75fe1764e0..1d398a6458fd2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1426,7 +1426,7 @@ pub(crate) struct Arguments { #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) struct Argument { pub(crate) type_: Type, - pub(crate) name: Symbol, + pub(crate) name: Option, /// This field is used to represent "const" arguments from the `rustc_legacy_const_generics` /// feature. More information in . pub(crate) is_const: bool, @@ -1434,7 +1434,7 @@ pub(crate) struct Argument { impl Argument { pub(crate) fn to_receiver(&self) -> Option<&Type> { - if self.name == kw::SelfLower { Some(&self.type_) } else { None } + if self.name == Some(kw::SelfLower) { Some(&self.type_) } else { None } } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index afcca81a485ff..8ee08edec1996 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -234,7 +234,7 @@ pub(super) fn clean_middle_path<'tcx>( args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, ) -> Path { let def_kind = cx.tcx.def_kind(did); - let name = cx.tcx.opt_item_name(did).unwrap_or(kw::Empty); + let name = cx.tcx.opt_item_name(did).unwrap_or(sym::dummy); Path { res: Res::Def(def_kind, did), segments: thin_vec![PathSegment { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 41e9a5a665169..4d55df71a910f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1238,8 +1238,8 @@ impl clean::Arguments { .iter() .map(|input| { fmt::from_fn(|f| { - if !input.name.is_empty() { - write!(f, "{}: ", input.name)?; + if let Some(name) = input.name { + write!(f, "{}: ", name)?; } input.type_.print(cx).fmt(f) }) @@ -1361,7 +1361,9 @@ impl clean::FnDecl { if input.is_const { write!(f, "const ")?; } - write!(f, "{}: ", input.name)?; + if let Some(name) = input.name { + write!(f, "{}: ", name)?; + } input.type_.print(cx).fmt(f)?; } match (line_wrapping_indent, last_input_index) { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 21c823f49d15f..adf15018ad2dc 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -208,7 +208,7 @@ pub(crate) struct IndexItemFunctionType { inputs: Vec, output: Vec, where_clause: Vec>, - param_names: Vec, + param_names: Vec>, } impl IndexItemFunctionType { diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 96847f13f655c..45cb0adecf3bf 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::DefId; use rustc_index::IndexVec; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; -use rustc_span::symbol::{Symbol, kw, sym}; +use rustc_span::symbol::{Symbol, sym}; use tracing::{debug, info}; use super::type_layout::document_type_layout; @@ -347,9 +347,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i // but we actually want stable items to come first return is_stable2.cmp(&is_stable1); } - let lhs = i1.name.unwrap_or(kw::Empty); - let rhs = i2.name.unwrap_or(kw::Empty); - compare_names(lhs.as_str(), rhs.as_str()) + match (i1.name, i2.name) { + (Some(name1), Some(name2)) => compare_names(name1.as_str(), name2.as_str()), + (Some(_), None) => Ordering::Greater, + (None, Some(_)) => Ordering::Less, + (None, None) => Ordering::Equal, + } } let tcx = cx.tcx(); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index b39701fae1d6a..1360ab94cb1ce 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -709,8 +709,11 @@ pub(crate) fn build_index( let mut result = Vec::new(); for (index, item) in self.items.iter().enumerate() { if let Some(ty) = &item.search_type - && let my = - ty.param_names.iter().map(|sym| sym.as_str()).collect::>() + && let my = ty + .param_names + .iter() + .filter_map(|sym| sym.map(|sym| sym.to_string())) + .collect::>() && my != prev { result.push((index, my.join(","))); @@ -1372,7 +1375,7 @@ fn simplify_fn_constraint<'a>( /// Used to allow type-based search on constants and statics. fn make_nullary_fn( clean_type: &clean::Type, -) -> (Vec, Vec, Vec, Vec>) { +) -> (Vec, Vec, Vec>, Vec>) { let mut rgen: FxIndexMap)> = Default::default(); let output = get_index_type(clean_type, vec![], &mut rgen); (vec![], vec![output], vec![], vec![]) @@ -1387,7 +1390,7 @@ fn get_fn_inputs_and_outputs( tcx: TyCtxt<'_>, impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>, cache: &Cache, -) -> (Vec, Vec, Vec, Vec>) { +) -> (Vec, Vec, Vec>, Vec>) { let decl = &func.decl; let mut rgen: FxIndexMap)> = Default::default(); @@ -1441,10 +1444,10 @@ fn get_fn_inputs_and_outputs( simplified_params .iter() .map(|(name, (_idx, _traits))| match name { - SimplifiedParam::Symbol(name) => *name, - SimplifiedParam::Anonymous(_) => kw::Empty, + SimplifiedParam::Symbol(name) => Some(*name), + SimplifiedParam::Anonymous(_) => None, SimplifiedParam::AssociatedType(def_id, name) => { - Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name)) + Some(Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name))) } }) .collect(), diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 9d8eb70fbe071..5d85a4676b7e9 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -11,7 +11,7 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; use rustc_middle::{bug, ty}; -use rustc_span::{Pos, Symbol}; +use rustc_span::{Pos, Symbol, kw}; use rustdoc_json_types::*; use crate::clean::{self, ItemId}; @@ -611,7 +611,10 @@ impl FromClean for FunctionSignature { inputs: inputs .values .into_iter() - .map(|arg| (arg.name.to_string(), arg.type_.into_json(renderer))) + // `_` is the most sensible name for missing param names. + .map(|arg| { + (arg.name.unwrap_or(kw::Underscore).to_string(), arg.type_.into_json(renderer)) + }) .collect(), output: if output.is_unit() { None } else { Some(output.into_json(renderer)) }, is_c_variadic: c_variadic,