-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Contract cannot be applied to const
functions
#136925
Comments
@rustbot labels +F-contracts |
@rustbot claim |
I don't expect this to be fixable anytime soon, since it relies on const closures which are not even coherently designed yet. |
This might require some design changes |
One possible workaround would be to remove the default body of the contract intrinsics, and implement them in the backend. In that case, contracts would not be checkable during constant evaluation. I'll see if I can think about other ways to fix this. |
I think I found a better work around. We could use
So we should track these limitations and solve them before stabilization. @tautschnig @compiler-errors does this solution sound reasonable for now? |
So, You can't pass closures to them until that functionality is specifically implemented in the compiler, which is blocked on constifying the |
And I don't think contracts can use the |
At least that's my understanding. You're welcome to try, though, but I'd rather not commit to hacks here, and perhaps go back to the drawing board. |
The idea would be to apply the pub const fn contract_check_requires<C: Fn() -> bool + Copy>(cond: C) {
const_eval_select!(
@capture[C: Fn() -> bool + Copy] { cond: C } :
if const {
// Do nothing
} else {
if contract_checks() && !cond() {
// Emit no unwind panic in case this was a safety requirement.
crate::panicking::panic_nounwind("failed requires check");
}
}
)
} The AST lowering injects a call to the intrinsic. |
Well the problem is that |
Sure... but I believe we can change that. Let me get something working, and see how that looks. BTW, I'm not opposed to rethinking the implementation. I think we can solve this issue now with |
I don't see how that approach (via fn foo() {
let _check = build_check_ensures(PRED);
... [return _check(R);] ...
} That means the transformed code makes fundamental use of closures, which are fundamentally not supported in |
Ah there's a PR for it already, interesting. It wasn't referenced anywhere in this issue so there's no way I could have known this.^^ |
My bad, I just linked them a few minutes ago |
I tried this code (minimal reproducer extracted from #136578):
I expected to see this happen: compilation would succeed
Instead, this happened: compiler rejected the code with the following errors:
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: