Skip to content

Commit 3debe9a

Browse files
committed
Auto merge of #82873 - GuillaumeGomez:rustdoc-const-ty, r=jyn514
Rework rustdoc const type This PR is mostly about two things: 1. Not storing some information in the `clean::Constant` type 2. Using `TyCtxt` in the formatting (which we will need in any case as we move forward in any case). Also: I'm very curious of the perf change in here. Thanks a lot `@danielhenrymantilla` for your `Captures` idea! It allowed me to solve the lifetime issue completely. :) r? `@jyn514`
2 parents 52e3dff + 7b59089 commit 3debe9a

File tree

11 files changed

+840
-634
lines changed

11 files changed

+840
-634
lines changed

src/librustdoc/clean/inline.rs

+8-12
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,23 +490,19 @@ 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

502-
fn build_const(cx: &mut DocContext<'_>, did: DefId) -> clean::Constant {
502+
fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
503503
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-
}),
504+
type_: cx.tcx.type_of(def_id).clean(cx),
505+
kind: clean::ConstantKind::Extern { def_id },
510506
}
511507
}
512508

src/librustdoc/clean/mod.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,7 @@ impl Clean<Constant> for hir::ConstArg {
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+
kind: ConstantKind::Anonymous { 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(tcx, self.def_id))
11391137
} else {
11401138
None
11411139
};
@@ -1745,11 +1743,10 @@ 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 {
1746+
// FIXME: instead of storing the stringified expression, store `self` directly instead.
17481747
Constant {
17491748
type_: self.ty.clean(cx),
1750-
expr: format!("{}", self),
1751-
value: None,
1752-
is_literal: false,
1749+
kind: ConstantKind::TyConst { expr: self.to_string() },
17531750
}
17541751
}
17551752
}
@@ -1953,9 +1950,7 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
19531950
}
19541951
ItemKind::Const(ty, body_id) => ConstantItem(Constant {
19551952
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),
1953+
kind: ConstantKind::Local { body: body_id, def_id },
19591954
}),
19601955
ItemKind::OpaqueTy(ref ty) => OpaqueTyItem(OpaqueTy {
19611956
bounds: ty.bounds.clean(cx),

src/librustdoc/clean/types.rs

+54-4
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;
@@ -1988,9 +1989,58 @@ crate struct Static {
19881989
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
19891990
crate struct Constant {
19901991
crate type_: Type,
1991-
crate expr: String,
1992-
crate value: Option<String>,
1993-
crate is_literal: bool,
1992+
crate kind: ConstantKind,
1993+
}
1994+
1995+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1996+
crate enum ConstantKind {
1997+
/// This is the wrapper around `ty::Const` for a non-local constant. Because it doesn't have a
1998+
/// `BodyId`, we need to handle it on its own.
1999+
///
2000+
/// Note that `ty::Const` includes generic parameters, and may not always be uniquely identified
2001+
/// by a DefId. So this field must be different from `Extern`.
2002+
TyConst { expr: String },
2003+
/// A constant (expression) that's not an item or associated item. These are usually found
2004+
/// nested inside types (e.g., array lengths) or expressions (e.g., repeat counts), and also
2005+
/// used to define explicit discriminant values for enum variants.
2006+
Anonymous { body: BodyId },
2007+
/// A constant from a different crate.
2008+
Extern { def_id: DefId },
2009+
/// `const FOO: u32 = ...;`
2010+
Local { def_id: DefId, body: BodyId },
2011+
}
2012+
2013+
impl Constant {
2014+
crate fn expr(&self, tcx: TyCtxt<'_>) -> String {
2015+
match self.kind {
2016+
ConstantKind::TyConst { ref expr } => expr.clone(),
2017+
ConstantKind::Extern { def_id } => print_inlined_const(tcx, def_id),
2018+
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
2019+
print_const_expr(tcx, body)
2020+
}
2021+
}
2022+
}
2023+
2024+
crate fn value(&self, tcx: TyCtxt<'_>) -> Option<String> {
2025+
match self.kind {
2026+
ConstantKind::TyConst { .. } | ConstantKind::Anonymous { .. } => None,
2027+
ConstantKind::Extern { def_id } | ConstantKind::Local { def_id, .. } => {
2028+
print_evaluated_const(tcx, def_id)
2029+
}
2030+
}
2031+
}
2032+
2033+
crate fn is_literal(&self, tcx: TyCtxt<'_>) -> bool {
2034+
match self.kind {
2035+
ConstantKind::TyConst { .. } => false,
2036+
ConstantKind::Extern { def_id } => def_id.as_local().map_or(false, |def_id| {
2037+
is_literal_expr(tcx, tcx.hir().local_def_id_to_hir_id(def_id))
2038+
}),
2039+
ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
2040+
is_literal_expr(tcx, body.hir_id)
2041+
}
2042+
}
2043+
}
19942044
}
19952045

19962046
#[derive(Clone, Debug)]

src/librustdoc/clean/utils.rs

+12-12
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)