Skip to content
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

Merged
merged 1 commit into from
Oct 26, 2018

Conversation

Aaron1011
Copy link
Member

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.

@rust-highfive
Copy link
Collaborator

r? @eddyb

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 22, 2018
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.
@Aaron1011
Copy link
Member Author

r? @GuillaumeGomez - they originally wrote the blanket impl finder code in #52585

@GuillaumeGomez
Copy link
Member

This is awesome! Thanks a lot!

@bors: r+

@bors
Copy link
Contributor

bors commented Oct 23, 2018

📌 Commit 4f2624c has been approved by GuillaumeGomez

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 23, 2018
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Oct 23, 2018
…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.
kennytm added a commit to kennytm/rust that referenced this pull request Oct 24, 2018
…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.
kennytm added a commit to kennytm/rust that referenced this pull request Oct 26, 2018
…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.
kennytm added a commit to kennytm/rust that referenced this pull request Oct 26, 2018
…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.
bors added a commit that referenced this pull request Oct 26, 2018
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)
@bors bors merged commit 4f2624c into rust-lang:master Oct 26, 2018
@QuietMisdreavus QuietMisdreavus added T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. beta-nominated Nominated for backporting to the compiler in the beta channel. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 7, 2018
@QuietMisdreavus
Copy link
Member

Nominating for beta backport, this fixes an ICE that is currently on stable. @rust-lang/compiler @rust-lang/rustdoc

@estebank estebank added beta-accepted Accepted for backporting to the compiler in the beta channel. and removed beta-nominated Nominated for backporting to the compiler in the beta channel. labels Nov 7, 2018
@estebank
Copy link
Contributor

estebank commented Nov 7, 2018

Accepting for beta promotion.

@arielb1
Copy link
Contributor

arielb1 commented Nov 10, 2018

Since when parameter environments with inference variables exist?

cc @nikomatsakis @rust-lang/wg-traits .

@pietroalbini pietroalbini added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Nov 20, 2018
@nikomatsakis nikomatsakis mentioned this pull request Nov 20, 2018
20 tasks
@alexcrichton alexcrichton removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Nov 20, 2018
bors added a commit that referenced this pull request Nov 20, 2018
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()))
Copy link
Member

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).

cc @nikomatsakis @pnkfelix @matthewjasper

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @eddyb is correct, this does seem slower (I hadn't noticed this PR at the time, though I agree also with @arielb1's comment that it's a bit surprising to see inference variables in the param env, though I suppose there may be some path by which it can occur -- and eventually it'll be true)

Copy link
Contributor

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..?)

Copy link
Contributor

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?

Copy link
Member

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).

Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.