Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: "You’ll also need explicit lifetimes when working with structs" :o #29742

Closed
ghost opened this issue Nov 10, 2015 · 3 comments
Closed

Comments

@ghost
Copy link

ghost commented Nov 10, 2015

You’ll also need explicit lifetimes when working with structs:
from here: https://doc.rust-lang.org/nightly/book/lifetimes.html#in-structs

That seems to say that you always need explicit lifetimes when working with structs, but, that's not true, is it? A quick peek ahead at structs, and lifetimes seem to be implicit there: https://doc.rust-lang.org/nightly/book/structs.html

This As you can see, structs can also have lifetimes. also made me realize I'm misinterpreting the above sentence.

EDIT: Ok but now I'm not sure again, there's that need again:
So why do we need a lifetime here? We need to ensure that any reference to a Foo cannot outlive the reference to an i32 it contains.

@eddyb
Copy link
Member

eddyb commented Nov 10, 2015

I'm not sure, that entire chapter seems lacking.

"structs can also have lifetimes" but they don't, they can have lifetime parameters, which are just like type parameters, except lifetimes instead of types.

struct values have lifetimes (in the other sense, of "liveness"), which new users may confuse with the lifetime parameters of a struct.

@eddyb eddyb added the A-docs label Nov 10, 2015
@ghost
Copy link
Author

ghost commented Nov 10, 2015

I've just realized that lifetime specifier is required when using & in the field there:

struct Foo<'a> {
    x: &'a i32,
}

I guess that sentence isn't completely false after all.

So, this won't work:

struct Foo2 {
    x: &i32,                                                                    
}
src/main.rs:6:8: 6:12 error: missing lifetime specifier [E0106]
src/main.rs:6     x: &i32,
                     ^~~~
src/main.rs:6:8: 6:12 help: run `rustc --explain E0106` to see a detailed explanation
error: aborting due to previous error

but this will:

struct Foo2 {
      x: i32,                                                                   
  }

For completion:

$ rustc --explain E0106
!! executing '/home/zazdxscf/build/1nonpkgs/rust/rust//x86_64-unknown-linux-gnu/stage1/bin//rustc' with args: '--explain E0106'
This error indicates that a lifetime is missing from a type. If it is an error
inside a function signature, the problem may be with failing to adhere to the
lifetime elision rules (see below).

Here are some simple examples of where you'll run into this error:
struct Foo { x: &bool }        // error
struct Foo<'a> { x: &'a bool } // correct

enum Bar { A(u8), B(&bool), }        // error
enum Bar<'a> { A(u8), B(&'a bool), } // correct

type MyStr = &str;        // error
type MyStr<'a> = &'a str; // correct
Lifetime elision is a special, limited kind of inference for lifetimes in
function signatures which allows you to leave out lifetimes in certain cases.
For more background on lifetime elision see [the book][book-le].

The lifetime elision rules require that any function signature with an elided
output lifetime must either have

 - exactly one input lifetime
 - or, multiple input lifetimes, but the function must also be a method with a
   `&self` or `&mut self` receiver

In the first case, the output lifetime is inferred to be the same as the unique
input lifetime. In the second case, the lifetime is instead inferred to be the
same as the lifetime on `&self` or `&mut self`.

Here are some examples of elision errors:

// error, no input lifetimes
fn foo() -> &str { ... }

// error, `x` and `y` have distinct lifetimes inferred
fn bar(x: &str, y: &str) -> &str { ... }

// error, `y`'s lifetime is inferred to be distinct from `x`'s
fn baz<'a>(x: &'a str, y: &str) -> &str { ... }
[book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision

@durka
Copy link
Contributor

durka commented Nov 11, 2015

Lifetime parameters for structs are never implicit. But some structs have no lifetime parameters.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants