Skip to content

If Foo<'a,'b> requires 'a <= 'b, need to infer (or provide easy way to express) constraint #13703

Closed
@pnkfelix

Description

@pnkfelix

Forked off from #10396 comment

Consider this code:

pub struct Foo<'a, 'b> { foo: &'a &'b int }

#[cfg(works)]
pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&'a &'b ()>) { let _y = x.foo; }
#[cfg(not(works))]
pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }

fn main() {}

I spoke with @eddyb and pointed him at regions-variance-covariant-use-contravariant.rs to illustrate that we do infer 'a <= 'b from the existence of &'a &'b T.

The fact that the code above does not compile as-is is interesting. I cannot tell if that is actually related to #10396 or not. (That's why I am filing this separate ticket.)

In particular, the constraints are generated by immediate occurrences of &'a &'b T, but not by occurrences of Foo<'a,'b> (despite Foo having a field of type &'a &'b T within it).

There are a couple different approaches to resolving this. The one with least user impact is probably to make occurrences of Foo<'a,'b> (when defined as above) also generate the constraint 'a <= 'b.


For completeness (and to save others the trouble of running rustc themselves on the above test case) here is the compile failure you get today if you attempt to compile the code above without --cfg works:

/tmp/lifetime.rs:6:66: 6:68 error: in type `&'a &'b int`, pointer has a longer lifetime than the data it references
/tmp/lifetime.rs:6 pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }
                                                                                    ^~
/tmp/lifetime.rs:6:60: 6:79 note: the pointer is valid for the lifetime &'a  as defined on the block at 6:59
/tmp/lifetime.rs:6 pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }
                                                                              ^~~~~~~~~~~~~~~~~~~
/tmp/lifetime.rs:6:60: 6:79 note: but the referenced data is only valid for the lifetime &'b  as defined on the block at 6:59
/tmp/lifetime.rs:6 pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<&   &   ()>) { let _y = x.foo; }
                                                                              ^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions