-
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
Add const_eval_select
intrinsic
#89247
Conversation
Some changes occured to the CTFE / Miri engine cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
b970740
to
2c0d4ac
Compare
cc @rust-lang/wg-const-eval |
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 would like to see some tests that hit the invalid use cases that typeck is catching and thus report errors. While it is not important for intrinsics, it's still good to check that they aren't completely bonkers
Alternative design idea #89291: have a pub fn call_if_rt<R, F: FnOnce() -> R + Copy>(f: F) -> Option<R>; that returns Pro:
const fn some_const_fn() {
if let Some(ret) = call_if_rt(|| {
// runtime part
}) {
return ret;
}
// const part
} Con:
|
Came up with a new idea while writing the above comment: How about have two functions pub fn is_const_eval() -> bool; and pub fn call_at_rt<R, F: FnOnce() -> R>(f: F) -> R; which will just call This should have the same pro as const fn some_const_fn() {
if !is_const_eval() {
return call_at_rt(|| {
// runtime part
});
}
// const part
} while it could still handle move. |
Seems a bit annoying to have two intrinsics. Also, const-check special handling will still be required to not subject the closure called by Why does this PR require such large typeck changes in the first place? |
Closure isn't considered const, so no changes are needed for that regard: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=2085fb30e0a126f84b16b1744901a0f7 |
Both cannot handle move, which can be a limitation, and I think that we shouldn't allow closures to be used in const contexts like this. There could be hidden problems. Therefore this might be the best and the most straightforward solution we have. I wouldn't consider being able to write them in one function a pro, IMO I think we should make this intrinsic a little bit intentionally complex and hard to use. |
This comment has been minimized.
This comment has been minimized.
Could we pick the API of this PR, but still use the lang item solution? So #[lang = "const_eval_select"]
pub fn const_eval_select<R, F: FnOnce() -> R, G: const FnOnce() -> R>(f: F) -> R {
f()
} Then the typeck change could be just checking that F and G are function items, while leaving all the rest (signature, constness, ..) to the regular typeck logic? This would avoid touching codegen backends entirely. |
#88963 would be needed first.
I don't think function item check would be necessary then. |
🙈 I thought I r+ed that already... Only allowing function items, in order to make it very explicit what is going on still stands, but it could "simply" be circumvented via |
843b469
to
d9163ae
Compare
This comment has been minimized.
This comment has been minimized.
d9163ae
to
98f8c76
Compare
This comment has been minimized.
This comment has been minimized.
98f8c76
to
5387b65
Compare
r=me with CI passing |
@bors r=oli-obk |
📌 Commit 11fac09 has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (c34ac87): comparison url. Summary: This benchmark run did not return any relevant changes. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression |
This commit re-enables the debug checks for valid usages of the two functions `copy()` and `copy_nonoverlapping()`. Those checks were com- mented out in rust-lang#79684 in order to make the functions const. All that's been left was a FIXME, that could not be resolved until there is was way to only do the checks at runtime. Since rust-lang#89247 there is such a way: `const_eval_select()`. This commit uses that new intrinsic in order to either do nothing (at compile time) or to do the old checks (at runtime). The change itself is rather small: in order to make the checks usable with `const_eval_select`, they are moved into a local function (one for `copy` and one for `copy_nonoverlapping` to keep symmetry). The change does not break referential transparency, as there is nothing you can do at compile time, which you cannot do on runtime without get- ting undefined behavior. The CTFE-engine won't allow missuses. The other way round is also fine.
…acrum Re-enable `copy[_nonoverlapping]()` debug-checks This commit re-enables the debug checks for valid usages of the two functions `copy()` and `copy_nonoverlapping()`. Those checks were commented out in rust-lang#79684 in order to make the functions const. All that's been left was a FIXME, that could not be resolved until there is was way to only do the checks at runtime. Since rust-lang#89247 there is such a way: `const_eval_select()`. This commit uses that new intrinsic in order to either do nothing (at compile time) or to do the old checks (at runtime). The change itself is rather small: in order to make the checks usable with `const_eval_select`, they are moved into a local function (one for `copy` and one for `copy_nonoverlapping` to keep symmetry). The change does not break referential transparency, as there is nothing you can do at compile time, which you cannot do on runtime without getting undefined behavior. The CTFE-engine won't allow missuses. The other way round is also fine. I've refactored the code to use `#[cfg(debug_assertions)]` on the new items. If that is not desired, the second commit can be dropped. I haven't added any checks, as I currently don't know, how to test this properly. Closes rust-lang#90012. cc `@rust-lang/lang,` `@rust-lang/libs` and `@rust-lang/wg-const-eval` (as those teams are linked in the issue above).
Adds an intrinsic that calls a given function when evaluated at compiler time, but generates a call to another function when called at runtime.
See rust-lang/const-eval#7 for previous discussion.
r? @oli-obk.