#Using SpawnIter results in E0521: borrowed data escapes outside of function

1 messages · Page 1 of 1 (latest)

frank prawn
#

Hey all, I'm a hobby game developer and new to rust (I have only ever used it for Bevy). I took inspiration from the official Bevy examples to create a main menu using SpawnIter. However, I wanted extract the closures into their own functions. So I created create_button_bundle , which uses SpawnIter to iterate over a list of ButtonInfos and calls create_menu_bundle for each element.

However, this leads to the lifetime error below. The passed in ButtonInfo has shorter lifetime than static, but I don't see why it needs to have static lifetime. The information in each ButtonInfo is cloned into the Bundle, so how is the data escaping create_menu_bundle? The suggested fix from rustc --explain E0521 is to not type annotate my closures, but I am not using closures.

Any tips, either to fix this issue, or to restructure my code, would be appreciated.

   --> src/main.rs:100:17
    |
82  |       button_infos: &[ButtonInfo],
    |       ------------  - let's call the lifetime of this reference `'1`
    |       |
    |       `button_infos` is a reference that is only valid in the function body
...
100 | /                 Children::spawn(SpawnIter(
101 | |                     button_infos.into_iter().map(create_button_bundle)
102 | |                 )),
    | |                  ^
    | |                  |
    | |__________________`button_infos` escapes the function body here
    |                    argument requires that `'1` must outlive `'static`

For more information about this error, try `rustc --explain E0521`.
royal bane
#
fn create_button_bundle(
    button_info: &ButtonInfo
) -> impl Bundle + use<>
frank prawn
#

That doesn't seem to make a difference for me

royal bane
#

did you put only on the one that i sent or on all of the -> impl Bundle?

frank prawn
#

Oh, I just updated the one in create_button_bundle. Adding it to create_menu_bundle gives me an error saying I must declare all the type parameters used, so I do

fn create_menu_bundle<T: Component>(
    menu_tag: T,
    button_infos: &[ButtonInfo],
) -> impl Bundle + use<T>

which removes the new error, but I still have the old error.

royal bane
#

the you probably need to pass Vec<ButtonInfo> instead of &[ButtonInfo]

frank prawn
#

That works, but why? Is it because create_menu_bundle now takes ownership? Why would that change the lifetime of the data?

royal bane
#

SpawnIter is lazy, it will only run after the system ends, so it can't hold references

frank prawn
#

Oh yeah, I also had to change .map(create_button_bundle) to map(|button_info| {return create_button_bundle(&button_info);}), for anyone having this issue later.

frank prawn
#

Is there a non-lazy SpawnIter?

royal bane
silk vale