Stream: rustdoc

Topic: Getting to know the code base to fix #82852


view this post on Zulip fmease (Mar 09 2021 at 13:32):

As a newbie, I spent a good amount of time familiarizing myself with rustdoc to attempt to fix #82852. I found some parts of the code base which I do not really understand.
To summarize, the GitHub issue concerns the fact that parameters (most notably const parameters) in types containing constants are not substituted with concrete (const) arguments when we clean_qpath parametric paths (type aliases, structs, …). To illustrate, given type A<T, const N: usize> = [(T,); N + 1], the type alias A<i32, 6> "is cleaned to" [(i32,); N + 1], similarly type B<T, const N: usize> = P<(T,), {N + 1}> "is cleaned to" P<(i32,), {N + 1}> for arguments i32 and 6 and some type constructor (e.g. struct) P. The parameter N remains untouched in the clean::Constant.
In fact, although we store and extend the list of const substitutions (ct_substs) just like we do with type and lifetimes, we never actually use it! Type parameters are subst. in clean_path and lifetime params are subst. in <hir::Lifetime as Clean<Lifetime>>::clean. For types (and prob. also lts), we recurse the structure (in the Clean impl for types) until we find a single-segment qualified-path aka a single identifier which we can easily subst.

My issue is that I need to recurse over/visit a constant expression to get to the base case of a single identifier which I can then finally substitute using ct_substs.get. However, I don't know which API to use or if that's actually the way to go forward. The cleaning code seems to map from rustc_middle::ty::Const and rust_hir::hir::ConstArg. As far as I can tell, we never recursively clean constant expressions but simply treat them as abstract entities and call out to rustc_middle::ty::Const::eval, rustc_middle::ty::context::TyCtxt::const_eval_poly (in clean::utils::print_evaluated_const) (NB: Should not be used for constants containing parameters). Of course, there is TyCtxt::const_eval_resolve which takes a list of substitutions but obviously that is incompatible with ct_substs: FxHashMap<DefId, clean::Constant>.

So, how should/can I subst (const) params inside constant expressions (prob preferably using ct_substs)?

Pinging @lcnr as they declared they would help with const generics and worked on that part of the code (see PR 76297). Apologies if that's too forward.

view this post on Zulip lcnr (Mar 09 2021 at 13:35):

pinging me is fine :thumbs_up:

view this post on Zulip lcnr (Mar 09 2021 at 13:35):

will look into this a bit more later today

view this post on Zulip lcnr (Mar 09 2021 at 13:36):

ideally we should be to convert the type of the alias to a ty::Ty and then print that which shouldn't have those problems... we might still use the hir::Ty here? :thinking:

view this post on Zulip fmease (Mar 09 2021 at 13:56):

Great! Thank you :)

view this post on Zulip fmease (Mar 09 2021 at 14:02):

Conversion to ty::Ty looks like a solution, although that may call for a larger refactoring. Yeah, I don't know why the ty::Ty (…) rustdoc receives to transform into a clean::Type is still unevaluated/non-normalized. A normalized type could get rid of all the substitution code in rustdoc::clean that is necessary. Edit: Well probably to have more control: E.g. rustdoc does not want to evaluate/resolve public type aliases inside larger type terms (only private ones).

view this post on Zulip GuillaumeGomez (Mar 09 2021 at 19:22):

Nice! There is https://github.com/rust-lang/rust/pull/82873 that updates the constant code too (hum... Actually there is a lot of noise in this PR so maybe better not to start going around with this one XD)

view this post on Zulip fmease (Mar 09 2021 at 19:57):

Cool! I've just noticed it! Haven't looked at the changes yet though


Last updated: Oct 11 2021 at 22:34 UTC