-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Fix Rustdoc ICE when checking blanket impls #55258
Conversation
r? @eddyb (rust_highfive has picked a reviewer for you, use r? to override) |
1d9d2bd
to
ace4af8
Compare
Fixes rust-lang#55001, rust-lang#54744 Previously, SelectionContext would unconditionally cache the selection result for an obligation. This worked fine for most users of SelectionContext, but it caused an issue when used by Rustdoc's blanket impl finder. The issue occured when SelectionContext chose a ParamCandidate which contained inference variables. Since inference variables can change between calls to select(), it's not safe to cache the selection result - the chosen candidate might not be applicable for future results, leading to an ICE when we try to run confirmation. This commit prevents SelectionContext from caching any ParamCandidate that contains inference variables. This should always be completely safe, as trait selection should never depend on a particular result being cached. I've also added some extra debug!() statements, which I found helpful in tracking down this bug.
ace4af8
to
4f2624c
Compare
r? @GuillaumeGomez - they originally wrote the blanket impl finder code in #52585 |
This is awesome! Thanks a lot! @bors: r+ |
📌 Commit 4f2624c has been approved by |
…illaumeGomez Fix Rustdoc ICE when checking blanket impls Fixes rust-lang#55001, rust-lang#54744 Previously, SelectionContext would unconditionally cache the selection result for an obligation. This worked fine for most users of SelectionContext, but it caused an issue when used by Rustdoc's blanket impl finder. The issue occured when SelectionContext chose a ParamCandidate which contained inference variables. Since inference variables can change between calls to select(), it's not safe to cache the selection result - the chosen candidate might not be applicable for future results, leading to an ICE when we try to run confirmation. This commit prevents SelectionContext from caching any ParamCandidate that contains inference variables. This should always be completely safe, as trait selection should never depend on a particular result being cached. I've also added some extra debug!() statements, which I found helpful in tracking down this bug.
…illaumeGomez Fix Rustdoc ICE when checking blanket impls Fixes rust-lang#55001, rust-lang#54744 Previously, SelectionContext would unconditionally cache the selection result for an obligation. This worked fine for most users of SelectionContext, but it caused an issue when used by Rustdoc's blanket impl finder. The issue occured when SelectionContext chose a ParamCandidate which contained inference variables. Since inference variables can change between calls to select(), it's not safe to cache the selection result - the chosen candidate might not be applicable for future results, leading to an ICE when we try to run confirmation. This commit prevents SelectionContext from caching any ParamCandidate that contains inference variables. This should always be completely safe, as trait selection should never depend on a particular result being cached. I've also added some extra debug!() statements, which I found helpful in tracking down this bug.
…illaumeGomez Fix Rustdoc ICE when checking blanket impls Fixes rust-lang#55001, rust-lang#54744 Previously, SelectionContext would unconditionally cache the selection result for an obligation. This worked fine for most users of SelectionContext, but it caused an issue when used by Rustdoc's blanket impl finder. The issue occured when SelectionContext chose a ParamCandidate which contained inference variables. Since inference variables can change between calls to select(), it's not safe to cache the selection result - the chosen candidate might not be applicable for future results, leading to an ICE when we try to run confirmation. This commit prevents SelectionContext from caching any ParamCandidate that contains inference variables. This should always be completely safe, as trait selection should never depend on a particular result being cached. I've also added some extra debug!() statements, which I found helpful in tracking down this bug.
…illaumeGomez Fix Rustdoc ICE when checking blanket impls Fixes rust-lang#55001, rust-lang#54744 Previously, SelectionContext would unconditionally cache the selection result for an obligation. This worked fine for most users of SelectionContext, but it caused an issue when used by Rustdoc's blanket impl finder. The issue occured when SelectionContext chose a ParamCandidate which contained inference variables. Since inference variables can change between calls to select(), it's not safe to cache the selection result - the chosen candidate might not be applicable for future results, leading to an ICE when we try to run confirmation. This commit prevents SelectionContext from caching any ParamCandidate that contains inference variables. This should always be completely safe, as trait selection should never depend on a particular result being cached. I've also added some extra debug!() statements, which I found helpful in tracking down this bug.
Rollup of 21 pull requests Successful merges: - #54816 (Don't try to promote already promoted out temporaries) - #54824 (Cleanup rustdoc tests with `@!has` and `@!matches`) - #54921 (Add line numbers option to rustdoc) - #55167 (Add a "cheap" mode for `compute_missing_ctors`.) - #55258 (Fix Rustdoc ICE when checking blanket impls) - #55264 (Compile the libstd we distribute with -Ccodegen-unit=1) - #55271 (Unimplement ExactSizeIterator for MIR traversing iterators) - #55292 (Macro diagnostics tweaks) - #55298 (Point at macro definition when no rules expect token) - #55301 (List allowed tokens after macro fragments) - #55302 (Extend the impl_stable_hash_for! macro for miri.) - #55325 (Fix link to macros chapter) - #55343 (rustbuild: fix remap-debuginfo when building a release) - #55346 (Shrink `Statement`.) - #55358 (Remove redundant clone (2)) - #55370 (Update mailmap for estebank) - #55375 (Typo fixes in configure_cmake comments) - #55378 (rustbuild: use configured linker to build boostrap) - #55379 (validity: assert that unions are non-empty) - #55383 (Use `SmallVec` for the queue in `coerce_unsized`.) - #55391 (bootstrap: clean up a few clippy findings)
Nominating for beta backport, this fixes an ICE that is currently on stable. @rust-lang/compiler @rust-lang/rustdoc |
Accepting for beta promotion. |
Since when parameter environments with inference variables exist? cc @nikomatsakis @rust-lang/wg-traits . |
beta backport rollup Backports of some beta-approved PRs - [x] #55385: NLL: cast causes failure to promote to static - [x] #56043: remove "approx env bounds" if we already know from trait - [x] #56003: do not propagate inferred bounds on trait objects if they involve `Self` - [x] #55852: Rewrite `...` as `..=` as a `MachineApplicable` 2018 idiom lint - [x] #55804: rustdoc: don't inline `pub use some_crate` unless directly asked to - [x] #56059: Increase `Duration` approximate equal threshold to 1us - [x] Keep resolved defs in path prefixes and emit them in save-analysis #54145 - [x] Adjust Ids of path segments in visibility modifiers #55487 - [x] save-analysis: bug fix and optimisation. #55521 - [x] save-analysis: be even more aggressive about ignorning macro-generated defs #55936 - [x] save-analysis: fallback to using path id #56060 - [x] save-analysis: Don't panic for macro-generated use globs #55879 - [x] Add temporary renames to manifests for rustfmt/clippy #56081 - [x] Revert #51601 #56049 - [x] Fix stability hole with `static _` #55983 - [x] #56077 - [x] Fix Rustdoc ICE when checking blanket impls #55258 - [x] Updated RELEASES.md for 1.31.0 #55678 - [x] ~~#56061~~ #56111 - [x] Stabilize `extern_crate_item_prelude` #56032 Still running tests locally, and I plan to backport @nrc's other PRs too (cc @petrochenkov -- thanks for the advice)
) -> bool { | ||
match result { | ||
Ok(Some(SelectionCandidate::ParamCandidate(trait_ref))) => { | ||
!trait_ref.skip_binder().input_types().any(|t| t.walk().any(|t_| t_.is_ty_infer())) |
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 equivalent to trait_ref.needs_infer()
, but potentially much slower (since methods like needs_infer
rely on precomputed flags), I wonder how much of a perf regression this is.
Both TraitRef::input_types
and Ty::walk
are warning flags, we might want to audit their uses (and make Ty::walk
more annoying to use, probably).
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.
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.
(I don't think I agree that input_types
is a warning flag, though -- walk
maybe is..?)
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.
Anyway, should we open an issue to try converting this to use the needs_infer
call?
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.
It's included in #69294 (comment), I haven't had the chance to split that into its own PR for perf testing (presumably we can just land it with rollup=never
and see the results there. it can't be slower than walk
-ing, anyway).
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.
I don't think I agree that
input_types
is a warning flag
Isn't it a leftover from the days of "output" modes on parameters? Like before associated types fully became a thing?
Also it's going to get really bad with const
generics, so @varkor or @yodaldevoid would probably have to remove input_types
just to make its callsites correct.
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.
Isn't it a leftover from the days of "output" modes on parameters? Like before associated types fully became a thing?
It seems like it just screens out lifetime parameters. I guess you're right that there is probably generally little reason to do this.
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.
It seems like it just screens out lifetime parameters
And const parameters 😨 (presumably), hence my comments on that.
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.
I see. And I suppose it's probably just wrong to ignore needs-infer in lifetime parameters anyway. OK, I agree it's probably a 'red flag' of some kind.
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.
But it seems like you're going to fix this in #69294, so that's good.
Fixes #55001, #54744
Previously, SelectionContext would unconditionally cache the selection
result for an obligation. This worked fine for most users of
SelectionContext, but it caused an issue when used by Rustdoc's blanket
impl finder.
The issue occured when SelectionContext chose a ParamCandidate which
contained inference variables. Since inference variables can change
between calls to select(), it's not safe to cache the selection result -
the chosen candidate might not be applicable for future results, leading
to an ICE when we try to run confirmation.
This commit prevents SelectionContext from caching any ParamCandidate
that contains inference variables. This should always be completely
safe, as trait selection should never depend on a particular result
being cached.
I've also added some extra debug!() statements, which I found helpful in
tracking down this bug.