1
Fork 0

Suppress = _ on associated constants in impls

This commit is contained in:
David Tolnay 2024-12-14 14:45:30 -08:00
parent da89d10264
commit 6bdfd12ee9
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
3 changed files with 47 additions and 14 deletions

View file

@ -835,12 +835,23 @@ fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>)
href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default() href.map(|href| format!(" href=\"{href}\"")).unwrap_or_default()
} }
#[derive(Debug)]
enum AssocConstValue<'a> {
// In trait definitions, it is relevant for the public API whether an
// associated constant comes with a default value, so even if we cannot
// render its value, the presence of a value must be shown using `= _`.
TraitDefault(&'a clean::ConstantKind),
// In impls, there is no need to show `= _`.
Impl(&'a clean::ConstantKind),
None,
}
fn assoc_const( fn assoc_const(
w: &mut Buffer, w: &mut Buffer,
it: &clean::Item, it: &clean::Item,
generics: &clean::Generics, generics: &clean::Generics,
ty: &clean::Type, ty: &clean::Type,
default: Option<&clean::ConstantKind>, value: AssocConstValue<'_>,
link: AssocItemLink<'_>, link: AssocItemLink<'_>,
indent: usize, indent: usize,
cx: &Context<'_>, cx: &Context<'_>,
@ -856,15 +867,20 @@ fn assoc_const(
generics = generics.print(cx), generics = generics.print(cx),
ty = ty.print(cx), ty = ty.print(cx),
); );
if let Some(default) = default { if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value {
w.write_str(" = ");
// FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
// hood which adds noisy underscores and a type suffix to number literals. // hood which adds noisy underscores and a type suffix to number literals.
// This hurts readability in this context especially when more complex expressions // This hurts readability in this context especially when more complex expressions
// are involved and it doesn't add much of value. // are involved and it doesn't add much of value.
// Find a way to print constants here without all that jazz. // Find a way to print constants here without all that jazz.
write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx)))); let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx));
if match value {
AssocConstValue::TraitDefault(_) => true, // always show
AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show
AssocConstValue::None => unreachable!(),
} {
write!(w, " = {}", Escape(&repr));
}
} }
write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline)); write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
} }
@ -1086,17 +1102,27 @@ fn render_assoc_item(
item, item,
generics, generics,
ty, ty,
None, AssocConstValue::None,
link, link,
if parent == ItemType::Trait { 4 } else { 0 }, if parent == ItemType::Trait { 4 } else { 0 },
cx, cx,
), ),
clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => assoc_const( clean::ProvidedAssocConstItem(ci) => assoc_const(
w, w,
item, item,
&ci.generics, &ci.generics,
&ci.type_, &ci.type_,
Some(&ci.kind), AssocConstValue::TraitDefault(&ci.kind),
link,
if parent == ItemType::Trait { 4 } else { 0 },
cx,
),
clean::ImplAssocConstItem(ci) => assoc_const(
w,
item,
&ci.generics,
&ci.type_,
AssocConstValue::Impl(&ci.kind),
link, link,
if parent == ItemType::Trait { 4 } else { 0 }, if parent == ItemType::Trait { 4 } else { 0 },
cx, cx,
@ -1704,7 +1730,7 @@ fn render_impl(
item, item,
generics, generics,
ty, ty,
None, AssocConstValue::None,
link.anchor(if trait_.is_some() { &source_id } else { &id }), link.anchor(if trait_.is_some() { &source_id } else { &id }),
0, 0,
cx, cx,
@ -1726,7 +1752,11 @@ fn render_impl(
item, item,
&ci.generics, &ci.generics,
&ci.type_, &ci.type_,
Some(&ci.kind), match item.kind {
clean::ProvidedAssocConstItem(_) => AssocConstValue::TraitDefault(&ci.kind),
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
_ => unreachable!(),
},
link.anchor(if trait_.is_some() { &source_id } else { &id }), link.anchor(if trait_.is_some() { &source_id } else { &id }),
0, 0,
cx, cx,

View file

@ -14,14 +14,17 @@ pub trait Trait {
} }
impl Trait for Struct { impl Trait for Struct {
//@ has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \ //@ !has assoc_consts_underscore/struct.Struct.html '//*[@id="associatedconstant.REQUIRED"]' \
// 'const REQUIRED: Struct = _' // 'const REQUIRED: Struct = _'
//@ has - '//*[@id="associatedconstant.REQUIRED"]' 'const REQUIRED: Struct'
const REQUIRED: Struct = Struct { _private: () }; const REQUIRED: Struct = Struct { _private: () };
//@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _' //@ !has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct = _'
//@ has - '//*[@id="associatedconstant.OPTIONAL"]' 'const OPTIONAL: Struct'
const OPTIONAL: Struct = Struct { _private: () }; const OPTIONAL: Struct = Struct { _private: () };
} }
impl Struct { impl Struct {
//@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _' //@ !has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct = _'
//@ has - '//*[@id="associatedconstant.INHERENT"]' 'const INHERENT: Struct'
pub const INHERENT: Struct = Struct { _private: () }; pub const INHERENT: Struct = Struct { _private: () };
} }

View file

@ -14,6 +14,6 @@ impl<const B: Word> Repr<B> {
// If we change back to rendering the value of consts, check this doesn't add // If we change back to rendering the value of consts, check this doesn't add
// a <b> tag, but escapes correctly // a <b> tag, but escapes correctly
//@ has foo/struct.Repr.html '//section[@id="associatedconstant.BASE"]/h4' '= _' //@ !has foo/struct.Repr.html '//section[@id="associatedconstant.BASE"]/h4' '='
pub const BASE: IBig = base_as_ibig::<B>(); pub const BASE: IBig = base_as_ibig::<B>();
} }