-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Const stability checks v2 #131349
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
Const stability checks v2 #131349
Conversation
This comment has been minimized.
This comment has been minimized.
f7d1d3c to
053d1a4
Compare
This comment has been minimized.
This comment has been minimized.
053d1a4 to
37ddcbf
Compare
This comment has been minimized.
This comment has been minimized.
37ddcbf to
203ca72
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
720f9e3 to
80785de
Compare
| fn into_iter(self) -> Self::IntoIter; | ||
| } | ||
|
|
||
| #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] |
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 found two remaining rustc_const_unstable attributes on impl blocks, I think those should all have been removed with the const trait purge and were probably just forgotten.
This comment has been minimized.
This comment has been minimized.
|
I have re-done the way we do const stability inheritance, by simply fetching the required data from the I have updated the PR description to match the new version. |
|
We have a slightly bigger problem with the proc_macro_harness. Took me a bit to figure out what happens... The harness synthesizes calls to rust/compiler/rustc_builtin_macros/src/proc_macro_harness.rs Lines 256 to 272 in c682aa1
It carefully computes a span for the identifier that has rust/compiler/rustc_builtin_macros/src/proc_macro_harness.rs Lines 273 to 279 in c682aa1
However, the span it sets for the call expression is different, it is this one: rust/compiler/rustc_builtin_macros/src/proc_macro_harness.rs Lines 299 to 302 in c682aa1
The const stability check does not have access to the span of the identifer, it only has the span of the call expression. So when we check whether that span allows the desired call, we error. Previously the const stability check had a bug where it didn't consider this call at all, but now that bug is fixed. @petrochenkov maybe you can help us with this... is there a deep reason that the synthesized call expression in the proc macro |
80785de to
d7a78db
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@bors try |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
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.
r=me after this try build is done of course
|
The try build is done. :) @bors r=compiler-errors rollup=never |
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (54761cb): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary 0.1%, secondary -2.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary -1.1%, secondary 2.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 787.658s -> 787.235s (-0.05%) |
The const stability system has served us well ever since
const fnwere first stabilized. It's main feature is that it enforces recursive validity -- a stable const fn cannot internally make use of unstable const features without an explicit marker in the form of#[rustc_allow_const_fn_unstable]. This is done to make sure that we don't accidentally expose unstable const features on stable in a way that would be hard to take back. As part of this, it is enforced that a#[rustc_const_stable]can only call#[rustc_const_stable]functions. However, some problems have been coming up with increased usage:#[rustc_const_stable]when they are used as helpers in regular stableconst fn, and often people will rather add#[rustc_allow_const_fn_unstable]instead which was not our intention.const fnwithout stability attributes whose inherited stability (walking up parent modules) is#[stable]is allowed to call arbitrary unstable const operations, but can itself be called from stableconst fn. Similarly,#[allow_internal_unstable]on a macro completely bypasses the recursive nature of the check.Fundamentally, the problem is that we have three disjoint categories of functions, and not enough attributes to distinguish them:
Functions in the first two categories cannot use unstable const features and they can only call functions from the first two categories.
This PR implements the following system:
#[rustc_const_stable]puts functions in the first category. It may only be applied to#[stable]functions.#[rustc_const_unstable]by default puts functions in the third category. The new attribute#[rustc_const_stable_indirect]can be added to such a function to move it into the second category.const fnwithout a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls.Also, all the holes mentioned above have been closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to be manually marked
#[rustc_const_stable_indirect]to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine.The net effect of this is that a
#[unstable]or unmarked function can be constified simply by marking it asconst fn, and it will then be const-callable from stableconst fnand subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes#[stable]does it need a#[rustc_const_unstable]or#[rustc_const_stable]marker to decide if this should also imply const-stability.Adding
#[rustc_const_unstable]is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b)#[stable]functions that are not yet intended to be const-stable. Adding#[rustc_const_stable]is only needed for functions that are actually meant to be directly callable from stable const code.#[rustc_const_stable_indirect]is used to mark intrinsics as const-callable and for#[rustc_const_unstable]functions that are actually called from other, exposed-on-stableconst fn. No other attributes are required.Also see the updated dev-guide at rust-lang/rustc-dev-guide#2098.
I think in the future we may want to tweak this further, so that in the hopefully common case where a public function's const-stability just exactly mirrors its regular stability, we never have to add any attribute. But right now, once the function is stable this requires
#[rustc_const_stable].Open question
There is one point I could see we might want to do differently, and that is putting
#[rustc_const_unstable]functions (but not intrinsics) in category 2 by default, and requiring an extra attribute for#[rustc_const_not_exposed_on_stable]or so. This would require a bunch of extra annotations, but would have the advantage that turning a#[rustc_const_unstable]into#[rustc_const_stable]will never change the way the function is const-checked. Currently, we often discover in the const stabilization PR that a function needs some other unstable const things, and then we rush to quickly deal with that. In this alternative universe, we'd work towards getting rid of therustc_const_not_exposed_on_stablebefore stabilization, and once that is done stabilization becomes a trivial matter.#[rustc_const_stable_indirect]would then only be used for intrinsics.I think I like this idea, but might want to do it in a follow-up PR, as it will need a whole bunch of annotations in the standard library. Also, we probably want to convert all const intrinsics to the "new" form (
#[rustc_intrinsic]instead of anexternblock) before doing this to avoid having to deal with two different ways of declaring intrinsics.Cc @rust-lang/wg-const-eval @rust-lang/libs-api
Part of #129815 (but not finished since this is not yet sufficient to safely let us expose
const fnfrom hashbrown)Fixes #131073 by making it so that const-stable functions are always stable
try-job: test-various