Skip to content

Commit 85c0d9e

Browse files
committed
rustdoc: rich-text and visibility-aware formatting for constant values
1 parent 2fbc08e commit 85c0d9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1636
-379
lines changed

src/librustdoc/clean/inline.rs

+2
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ fn build_module_items(
596596
}
597597

598598
pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
599+
// FIXME: Both branches rely on HIR pretty-printing which
600+
// leaks private and doc(hidden) struct fields.
599601
if let Some(did) = did.as_local() {
600602
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
601603
rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id)

src/librustdoc/clean/types.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ use crate::clean::cfg::Cfg;
3737
use crate::clean::clean_visibility;
3838
use crate::clean::external_path;
3939
use crate::clean::inline::{self, print_inlined_const};
40-
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
40+
use crate::clean::utils::is_literal_expr;
4141
use crate::core::DocContext;
4242
use crate::formats::cache::Cache;
4343
use crate::formats::item_type::ItemType;
44-
use crate::html::render::Context;
44+
use crate::html::render::{constant::Renderer as ConstantRenderer, Context};
4545
use crate::passes::collect_intra_doc_links::UrlFragment;
4646

4747
pub(crate) use self::FnRetTy::*;
@@ -2292,8 +2292,8 @@ impl Constant {
22922292
self.kind.expr(tcx)
22932293
}
22942294

2295-
pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
2296-
self.kind.value(tcx)
2295+
pub(crate) fn eval_and_render(&self, renderer: &ConstantRenderer<'_, '_>) -> Option<String> {
2296+
self.kind.eval_and_render(renderer)
22972297
}
22982298

22992299
pub(crate) fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
@@ -2307,16 +2307,16 @@ impl ConstantKind {
23072307
ConstantKind::TyConst { ref expr } => expr.clone(),
23082308
ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
23092309
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
2310-
print_const_expr(tcx, body)
2310+
super::utils::print_const_expr(tcx, body)
23112311
}
23122312
}
23132313
}
23142314

2315-
pub(crate) fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
2315+
pub(crate) fn eval_and_render(&self, renderer: &ConstantRenderer<'_, '_>) -> Option<String> {
23162316
match *self {
23172317
ConstantKind::TyConst { .. } | ConstantKind::Anonymous { .. } => None,
23182318
ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => {
2319-
print_evaluated_const(tcx, def_id)
2319+
crate::html::render::eval_and_render_const(def_id, renderer)
23202320
}
23212321
}
23222322
}

src/librustdoc/clean/utils.rs

+2-68
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,12 @@ use rustc_data_structures::thin_vec::ThinVec;
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{DefKind, Res};
1818
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
19-
use rustc_middle::mir;
20-
use rustc_middle::mir::interpret::ConstValue;
2119
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
2220
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
2321
use rustc_span::symbol::{kw, sym, Symbol};
2422
use std::fmt::Write as _;
2523
use std::mem;
2624

27-
#[cfg(test)]
28-
mod tests;
29-
3025
pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
3126
let module = crate::visit_ast::RustdocVisitor::new(cx).visit();
3227

@@ -238,6 +233,8 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
238233
let mut s = if let Some(def) = def.as_local() {
239234
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did))
240235
} else {
236+
// FIXME: This relies on the HIR pretty-printer which leaks private and
237+
// doc(hidden) struct fields.
241238
inline::print_inlined_const(cx.tcx, def.did)
242239
};
243240
if let Some(promoted) = promoted {
@@ -261,69 +258,6 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
261258
}
262259
}
263260

264-
pub(crate) fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
265-
tcx.const_eval_poly(def_id).ok().and_then(|val| {
266-
let ty = tcx.type_of(def_id);
267-
match (val, ty.kind()) {
268-
(_, &ty::Ref(..)) => None,
269-
(ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
270-
(ConstValue::Scalar(_), _) => {
271-
let const_ = mir::ConstantKind::from_value(val, ty);
272-
Some(print_const_with_custom_print_scalar(tcx, const_))
273-
}
274-
_ => None,
275-
}
276-
})
277-
}
278-
279-
fn format_integer_with_underscore_sep(num: &str) -> String {
280-
let num_chars: Vec<_> = num.chars().collect();
281-
let mut num_start_index = if num_chars.get(0) == Some(&'-') { 1 } else { 0 };
282-
let chunk_size = match num[num_start_index..].as_bytes() {
283-
[b'0', b'b' | b'x', ..] => {
284-
num_start_index += 2;
285-
4
286-
}
287-
[b'0', b'o', ..] => {
288-
num_start_index += 2;
289-
let remaining_chars = num_chars.len() - num_start_index;
290-
if remaining_chars <= 6 {
291-
// don't add underscores to Unix permissions like 0755 or 100755
292-
return num.to_string();
293-
}
294-
3
295-
}
296-
_ => 3,
297-
};
298-
299-
num_chars[..num_start_index]
300-
.iter()
301-
.chain(num_chars[num_start_index..].rchunks(chunk_size).rev().intersperse(&['_']).flatten())
302-
.collect()
303-
}
304-
305-
fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: mir::ConstantKind<'_>) -> String {
306-
// Use a slightly different format for integer types which always shows the actual value.
307-
// For all other types, fallback to the original `pretty_print_const`.
308-
match (ct, ct.ty().kind()) {
309-
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Uint(ui)) => {
310-
format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
311-
}
312-
(mir::ConstantKind::Val(ConstValue::Scalar(int), _), ty::Int(i)) => {
313-
let ty = tcx.lift(ct.ty()).unwrap();
314-
let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size;
315-
let data = int.assert_bits(size);
316-
let sign_extended_data = size.sign_extend(data) as i128;
317-
format!(
318-
"{}{}",
319-
format_integer_with_underscore_sep(&sign_extended_data.to_string()),
320-
i.name_str()
321-
)
322-
}
323-
_ => ct.to_string(),
324-
}
325-
}
326-
327261
pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
328262
if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) {
329263
if let hir::ExprKind::Lit(_) = &expr.kind {

src/librustdoc/clean/utils/tests.rs

-41
This file was deleted.

src/librustdoc/core.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,11 @@ pub(crate) fn run_global_ctxt(
379379
impl_trait_bounds: Default::default(),
380380
generated_synthetics: Default::default(),
381381
auto_traits,
382-
cache: Cache::new(access_levels, render_options.document_private),
382+
cache: Cache::new(
383+
access_levels,
384+
render_options.document_private,
385+
render_options.document_hidden,
386+
),
383387
inlined: FxHashSet::default(),
384388
output_format,
385389
render_options,

src/librustdoc/formats/cache.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ pub(crate) struct Cache {
8787
/// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
8888
pub(crate) document_private: bool,
8989

90+
/// Whether to document `#[doc(hidden)]` items.
91+
/// This is stored in `Cache` so it doesn't need to be passed through all rustdoc functions.
92+
pub(crate) document_hidden: bool,
93+
9094
/// Crates marked with [`#[doc(masked)]`][doc_masked].
9195
///
9296
/// [doc_masked]: https://doc.rust-lang.org/nightly/unstable-book/language-features/doc-masked.html
@@ -132,8 +136,12 @@ struct CacheBuilder<'a, 'tcx> {
132136
}
133137

134138
impl Cache {
135-
pub(crate) fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
136-
Cache { access_levels, document_private, ..Cache::default() }
139+
pub(crate) fn new(
140+
access_levels: AccessLevels<DefId>,
141+
document_private: bool,
142+
document_hidden: bool,
143+
) -> Self {
144+
Cache { access_levels, document_private, document_hidden, ..Cache::default() }
137145
}
138146

139147
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was

src/librustdoc/html/format.rs

+7
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,13 @@ pub(crate) fn href_with_root_path(
654654
// documented on their parent's page
655655
tcx.parent(did)
656656
}
657+
DefKind::Field => {
658+
let parent_id = tcx.parent(did);
659+
match tcx.def_kind(parent_id) {
660+
DefKind::Variant => tcx.parent(parent_id),
661+
_ => parent_id,
662+
}
663+
}
657664
_ => did,
658665
};
659666
let cache = cx.cache();

0 commit comments

Comments
 (0)