Skip to content

Compile failure when trying to use as a Future #26

@WorldSEnder

Description

@WorldSEnder

Just trying to upgrade my project to a new rust version, and it seems that there are some more rough edges with Precise capturing in the 2024 edition. Specifically,

stacklover::define_struct! {
    Foo,
    fn () -> impl Future<Output = i32> {
        async { 4 }
    },
    impls = (Send, Sync),
}

leads to an error

error[E0308]: mismatched types
    --> src/main.rs:4:1
     |
4    | / stacklover::define_struct! {
5    | |     Foo,
6    | |     fn () -> impl Future<Output = i32> {
     | |              -------------------------
     | |              |
     | |              the expected future
     | |              the found future
7    | |         async { 4 }
8    | |     },
9    | |     impls = (Send, Sync),
10   | | }
     | |_^ one type is more general than the other
     |
     = note: expected mutable reference `&mut impl for<'a> Future<Output = i32>`
                found mutable reference `&mut impl Future<Output = i32>`

to prevent this, one should always use the following form when using an impl return type and add an empty use<> clause:

stacklover::define_struct! {
    Foo,
    fn () -> impl Future<Output = i32> + use<> {
                                      // ^^^^^
        async { 4 }
    },
    impls = (Send, Sync),
}

which will make the above definition work. Not sure if this deserves to be linted for by the macro, but the documentation should perhaps reflect this.

The reason is that all methods returning a (mutable) borrow implicitly capture the lifetime of self if such a use clause is not present, which is too restrictive (the existential type lives for 'static). Not sure how previous rust editions behaved, exactly, to allow this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions