Skip to content

Commit 2672f0c

Browse files
committed
make item_module return impl fmt::Display
1 parent 0753215 commit 2672f0c

File tree

1 file changed

+172
-169
lines changed

1 file changed

+172
-169
lines changed

src/librustdoc/html/render/print_item.rs

Lines changed: 172 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut String)
247247
item_vars.render_into(buf).unwrap();
248248

249249
match &item.kind {
250-
clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
250+
clean::ModuleItem(ref m) => {
251+
write_str(buf, format_args!("{}", item_module(cx, item, &m.items)))
252+
}
251253
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => {
252254
item_function(buf, cx, item, f)
253255
}
@@ -309,198 +311,198 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display {
309311
fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>);
310312
}
311313

312-
fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) {
313-
write_str(w, format_args!("{}", document(cx, item, None, HeadingOffset::H2)));
314-
315-
let mut not_stripped_items =
316-
items.iter().filter(|i| !i.is_stripped()).enumerate().collect::<Vec<_>>();
317-
318-
// the order of item types in the listing
319-
fn reorder(ty: ItemType) -> u8 {
320-
match ty {
321-
ItemType::ExternCrate => 0,
322-
ItemType::Import => 1,
323-
ItemType::Primitive => 2,
324-
ItemType::Module => 3,
325-
ItemType::Macro => 4,
326-
ItemType::Struct => 5,
327-
ItemType::Enum => 6,
328-
ItemType::Constant => 7,
329-
ItemType::Static => 8,
330-
ItemType::Trait => 9,
331-
ItemType::Function => 10,
332-
ItemType::TypeAlias => 12,
333-
ItemType::Union => 13,
334-
_ => 14 + ty as u8,
314+
fn item_module<'a, 'tcx>(
315+
cx: &'a Context<'tcx>,
316+
item: &'a clean::Item,
317+
items: &'a [clean::Item],
318+
) -> impl fmt::Display + 'a + Captures<'tcx> {
319+
fmt::from_fn(|w| {
320+
write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?;
321+
322+
let mut not_stripped_items =
323+
items.iter().filter(|i| !i.is_stripped()).enumerate().collect::<Vec<_>>();
324+
325+
// the order of item types in the listing
326+
fn reorder(ty: ItemType) -> u8 {
327+
match ty {
328+
ItemType::ExternCrate => 0,
329+
ItemType::Import => 1,
330+
ItemType::Primitive => 2,
331+
ItemType::Module => 3,
332+
ItemType::Macro => 4,
333+
ItemType::Struct => 5,
334+
ItemType::Enum => 6,
335+
ItemType::Constant => 7,
336+
ItemType::Static => 8,
337+
ItemType::Trait => 9,
338+
ItemType::Function => 10,
339+
ItemType::TypeAlias => 12,
340+
ItemType::Union => 13,
341+
_ => 14 + ty as u8,
342+
}
335343
}
336-
}
337344

338-
fn cmp(i1: &clean::Item, i2: &clean::Item, tcx: TyCtxt<'_>) -> Ordering {
339-
let rty1 = reorder(i1.type_());
340-
let rty2 = reorder(i2.type_());
341-
if rty1 != rty2 {
342-
return rty1.cmp(&rty2);
343-
}
344-
let is_stable1 = i1.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true);
345-
let is_stable2 = i2.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true);
346-
if is_stable1 != is_stable2 {
347-
// true is bigger than false in the standard bool ordering,
348-
// but we actually want stable items to come first
349-
return is_stable2.cmp(&is_stable1);
350-
}
351-
let lhs = i1.name.unwrap_or(kw::Empty);
352-
let rhs = i2.name.unwrap_or(kw::Empty);
353-
compare_names(lhs.as_str(), rhs.as_str())
354-
}
355-
356-
let tcx = cx.tcx();
357-
358-
match cx.shared.module_sorting {
359-
ModuleSorting::Alphabetical => {
360-
not_stripped_items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx));
345+
fn cmp(i1: &clean::Item, i2: &clean::Item, tcx: TyCtxt<'_>) -> Ordering {
346+
let rty1 = reorder(i1.type_());
347+
let rty2 = reorder(i2.type_());
348+
if rty1 != rty2 {
349+
return rty1.cmp(&rty2);
350+
}
351+
let is_stable1 =
352+
i1.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true);
353+
let is_stable2 =
354+
i2.stability(tcx).as_ref().map(|s| s.level.is_stable()).unwrap_or(true);
355+
if is_stable1 != is_stable2 {
356+
// true is bigger than false in the standard bool ordering,
357+
// but we actually want stable items to come first
358+
return is_stable2.cmp(&is_stable1);
359+
}
360+
let lhs = i1.name.unwrap_or(kw::Empty);
361+
let rhs = i2.name.unwrap_or(kw::Empty);
362+
compare_names(lhs.as_str(), rhs.as_str())
361363
}
362-
ModuleSorting::DeclarationOrder => {}
363-
}
364-
// This call is to remove re-export duplicates in cases such as:
365-
//
366-
// ```
367-
// pub(crate) mod foo {
368-
// pub(crate) mod bar {
369-
// pub(crate) trait Double { fn foo(); }
370-
// }
371-
// }
372-
//
373-
// pub(crate) use foo::bar::*;
374-
// pub(crate) use foo::*;
375-
// ```
376-
//
377-
// `Double` will appear twice in the generated docs.
378-
//
379-
// FIXME: This code is quite ugly and could be improved. Small issue: DefId
380-
// can be identical even if the elements are different (mostly in imports).
381-
// So in case this is an import, we keep everything by adding a "unique id"
382-
// (which is the position in the vector).
383-
not_stripped_items.dedup_by_key(|(idx, i)| {
384-
(
385-
i.item_id,
386-
if i.name.is_some() { Some(full_path(cx, i)) } else { None },
387-
i.type_(),
388-
if i.is_import() { *idx } else { 0 },
389-
)
390-
});
391364

392-
debug!("{not_stripped_items:?}");
393-
let mut last_section = None;
365+
let tcx = cx.tcx();
394366

395-
for (_, myitem) in &not_stripped_items {
396-
let my_section = item_ty_to_section(myitem.type_());
397-
if Some(my_section) != last_section {
398-
if last_section.is_some() {
399-
w.push_str(ITEM_TABLE_CLOSE);
367+
match cx.shared.module_sorting {
368+
ModuleSorting::Alphabetical => {
369+
not_stripped_items.sort_by(|(_, i1), (_, i2)| cmp(i1, i2, tcx));
400370
}
401-
last_section = Some(my_section);
402-
let section_id = my_section.id();
403-
let tag =
404-
if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN };
405-
write_str(
406-
w,
407-
format_args!(
371+
ModuleSorting::DeclarationOrder => {}
372+
}
373+
// This call is to remove re-export duplicates in cases such as:
374+
//
375+
// ```
376+
// pub(crate) mod foo {
377+
// pub(crate) mod bar {
378+
// pub(crate) trait Double { fn foo(); }
379+
// }
380+
// }
381+
//
382+
// pub(crate) use foo::bar::*;
383+
// pub(crate) use foo::*;
384+
// ```
385+
//
386+
// `Double` will appear twice in the generated docs.
387+
//
388+
// FIXME: This code is quite ugly and could be improved. Small issue: DefId
389+
// can be identical even if the elements are different (mostly in imports).
390+
// So in case this is an import, we keep everything by adding a "unique id"
391+
// (which is the position in the vector).
392+
not_stripped_items.dedup_by_key(|(idx, i)| {
393+
(
394+
i.item_id,
395+
if i.name.is_some() { Some(full_path(cx, i)) } else { None },
396+
i.type_(),
397+
if i.is_import() { *idx } else { 0 },
398+
)
399+
});
400+
401+
debug!("{not_stripped_items:?}");
402+
let mut last_section = None;
403+
404+
for (_, myitem) in &not_stripped_items {
405+
let my_section = item_ty_to_section(myitem.type_());
406+
if Some(my_section) != last_section {
407+
if last_section.is_some() {
408+
w.write_str(ITEM_TABLE_CLOSE)?;
409+
}
410+
last_section = Some(my_section);
411+
let section_id = my_section.id();
412+
let tag =
413+
if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN };
414+
write!(
415+
w,
408416
"{}",
409417
write_section_heading(my_section.name(), &cx.derive_id(section_id), None, tag)
410-
),
411-
);
412-
}
418+
)?;
419+
}
413420

414-
match myitem.kind {
415-
clean::ExternCrateItem { ref src } => {
416-
use crate::html::format::anchor;
421+
match myitem.kind {
422+
clean::ExternCrateItem { ref src } => {
423+
use crate::html::format::anchor;
417424

418-
match *src {
419-
Some(src) => {
420-
write_str(
421-
w,
422-
format_args!(
425+
match *src {
426+
Some(src) => {
427+
write!(
428+
w,
423429
"<dt><code>{}extern crate {} as {};",
424430
visibility_print_with_space(myitem, cx),
425431
anchor(myitem.item_id.expect_def_id(), src, cx),
426432
EscapeBodyTextWithWbr(myitem.name.unwrap().as_str())
427-
),
428-
);
429-
}
430-
None => {
431-
write_str(
432-
w,
433-
format_args!(
433+
)?;
434+
}
435+
None => {
436+
write!(
437+
w,
434438
"<dt><code>{}extern crate {};",
435439
visibility_print_with_space(myitem, cx),
436440
anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx)
437-
),
438-
);
441+
)?;
442+
}
439443
}
444+
w.write_str("</code></dt>")?;
440445
}
441-
w.push_str("</code></dt>");
442-
}
443446

444-
clean::ImportItem(ref import) => {
445-
let stab_tags = import.source.did.map_or_else(String::new, |import_def_id| {
446-
extra_info_tags(tcx, myitem, item, Some(import_def_id)).to_string()
447-
});
447+
clean::ImportItem(ref import) => {
448+
let stab_tags = import.source.did.map_or_else(String::new, |import_def_id| {
449+
extra_info_tags(tcx, myitem, item, Some(import_def_id)).to_string()
450+
});
448451

449-
let id = match import.kind {
450-
clean::ImportKind::Simple(s) => {
451-
format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}")))
452-
}
453-
clean::ImportKind::Glob => String::new(),
454-
};
455-
write_str(
456-
w,
457-
format_args!(
452+
let id = match import.kind {
453+
clean::ImportKind::Simple(s) => {
454+
format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}")))
455+
}
456+
clean::ImportKind::Glob => String::new(),
457+
};
458+
write!(
459+
w,
458460
"<dt{id}>\
459461
<code>{vis}{imp}</code>{stab_tags}\
460462
</dt>",
461463
vis = visibility_print_with_space(myitem, cx),
462464
imp = import.print(cx)
463-
),
464-
);
465-
}
466-
467-
_ => {
468-
if myitem.name.is_none() {
469-
continue;
465+
)?;
470466
}
471467

472-
let unsafety_flag = match myitem.kind {
473-
clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
474-
if myitem.fn_header(tcx).unwrap().is_unsafe() =>
475-
{
476-
"<sup title=\"unsafe function\">⚠</sup>"
477-
}
478-
clean::ForeignStaticItem(_, hir::Safety::Unsafe) => {
479-
"<sup title=\"unsafe static\">⚠</sup>"
468+
_ => {
469+
if myitem.name.is_none() {
470+
continue;
480471
}
481-
_ => "",
482-
};
483-
484-
let visibility_and_hidden = match myitem.visibility(tcx) {
485-
Some(ty::Visibility::Restricted(_)) => {
486-
if myitem.is_doc_hidden() {
487-
// Don't separate with a space when there are two of them
488-
"<span title=\"Restricted Visibility\">&nbsp;🔒</span><span title=\"Hidden item\">👻</span> "
489-
} else {
490-
"<span title=\"Restricted Visibility\">&nbsp;🔒</span> "
472+
473+
let unsafety_flag = match myitem.kind {
474+
clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
475+
if myitem.fn_header(tcx).unwrap().is_unsafe() =>
476+
{
477+
"<sup title=\"unsafe function\">⚠</sup>"
491478
}
492-
}
493-
_ if myitem.is_doc_hidden() => "<span title=\"Hidden item\">&nbsp;👻</span> ",
494-
_ => "",
495-
};
496-
497-
let docs =
498-
MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string();
499-
let (docs_before, docs_after) =
500-
if docs.is_empty() { ("", "") } else { ("<dd>", "</dd>") };
501-
write_str(
502-
w,
503-
format_args!(
479+
clean::ForeignStaticItem(_, hir::Safety::Unsafe) => {
480+
"<sup title=\"unsafe static\">⚠</sup>"
481+
}
482+
_ => "",
483+
};
484+
485+
let visibility_and_hidden = match myitem.visibility(tcx) {
486+
Some(ty::Visibility::Restricted(_)) => {
487+
if myitem.is_doc_hidden() {
488+
// Don't separate with a space when there are two of them
489+
"<span title=\"Restricted Visibility\">&nbsp;🔒</span><span title=\"Hidden item\">👻</span> "
490+
} else {
491+
"<span title=\"Restricted Visibility\">&nbsp;🔒</span> "
492+
}
493+
}
494+
_ if myitem.is_doc_hidden() => {
495+
"<span title=\"Hidden item\">&nbsp;👻</span> "
496+
}
497+
_ => "",
498+
};
499+
500+
let docs =
501+
MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)).into_string();
502+
let (docs_before, docs_after) =
503+
if docs.is_empty() { ("", "") } else { ("<dd>", "</dd>") };
504+
write!(
505+
w,
504506
"<dt>\
505507
<a class=\"{class}\" href=\"{href}\" title=\"{title}\">{name}</a>\
506508
{visibility_and_hidden}\
@@ -515,15 +517,16 @@ fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[cl
515517
unsafety_flag = unsafety_flag,
516518
href = item_path(myitem.type_(), myitem.name.unwrap().as_str()),
517519
title = format_args!("{} {}", myitem.type_(), full_path(cx, myitem)),
518-
),
519-
);
520+
)?;
521+
}
520522
}
521523
}
522-
}
523524

524-
if last_section.is_some() {
525-
w.push_str(ITEM_TABLE_CLOSE);
526-
}
525+
if last_section.is_some() {
526+
w.write_str(ITEM_TABLE_CLOSE)?;
527+
}
528+
Ok(())
529+
})
527530
}
528531

529532
/// Render the stability, deprecation and portability tags that are displayed in the item's summary

0 commit comments

Comments
 (0)