Skip to content

Commit ee0ea95

Browse files
committed
rustdoc: pretty-print nested bodies in inlined constants.
1 parent 4aae835 commit ee0ea95

File tree

6 files changed

+79
-5
lines changed

6 files changed

+79
-5
lines changed

src/librustc/hir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ pub enum UnsafeSource {
856856
UserProvided,
857857
}
858858

859-
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
859+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
860860
pub struct BodyId {
861861
pub node_id: NodeId,
862862
}

src/librustc/middle/cstore.rs

+6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ use mir::Mir;
3333
use session::Session;
3434
use session::search_paths::PathKind;
3535
use util::nodemap::{NodeSet, DefIdMap};
36+
37+
use std::collections::BTreeMap;
3638
use std::path::PathBuf;
3739
use std::rc::Rc;
3840
use syntax::ast;
@@ -250,6 +252,7 @@ pub trait CrateStore<'tcx> {
250252
// misc. metadata
251253
fn maybe_get_item_body<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
252254
-> Option<&'tcx hir::Body>;
255+
fn item_body_nested_bodies(&self, def: DefId) -> BTreeMap<hir::BodyId, hir::Body>;
253256
fn const_is_rvalue_promotable_to_static(&self, def: DefId) -> bool;
254257

255258
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
@@ -421,6 +424,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
421424
-> Option<&'tcx hir::Body> {
422425
bug!("maybe_get_item_body")
423426
}
427+
fn item_body_nested_bodies(&self, def: DefId) -> BTreeMap<hir::BodyId, hir::Body> {
428+
bug!("item_body_nested_bodies")
429+
}
424430
fn const_is_rvalue_promotable_to_static(&self, def: DefId) -> bool {
425431
bug!("const_is_rvalue_promotable_to_static")
426432
}

src/librustc_metadata/astencode.rs

+31
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct Ast<'tcx> {
3030
id_range: IdRange,
3131
body: Lazy<hir::Body>,
3232
side_tables: LazySeq<(ast::NodeId, TableEntry<'tcx>)>,
33+
pub nested_bodies: LazySeq<hir::Body>,
3334
pub rvalue_promotable_to_static: bool,
3435
}
3536

@@ -61,13 +62,24 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
6162
visitor.count
6263
};
6364

65+
let nested_pos = self.position();
66+
let nested_count = {
67+
let mut visitor = NestedBodyEncodingVisitor {
68+
ecx: self,
69+
count: 0,
70+
};
71+
visitor.visit_body(body);
72+
visitor.count
73+
};
74+
6475
let rvalue_promotable_to_static =
6576
self.tcx.rvalue_promotable_to_static.borrow()[&body.value.id];
6677

6778
self.lazy(&Ast {
6879
id_range: id_visitor.result(),
6980
body: Lazy::with_position(body_pos),
7081
side_tables: LazySeq::with_position_and_length(tables_pos, tables_count),
82+
nested_bodies: LazySeq::with_position_and_length(nested_pos, nested_count),
7183
rvalue_promotable_to_static: rvalue_promotable_to_static
7284
})
7385
}
@@ -102,6 +114,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> {
102114
}
103115
}
104116

117+
struct NestedBodyEncodingVisitor<'a, 'b: 'a, 'tcx: 'b> {
118+
ecx: &'a mut EncodeContext<'b, 'tcx>,
119+
count: usize,
120+
}
121+
122+
impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedBodyEncodingVisitor<'a, 'b, 'tcx> {
123+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
124+
NestedVisitorMap::None
125+
}
126+
127+
fn visit_nested_body(&mut self, body: hir::BodyId) {
128+
let body = self.ecx.tcx.map.body(body);
129+
body.encode(self.ecx).unwrap();
130+
self.count += 1;
131+
132+
self.visit_body(body);
133+
}
134+
}
135+
105136
/// Decodes an item's body from its AST in the cdata's metadata and adds it to the
106137
/// ast-map.
107138
pub fn decode_body<'a, 'tcx>(cdata: &CrateMetadata,

src/librustc_metadata/cstore_impl.rs

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ use rustc::hir::svh::Svh;
3636
use rustc_back::target::Target;
3737
use rustc::hir;
3838

39+
use std::collections::BTreeMap;
40+
3941
impl<'tcx> CrateStore<'tcx> for cstore::CStore {
4042
fn describe_def(&self, def: DefId) -> Option<Def> {
4143
self.dep_graph.read(DepNode::MetaData(def));
@@ -455,6 +457,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
455457
inlined
456458
}
457459

460+
fn item_body_nested_bodies(&self, def: DefId) -> BTreeMap<hir::BodyId, hir::Body> {
461+
self.dep_graph.read(DepNode::MetaData(def));
462+
self.get_crate_data(def.krate).item_body_nested_bodies(def.index)
463+
}
464+
458465
fn const_is_rvalue_promotable_to_static(&self, def: DefId) -> bool {
459466
self.dep_graph.read(DepNode::MetaData(def));
460467
self.get_crate_data(def.krate).const_is_rvalue_promotable_to_static(def.index)

src/librustc_metadata/decoder.rs

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use rustc::mir::Mir;
3232

3333
use std::borrow::Cow;
3434
use std::cell::Ref;
35+
use std::collections::BTreeMap;
3536
use std::io;
3637
use std::mem;
3738
use std::str;
@@ -829,6 +830,12 @@ impl<'a, 'tcx> CrateMetadata {
829830
})
830831
}
831832

833+
pub fn item_body_nested_bodies(&self, id: DefIndex) -> BTreeMap<hir::BodyId, hir::Body> {
834+
self.entry(id).ast.into_iter().flat_map(|ast| {
835+
ast.decode(self).nested_bodies.decode(self).map(|body| (body.id(), body))
836+
}).collect()
837+
}
838+
832839
pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool {
833840
self.entry(id).ast.expect("const item missing `ast`")
834841
.decode(self).rvalue_promotable_to_static

src/librustdoc/clean/inline.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! Support for inlining external documentation into the current AST.
1212
13+
use std::collections::BTreeMap;
14+
use std::io;
1315
use std::iter::once;
1416

1517
use syntax::ast;
@@ -342,8 +344,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
342344
match item.kind {
343345
ty::AssociatedKind::Const => {
344346
let default = if item.defaultness.has_value() {
345-
Some(hir::print::to_string(&cx.tcx.map, |s| s.print_expr(
346-
&tcx.sess.cstore.maybe_get_item_body(tcx, item.def_id).unwrap().value)))
347+
Some(print_inlined_const(cx, item.def_id))
347348
} else {
348349
None
349350
};
@@ -473,11 +474,33 @@ fn build_module(cx: &DocContext, did: DefId) -> clean::Module {
473474
}
474475
}
475476

477+
struct InlinedConst {
478+
nested_bodies: BTreeMap<hir::BodyId, hir::Body>
479+
}
480+
481+
impl hir::print::PpAnn for InlinedConst {
482+
fn nested(&self, state: &mut hir::print::State, nested: hir::print::Nested)
483+
-> io::Result<()> {
484+
if let hir::print::Nested::Body(body) = nested {
485+
state.print_expr(&self.nested_bodies[&body].value)
486+
} else {
487+
Ok(())
488+
}
489+
}
490+
}
491+
492+
fn print_inlined_const(cx: &DocContext, did: DefId) -> String {
493+
let body = cx.tcx.sess.cstore.maybe_get_item_body(cx.tcx, did).unwrap();
494+
let inlined = InlinedConst {
495+
nested_bodies: cx.tcx.sess.cstore.item_body_nested_bodies(did)
496+
};
497+
hir::print::to_string(&inlined, |s| s.print_expr(&body.value))
498+
}
499+
476500
fn build_const(cx: &DocContext, did: DefId) -> clean::Constant {
477501
clean::Constant {
478502
type_: cx.tcx.item_type(did).clean(cx),
479-
expr: hir::print::to_string(&cx.tcx.map, |s| s.print_expr(
480-
&cx.tcx.sess.cstore.maybe_get_item_body(cx.tcx, did).unwrap().value))
503+
expr: print_inlined_const(cx, did)
481504
}
482505
}
483506

0 commit comments

Comments
 (0)