diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index dd91cec531f59..eee13ff2b0dc0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1252,9 +1252,9 @@ struct Indent(usize); impl Display for Indent { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (0..self.0).for_each(|_| { - f.write_char(' ').unwrap(); - }); + for _ in 0..self.0 { + f.write_char(' ')?; + } Ok(()) } } diff --git a/src/librustdoc/html/length_limit.rs b/src/librustdoc/html/length_limit.rs index fdb1ddc1f5311..f786215a93be4 100644 --- a/src/librustdoc/html/length_limit.rs +++ b/src/librustdoc/html/length_limit.rs @@ -87,7 +87,7 @@ impl HtmlWithLimit { pub(super) fn close_tag(&mut self) { if let Some(tag_name) = self.unclosed_tags.pop() { // Close the most recently opened tag. - write!(self.buf, "").unwrap() + write!(self.buf, "").expect("infallible string operation"); } // There are valid cases where `close_tag()` is called without // there being any tags to close. For example, this occurs when @@ -99,7 +99,7 @@ impl HtmlWithLimit { /// Write all queued tags and add them to the `unclosed_tags` list. fn flush_queue(&mut self) { for tag_name in self.queued_tags.drain(..) { - write!(self.buf, "<{tag_name}>").unwrap(); + write!(self.buf, "<{tag_name}>").expect("infallible string operation"); self.unclosed_tags.push(tag_name); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 871ed53bd3380..9c8e599104be4 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -916,7 +916,7 @@ fn render_impls( impls: &[&Impl], containing_item: &clean::Item, toggle_open_by_default: bool, -) { +) -> fmt::Result { let mut rendered_impls = impls .iter() .map(|i| { @@ -942,7 +942,7 @@ fn render_impls( }) .collect::>(); rendered_impls.sort(); - w.write_str(&rendered_impls.join("")).unwrap(); + w.write_str(&rendered_impls.join("")) } /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. @@ -1037,7 +1037,7 @@ fn assoc_const( ) -> impl fmt::Display { let tcx = cx.tcx(); fmt::from_fn(move |w| { - render_attributes_in_code(w, it, &" ".repeat(indent), cx); + render_attributes_in_code(w, it, &" ".repeat(indent), cx)?; write!( w, "{indent}{vis}const {name}{generics}: {ty}", @@ -1145,10 +1145,10 @@ fn assoc_method( let (indent, indent_str, end_newline) = if parent == ItemType::Trait { header_len += 4; let indent_str = " "; - render_attributes_in_code(w, meth, indent_str, cx); + render_attributes_in_code(w, meth, indent_str, cx)?; (4, indent_str, Ending::NoNewline) } else { - render_attributes_in_code(w, meth, "", cx); + render_attributes_in_code(w, meth, "", cx)?; (0, "", Ending::Newline) }; write!( @@ -1365,10 +1365,10 @@ fn render_all_impls( concrete: &[&Impl], synthetic: &[&Impl], blanket_impl: &[&Impl], -) { +) -> fmt::Result { let impls = { let mut buf = String::new(); - render_impls(cx, &mut buf, concrete, containing_item, true); + render_impls(cx, &mut buf, concrete, containing_item, true)?; buf }; if !impls.is_empty() { @@ -1376,8 +1376,7 @@ fn render_all_impls( w, "{}
{impls}
", write_impl_section_heading("Trait Implementations", "trait-implementations") - ) - .unwrap(); + )?; } if !synthetic.is_empty() { @@ -1385,10 +1384,9 @@ fn render_all_impls( w, "{}
", write_impl_section_heading("Auto Trait Implementations", "synthetic-implementations",) - ) - .unwrap(); - render_impls(cx, &mut w, synthetic, containing_item, false); - w.write_str("
").unwrap(); + )?; + render_impls(cx, &mut w, synthetic, containing_item, false)?; + w.write_str("")?; } if !blanket_impl.is_empty() { @@ -1396,11 +1394,11 @@ fn render_all_impls( w, "{}
", write_impl_section_heading("Blanket Implementations", "blanket-implementations") - ) - .unwrap(); - render_impls(cx, &mut w, blanket_impl, containing_item, false); - w.write_str("
").unwrap(); + )?; + render_impls(cx, &mut w, blanket_impl, containing_item, false)?; + w.write_str("")?; } + Ok(()) } fn render_assoc_items( @@ -1412,8 +1410,7 @@ fn render_assoc_items( fmt::from_fn(move |f| { let mut derefs = DefIdSet::default(); derefs.insert(it); - render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs); - Ok(()) + render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs) }) } @@ -1424,10 +1421,10 @@ fn render_assoc_items_inner( it: DefId, what: AssocItemRender<'_>, derefs: &mut DefIdSet, -) { +) -> fmt::Result { info!("Documenting associated items of {:?}", containing_item.name); let cache = &cx.shared.cache; - let Some(v) = cache.impls.get(&it) else { return }; + let Some(v) = cache.impls.get(&it) else { return Ok(()) }; let (mut non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { @@ -1511,8 +1508,7 @@ fn render_assoc_items_inner( matches!(what, AssocItemRender::DerefFor { .. }) .then_some("") .maybe_display(), - ) - .unwrap(); + )?; } } @@ -1522,13 +1518,13 @@ fn render_assoc_items_inner( if let Some(impl_) = deref_impl { let has_deref_mut = traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait()); - render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs); + render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs)?; } // If we were already one level into rendering deref methods, we don't want to render // anything after recursing into any further deref methods above. if let AssocItemRender::DerefFor { .. } = what { - return; + return Ok(()); } let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = @@ -1536,8 +1532,9 @@ fn render_assoc_items_inner( let (blanket_impl, concrete): (Vec<&Impl>, _) = concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket()); - render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl); + render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl)?; } + Ok(()) } /// `derefs` is the set of all deref targets that have already been handled. @@ -1548,7 +1545,7 @@ fn render_deref_methods( container_item: &clean::Item, deref_mut: bool, derefs: &mut DefIdSet, -) { +) -> fmt::Result { let cache = cx.cache(); let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); let (target, real_target) = impl_ @@ -1574,15 +1571,16 @@ fn render_deref_methods( // `impl Deref for S` if did == type_did || !derefs.insert(did) { // Avoid infinite cycles - return; + return Ok(()); } } - render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs); + render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?; } else if let Some(prim) = target.primitive_type() && let Some(&did) = cache.primitive_locations.get(&prim) { - render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs); + render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?; } + Ok(()) } fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool { @@ -1805,8 +1803,7 @@ fn render_impl( // because impls can't have a stability. if !item.doc_value().is_empty() { document_item_info(cx, it, Some(parent)) - .render_into(&mut info_buffer) - .unwrap(); + .render_into(&mut info_buffer)?; doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string(); short_documented = false; } else { @@ -1823,9 +1820,7 @@ fn render_impl( } } } else { - document_item_info(cx, item, Some(parent)) - .render_into(&mut info_buffer) - .unwrap(); + document_item_info(cx, item, Some(parent)).render_into(&mut info_buffer)?; if rendering_params.show_def_docs { doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string(); short_documented = false; @@ -2920,7 +2915,7 @@ fn render_attributes_in_code( item: &clean::Item, prefix: &str, cx: &Context<'_>, -) { +) -> fmt::Result { for attr in &item.attrs.other_attrs { let hir::Attribute::Parsed(kind) = attr else { continue }; let attr = match kind { @@ -2934,24 +2929,30 @@ fn render_attributes_in_code( AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"), _ => continue, }; - render_code_attribute(prefix, attr.as_ref(), w); + render_code_attribute(prefix, attr.as_ref(), w)?; } if let Some(def_id) = item.def_id() && let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) { - render_code_attribute(prefix, &repr, w); + render_code_attribute(prefix, &repr, w)?; } + Ok(()) } -fn render_repr_attribute_in_code(w: &mut impl fmt::Write, cx: &Context<'_>, def_id: DefId) { +fn render_repr_attribute_in_code( + w: &mut impl fmt::Write, + cx: &Context<'_>, + def_id: DefId, +) -> fmt::Result { if let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) { - render_code_attribute("", &repr, w); + render_code_attribute("", &repr, w)?; } + Ok(()) } -fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) { - write!(w, "
{prefix}{attr}
").unwrap(); +fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) -> fmt::Result { + write!(w, "
{prefix}{attr}
") } /// Compute the *public* `#[repr]` of the item given by `DefId`. diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index fa7c9e75fdac4..0c511738d7c8a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -457,7 +457,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i "\ " )?; - render_attributes_in_code(w, myitem, "", cx); + render_attributes_in_code(w, myitem, "", cx)?; write!( w, "{vis}{imp}{stab_tags}\ @@ -625,7 +625,7 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp let notable_traits = notable_traits_button(&f.decl.output, cx).maybe_display(); wrap_item(w, |w| { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; write!( w, "{vis}{constness}{asyncness}{safety}{abi}fn \ @@ -666,7 +666,7 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: // Output the trait definition wrap_item(w, |mut w| { - render_attributes_in_code(&mut w, it, "", cx); + render_attributes_in_code(&mut w, it, "", cx)?; write!( w, "{vis}{safety}{is_auto}trait {name}{generics}{bounds}", @@ -1240,7 +1240,7 @@ fn item_trait_alias( ) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; write!( w, "trait {name}{generics} = {bounds}{where_clause};", @@ -1268,7 +1268,7 @@ fn item_trait_alias( fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; write!( w, "{vis}type {name}{generics}{where_clause} = {type_};", @@ -1464,7 +1464,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { fn print_field_attrs(&self, field: &'a clean::Item) -> impl Display { fmt::from_fn(move |w| { - render_attributes_in_code(w, field, "", self.cx); + render_attributes_in_code(w, field, "", self.cx)?; Ok(()) }) } @@ -1554,9 +1554,9 @@ impl<'clean> DisplayEnum<'clean> { wrap_item(w, |w| { if is_type_alias { // For now the only attributes we render for type aliases are `repr` attributes. - render_repr_attribute_in_code(w, cx, self.def_id); + render_repr_attribute_in_code(w, cx, self.def_id)?; } else { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; } write!( w, @@ -1695,7 +1695,7 @@ fn render_enum_fields( if v.is_stripped() { continue; } - render_attributes_in_code(w, v, TAB, cx); + render_attributes_in_code(w, v, TAB, cx)?; w.write_str(TAB)?; match v.kind { clean::VariantItem(ref var) => match var.kind { @@ -1779,7 +1779,7 @@ fn item_variants( ) .maybe_display() )?; - render_attributes_in_code(w, variant, "", cx); + render_attributes_in_code(w, variant, "", cx)?; if let clean::VariantItem(ref var) = variant.kind && let clean::VariantKind::CLike = var.kind { @@ -1855,7 +1855,7 @@ fn item_variants( ยง\ " )?; - render_attributes_in_code(w, field, "", cx); + render_attributes_in_code(w, field, "", cx)?; write!( w, "{f}: {t}\ @@ -1881,7 +1881,7 @@ fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt: fmt::from_fn(|w| { wrap_item(w, |w| { // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; if !t.macro_rules { write!(w, "{}", visibility_print_with_space(it, cx))?; } @@ -1927,16 +1927,15 @@ fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { let def_id = it.item_id.expect_def_id(); write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; if it.name.map(|n| n.as_str() != "reference").unwrap_or(false) { - write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All))?; + write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All)) } else { // We handle the "reference" primitive type on its own because we only want to list // implementations on generic types. let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&cx.shared, it); - render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl); + render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl) } - Ok(()) }) } @@ -1950,7 +1949,7 @@ fn item_constant( fmt::from_fn(|w| { wrap_item(w, |w| { let tcx = cx.tcx(); - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; write!( w, @@ -2016,9 +2015,9 @@ impl<'a> DisplayStruct<'a> { wrap_item(w, |w| { if is_type_alias { // For now the only attributes we render for type aliases are `repr` attributes. - render_repr_attribute_in_code(w, cx, self.def_id); + render_repr_attribute_in_code(w, cx, self.def_id)?; } else { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; } write!( w, @@ -2097,7 +2096,7 @@ fn item_fields( ", item_type = ItemType::StructField, )?; - render_attributes_in_code(w, field, "", cx); + render_attributes_in_code(w, field, "", cx)?; write!( w, "{field_name}: {ty}\ @@ -2120,7 +2119,7 @@ fn item_static( ) -> impl fmt::Display { fmt::from_fn(move |w| { wrap_item(w, |w| { - render_attributes_in_code(w, it, "", cx); + render_attributes_in_code(w, it, "", cx)?; write!( w, "{vis}{safe}static {mutability}{name}: {typ}", @@ -2140,8 +2139,8 @@ fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { w.write_str("extern {\n")?; - render_attributes_in_code(w, it, "", cx); - write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap(),) + render_attributes_in_code(w, it, "", cx)?; + write!(w, " {}type {};\n}}", visibility_print_with_space(it, cx), it.name.unwrap()) })?; write!( @@ -2292,15 +2291,14 @@ fn print_bounds( .maybe_display() } -fn wrap_item(w: &mut W, f: F) -> T +fn wrap_item(w: &mut W, f: F) -> fmt::Result where W: fmt::Write, - F: FnOnce(&mut W) -> T, + F: FnOnce(&mut W) -> fmt::Result, { - write!(w, r#"
"#).unwrap();
-    let res = f(w);
-    write!(w, "
").unwrap(); - res + w.write_str(r#"
"#)?;
+    f(w)?;
+    w.write_str("
") } #[derive(PartialEq, Eq)] @@ -2370,9 +2368,9 @@ fn render_union( fmt::from_fn(move |mut f| { if is_type_alias { // For now the only attributes we render for type aliases are `repr` attributes. - render_repr_attribute_in_code(f, cx, def_id); + render_repr_attribute_in_code(f, cx, def_id)?; } else { - render_attributes_in_code(f, it, "", cx); + render_attributes_in_code(f, it, "", cx)?; } write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; @@ -2403,7 +2401,7 @@ fn render_union( for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { - render_attributes_in_code(&mut f, field, " ", cx); + render_attributes_in_code(&mut f, field, " ", cx)?; writeln!( f, " {}{}: {},", @@ -2500,7 +2498,7 @@ fn render_struct_fields( } for field in fields { if let clean::StructFieldItem(ref ty) = field.kind { - render_attributes_in_code(w, field, &format!("{tab} "), cx); + render_attributes_in_code(w, field, &format!("{tab} "), cx)?; writeln!( w, "{tab} {vis}{name}: {ty},",