Skip to content

Commit 0cde855

Browse files
Rework rustdoc const type
1 parent f5fe425 commit 0cde855

File tree

11 files changed

+805
-608
lines changed

11 files changed

+805
-608
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res};
99
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
1010
use rustc_hir::Mutability;
1111
use rustc_metadata::creader::LoadedMacro;
12-
use rustc_middle::ty;
12+
use rustc_middle::ty::{self, TyCtxt};
1313
use rustc_mir::const_eval::is_min_const_fn;
1414
use rustc_span::hygiene::MacroKind;
1515
use rustc_span::symbol::{kw, sym, Symbol};
@@ -490,24 +490,17 @@ fn build_module(
490490
clean::Module { items, is_crate: false }
491491
}
492492

493-
crate fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String {
493+
crate fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
494494
if let Some(did) = did.as_local() {
495-
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(did);
496-
rustc_hir_pretty::id_to_string(&cx.tcx.hir(), hir_id)
495+
let hir_id = tcx.hir().local_def_id_to_hir_id(did);
496+
rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id)
497497
} else {
498-
cx.tcx.rendered_const(did)
498+
tcx.rendered_const(did)
499499
}
500500
}
501501

502502
fn build_const(cx: &mut DocContext<'_>, did: DefId) -> clean::Constant {
503-
clean::Constant {
504-
type_: cx.tcx.type_of(did).clean(cx),
505-
expr: print_inlined_const(cx, did),
506-
value: clean::utils::print_evaluated_const(cx, did),
507-
is_literal: did.as_local().map_or(false, |did| {
508-
clean::utils::is_literal_expr(cx, cx.tcx.hir().local_def_id_to_hir_id(did))
509-
}),
510-
}
503+
clean::Constant::Inline { type_: cx.tcx.type_of(did).clean(cx), did }
511504
}
512505

513506
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {

src/librustdoc/clean/mod.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -393,14 +393,12 @@ impl Clean<Lifetime> for hir::GenericParam<'_> {
393393

394394
impl Clean<Constant> for hir::ConstArg {
395395
fn clean(&self, cx: &mut DocContext<'_>) -> Constant {
396-
Constant {
396+
Constant::Generic {
397397
type_: cx
398398
.tcx
399399
.type_of(cx.tcx.hir().body_owner_def_id(self.value.body).to_def_id())
400400
.clean(cx),
401-
expr: print_const_expr(cx.tcx, self.value.body),
402-
value: None,
403-
is_literal: is_literal_expr(cx, self.value.body.hir_id),
401+
body: self.value.body,
404402
}
405403
}
406404
}
@@ -1135,7 +1133,7 @@ impl Clean<Item> for ty::AssocItem {
11351133
ty::AssocKind::Const => {
11361134
let ty = tcx.type_of(self.def_id);
11371135
let default = if self.defaultness.has_value() {
1138-
Some(inline::print_inlined_const(cx, self.def_id))
1136+
Some(inline::print_inlined_const(cx.tcx, self.def_id))
11391137
} else {
11401138
None
11411139
};
@@ -1745,12 +1743,8 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
17451743

17461744
impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
17471745
fn clean(&self, cx: &mut DocContext<'_>) -> Constant {
1748-
Constant {
1749-
type_: self.ty.clean(cx),
1750-
expr: format!("{}", self),
1751-
value: None,
1752-
is_literal: false,
1753-
}
1746+
// FIXME: instead of storing `format!("{}", self)`, store `self` directly instead.
1747+
Constant::TyConst { type_: self.ty.clean(cx), expr: format!("{}", self) }
17541748
}
17551749
}
17561750

@@ -1951,11 +1945,10 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
19511945
ItemKind::Static(ty, mutability, body_id) => {
19521946
StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) })
19531947
}
1954-
ItemKind::Const(ty, body_id) => ConstantItem(Constant {
1948+
ItemKind::Const(ty, body_id) => ConstantItem(Constant::Const {
19551949
type_: ty.clean(cx),
1956-
expr: print_const_expr(cx.tcx, body_id),
1957-
value: print_evaluated_const(cx, def_id),
1958-
is_literal: is_literal_expr(cx, body_id.hir_id),
1950+
body: body_id,
1951+
did: def_id,
19591952
}),
19601953
ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
19611954
bounds: ty.bounds.clean(cx),

src/librustdoc/clean/types.rs

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ use rustc_target::spec::abi::Abi;
3232

3333
use crate::clean::cfg::Cfg;
3434
use crate::clean::external_path;
35-
use crate::clean::inline;
35+
use crate::clean::inline::{self, print_inlined_const};
3636
use crate::clean::types::Type::{QPath, ResolvedPath};
37+
use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
3738
use crate::clean::Clean;
3839
use crate::core::DocContext;
3940
use crate::formats::cache::Cache;
@@ -1986,11 +1987,64 @@ crate struct Static {
19861987
}
19871988

19881989
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1989-
crate struct Constant {
1990-
crate type_: Type,
1991-
crate expr: String,
1992-
crate value: Option<String>,
1993-
crate is_literal: bool,
1990+
crate enum Constant {
1991+
/// Typed constant value.
1992+
TyConst { type_: Type, expr: String },
1993+
/// A constant (expression) that’s not an item or associated item. These are usually found
1994+
/// nested inside types (e.g., array lengths) or expressions (e.g., repeat counts), and also
1995+
/// used to define explicit discriminant values for enum variants.
1996+
Generic { type_: Type, body: BodyId },
1997+
/// Inlined constant (from another crate).
1998+
Inline { type_: Type, did: DefId },
1999+
/// const FOO: u32 = ...;
2000+
Const { type_: Type, did: DefId, body: BodyId },
2001+
}
2002+
2003+
impl Constant {
2004+
crate fn expr(&self, tcx: TyCtxt<'_>) -> String {
2005+
match self {
2006+
Self::TyConst { expr, .. } => expr.clone(),
2007+
Self::Inline { did, .. } => print_inlined_const(tcx, *did),
2008+
Self::Const { body, .. } | Self::Generic { body, .. } => print_const_expr(tcx, *body),
2009+
}
2010+
}
2011+
2012+
crate fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
2013+
match self {
2014+
Self::TyConst { .. } | Self::Generic { .. } => None,
2015+
Self::Inline { did, .. } | Self::Const { did, .. } => print_evaluated_const(tcx, *did),
2016+
}
2017+
}
2018+
2019+
crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
2020+
match self {
2021+
Self::TyConst { .. } => false,
2022+
Self::Inline { did, .. } => did
2023+
.as_local()
2024+
.map_or(false, |did| is_literal_expr(tcx, tcx.hir().local_def_id_to_hir_id(did))),
2025+
Self::Const { body, .. } | Self::Generic { body, .. } => {
2026+
is_literal_expr(tcx, body.hir_id)
2027+
}
2028+
}
2029+
}
2030+
2031+
crate fn type_(&self) -> &Type {
2032+
match *self {
2033+
Self::TyConst { ref type_, .. }
2034+
| Self::Inline { ref type_, .. }
2035+
| Self::Const { ref type_, .. }
2036+
| Self::Generic { ref type_, .. } => type_,
2037+
}
2038+
}
2039+
2040+
crate fn to_type(self) -> Type {
2041+
match self {
2042+
Self::TyConst { type_, .. }
2043+
| Self::Inline { type_, .. }
2044+
| Self::Const { type_, .. }
2045+
| Self::Generic { type_, .. } => type_,
2046+
}
2047+
}
19942048
}
19952049

19962050
#[derive(Clone, Debug)]

src/librustdoc/clean/utils.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
301301
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def.did);
302302
print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(hir_id))
303303
} else {
304-
inline::print_inlined_const(cx, def.did)
304+
inline::print_inlined_const(cx.tcx, def.did)
305305
};
306306
if let Some(promoted) = promoted {
307307
s.push_str(&format!("::{:?}", promoted))
@@ -324,15 +324,15 @@ crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
324324
}
325325
}
326326

327-
crate fn print_evaluated_const(cx: &DocContext<'_>, def_id: DefId) -> Option<String> {
328-
cx.tcx.const_eval_poly(def_id).ok().and_then(|val| {
329-
let ty = cx.tcx.type_of(def_id);
327+
crate fn print_evaluated_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<String> {
328+
tcx.const_eval_poly(def_id).ok().and_then(|val| {
329+
let ty = tcx.type_of(def_id);
330330
match (val, ty.kind()) {
331331
(_, &ty::Ref(..)) => None,
332332
(ConstValue::Scalar(_), &ty::Adt(_, _)) => None,
333333
(ConstValue::Scalar(_), _) => {
334-
let const_ = ty::Const::from_value(cx.tcx, val, ty);
335-
Some(print_const_with_custom_print_scalar(cx, const_))
334+
let const_ = ty::Const::from_value(tcx, val, ty);
335+
Some(print_const_with_custom_print_scalar(tcx, const_))
336336
}
337337
_ => None,
338338
}
@@ -349,16 +349,16 @@ fn format_integer_with_underscore_sep(num: &str) -> String {
349349
.collect()
350350
}
351351

352-
fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const<'tcx>) -> String {
352+
fn print_const_with_custom_print_scalar(tcx: TyCtxt<'_>, ct: &'tcx ty::Const<'tcx>) -> String {
353353
// Use a slightly different format for integer types which always shows the actual value.
354354
// For all other types, fallback to the original `pretty_print_const`.
355355
match (ct.val, ct.ty.kind()) {
356356
(ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Uint(ui)) => {
357357
format!("{}{}", format_integer_with_underscore_sep(&int.to_string()), ui.name_str())
358358
}
359359
(ty::ConstKind::Value(ConstValue::Scalar(int)), ty::Int(i)) => {
360-
let ty = cx.tcx.lift(ct.ty).unwrap();
361-
let size = cx.tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size;
360+
let ty = tcx.lift(ct.ty).unwrap();
361+
let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size;
362362
let data = int.assert_bits(size);
363363
let sign_extended_data = size.sign_extend(data) as i128;
364364

@@ -372,8 +372,8 @@ fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const
372372
}
373373
}
374374

375-
crate fn is_literal_expr(cx: &DocContext<'_>, hir_id: hir::HirId) -> bool {
376-
if let hir::Node::Expr(expr) = cx.tcx.hir().get(hir_id) {
375+
crate fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
376+
if let hir::Node::Expr(expr) = tcx.hir().get(hir_id) {
377377
if let hir::ExprKind::Lit(_) = &expr.kind {
378378
return true;
379379
}
@@ -411,7 +411,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Ty
411411
return Generic(kw::SelfUpper);
412412
}
413413
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
414-
return Generic(Symbol::intern(&format!("{:#}", path.print(&cx.cache))));
414+
return Generic(Symbol::intern(&format!("{:#}", path.print(&cx.cache, cx.tcx))));
415415
}
416416
Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
417417
_ => false,

0 commit comments

Comments
 (0)