Fails to compile after applying `no_panic`
- Dominant language
- Rust
- Stars
- 1.2k
- Forks
- 20
- PR merge metrics
- No merged PRs in 30d
Description
I have a function that looks [like this](https://github.com/nazar-pc/abundance/blob/6370d5c9ab00982ea9023c830696f575fcceac65/crates/contracts/system/ab-system-contract-simple-wallet-base/src/utils.rs#L15-L25):
```rust
pub fn initialize_state(env: &mut Env<'_>, public_key: &[u8; 32]) -> Result<(), ContractError> {
let state =
env.simple_wallet_base_initialize(Address::SYSTEM_SIMPLE_WALLET_BASE, public_key)?;
env.state_initialize(
MethodContext::Reset,
Address::SYSTEM_STATE,
&env.own_address(),
&VariableBytes::from_buffer(state.as_bytes(), &state.size()),
)
}
```
Adding this to it results in compilation error:
```
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
```
```
error[E0597]: `state` does not live long enough
--> crates/contracts/system/ab-system-contract-simple-wallet-base/src/utils.rs:24:37
|
15 | #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
| -
| |
| `state` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `impl Deref> + '_`
16 | pub fn initialize_state(env: &mut Env<'_>, public_key: &[u8; 32]) -> Result<(), ContractError> {
17 | let state =
| ----- binding `state` declared here
...
24 | &VariableBytes::from_buffer(state.as_bytes(), &state.size()),
| ---------------------------^^^^^---------------------------
| | |
| | borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
20 ~ let x = env.state_initialize(
21 | MethodContext::Reset,
...
24 | &VariableBytes::from_buffer(state.as_bytes(), &state.size()),
25 ~ ); x
|
```
Here is what it is being expanded to:
```
pub fn initialize_state(
mut env: &mut Env<'_>,
mut public_key: &[u8; 32],
) -> Result<(), ContractError> {
struct __NoPanic;
unsafe extern "C" {
#[link_name = "\n\nERROR[no-panic]: detected panic in function `initialize_state`\n"]
fn trigger() -> !;
}
impl ::core::ops::Drop for __NoPanic {
fn drop(&mut self) {
unsafe {
trigger();
}
}
}
let __guard = __NoPanic;
let __result = (move || -> Result<(), ContractError> {
let env = env;
let public_key = public_key;
let state = env
.simple_wallet_base_initialize(
Address::SYSTEM_SIMPLE_WALLET_BASE,
public_key,
)?;
env.state_initialize(
MethodContext::Reset,
Address::SYSTEM_STATE,
&env.own_address(),
&VariableBytes::from_buffer(state.as_bytes(), &state.size()),
)
})();
::core::mem::forget(__guard);
__result
}
```
Interestingly, simply wrapping function body with extra `{}` fixes compilation issue, so I think macro should be fixed to support this too.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.