Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rustdoc UI for very long type names #90018

Merged
merged 4 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 153 additions & 122 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,24 +482,26 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
+ name.as_str().len()
+ generics_len;

wrap_item(w, "fn", |w| {
render_attributes_in_pre(w, it, "");
w.reserve(header_len);
write!(
w,
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
{name}{generics}{decl}{notable_traits}{where_clause}",
vis = vis,
constness = constness,
asyncness = asyncness,
unsafety = unsafety,
abi = abi,
name = name,
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, true),
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
notable_traits = notable_traits_decl(&f.decl, cx),
);
wrap_into_docblock(w, |w| {
wrap_item(w, "fn", |w| {
render_attributes_in_pre(w, it, "");
w.reserve(header_len);
write!(
w,
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
{name}{generics}{decl}{notable_traits}{where_clause}",
vis = vis,
constness = constness,
asyncness = asyncness,
unsafety = unsafety,
abi = abi,
name = name,
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, true),
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
notable_traits = notable_traits_decl(&f.decl, cx),
);
});
});
document(w, cx, it, None, HeadingOffset::H2)
}
Expand Down Expand Up @@ -844,16 +846,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
}

fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
wrap_item(w, "trait-alias", |w| {
render_attributes_in_pre(w, it, "");
write!(
w,
"trait {}{}{} = {};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
print_where_clause(&t.generics, cx, 0, true),
bounds(&t.bounds, true, cx)
);
wrap_into_docblock(w, |w| {
wrap_item(w, "trait-alias", |w| {
render_attributes_in_pre(w, it, "");
write!(
w,
"trait {}{}{} = {};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
print_where_clause(&t.generics, cx, 0, true),
bounds(&t.bounds, true, cx)
);
});
});

document(w, cx, it, None, HeadingOffset::H2);
Expand All @@ -866,16 +870,18 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
}

fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
wrap_item(w, "opaque", |w| {
render_attributes_in_pre(w, it, "");
write!(
w,
"type {}{}{where_clause} = impl {bounds};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
bounds = bounds(&t.bounds, false, cx),
);
wrap_into_docblock(w, |w| {
wrap_item(w, "opaque", |w| {
render_attributes_in_pre(w, it, "");
write!(
w,
"type {}{}{where_clause} = impl {bounds};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
bounds = bounds(&t.bounds, false, cx),
);
});
});

document(w, cx, it, None, HeadingOffset::H2);
Expand All @@ -894,20 +900,37 @@ fn item_typedef(
t: &clean::Typedef,
is_associated: bool,
) {
wrap_item(w, "typedef", |w| {
render_attributes_in_pre(w, it, "");
if !is_associated {
write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
}
write!(
w,
"type {}{}{where_clause} = {type_};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
type_ = t.type_.print(cx),
);
});
fn write_content(
w: &mut Buffer,
cx: &Context<'_>,
it: &clean::Item,
t: &clean::Typedef,
is_associated: bool,
) {
wrap_item(w, "typedef", |w| {
render_attributes_in_pre(w, it, "");
if !is_associated {
write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
}
write!(
w,
"type {}{}{where_clause} = {type_};",
it.name.as_ref().unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
type_ = t.type_.print(cx),
);
});
}

// If this is an associated typedef, we don't want to wrap it into a docblock.
if is_associated {
write_content(w, cx, it, t, is_associated);
} else {
wrap_into_docblock(w, |w| {
write_content(w, cx, it, t, is_associated);
});
}

document(w, cx, it, None, HeadingOffset::H2);

Expand Down Expand Up @@ -1142,32 +1165,34 @@ fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Mac
}

fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
let name = it.name.as_ref().expect("proc-macros always have names");
match m.kind {
MacroKind::Bang => {
wrap_item(w, "macro", |w| {
write!(w, "{}!() {{ /* proc-macro */ }}", name);
});
}
MacroKind::Attr => {
wrap_item(w, "attr", |w| {
write!(w, "#[{}]", name);
});
}
MacroKind::Derive => {
wrap_item(w, "derive", |w| {
write!(w, "#[derive({})]", name);
if !m.helpers.is_empty() {
w.push_str("\n{\n");
w.push_str(" // Attributes available to this derive:\n");
for attr in &m.helpers {
writeln!(w, " #[{}]", attr);
wrap_into_docblock(w, |w| {
let name = it.name.as_ref().expect("proc-macros always have names");
match m.kind {
MacroKind::Bang => {
wrap_item(w, "macro", |w| {
write!(w, "{}!() {{ /* proc-macro */ }}", name);
});
}
MacroKind::Attr => {
wrap_item(w, "attr", |w| {
write!(w, "#[{}]", name);
});
}
MacroKind::Derive => {
wrap_item(w, "derive", |w| {
write!(w, "#[derive({})]", name);
if !m.helpers.is_empty() {
w.push_str("\n{\n");
w.push_str(" // Attributes available to this derive:\n");
for attr in &m.helpers {
writeln!(w, " #[{}]", attr);
}
w.push_str("}\n");
}
w.push_str("}\n");
}
});
});
}
}
}
});
document(w, cx, it, None, HeadingOffset::H2)
}

Expand All @@ -1177,38 +1202,40 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
}

fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
wrap_item(w, "const", |w| {
render_attributes_in_code(w, it);
wrap_into_docblock(w, |w| {
wrap_item(w, "const", |w| {
render_attributes_in_code(w, it);

write!(
w,
"{vis}const {name}: {typ}",
vis = it.visibility.print_with_space(it.def_id, cx),
name = it.name.as_ref().unwrap(),
typ = c.type_.print(cx),
);
write!(
w,
"{vis}const {name}: {typ}",
vis = it.visibility.print_with_space(it.def_id, cx),
name = it.name.as_ref().unwrap(),
typ = c.type_.print(cx),
);

let value = c.value(cx.tcx());
let is_literal = c.is_literal(cx.tcx());
let expr = c.expr(cx.tcx());
if value.is_some() || is_literal {
write!(w, " = {expr};", expr = Escape(&expr));
} else {
w.write_str(";");
}
let value = c.value(cx.tcx());
let is_literal = c.is_literal(cx.tcx());
let expr = c.expr(cx.tcx());
if value.is_some() || is_literal {
write!(w, " = {expr};", expr = Escape(&expr));
} else {
w.write_str(";");
}

if !is_literal {
if let Some(value) = &value {
let value_lowercase = value.to_lowercase();
let expr_lowercase = expr.to_lowercase();
if !is_literal {
if let Some(value) = &value {
let value_lowercase = value.to_lowercase();
let expr_lowercase = expr.to_lowercase();

if value_lowercase != expr_lowercase
&& value_lowercase.trim_end_matches("i32") != expr_lowercase
{
write!(w, " // {value}", value = Escape(value));
if value_lowercase != expr_lowercase
&& value_lowercase.trim_end_matches("i32") != expr_lowercase
{
write!(w, " // {value}", value = Escape(value));
}
}
}
}
});
});

document(w, cx, it, None, HeadingOffset::H2)
Expand Down Expand Up @@ -1268,30 +1295,34 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
}

fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
wrap_item(w, "static", |w| {
render_attributes_in_code(w, it);
write!(
w,
"{vis}static {mutability}{name}: {typ}",
vis = it.visibility.print_with_space(it.def_id, cx),
mutability = s.mutability.print_with_space(),
name = it.name.as_ref().unwrap(),
typ = s.type_.print(cx)
);
wrap_into_docblock(w, |w| {
wrap_item(w, "static", |w| {
render_attributes_in_code(w, it);
write!(
w,
"{vis}static {mutability}{name}: {typ}",
vis = it.visibility.print_with_space(it.def_id, cx),
mutability = s.mutability.print_with_space(),
name = it.name.as_ref().unwrap(),
typ = s.type_.print(cx)
);
});
});
document(w, cx, it, None, HeadingOffset::H2)
}

fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
wrap_item(w, "foreigntype", |w| {
w.write_str("extern {\n");
render_attributes_in_code(w, it);
write!(
w,
" {}type {};\n}}",
it.visibility.print_with_space(it.def_id, cx),
it.name.as_ref().unwrap(),
);
wrap_into_docblock(w, |w| {
wrap_item(w, "foreigntype", |w| {
w.write_str("extern {\n");
render_attributes_in_code(w, it);
write!(
w,
" {}type {};\n}}",
it.visibility.print_with_space(it.def_id, cx),
it.name.as_ref().unwrap(),
);
});
});

document(w, cx, it, None, HeadingOffset::H2);
Expand Down Expand Up @@ -1374,7 +1405,7 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
where
F: FnOnce(&mut Buffer),
{
w.write_str("<div class=\"docblock type-decl\">");
w.write_str("<div class=\"docblock item-decl\">");
f(w);
w.write_str("</div>")
}
Expand Down
6 changes: 5 additions & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,10 @@ code, pre, a.test-arrow, .code-header {
pre {
padding: 14px;
}
.type-decl pre {
.docblock.item-decl {
margin-left: 0;
}
.item-decl pre {
overflow-x: auto;
}

Expand Down Expand Up @@ -549,6 +552,7 @@ nav.sub {
flex-grow: 1;
margin: 0px;
padding: 0px;
overflow-wrap: anywhere;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want this to break at natural word breaks when possible.

Suggested change
overflow-wrap: anywhere;
overflow-wrap: break-word;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this can be used to avoid adding more elements?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, idents are not composed of words. ;)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you put this property around foo::ReallyLongName?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or the entire line Constant foo::Name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned in #89618 (comment) that break-word doesn't actually change the behavior of preferring to break at word boundaries. Instead, "this means that the content will take all soft-wrapping opportunities, becoming as small as the longest word." In that PR we concluded anywhere was better, and I think that's true here too.

The added elements you're talking about - is the issue that we're things in a docblock that we weren't previously?

Also, does using the term "docblock" here really fit? I thought a docblock was for a chunk of rendered markdown supplied by the doc author.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It includes doc provided by the author too. :)

}

.in-band > code, .in-band > .code-header {
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/css/themes/ayu.css
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ body.source .example-wrap pre.rust a {
background: #333;
}

.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
#help a {
color: #39AFD7;
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/css/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ body.source .example-wrap pre.rust a {
background: #333;
}

.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
#help a {
color: #D2991D;
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/css/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ body.source .example-wrap pre.rust a {
background: #eee;
}

.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
#help a {
color: #3873AD;
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc-gui/basic.goml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
goto: file://|DOC_PATH|/test_docs/index.html
assert: ("#functions")
goto: ./struct.Foo.html
assert: ("div.type-decl")
assert: ("div.item-decl")
Loading