-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't run everybody_loops
for rustdoc; instead ignore resolution errors
#73566
Conversation
7df08b7
to
b4ea61b
Compare
I'm not sure if perf runs are a thing for rustdoc, but if so I would be very curious whether this helps or hurts performance. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a neat approach! Looks like there's still some work to be done for missing_docs, but I like this idea!
(I'd defer to eddy on the actual review)
Why do we need typeck for this lint? I'm confused: can we not run this lint on the HIR? |
We don't need typeck, but it's being run anyway. Currently typeck is run unconditionally for all lints: rust/src/librustc_lint/late.rs Lines 107 to 113 in d4e143e
body_tables calls typeck_tables_of .
|
r? @pnkfelix |
Wait, but, we want to run the missing_docs lint in rustc, not rustdoc, yes? So how does this matter? The only issue is that missing_docs won't complain about cross-platform docs, which seems okay |
To be clear: Are you suggesting that @jyn514 just revise their PR to disable the missing_docs lint solely when rustdoc is running (i.e. baseed on I just wanted to make sure I'm interpreting your feedback the right way. |
So I was under the impression that rustdoc doesn't run normal lints. Turns out, it does, just some very whitelisted ones Lines 306 to 311 in 1a4e2b6
Given this mechanism it seems like this just disables the reporting of some lints, it's not clear how this disables them from running, though. Maybe I'm misreading this. Either way! It should be possible to write missing_docs as a builtin rustdoc pass if we so wish, so it relies on rustdoc's lint framework, not rustc's. This would mean having two potentially different versions of the lint running, though. |
As far as I understand, all the lints were previously run by
That seems a lot more complicated than making |
To remove the |
aha! I see.
Right, but you still have the problem that all lints are being run when you do this, not just the ones you care about. What I'm trying to suggest is that we manually run the missing_docs pass, either by reusing the same code or rewriting it, as part of rustdoc directly. |
I don't think that's the case? The |
Oh, I see. Never mind. I guess it's okayish to take that approach, I'm just concerned that it will make the lints more brittle. The missing docs lint pass is quite straightforward, it should be super easy to replicate it as a visitor or a doc pass. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Originally I tried to do a much broader refactoring that got rid of `init_lints` altogether. My reasoning is that now the lints aren't being run anymore (after rust-lang#73566), there's no need to ignore them explicitly. But it seems there are still some lints that aren't affected by setting `lint_mod` to a no-op: ``` deny(pub_use_of_private_extern_crate) deny(const_err) warn(unused_imports) ``` (there are possibly more, these are just the ones that failed in the rustdoc test suite). Some of these seem like we really should be warning about, but that's a much larger change and I don't propose to make it here. So for the time being, this just adds the `unknown_lints` and `renamed_or_removed_lints` passes to the list of lints rustdoc warns about.
Warn about unknown or renamed lints in rustdoc Fixes rust-lang#75884. This is best reviewed one commit at a time. r? @GuillaumeGomez Originally I tried to do a much broader refactoring that got rid of `init_lints` altogether. My reasoning is that now the lints aren't being run anymore (after rust-lang#73566), there's no need to ignore them explicitly. But it seems there are still some lints that aren't affected by setting `lint_mod` to a no-op: ``` deny(pub_use_of_private_extern_crate) deny(const_err) warn(unused_imports) ``` (there are possibly more, these are just the ones that failed in the rustdoc test suite). Some of these seem like we really should be warning about, but that's a much larger change and I don't propose to make it here. So for the time being, this just adds the `unknown_lints` and `renamed_or_removed_lints` passes to the list of lints rustdoc warns about.
r? @eddyb
cc @petrochenkov, @GuillaumeGomez, @Manishearth, @ecstatic-morse, @marmeladema
Blocked on #73743Merged.Blocked on crater run.Crater popped up some ICEs (now fixed). See crater run, ICEs.Blocked on #74070 so that we don't make typeck_tables_of public when it shouldn't be.Merged.Closes #71820, closes #71104, closes #65863.
What is the motivation for this change?
As seen from a lengthy trail of PRs and issues (#73532, #73103, #71820, #71104),
everybody_loops
is causing bugs in rustdoc. The main issue is that it does not preserve the validity of theDefId
tree, meaning that operations on DefIds may unexpectedly fail when called later. This is blocking intra-doc links (see #73101).This PR starts by removing
everybody_loops
, fixing #71104 and #71820. However, that brings back the bugs seen originally in #43348: Since libstd documents items for all platforms, the function bodies sometimes do not type check. Here are the errors from documentinglibstd
witheverybody_loops
disabled and no other changes:Why does this need changes to
rustc_resolve
?Normally, this could be avoided by simply not calling the
typeck_item_bodies
pass. However, the errors above happen before type checking, in name resolution itself. Since name resolution is intermingled with macro expansion, and rustdoc needs expansion to happen before it knows all items to be documented, there needs to be someway to ignore resolution errors in function bodies.An alternative solution suggested by @petrochenkov was to not run
everybody_loops
on anything containing a nestedDefId
. This would solve some of the immediate issues, but isn't bullet-proof: the following functions still could not be documented if the items in the body failed to resolve:DefId
(SomeNodeId
/LocalDefId
don't have a correspondingHirId
#71104)Functions returningThese ended up not resolving anyway with this PR.impl Trait
(Excludeimpl Trait
functions from everybody_loops. #43878)const fn
, becauseloop {}
inconst fn
is unstable (--unpretty everybody_loops
is not compatible withconst fn
. #43636)const_loop
was just stabilized.This also isn't exactly what rustdoc wants, which is to avoid looking at function bodies in the first place.
What changes were made?
The hack implemented in this PR is to add an option to ignore all resolution errors in function bodies. This is enabled only for rustdoc. Since resolution errors are ignored, the MIR generated will be invalid, as can be seen in the following ICE:
Fortunately, rustdoc does not need to access MIR in order to generate documentation. Therefore this also removes the call to
analyze()
inrustdoc::run_core
. This has the side effect of not generating all lints by default. Most lints are safe to ignore (does rustdoc really need to run liveness analysis?) butmissing_docs
in particular is disabled when it should not be. Re-runningmissing_docs
specifically does not help, because it causes the typechecking pass to be run, bringing back the errors from #24658:Because of #73743, we only run typeck on demand. So this only causes an issue for functions returning
impl Trait
, which were already special cased byReplaceFunctionWithBody
. However, it now considersasync fn f() -> T
to be consideredimpl Future<Output = T>
, where before it was considered to have a concreteT
type.How will this affect future changes to rustdoc?
typeck_tables_of
when a lint needs it. #73743.tcx.analysis()
unless this PR is reverted altogether.Current status
I am not yet sure how to bring backThe opt-out was implemented in rustc_lint: only querymissing_docs
without running typeck. @eddyb suggested allowing lints to opt-out of type-checking, which would probably be another rabbit hole.typeck_tables_of
when a lint needs it. #73743. However, of the rustc lints, now only missing_docs is run and no other lints: Don't runeverybody_loops
for rustdoc; instead ignore resolution errors #73566 (comment). We need a team decision on whether that's an acceptable tradeoff. Note that all rustdoc lints are still run (intra_doc_link_resolution_failure
, etc). UPDATE: This was deemed acceptable in Don't runeverybody_loops
for rustdoc; instead ignore resolution errors #73566 (comment)The implementation of optional errors inI'm mostly happy with it now.rustc_resolve
is very brute force, it should probably be moved fromLateResolver
toResolver
to avoid duplicating the logic in many places.This no longer allows errors in
async fn f() -> T
. This caused breakage in 50 crates out of a full crater run, all of which (that I looked at) didn't compile when run with rustc directly. In other words, it used to be that they could not be compiled but could still be documented; now they can't be documented either. This needs a decision from the rustdoc team on whether this is acceptable breakage. UPDATE: This was deemed acceptable in Don't runeverybody_loops
for rustdoc; instead ignore resolution errors #73566 (comment)This makesReverted.fn typeck_tables_of
inrustc_typeck
public. This is not desired behavior, but needs the changes from Use for<'tcx> fn pointers in Providers, instead of having Providers<'tcx>. #74070 in order to be fixed.