-
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
limit the length of types in monomorphization #37789
Conversation
Why not |
Because |
I agree, it is :) |
The type size limit could be a multiplier of the recursion limit, or something. |
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). |
Please explain why this is insta-stable. |
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. |
@arielb1 the workaround could certainly be to use nightly for some time, if they need to lift the limit? |
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>, |
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 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?
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.
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.
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 actually expected this value to be stored inside each TyS
- seems cheaper that way?
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.
That's what I meant. Looks like a bump in memory use, and there's no killer case for 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.
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?
☔ The latest upstream changes (presumably #37824) made this pull request unmergeable. Please resolve the merge conflicts. |
2b923f5
to
050b9b5
Compare
Has anyone run crater on this? |
I'm satisfied with @arielb1's reason to limit it to monomorphization. We can always expand to more things later if needed. |
Started a crater run. |
Crater results: https://gist.github.com/nikomatsakis/731f7057c3bb9443a0744449d2a328a3
Things to investigate:
|
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 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 ? |
@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. |
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? |
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 |
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. |
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. |
@rfcbot reviewed |
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. |
Nonetheless, I wouldn't expect a lot of regressions here. |
@bors r+ |
📌 Commit 050b9b5 has been approved by |
⌛ Testing commit 050b9b5 with merge 0274e60... |
💔 Test failed - auto-win-msvc-64-opt-rustbuild |
Looks like you have to run the script to update the test output:
|
This adds the new insta-stable `#![type_size_limit]` crate attribute to control the limit, and is obviously a [breaking-change] fixable by that.
@bors r=nikomatsakis |
📌 Commit 242cd7e has been approved by |
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
…=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
…=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
This adds the new insta-stable
#![type_size_limit]
crate attribute to controlthe limit, and is obviously a [breaking-change] fixable by that.
Fixes #37311.
r? @nikomatsakis