Skip to content

Commit a8714e6

Browse files
committed
Show values for const values in the documentation
1 parent c4375c9 commit a8714e6

File tree

5 files changed

+95
-10
lines changed

5 files changed

+95
-10
lines changed

src/librustdoc/clean/inline.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ pub fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String {
465465
fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant {
466466
clean::Constant {
467467
type_: cx.tcx.type_of(did).clean(cx),
468-
expr: print_inlined_const(cx, did)
468+
expr: print_inlined_const(cx, did),
469+
value: clean::print_evaluated_const(cx, did),
469470
}
470471
}
471472

src/librustdoc/clean/mod.rs

+51-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
1616
use rustc::middle::resolve_lifetime as rl;
1717
use rustc::middle::lang_items;
1818
use rustc::middle::stability;
19-
use rustc::mir::interpret::GlobalId;
19+
use rustc::mir::interpret::{GlobalId, ConstValue, Scalar, sign_extend};
2020
use rustc::hir;
2121
use rustc::hir::def::{CtorKind, DefKind, Res};
2222
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -1300,6 +1300,7 @@ impl Clean<Constant> for hir::ConstArg {
13001300
Constant {
13011301
type_: cx.tcx.type_of(cx.tcx.hir().body_owner_def_id(self.value.body)).clean(cx),
13021302
expr: print_const_expr(cx, self.value.body),
1303+
value: None,
13031304
}
13041305
}
13051306
}
@@ -3274,6 +3275,7 @@ impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
32743275
Constant {
32753276
type_: self.ty.clean(cx),
32763277
expr: format!("{}", self),
3278+
value: None,
32773279
}
32783280
}
32793281
}
@@ -3831,21 +3833,24 @@ impl Clean<Item> for doctree::Static<'_> {
38313833
pub struct Constant {
38323834
pub type_: Type,
38333835
pub expr: String,
3836+
pub value: Option<String>,
38343837
}
38353838

38363839
impl Clean<Item> for doctree::Constant<'_> {
38373840
fn clean(&self, cx: &DocContext<'_>) -> Item {
3841+
let def_id = cx.tcx.hir().local_def_id(self.id);
38383842
Item {
38393843
name: Some(self.name.clean(cx)),
38403844
attrs: self.attrs.clean(cx),
38413845
source: self.whence.clean(cx),
3842-
def_id: cx.tcx.hir().local_def_id(self.id),
3846+
def_id: def_id,
38433847
visibility: self.vis.clean(cx),
38443848
stability: cx.stability(self.id).clean(cx),
38453849
deprecation: cx.deprecation(self.id).clean(cx),
38463850
inner: ConstantItem(Constant {
38473851
type_: self.type_.clean(cx),
38483852
expr: print_const_expr(cx, self.expr),
3853+
value: print_evaluated_const(cx, def_id),
38493854
}),
38503855
}
38513856
}
@@ -4232,6 +4237,50 @@ fn name_from_pat(p: &hir::Pat) -> String {
42324237
}
42334238
}
42344239

4240+
pub fn print_evaluated_const(cx: &DocContext<'_>, def_id: DefId) -> Option<String> {
4241+
let param_env = cx.tcx.param_env(def_id);
4242+
let substs = InternalSubsts::identity_for_item(cx.tcx, def_id);
4243+
let cid = GlobalId {
4244+
instance: ty::Instance::new(def_id, substs),
4245+
promoted: None
4246+
};
4247+
4248+
let value = cx.tcx.const_eval(param_env.and(cid)).ok().and_then(|value| {
4249+
match (value.val, &value.ty.kind) {
4250+
(_, ty::Ref(..)) => None,
4251+
(ty::ConstKind::Value(ConstValue::Scalar(_)), _) =>
4252+
Some(print_const_with_custom_print_scalar(cx, value)),
4253+
_ => None,
4254+
}
4255+
});
4256+
4257+
value
4258+
}
4259+
4260+
fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const<'tcx>) -> String {
4261+
// Use a slightly different format for integer types which always shows the actual value.
4262+
// For all other types, fallback to the original `pretty_print_const`.
4263+
match (ct.val, &ct.ty.kind) {
4264+
(ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data, .. })), ty::Uint(ui)) => {
4265+
let ui_str = ui.name_str();
4266+
format!("{}{}", data, ui_str)
4267+
},
4268+
(ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data, .. })), ty::Int(i)) => {
4269+
let ty = cx.tcx.lift(&ct.ty).unwrap();
4270+
let size = cx.tcx.layout_of(ty::ParamEnv::empty().and(ty))
4271+
.unwrap()
4272+
.size;
4273+
let i_str = i.name_str();
4274+
let sign_extended_data = sign_extend(data, size) as i128;
4275+
4276+
format!("{}{}", sign_extended_data, i_str)
4277+
},
4278+
_ => {
4279+
ct.to_string()
4280+
}
4281+
}
4282+
}
4283+
42354284
fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String {
42364285
match n.val {
42374286
ty::ConstKind::Unevaluated(def_id, _) => {

src/librustdoc/html/render.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -2287,11 +2287,22 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
22872287
fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) {
22882288
write!(w, "<pre class='rust const'>");
22892289
render_attributes(w, it, false);
2290+
22902291
write!(w, "{vis}const \
2291-
{name}: {typ}</pre>",
2292+
{name}: {typ} = {expr};",
22922293
vis = it.visibility.print_with_space(),
22932294
name = it.name.as_ref().unwrap(),
2294-
typ = c.type_.print());
2295+
typ = c.type_.print(),
2296+
expr = c.expr,
2297+
);
2298+
2299+
if let Some(value) = &c.value {
2300+
if value != &c.expr {
2301+
write!(w, " /* {value} */", value = value);
2302+
}
2303+
}
2304+
2305+
write!(w, "</pre>");
22952306
document(w, cx, it)
22962307
}
22972308

src/test/rustdoc/dont-show-const-contents.rs

-5
This file was deleted.
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Test that the contents of constants are displayed as part of the
2+
// documentation.
3+
4+
// @has show_const_contents/constant.CONST_S.html 'show this'
5+
pub const CONST_S: &'static str = "show this";
6+
7+
// @has show_const_contents/constant.CONST_I32.html '= 42; /* 42i32 */'
8+
pub const CONST_I32: i32 = 42;
9+
10+
// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
11+
// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '/* 42i32 */'
12+
pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;
13+
14+
// @has show_const_contents/constant.CONST_CALC_I32.html '= 42 + 1; /* 43i32 */'
15+
pub const CONST_CALC_I32: i32 = 42 + 1;
16+
17+
// @has show_const_contents/constant.CONST_REF_I32.html '= &42;'
18+
pub const CONST_REF_I32: &'static i32 = &42;
19+
20+
// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::max_value(); /* 2147483647i32 */'
21+
pub const CONST_I32_MAX: i32 = i32::max_value();
22+
23+
// @has show_const_contents/constant.UNIT.html '= ();'
24+
pub const UNIT: () = ();
25+
26+
pub struct MyType(i32);
27+
28+
// @has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
29+
pub const MY_TYPE: MyType = MyType(42);

0 commit comments

Comments
 (0)