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

limit the length of types in monomorphization #37789

Merged
merged 1 commit into from
Dec 2, 2016

Conversation

arielb1
Copy link
Contributor

@arielb1 arielb1 commented Nov 15, 2016

This adds the new insta-stable #![type_size_limit] crate attribute to control
the limit, and is obviously a [breaking-change] fixable by that.

Fixes #37311.

r? @nikomatsakis

@durka
Copy link
Contributor

durka commented Nov 15, 2016

Why not #![recursion_limit]?

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 15, 2016

@durka

Because recursion_limit is way too small.

@durka
Copy link
Contributor

durka commented Nov 15, 2016

I agree, it is :)

@durka
Copy link
Contributor

durka commented Nov 15, 2016

The type size limit could be a multiplier of the recursion limit, or something.

@Mark-Simulacrum
Copy link
Member

Is there a reason we can't increase the recursion limit itself? @jseyfried mentioned here that this is probably something that would be reasonable to do: #36214 (comment).

@brson brson added the relnotes Marks issues that should be documented in the release notes of the next release. label Nov 16, 2016
@brson
Copy link
Contributor

brson commented Nov 16, 2016

Please explain why this is insta-stable.

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 16, 2016

@brson

type_length_limit is insta-stable because I want to provide people that exceed the maximum type length limit some workaround.

Maybe it would be better to just make this a rate-limited warning instead of an error to avoid the worries, but then testing it would be difficult and the compiler would still hang.

@nikomatsakis nikomatsakis added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Nov 16, 2016
@nikomatsakis
Copy link
Contributor

@arielb1 the workaround could certainly be to use nightly for some time, if they need to lift the limit?

@nikomatsakis
Copy link
Contributor

We should run crater here, though

@@ -433,6 +434,40 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(instance.def, recursion_depth)
}

fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems good; I'm wondering if this is the only place we have to check it. I was originally considering checking this directly in the type interner (i.e., we just couldn't create a type that is too big). What do you think about that?

Copy link
Contributor Author

@arielb1 arielb1 Nov 17, 2016

Choose a reason for hiding this comment

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

Checking it in other places would basically require us to interncache "type sizes" in types, which would bump our memory usage for no very good reason.

Copy link
Member

Choose a reason for hiding this comment

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

I actually expected this value to be stored inside each TyS - seems cheaper that way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@eddyb

That's what I meant. Looks like a bump in memory use, and there's no killer case for that.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I wrote my message before seeing yours. Any chance this can be done with recursion, to avoid the memory allocations of the walker? Or is it amortized and otherwise not a problem?
Could we reuse the walker?

@bors
Copy link
Contributor

bors commented Nov 21, 2016

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

@nikomatsakis
Copy link
Contributor

Has anyone run crater on this?

@nikomatsakis
Copy link
Contributor

I'm satisfied with @arielb1's reason to limit it to monomorphization. We can always expand to more things later if needed.

@nikomatsakis
Copy link
Contributor

Started a crater run.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Nov 22, 2016

Crater results: https://gist.github.com/nikomatsakis/731f7057c3bb9443a0744449d2a328a3

  • 6626 crates tested: 4652 working / 1616 broken / 1 regressed / 3 fixed / 354 unknown.

Things to investigate:

@nikomatsakis
Copy link
Contributor

Looks good. The only question then is perma-stability. But this doesn't bother me. I think there is an inherent need for this sort of threshold, given that we have adopted a monomorphization strategy without any fixed limits to prevent infinite recursion. And of course if this threshold became unnecessary in the future, we could always make it a no-op, or use it to inform the value for a newer threshold.

cc @rust-lang/compiler @rust-lang/lang -- I plan to r+ this commit, which adds an attribute that limits the maximum size (not just depth) of types we construct during monomorphization. This is to give nice errors for programs that construct types whose sizes grows exponentially with depth. It augments the existing recursion counter. People ok with this?

Another option would be to somehow try to drive this limit as some function of the recursion depth, or to make a meta-attribute like #[compilation_limits(recursion_depth = "2", type_size = "4")].

Yet another option is to make this option unstable. Given the zero impact on crater, it seems like nobody needs to use this option to compile today, so I guess there isn't much reason to stabilize it just yet. But I'd want to act quickly, so that when we do find people who need it, they have a stable option available to them. Thoughts, @arielb1 ?

@aturon
Copy link
Member

aturon commented Nov 22, 2016

@nikomatsakis Sounds like a nice improvement. I'm personally ambivalent about how precisely we express the limit -- it should be rare enough that it doesn't matter that much.

@arielb1
Copy link
Contributor Author

arielb1 commented Nov 22, 2016

Won't a compilation limit break the recursion depth code? Or should we have it over the normal recursion depth?

I'm not sure whether to feature-gate the type size limit. I don't expect anyone to encounter it, but this could really be a problem to someone. What do you prefer?

@aturon aturon added T-lang Relevant to the language team, which will review and decide on the PR/issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 22, 2016
@aturon
Copy link
Member

aturon commented Nov 22, 2016

See @nikomatsakis's comment for the summary. The biggest question right now is whether we're OK making the crate attribute insta-stable.

@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Nov 22, 2016

Team member @aturon has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@nikomatsakis
Copy link
Contributor

@arielb1

Won't a compilation limit break the recursion depth code?

I don't follow. I just meant that we would deprecate the existing attribute and prefer a new, unified syntax. I don't care enough to do that deprecation though. Can always do it later (and deprecate the two attributes).

Or did you mean, would it break code if we based this limit on the recursion depth? Potentially, I think is the answer.

@withoutboats
Copy link
Contributor

@rfcbot reviewed

@bluss
Copy link
Member

bluss commented Nov 23, 2016

As a sidenote (I saw it from this crater report), crater doesn't build crates that use workspaces correctly. For example libc, macro-attr, and others are listed as broken for this reason.

@nikomatsakis
Copy link
Contributor

@bluss good catch. @brson, how's that crater replacement coming along?

@nikomatsakis
Copy link
Contributor

Nonetheless, I wouldn't expect a lot of regressions here.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Nov 29, 2016

📌 Commit 050b9b5 has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Nov 29, 2016

⌛ Testing commit 050b9b5 with merge 0274e60...

@bors
Copy link
Contributor

bors commented Nov 29, 2016

💔 Test failed - auto-win-msvc-64-opt-rustbuild

@nikomatsakis
Copy link
Contributor

@arielb1

Looks like you have to run the script to update the test output:

error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(&(), &()), &(&()...`
  --> C:\bot\slave\auto-win-msvc-64-opt-rustbuild\build\src/test\ui\issue-37311-type-length-limit\issue-37311.rs:23:5
   |
23 |       fn recurse(&self) {
   |  _____^ starting here...
24 | |         (self, self).recurse();
25 | |     }
   | |_____^ ...ending here
   |
   = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate

error: aborting due to previous error

This adds the new insta-stable `#![type_size_limit]` crate attribute to control
the limit, and is obviously a [breaking-change] fixable by that.
@arielb1
Copy link
Contributor Author

arielb1 commented Dec 1, 2016

@bors r=nikomatsakis

@bors
Copy link
Contributor

bors commented Dec 1, 2016

📌 Commit 242cd7e has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Dec 2, 2016

⌛ Testing commit 242cd7e with merge 1077149...

bors added a commit that referenced this pull request Dec 2, 2016
limit the length of types in monomorphization

This adds the new insta-stable `#![type_size_limit]` crate attribute to control
the limit, and is obviously a [breaking-change] fixable by that.

Fixes #37311.

r? @nikomatsakis
@bors bors merged commit 242cd7e into rust-lang:master Dec 2, 2016
@bluss bluss removed the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Dec 6, 2016
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 3, 2024
…=lcnr

Re-implement a type-size based limit

r? lcnr

This PR reintroduces the type length limit added in rust-lang#37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in rust-lang#72412, which caused the `walk` function to no longer walk over identical elements.

Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).

This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.

Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.

Fixes rust-lang#125460
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jul 11, 2024
…=lcnr

Re-implement a type-size based limit

r? lcnr

This PR reintroduces the type length limit added in rust-lang#37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in rust-lang#72412, which caused the `walk` function to no longer walk over identical elements.

Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).

This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.

Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.

Fixes rust-lang#125460
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compiler hangs after 'write metadata stage'