Skip to content

Struct and variant constructors are not generic over lifetimes like regular functions. #30904

Open
@eddyb

Description

@eddyb

The following testcase produces the errors noted in comments and the last one is an ICE (run on playpen):

#![feature(fn_traits, unboxed_closures)]

fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}

struct Compose<F,G>(F,G);
impl<T,F,G> FnOnce<(T,)> for Compose<F,G>
where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> {
    type Output = G::Output;
    extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output {
        (self.1)((self.0)(x))
    }
}

struct Str<'a>(&'a str);
fn mk_str<'a>(s: &'a str) -> Str<'a> { Str(s) }

fn main() {
    let _: for<'a> fn(&'a str) -> Str<'a> = mk_str;
    // expected concrete lifetime, found bound lifetime parameter 'a
    let _: for<'a> fn(&'a str) -> Str<'a> = Str;

    test(|_: &str| {});
    test(mk_str);
    // expected concrete lifetime, found bound lifetime parameter 'x
    test(Str);

    test(Compose(|_: &str| {}, |_| {}));
    test(Compose(mk_str, |_| {}));
    // internal compiler error: cannot relate bound region:
    //   ReLateBound(DebruijnIndex { depth: 2 },
    //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65)))
    //<= ReSkolemized(0,
    //     BrNamed(DefId { krate: 0, node: DefIndex(6) => test::'x }, 'x(65)))
    test(Compose(Str, |_| {}));
}

The same errors occur if an enum Foo<'a> { Str(&'a str) } is used.

Usage of FnOnce<(T,)> is to avoid proving an explicit type parameter for the Output associated type, as an workaround for #30867.

Originally found in @asajeffrey's wasm repo (see my comment on asajeffrey/wasm#1).
cc @nikomatsakis @arielb1

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lifetimesArea: Lifetimes / regionsC-enhancementCategory: An issue proposing an enhancement or a PR with one.F-unboxed_closures`#![feature(unboxed_closures)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions