You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/subtyping.md
+44-34Lines changed: 44 additions & 34 deletions
Original file line number
Diff line number
Diff line change
@@ -7,34 +7,7 @@ or permit undefined behavior.
7
7
In order to allow flexible usage of lifetimes
8
8
while also preventing their misuse, Rust uses a combination of **Subtyping** and **Variance**.
9
9
10
-
## Subtyping
11
-
12
-
Subtyping is the idea that one type can be used in place of another.
13
-
14
-
Let's define that `Sub` is a subtype of `Super` (we'll be using the notation `Sub: Super` throughout this chapter)
15
-
16
-
What this is suggesting to us is that the set of *requirements* that `Super` defines
17
-
are completely satisfied by `Sub`. `Sub` may then have more requirements.
18
-
19
-
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)
20
-
21
-
```rust
22
-
usestd::fmt;
23
-
24
-
pubtraitError:fmt::Display {
25
-
fnsource(&self) ->Option<&(dynError+ 'static)>;
26
-
fndescription(&self) ->&str;
27
-
fncause(&self) ->Option<&dynError>;
28
-
}
29
-
```
30
-
31
-
Here, we have that `Error: fmt::Display` (`Error` is a *subtype* of `Display`),
32
-
because it has all the requirements of `fmt::Display`, plus the `source`/`description`/`cause` functions.
33
-
34
-
However, subtyping in traits is not that interesting in the case of Rust.
35
-
Here in the nomicon, we're going to focus more with how subtyping interacts with **lifetimes**
36
-
37
-
Take this example
10
+
Let's start with a example.
38
11
39
12
```rust
40
13
fndebug<T:std::fmt::Debug>(a:T, b:T) {
@@ -68,16 +41,53 @@ This would be rather unfortunate. In this case,
68
41
what we want is to accept any type that lives *at least as long* as `'b`.
69
42
Let's try using subtyping with our lifetimes.
70
43
71
-
Let's define a lifetime to have the a simple set of requirements:
44
+
## Subtyping
45
+
46
+
Subtyping is the idea that one type can be used in place of another.
47
+
48
+
Let's define that `Sub` is a subtype of `Super` (we'll be using the notation `Sub: Super` throughout this chapter)
49
+
50
+
What this is suggesting to us is that the set of *requirements* that `Super` defines
51
+
are completely satisfied by `Sub`. `Sub` may then have more requirements.
52
+
53
+
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)
54
+
55
+
```rust
56
+
usestd::fmt;
57
+
58
+
pubtraitError:fmt::Display {
59
+
fnsource(&self) ->Option<&(dynError+ 'static)>;
60
+
fndescription(&self) ->&str;
61
+
fncause(&self) ->Option<&dynError>;
62
+
}
63
+
```
64
+
65
+
Here, we have that `Error: fmt::Display` (`Error` is a *subtype* of `Display`),
66
+
because it has all the requirements of `fmt::Display`, plus the `source`/`description`/`cause` functions.
67
+
68
+
However, subtyping in traits is not that interesting.
69
+
Here in the nomicon, we're going to focus more with how subtyping interacts with lifetimes
70
+
71
+
Let's define a lifetime to be the simple requirement:
72
72
`'a` defines a region of code in which a value will be alive.
73
73
Now that we have a defined set of requirements for lifetimes, we can define how they relate to each other.
74
-
`'a: 'b` if and only if `'a` defines a region of code that **completely contains**`'b`.
74
+
`'long: 'short` if and only if `'long` defines a region of code that **completely contains**`'short`.
75
75
76
-
`'a` may define a region larger than `'b`, but that still fits our definition.
77
-
Going back to our example above, we can say that `'static: 'b`.
76
+
`'long` may define a region larger than `'short`, but that still fits our definition.
78
77
79
-
For now, let's accept the idea that subtypes of lifetimes can be passed through references (more on this in [Variance](#variance)),
80
-
eg. `&'static str` is a subtype of `&'b str`, then we can let them coerce, and then the example above will compile
78
+
> As we will see throughout the rest of this chapter,
79
+
subtyping is a lot more complicated and subtle than this,
80
+
but this simple rule is a very good 99% intuition.
81
+
And unless you write unsafe code, the compiler will automatically handle all the corner cases for you.
82
+
83
+
> But this is the Rustonomicon. We're writing unsafe code,
84
+
so we need to understand how this stuff really works, and how we can mess it up.
85
+
86
+
Going back to our example above, we can say that `'static: 'b`.
87
+
For now, let's also accept the idea that subtypes of lifetimes can be passed through references
88
+
(more on this in [Variance](#variance)),
89
+
eg. `&'static str` is a subtype of `&'b str`, then we can let them coerce,
0 commit comments