@ -5,12 +5,12 @@ However, a naive implementation of lifetimes would be either too restrictive,
or permit undefined behavior.
or permit undefined behavior.
In order to allow flexible usage of lifetimes
In order to allow flexible usage of lifetimes
while also preventing their misuse, Rust uses a combination of **Subtyping** and **Variance**.
while also preventing their misuse, Rust uses **subtyping** and **variance**.
Let's start with a example.
Let's start with an example.
```rust
```rust
fn debug<T:std::fmt::Debug>(a: T, b: T) {
fn debug<'a>(a: &'a str, b: &'a str) {
println!("a = {:?} b = {:?}", a, b);
println!("a = {:?} b = {:?}", a, b);
}
}
@ -18,13 +18,13 @@ fn main() {
let hello: &'static str = "hello";
let hello: &'static str = "hello";
{
{
let world = String::from("world");
let world = String::from("world");
let world = &world; // 'b has a shorter lifetime than 'static
let world = &world; // 'world has a shorter lifetime than 'static
debug(hello, world);
debug(hello, world);
}
}
}
}
```
```
In a conservative implementation of lifetimes, since `a` and `b` have differeing lifetimes,
In a conservative implementation of lifetimes, since `hello` and `world` have differing lifetimes,
we might see the following error:
we might see the following error:
```text
```text
@ -34,23 +34,25 @@ error[E0308]: mismatched types
10 | debug(hello, world);
10 | debug(hello, world);
| ^
| ^
| |
| |
| expected `&'static str`, found struct `&'b str`
| expected `&'static str`, found struct `&'world str`
```
```
This would be rather unfortunate. In this case,
This would be rather unfortunate. In this case,
what we want is to accept any type that lives *at least as long* as `'b`.
what we want is to accept any type that lives *at least as long* as `'world`.
Let's try using subtyping with our lifetimes.
Let's try using subtyping with our lifetimes.
## Subtyping
## Subtyping
Subtyping is the idea that one type can be used in place of another.
Subtyping is the idea that one type can be used in place of another.
Let's define that `Sub` is a subtype of `Super` (we'll be using the notation `Sub: Super` throughout this chapter)
Let's define that `Sub` is a subtype of `Super` (we'll be using the notation `Sub: Super` throughout this chapter).
What this is suggesting to us is that the set of *requirements* that `Super` defines
What this is suggesting to us is that the set of *requirements* that `Super` defines
are completely satisfied by `Sub`. `Sub` may then have more requirements.
are completely satisfied by `Sub`. `Sub` may then have more requirements.
An example of simple subtyping that exists in the language are [supertraits](https://doc.rust-lang.org/stable/book/ch19-03-advanced-traits.html?highlight=supertraits#using-supertraits-to-require-one-traits-functionality-within-another-trait)
An example of simple subtyping that exists in the language is [supertraits][supertraits]: