-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Generalize object and type parameter bounds #16453
Conversation
r? @pnkfelix Note: there are still a lot of commits here. I got tired of grouping them together. I will likely come back and group them some more later, but I'd also like to walk you through the code a bit. |
Per discussion with @nick29581 and @pnkfelix, we're going to delay review (or at least landing) somewhat so as to try and avoid conflicts with DST branch. |
OK, I cleaned up the set of commits, grouping things together as best I could. It's reasonably clean now, though the commits will not build independently. |
Closes #16462 |
1a584c0
to
d12d394
Compare
48887b6
to
e336eaf
Compare
1bd83ce
to
1b487a8
Compare
Rebased over DST. At this point the history is ruined, so I squashed down to a single commit now that the review has been done. |
Implements rust-lang/rfcs#192. In particular: 1. type parameters can have lifetime bounds and objects can close over borrowed values, presuming that they have suitable bounds. 2. objects must have a bound, though it may be derived from the trait itself or from a `Send` bound. 3. all types must be well-formed. 4. type parameters and lifetime parameters may themselves have lifetimes as bounds. Something like `T:'a` means "the type T outlives 'a`" and something like `'a:'b`" means "'a outlives 'b". Outlives here means "all borrowed data has a lifetime at least as long". This is a [breaking-change]. The most common things you have to fix after this change are: 1. Introduce lifetime bounds onto type parameters if your type (directly or indirectly) contains a reference. Thus a struct like `struct Ref<'a, T> { x: &'a T }` would be changed to `struct Ref<'a, T:'a> { x: &'a T }`. 2. Introduce lifetime bounds onto lifetime parameters if your type contains a double reference. Thus a type like `struct RefWrapper<'a, 'b> { r: &'a Ref<'b, int> }` (where `Ref` is defined as before) would need to be changed to `struct RefWrapper<'a, 'b:'a> { ... }`. 2. Explicitly give object lifetimes in structure definitions. Most commonly, this means changing something like `Box<Reader>` to `Box<Reader+'static>`, so as to indicate that this is a reader without any borrowed data. (Note: you may wish to just change to `Box<Reader+Send>` while you're at it; it's a more restrictive type, technically, but means you can send the reader between threads.) The intuition for points 1 and 2 is that a reference must never outlive its referent (the thing it points at). Therefore, if you have a type `&'a T`, we must know that `T` (whatever it is) outlives `'a`. And so on. Closes #5723.
Now that rust-lang/rust#16453 has landed, the body API can be improved to not require hard casting to trait objects
This is due to a breaking change from: rust-lang/rust#16453
internal: Undo special bracket classification for attributes in vscode config I changed this thinking the `#` could be considered part of the bracket but on second though I don't think that's quite right in general. Fixes rust-lang/rust-analyzer#16449
Implements rust-lang/rfcs#192.
In particular:
Send
bound.T:'a
means "the type T outlives 'a" and something like
'a:'b`" means "'a outlives 'b". Outlives here means "all borrowed data has a lifetime at least as long".This is a [breaking-change]. The most common things you have to fix after this change are:
struct Ref<'a, T> { x: &'a T }
would be changed tostruct Ref<'a, T:'a> { x: &'a T }
.struct RefWrapper<'a, 'b> { r: &'a Ref<'b, int> }
(whereRef
is defined as before) would need to be changed tostruct RefWrapper<'a, 'b:'a> { ... }
.Box<Reader>
toBox<Reader+'static>
, so as to indicate that this is a reader without any borrowed data. (Note: you may wish to just change toBox<Reader+Send>
while you're at it; it's a more restrictive type, technically, but means you can send the reader between threads.)The intuition for points 1 and 2 is that a reference must never outlive its referent (the thing it points at). Therefore, if you have a type
&'a T
, we must know thatT
(whatever it is) outlives'a
. And so on.Closes #5723.