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

Hierarchic anonymous life-time #2949

Closed
wants to merge 12 commits into from
151 changes: 151 additions & 0 deletions text/0000-hierarchic-anonymous-life-time.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
- Feature Name: Hierarchic anonymous life-time
- Start Date: 2020-06-24
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)

# Summary

New use of anonymous life-time `'_` that implicitly added to current structure.

# Motivation

Motivation is to simplify iterative development and improving refactoring of the code

Sometimes during refactoring such code:
```rust
struct City {
name: String,
}

struct State {
city: Vec<City>,
covid_deaths: u32,
}

struct Country {
state: Vec<State>,
}
```

developer decides to make an inner item a reference:
```rust
struct City<'a> {
name: &'a str,
}

struct State<'a> {
city: Vec<City<'a>>,
covid_deaths: u32,
}

struct Country<'a> {
state: Vec<State<'a>>,
}
```
Everywhere in composition hierarchy I need to write 'a ... most of the times it is just boilerplate code ...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Everywhere in composition hierarchy I need to write 'a ... most of the times it is just boilerplate code ...
The developer need to write `'a` throughout the hierarchy.


What if instead of writing manually we will specify reference fields with anonymous life-time:
```rust
struct City& {
name: &str,
}

struct State& {
cities: Vec<City&>,
covid_deaths: u32,
}

struct Country& {
state: Vec<State&>,
}
```

With this solution developer could just declar with `<type_name>["&"]` name that this structure could have used some references, just be attentive
Developer just could anons that this structure will use references some times without even using references inside:
```rust
struct City& {
name: String,
}

struct State& {
cities: Vec<City&>,
covid_deaths: u32,
}

struct Country& {
state: Vec<State&>,
}
```

Compiler underhood will generate the following code:
```rust
struct City&<'anon> { // 'anon is implicitly added life-time
obj: &'anon str,
}

struct State&<'anon> { // 'anon is implicitly added life-time
composite_obj: Vec<City&<'anon>>, // 'anon is implicitly used here
covid_deaths: i32,
}

struct Country&<'anon> { // 'anon is implicitly added life-time
state: Vec<State&>, // 'anon is implicitly used here
}
```

Take a look at example with multiple anonymose life-times:
```rust
struct CompositeObject {
obj0: &'_ SomeType,
obj1: &'_ SomeType,
}
Comment on lines +98 to +101
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct CompositeObject {
obj0: &'_ SomeType,
obj1: &'_ SomeType,
}
struct CompositeObject<'_> {
obj0: &SomeType,
obj1: &SomeType,
}

Hidden lifetimes are deprecated, you also don't ever want '_ on references, as that's implied.

Copy link
Author

@redradist redradist Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CryZe
Why they deprecated ?

What if the obj0 and obj1 would have different life-times ? How it will work with single anonymous life-time in declaration ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@redradist Why not? Both of them could depend on the same lifetime and life as long as each other.

Copy link
Author

@redradist redradist Jun 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@redradist Why not? Both of them could depend on the same lifetime and life as long as each other.

@pickfire But what would be semantic of struct CompositeObject<'_> ? Does '_ mean one life-time or it mean several different life-times ? What if obj0 and obj1 has different life-times ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true even though it is uncommon.


struct BigObject {
composite_obj: CompositeObject,
count: i32,
}

struct Application {
big_obj: BigObject,
}
```
code will be translated to:
```rust
struct CompositeObject<'anon0, 'anon1> { // 'anon0 and 'anon1 are implicitly added life-times
obj0: &'anon0 SomeType,
obj1: &'anon1 SomeType,
}

struct BigObject<'anon0, 'anon1> { // 'anon is implicitly added life-time
composite_obj: CompositeObject<'anon0, 'anon1>, // 'anon is implicitly used here
count: i32,
}

struct Application<'anon0, 'anon1> { // 'anon is implicitly added life-time
big_obj: BigObject<'anon0, 'anon1>, // 'anon is implicitly used here
}
```

On user side call should be like this:
```rust
fn make_app(config: &Config) -> Application;
```
or
```rust
fn make_app(config: &Config) -> Application<'_>;
```

# Drawbacks
[drawbacks]: #drawbacks

Not known at the current time

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several drawbacks mentioned in the corresponding thread on IRLO and the comments on this PR. It would be helpful to list them here to get a better overview.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pythoneer I will add ;)


# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

This design will help developers to iteravly play with library design, which should increase qualitty of the final library or application

# Prior art
[prior-art]: #prior-art

There was disscutions on this topic in https://internals.rust-lang.org/t/simplification-reference-life-time/12224/20