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

Rustdoc: Account for const-unstable functions #86473

Merged
merged 6 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
26 changes: 17 additions & 9 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::cell::Cell;
use std::fmt;
use std::iter;

use rustc_attr::{ConstStability, StabilityLevel};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
Expand Down Expand Up @@ -1253,15 +1254,6 @@ impl PrintWithSpace for hir::Unsafety {
}
}

impl PrintWithSpace for hir::Constness {
fn print_with_space(&self) -> &str {
match self {
hir::Constness::Const => "const ",
hir::Constness::NotConst => "",
}
}
}

impl PrintWithSpace for hir::IsAsync {
fn print_with_space(&self) -> &str {
match self {
Expand All @@ -1280,6 +1272,22 @@ impl PrintWithSpace for hir::Mutability {
}
}

crate fn print_constness_with_space(
c: &hir::Constness,
s: Option<&ConstStability>,
) -> &'static str {
match (c, s) {
// const stable or when feature(staged_api) is not set
(
hir::Constness::Const,
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }),
)
| (hir::Constness::Const, None) => "const ",
// const unstable or not const
_ => "",
}
}

impl clean::Import {
crate fn print<'a, 'tcx: 'a>(
&'a self,
Expand Down
62 changes: 44 additions & 18 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use std::str;
use std::string::ToString;

use rustc_ast_pretty::pprust;
use rustc_attr::{Deprecation, StabilityLevel};
use rustc_attr::{ConstStability, Deprecation, StabilityLevel};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::CtorKind;
Expand All @@ -61,8 +61,8 @@ use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
href, print_abi_with_space, print_default_space, print_generic_bounds, print_where_clause,
Buffer, PrintWithSpace,
href, print_abi_with_space, print_constness_with_space, print_default_space,
print_generic_bounds, print_where_clause, Buffer, PrintWithSpace,
};
use crate::html::markdown::{Markdown, MarkdownHtml, MarkdownSummaryLine};

Expand Down Expand Up @@ -826,21 +826,45 @@ fn assoc_type(
fn render_stability_since_raw(
w: &mut Buffer,
ver: Option<&str>,
const_ver: Option<&str>,
const_stability: Option<&ConstStability>,
containing_ver: Option<&str>,
containing_const_ver: Option<&str>,
) {
let ver = ver.filter(|inner| !inner.is_empty());
let const_ver = const_ver.filter(|inner| !inner.is_empty());

match (ver, const_ver) {
(Some(v), Some(cv)) if const_ver != containing_const_ver => {
match (ver, const_stability) {
// stable and const stable
(Some(v), Some(ConstStability { level: StabilityLevel::Stable { since }, .. }))
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved
if Some(since.as_str()).as_deref() != containing_const_ver =>
{
write!(
w,
"<span class=\"since\" title=\"Stable since Rust version {0}, const since {1}\">{0} (const: {1})</span>",
v, cv
v, since
);
}
// stable and const unstable
(
Some(v),
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }),
) => {
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved
write!(
w,
"<span class=\"since\" title=\"Stable since Rust version {0}, const unstable\">{0} (const: ",
v
);
if let Some(n) = issue {
write!(
w,
"<a href=\"https://github.com/rust-lang/rust/issues/{}\" title=\"Tracking issue for {}\">unstable</a>",
n, feature
);
} else {
write!(w, "unstable");
}
write!(w, ")</span>");
}
// stable
(Some(v), _) if ver != containing_ver => {
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved
write!(
w,
Expand Down Expand Up @@ -888,11 +912,13 @@ fn render_assoc_item(
}
};
let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string();
let constness = header.constness.print_with_space();
let constness =
print_constness_with_space(&header.constness, meth.const_stability(cx.tcx()));
let asyncness = header.asyncness.print_with_space();
let unsafety = header.unsafety.print_with_space();
let defaultness = print_default_space(meth.is_default());
let abi = print_abi_with_space(header.abi).to_string();

// NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
let generics_len = format!("{:#}", g.print(cx)).len();
let mut header_len = "fn ".len()
Expand All @@ -917,15 +943,15 @@ fn render_assoc_item(
w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len());
write!(
w,
"{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
"{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
{generics}{decl}{notable_traits}{where_clause}",
indent_str,
vis,
constness,
asyncness,
unsafety,
defaultness,
abi,
indent = indent_str,
vis = vis,
constness = constness,
asyncness = asyncness,
unsafety = unsafety,
defaultness = defaultness,
abi = abi,
href = href,
name = name,
generics = g.print(cx),
Expand Down Expand Up @@ -1583,7 +1609,7 @@ fn render_rightside(
render_stability_since_raw(
w,
item.stable_since(tcx).as_deref(),
item.const_stable_since(tcx).as_deref(),
item.const_stability(tcx),
containing_item.stable_since(tcx).as_deref(),
containing_item.const_stable_since(tcx).as_deref(),
);
Expand Down
49 changes: 29 additions & 20 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use crate::clean::{self, GetDefId};
use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace};
use crate::html::format::{
print_abi_with_space, print_constness_with_space, print_where_clause, Buffer, PrintWithSpace,
};
use crate::html::highlight;
use crate::html::layout::Page;
use crate::html::markdown::MarkdownSummaryLine;
Expand Down Expand Up @@ -94,7 +96,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
render_stability_since_raw(
buf,
item.stable_since(cx.tcx()).as_deref(),
item.const_stable_since(cx.tcx()).as_deref(),
item.const_stability(cx.tcx()),
None,
None,
);
Expand Down Expand Up @@ -430,29 +432,36 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
}

fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
let header_len = format!(
"{}{}{}{}{:#}fn {}{:#}",
it.visibility.print_with_space(it.def_id, cx),
f.header.constness.print_with_space(),
f.header.asyncness.print_with_space(),
f.header.unsafety.print_with_space(),
print_abi_with_space(f.header.abi),
it.name.as_ref().unwrap(),
f.generics.print(cx),
)
.len();
let vis = it.visibility.print_with_space(it.def_id, cx).to_string();
let constness = print_constness_with_space(&f.header.constness, it.const_stability(cx.tcx()));
let asyncness = f.header.asyncness.print_with_space();
let unsafety = f.header.unsafety.print_with_space();
let abi = print_abi_with_space(f.header.abi).to_string();
let name = it.name.as_ref().unwrap();

let generics_len = format!("{:#}", f.generics.print(cx)).len();
let header_len = "fn ".len()
+ vis.len()
+ constness.len()
+ asyncness.len()
+ unsafety.len()
+ abi.len()
+ name.as_str().len()
+ generics_len;

w.write_str("<pre class=\"rust fn\">");
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}</pre>",
vis = it.visibility.print_with_space(it.def_id, cx),
constness = f.header.constness.print_with_space(),
asyncness = f.header.asyncness.print_with_space(),
unsafety = f.header.unsafety.print_with_space(),
abi = print_abi_with_space(f.header.abi),
name = it.name.as_ref().unwrap(),
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),
Expand Down Expand Up @@ -1291,7 +1300,7 @@ fn render_stability_since(
render_stability_since_raw(
w,
item.stable_since(tcx).as_deref(),
item.const_stable_since(tcx).as_deref(),
item.const_stability(tcx),
containing_item.stable_since(tcx).as_deref(),
containing_item.const_stable_since(tcx).as_deref(),
)
Expand Down
38 changes: 28 additions & 10 deletions src/test/rustdoc/const-display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@
#![feature(foo, foo2)]
#![feature(staged_api)]

// @has 'foo/fn.foo.html' '//pre' 'pub unsafe fn foo() -> u32'
// @has 'foo/fn.foo.html' '//pre' 'pub fn foo() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn foo() -> u32 { 42 }
pub const fn foo() -> u32 { 42 }

// @has 'foo/fn.foo_unsafe.html' '//pre' 'pub unsafe fn foo_unsafe() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn foo_unsafe() -> u32 { 42 }

// @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
// @!has - '//span[@class="since"]'
#[unstable(feature = "humans", issue = "none")]
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved
pub const fn foo2() -> u32 { 42 }

Expand All @@ -22,26 +30,36 @@ pub const fn foo2() -> u32 { 42 }
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const fn bar2() -> u32 { 42 }

// @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'

// @has 'foo/fn.foo2_gated.html' '//pre' 'pub const fn foo2_gated() -> u32'
// @!has - '//span[@class="since"]'
#[unstable(feature = "foo2", issue = "none")]
pub const unsafe fn foo2_gated() -> u32 { 42 }
pub const fn foo2_gated() -> u32 { 42 }
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved

// @has 'foo/fn.bar2_gated.html' '//pre' 'pub const unsafe fn bar2_gated() -> u32'
// @has 'foo/fn.bar2_gated.html' '//pre' 'pub const fn bar2_gated() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: 1.0.0)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const unsafe fn bar2_gated() -> u32 { 42 }
pub const fn bar2_gated() -> u32 { 42 }
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved

// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
pub const unsafe fn bar_not_gated() -> u32 { 42 }
// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const fn bar_not_gated() -> u32'
// @!has - '//span[@class="since"]'
pub const fn bar_not_gated() -> u32 { 42 }
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved

pub struct Foo;

impl Foo {
// @has 'foo/struct.Foo.html' '//div[@id="method.gated"]/code' 'pub unsafe fn gated() -> u32'
// @has 'foo/struct.Foo.html' '//div[@id="method.gated"]/code' 'pub fn gated() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const fn gated() -> u32 { 42 }
fee1-dead marked this conversation as resolved.
Show resolved Hide resolved

// @has 'foo/struct.Foo.html' '//div[@id="method.gated_unsafe"]/code' 'pub unsafe fn gated_unsafe() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn gated() -> u32 { 42 }
pub const unsafe fn gated_unsafe() -> u32 { 42 }

// @has 'foo/struct.Foo.html' '//div[@id="method.stable_impl"]/code' 'pub const fn stable_impl() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)'
Expand Down