Implementation of GATs outlives lint by jackh726 · Pull Request #89970 · rust-la...
source link: https://github.com/rust-lang/rust/pull/89970
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
See #87479 for background. Closes #87479
The basic premise of this lint/error is to require the user to write where clauses on a GAT when those bounds can be implied or proven from any function on the trait returning that GAT.
Intuitive Explanation (Attempt)
Let's take this trait definition as an example:
trait Iterable { type Item<'x>; fn iter<'a>(&'a self) -> Self::Item<'a>; }
Let's focus on the iter
function. The first thing to realize is that we know that Self: 'a
because of &'a self
. If an impl wants Self::Item
to contain any data with references, then those references must be derived from &'a self
. Thus, they must live only as long as 'a
. Furthermore, because of the Self: 'a
implied bound, they must live only as long as Self
. Since it's 'a
is used in place of 'x
, it is reasonable to assume that any value of Self::Item<'x>
, and thus 'x
, will only be able to live as long as Self
. Therefore, we require this bound on Item
in the trait.
As another example:
trait Deserializer<T> { type Out<'x>; fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>; }
The intuition is similar here, except rather than a Self: 'a
implied bound, we have a T: 'a
implied bound. Thus, the data on Self::Out<'a>
is derived from &'a T
, and thus it is reasonable to expect that the lifetime 'x
will always be less than T
.
Implementation Algorithm
- Given a GAT
<P0 as Trait<P1..Pi>>::G<Pi...Pn>
declared astrait T<A1..Ai> for A0 { type G<Ai...An>; }
used in return type of one associated functionF
- Given env
E
(including implied bounds) forF
- For each lifetime parameter
'a
inP0...Pn
:- For each other type parameter
Pi != 'a
inP0...Pn
: // FIXME: this include of lifetime parameters too- If
E => (P: 'a)
:- Require where clause
Ai: 'a
- Require where clause
- If
- For each other type parameter
Follow-up questions
- What should we do when we don't pass params exactly?
For this example:
trait Des { type Out<'x, D>; fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>; }
Should we be requiring a D: 'x
clause? We pass Wrap<T>
as D
and 'z
as 'x
, and should be able to prove that Wrap<T>: 'z
.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK