#Fixing error E0521 - borrowed data escapes function

60 messages · Page 1 of 1 (latest)

fresh lava
#

I am using the iced graphics library, and upon updating the version of iced I'm using, I get a new error. The following code errors, and is immediately just added into my full ui component and then returned from the Application::view function:

let bottom_bar: Container<Message> = container(row()
    .spacing(2)
    .push_space(4)
    .push(update_state)
    .push_space(Length::Fill)
    .push(col_slider_reset)
    .push(col_slider)
    .push(slider_text)
    .push(toggle_style)
    .height(Length::Units(20))
    .align_items(Alignment::Center)
).style(style.settings_bar())
    .align_y(Vertical::Center);

The error is as follows:

error[E0521]: borrowed data escapes outside of associated function
   --> src\main.rs:953:46
    |
895 |       fn view<'a>(&'a self) -> Element<'a, Self::Message> {
    |               --  -------- `self` is a reference that is only valid in the associated function body
    |               |
    |               lifetime `'a` defined here
...
953 |           let bottom_bar: Container<Message> = container(row()
    |  ______________________________________________^
954 | |             .spacing(2)
955 | |             .push_space(4)
956 | |             .push(update_state)
...   |
963 | |             .align_items(Alignment::Center)
964 | |         ).style(style.settings_bar())
    | |         ^
    | |         |
    | |_________`self` escapes the associated function body here
    |           argument requires that `'a` must outlive `'static`

Looking at E0521 (https://doc.rust-lang.org/error-index.html#E0521), it seems to be an error about closures, and the fix shown is to remove a lifetime parameter from the closure, but my code isn't in a closure, and I can't remove the type from the function since its a function.

I also don't quite understand what it means that self escapes the function body, as this isn't a lifetime error I've seen/dealt with before.

Any ideas how to fix this error?

covert nymph
#

I don't know iced or exactly what's going on here, but I can say that by writing
... <'a>(&'a self) -> Element<'a, ...
you're specifying that the returned Element is a borrow of self.

#

and then something else (I don't know what) is specifying that that borrow must be 'static instead

#

it is possible that you should be writing -> Element<'static, Self::Message> instead

fresh lava
#

I can re-elide the lifetimes, I just put in the 'a to get a more clear error, otherwise it gives it the default name '1

covert nymph
#

the elided lifetime is the same as your 'a in this case

fresh lava
#

yeah

covert nymph
#

is this fn view() in a trait implementation?

fresh lava
#

I don't think I can make it 'static, cuz its implementing iced::pure::Application

covert nymph
#

and what is that trait?

#

docs link, preferably

fresh lava
#

oh turns out I can make it Element<'static, Message>, but I get the same error

covert nymph
#

when you're implementing a trait, you can't arbitrarily change the signature. It has to be equivalent to the trait's

#

okay, so your original decl is fine

#

I don't follow what the error message is actually trying to tell you, sorry

fresh lava
#

yeah :(

fresh lava
covert nymph
#

what is container() ?

covert nymph
covert nymph
#

oh

#

let bottom_bar: Container<Message> =
try
let bottom_bar: Container<'a, Message> =
and see what happens

fresh lava
#
error: lifetime may not live long enough
   --> src\main.rs:953:25
    |
895 |     fn view<'a>(&'a self) -> Element<'a, Self::Message> {
    |             -- lifetime `'a` defined here
...
953 |         let bottom_bar: Container<'a, Message> = container(row()
    |                         ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
#

let me check to make sure none of the ui components I'm pushing specify 'static lifetime, don't think they should but idk

covert nymph
#

well, the annotation change is at least an improvement in the sense that it's narrowing down where the problem is and "should" work if the code is possible at all

fresh lava
#

ok I've narrowed down the error I think:

#
let toggle_style: Button<'a, _> = button(
            text(iced_aw::Icon::BrightnessHigh)
                .font(ICON_FONT)
                .size(12),
        ).style(style.settings_bar())
            .on_press(Message::ToggleTheme);
#
error: lifetime may not live long enough
   --> src\main.rs:943:27
    |
895 |     fn view<'a>(&'a self) -> Element<'a, Self::Message> {
    |             -- lifetime `'a` defined here
...
943 |         let toggle_style: Button<'a, _> = button(
    |                           ^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
covert nymph
#

hm

#

well

#

in any case, I would suggest adding #[warn(elided_lifetimes_in_paths)] to your code, and then fixing all the warnings that result

#

that will ensure you always write out lifetimes for types that borrow things

#

(you can use '_ instead of eliding in a particular case)

fresh lava
#

didn't do anything to fix the error unfortunately

#

altho I've narrowed it to specifically making the text into an element:

#
error: lifetime may not live long enough
   --> src\main.rs:945:20
    |
897 |     fn view<'a>(&'a self) -> Element<'a, Self::Message> {
    |             -- lifetime `'a` defined here
...
945 |         let text1: Element<'a, _> = text(iced_aw::Icon::BrightnessHigh)
    |                    ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
#
let text1: Element<'a, _> = text(iced_aw::Icon::BrightnessHigh)
            .font(ICON_FONT)
            .size(12)
            .into();
#

even tho that into is implemented by iced:

#
impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>>
    for Text<Renderer>
where
    Renderer: text::Renderer + 'a,
{
    fn into(self) -> Element<'a, Message, Renderer> {
        Element::new(self)
    }
}
covert nymph
#

I think you need someone who knows "how iced is meant to be used" to solve this further

fresh lava
#

mmm

fresh lava
#

what does the

let text1: Element<'a, _> = text(iced_aw::Icon::BrightnessHigh)
    |      ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` 

mean in general?

#

I don't understand why that type annotation gives that requirement to 'a

covert nymph
#

I think it's saying it backwards relative to what you're interested in

#
  1. somehow, something requires text1 to be valid for 'static
  2. therefore if its type contains 'a, 'a must outlive (or more precisely, equal) 'static
#

can you quote the entire function?

fresh lava
#

ok I think I actually managed to fix it:

#

that text error was a complete red herring

#

in terms of where the error was actually coming from

#
let update_state = self.update_state.view(style.settings_bar());

where view is:

pub fn view<'s, 'c: 's>(&'s self, style: SettingsBarStyle) -> Container<'c, Message> {
#

does work, the lifetimes need to be specified like that exactly, can't let rust infer them or it 💥

#

although, in some of my other view functions, adding those bounds is not as easy 😭

#

but now its normal "lifetime may not live long enough" errors

#

aha!

#

got it!