-1

The following won't compile:

struct Person<'z> {
    street_address: String,
    postcode: String,
    city: String,

    company_name: String,
    position: String,
    annual_income: usize,
}

struct PersonBuilder<'z> {
    person: &'z Person<'z>,
}

impl<'z> PersonBuilder<'z> {
    fn new() -> PersonBuilder<'z> {
        PersonBuilder {
            person: Person {
                street_address: "".to_string(),
                postcode: "".to_string(),
                city: "".to_string(),
                company_name: "".to_string(),
                position: "".to_string(),
                annual_income: 0,
            },
        }
    }
}
error[E0392]: parameter `'z` is never used
 --> src/main.rs:1:15
  |
1 | struct Person<'z> {
  |               ^^ unused type parameter
  |
  = help: consider removing `'z` or using a marker such as `std::marker::PhantomData`

But that's not true, is it? I mean, PersonBuilder keeps a reference to a person as Person<'z> and when I instantiate it with PersonBuilder::new(), clearly the type parameter is in play to tie the two lifetimes together. So what's going on here?

Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166

1 Answers1

5

The compiler is completely correct here; 'z is not used on Person. Remove it from Person and from PersonBuilder:

struct Person { /* ... */ }

struct PersonBuilder<'z> {
    person: &'z Person,
}

One you remove that, what you are trying to do is impossible. See Is there any way to return a reference to a variable created in a function?. Remove all lifetimes and references from your code and it will work.


PersonBuilder keeps a reference to a person

Yes, that's what &Person would be.

as Person<'z>

Person<'z> indicates that the Person struct contains a reference of the specified lifetime. &'z Person is a reference to a person with the specified lifetime.

instantiate it with PersonBuilder::new(), clearly the type parameter

Which "type parameter" are you referring to, as I don't see any in this code. While it's true that lifetimes and type parameters are both kinds of generics, they are different kinds of generics and are not treated the same.


You may also be interested in the Default trait:

#[derive(Debug, Default)]
struct Person { /* ... */ }

impl PersonBuilder {
    fn new() -> PersonBuilder {
        PersonBuilder {
            person: Person::default(),
        }
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I tried removing the lifetime, but then other parts break. Self-contained example here: https://gist.github.com/nesteruk/8b6e967affbd27e6c099f20be18d157a – Dmitri Nesteruk Jul 24 '17 at 12:56
  • @DmitriNesteruk please go back and re-read my answer. My **third** and **fourth** sentences explain that error: *One you remove that, what you are trying to do is impossible. See [Is there any way to return a reference to a variable created in a function?](https://stackoverflow.com/q/32682876/155423).* Then my **fifth** sentence explains how to fix it: *Remove all lifetimes and references from your code and it will work.* – Shepmaster Jul 24 '17 at 13:00
  • that, by itself, did not help: https://gist.github.com/nesteruk/d1fcfbd8d9fbedce27a478a26a8d65cf – Dmitri Nesteruk Jul 24 '17 at 13:17