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

Prevent very long compilation runtimes in LateBoundRegionNameCollector #83406

Merged
merged 1 commit into from
Apr 5, 2021

Conversation

b-naber
Copy link
Contributor

@b-naber b-naber commented Mar 23, 2021

Fixes #83150

On recursive types such as in the example given in #83150, the current implementation of LateBoundRegionNameCollector has very long compilation runtimes. To prevent those we store the types visited in the middle::ty::Visitor implementation of LateBoundRegionNameCollector in a SsoHashSet.

@rust-highfive
Copy link
Collaborator

r? @lcnr

(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 Mar 23, 2021
@@ -0,0 +1,9 @@
fn main() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test passes for an unexplainable reason. When I compile this file I get the expected error:

error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<.....

But the test suite cannot find an error.

Copy link
Contributor

Choose a reason for hiding this comment

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

i expect you to need at least // build-pass here, as the overly large types should only get created during mono item collection

@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor

@lcnr lcnr left a 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 that using type length limit is the best approach here.

The issue here is that the type T is &mut Map<T_prev, closure [T_prev]> so the type size scales by 2^depth instead of just depth.

Using https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/sso/struct.SsoHashSet.html in visit_ty seems like a potentially better solution to me

@@ -0,0 +1,9 @@
fn main() {
Copy link
Contributor

Choose a reason for hiding this comment

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

i expect you to need at least // build-pass here, as the overly large types should only get created during mono item collection

}
r.super_visit_with(self)
}

// In order to prohibit infinite recursion on infinitely recursed types we count the
Copy link
Contributor

@lcnr lcnr Mar 26, 2021

Choose a reason for hiding this comment

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

infinitely recursed types

nit: there are no infinite types. Types are finite trees, so infinite types are impossible.
We can get very large types though, which causes the hang here.

@b-naber
Copy link
Contributor Author

b-naber commented Mar 29, 2021

@lcnr Thanks for the review.

I don't understand how you would want to use SsoHashSet. Do you want to fill SsoHashSet until some given capacity is reached and then break control?

@lcnr
Copy link
Contributor

lcnr commented Mar 29, 2021

I don't want to break control at all here. Afaict this is not an infinite hang, this is a finite, but incredibly large perf regression.

I want to use a SsoHashSet to not look multiple times into identical parts of our type

@b-naber
Copy link
Contributor Author

b-naber commented Mar 29, 2021

@lcnr Thanks, that clarifies things. You're right, this isn't a hang.

I updated the PR to use the SsoHashSet. There's still a problem with the test though. When I changed this to build-pass the test fails, but it also fails when I add an expected error to the test with the reason that the test compiled successfully?!

@rust-log-analyzer

This comment has been minimized.

@b-naber
Copy link
Contributor Author

b-naber commented Mar 29, 2021

There's also a problem with another test, seems as if `LateBoundRegionNameCollector' has different functionality if we skip types we've seen before.

@b-naber
Copy link
Contributor Author

b-naber commented Mar 29, 2021

@lcnr Can you take another look? What do we do about the tests?

@rust-log-analyzer

This comment has been minimized.

@lcnr
Copy link
Contributor

lcnr commented Mar 29, 2021

i think the correct attribute here is // build-fail. By default we only try to check (like cargo check) ui tests afaik.

@b-naber
Copy link
Contributor Author

b-naber commented Mar 29, 2021

@lcnr Yes, that's the correct attribute. Thanks for the review and the help.

let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
let mut collector = LateBoundRegionNameCollector {
used_region_names: &mut self.used_region_names,
type_collector: SsoHashSet::with_capacity(1000),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
type_collector: SsoHashSet::with_capacity(1000),
type_collector: SsoHashSet::new(),

we don't want to allocate here by default.

@@ -0,0 +1,11 @@
// build-fail
//~^ overflow evaluating
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
//~^ overflow evaluating
//~^ overflow evaluating

@lcnr
Copy link
Contributor

lcnr commented Mar 30, 2021

please update the PR name and description, then this should be ready after a perf run.

@b-naber b-naber changed the title Introduce recursion limit in LateBoundRegionNameCollector Prevent very long compilation runtimes in LateBoundRegionNameCollector Mar 31, 2021
@b-naber
Copy link
Contributor Author

b-naber commented Mar 31, 2021

@lcnr This is ready for the perf run.

@bors
Copy link
Contributor

bors commented Mar 31, 2021

☔ The latest upstream changes (presumably #76814) made this pull request unmergeable. Please resolve the merge conflicts.

@lcnr
Copy link
Contributor

lcnr commented Apr 5, 2021

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Apr 5, 2021
@bors
Copy link
Contributor

bors commented Apr 5, 2021

⌛ Trying commit 3194b26 with merge 9fb1f198bce56ca989b0203c337bedffb89b96a1...

@bors
Copy link
Contributor

bors commented Apr 5, 2021

☀️ Try build successful - checks-actions
Build commit: 9fb1f198bce56ca989b0203c337bedffb89b96a1 (9fb1f198bce56ca989b0203c337bedffb89b96a1)

@rust-timer
Copy link
Collaborator

Queued 9fb1f198bce56ca989b0203c337bedffb89b96a1 with parent b1b0a15, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (9fb1f198bce56ca989b0203c337bedffb89b96a1): comparison url.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying rollup- to bors.

Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Apr 5, 2021
@lcnr
Copy link
Contributor

lcnr commented Apr 5, 2021

@bors r+

@bors
Copy link
Contributor

bors commented Apr 5, 2021

📌 Commit 3194b26 has been approved by lcnr

@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 Apr 5, 2021
@bors
Copy link
Contributor

bors commented Apr 5, 2021

⌛ Testing commit 3194b26 with merge d203fce...

@bors
Copy link
Contributor

bors commented Apr 5, 2021

☀️ Test successful - checks-actions
Approved by: lcnr
Pushing d203fce to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Apr 5, 2021
@bors bors merged commit d203fce into rust-lang:master Apr 5, 2021
@rustbot rustbot added this to the 1.53.0 milestone Apr 5, 2021
@b-naber b-naber deleted the issue-83510 branch April 5, 2021 21:15
@estebank
Copy link
Contributor

estebank commented May 4, 2021

Should this be backported to 1.52? @rust-lang/compiler


Context: this fixes a t-hang stable-to-stable regression that has been reported multiple times caused by big type names, the latest report being #84102

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

compiler hangs trying to print an overflow error
8 participants