Skip to content

Can derive be smarter about lifetime parameters? #27950

Closed
@solson

Description

@solson

briansmith on IRC ran into trouble using #[derive(PartialEq)] on a struct with a lifetime parameter. See the code at http://is.gd/R6Jx2x which fails with:

<anon>:8:59: 8:65 error: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
<anon>:8 fn doesnt_work_with_derived(x: Input, y: Input) -> bool { x == y }
                                                                   ^~~~~~
<anon>:8:1: 8:67 help: consider using an explicit lifetime parameter as shown: fn doesnt_work_with_derived<'a>(x: Input<'a>, y: Input<'a>) -> bool
<anon>:8 fn doesnt_work_with_derived(x: Input, y: Input) -> bool { x == y }
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Even though a similar function working directly with byte slices is fine with the lifetime parameters differing. Following the error message's suggestion works, but forces explicit lifetimes where one would expect elision to work (as it does with the byte slices).

The issue is shown in the expanded code from derive pasted below. It's because the Rhs type for the impl defaults to Self, which is Input<'a>, which strictly requires the exact same lifetime.

Below that, I wrote a modified version of the derived impl showing what we wanted to be generated. It introduces a new lifetime parameter on the impl for each lifetime parameter on the original struct and sets Rhs to be the same type as Self except with those lifetime parameters substituted. (In this case, just 'a replaced with 'b.) This actually works: http://is.gd/1GjWDD

So, can derive do this (seemingly) simple transformation for types with lifetime parameters? Can someone with more experience chip in and explain why this would go horribly wrong? :P

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-syntaxextArea: Syntax extensions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions