Skip to content
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

Lifetime error when using nested views #387

Closed
jafioti opened this issue Mar 16, 2022 · 5 comments
Closed

Lifetime error when using nested views #387

jafioti opened this issue Mar 16, 2022 · 5 comments
Labels
A-reactivity Area: reactivity and state handling

Comments

@jafioti
Copy link

jafioti commented Mar 16, 2022

When using nested views and an action callback, a lifetime error is thrown.

Steps to reproduce the behavior:
Open any sycamore project and paste:

#[component]
pub fn TempComponent<G: Html>(ctx: Scope) -> View<G> {
    let action = |_| ctx.spawn_local(async move {});
    view!{ctx, 
        ({
            view!{ctx, 
                input (on:click=action)
            }
        })
    }
}

Expected that no lifetime error is thrown since this is valid code.

  • Sycamore: master
@jafioti jafioti added the C-bug Category: bug, something isn't working label Mar 16, 2022
@lukechu10
Copy link
Collaborator

This regression was introduced by 9fdff59 because it adds an addition create_effect_scoped call.

Unfortunately, this change is necessary to prevent memory leaks and it seems like it interferes with Rust's borrow checker. I suspect it has something to do with the invariance of the lifetime parameter on Scope because accessing a signal or other from inside the closure works.

In other words, the following works:

#[component]
pub fn TempComponent<G: Html>(ctx: Scope) -> View<G> {
    let action = |_| {
        ctx.create_signal(0);
    };
    view!{ ctx, 
        ({
            view!{ ctx, 
                input (on:click=action)
            }
        })
    }
}

I'm guessing because &'a Signal<i32> is covariant over 'a.

If somebody can figure this out, that would be greatly appreciated!

@lukechu10
Copy link
Collaborator

But for your specific use case, since the interpolated value is not actually reactive, you can just create the inner view outside of the outer view like so:

#[component]
pub fn TempComponent<G: Html>(ctx: Scope) -> View<G> {
    let action = |_| ctx.spawn_local(async move {});
    let inner = view!{ ctx, 
        input (on:click=action)
    };
    view!{ ctx, 
        (inner)
    }
}

@lukechu10 lukechu10 added A-reactivity Area: reactivity and state handling and removed C-bug Category: bug, something isn't working labels Mar 20, 2022
@lukechu10
Copy link
Collaborator

Eureka! This is because of rustc non-lexical-lifetimes "migration mode". If you add #![feature(nll)] with nightly toolchain, the issue is fixed!

@lukechu10
Copy link
Collaborator

Rust tracking issue for turning off nll migration mode: rust-lang/rust#58781

@lukechu10 lukechu10 added the S-blocked-upstream Waiting on issue in upstream label Jul 2, 2022
@lukechu10 lukechu10 removed the S-blocked-upstream Waiting on issue in upstream label Sep 20, 2022
@lukechu10
Copy link
Collaborator

Release v0.8 now relies on nll mode so I will close this issue. Please create a new issue if your problem is not resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-reactivity Area: reactivity and state handling
Projects
None yet
Development

No branches or pull requests

2 participants