Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upintroduce region-clauses into the `ParamEnv`, use to replace the `body_id` #42341
Comments
nikomatsakis
added
A-traits
T-compiler
labels
May 31, 2017
This comment has been minimized.
This comment has been minimized.
|
Is it possible to fully desugar closures into structs that implement the So if you have a closure struct Closure<T> {
x: T,
}
impl<'a, T, U> FnOnce<(&'a U,)> for Closure<T>
where T: Add<U>,
U: Copy + 'a,
{
type Output = <T as Add<U>>::Output;
extern "rust-call" fn call_once(self, (&y,): (&'a U,)) -> Self::Output {
self.x + y
}
}
foo(Closure{x: &x}) |
This comment has been minimized.
This comment has been minimized.
|
@djzin this does happen during MIR lowering, and eventually I do plan to move all the region processing so that it occurs on the MIR. It's good point -- maybe it's not worth worrying about the |
This comment has been minimized.
This comment has been minimized.
|
So what does it take to move regionck to MIR? I am happy to help with this any way I can; I'm not super well-versed in this stuff at the moment but I can learn :) |
nikomatsakis commentedMay 31, 2017
When we are in a closure body, we often gain additional implied "outlives" relation based on the types of the closure arguments. Consider this:
Here, the type of
xwill be&'0 Tfor some anonymous region'0. Within the function body, then, we can conclude thatT: '0. We currently handle this through a variety of messy schemes. As part of chalkificaton, I would like to consolidate this into a cleaner, more uniform handling of environments and universes. This issue lays out an "evolving" plan for doing that.Current handling
Currently, for every trait obligation that we have to prove (e.g.,
T: Debug), we have anObligationCause-- this is primarily used for debugging, in that it specifies why we have to prove this thing. However, this type also carries abody_ididentifying the closure it came from. When we wind up having to prove an outlives relationship likeFoo: 'a, we record this in the fulfillment context (a kind of record of things we have yet to prove), and we track thebody_idwhere the obligation was incurred. Then, after type-checking, in the region-checking phase, we walk down the AST and figure out -- for each closure body -- what outlives facts we know at that point in time. We then pull out the list of outlives obligations from the fulfillment cx for a given body-id and try to prove them, using those facts. This whole process is complex and fragile.Roughly how I want it to work
We now have the ability to have every obligation have its own, distinct environment (we used to have just one ambient environment). This means that instead of having this ad-hoc
body_idfield, we can just extend the environment when we enter into a closure body. So, for example, when type-checking the body of the closure in the beginning, our environment would be extended with aT: 'aoutlives clause. We can do this right away, just as soon as we start type-checking the closure. This environment is automatically propagated to sub-goals, so when we wind up with some outlives obligations that we have to prove, they will haveT: 'ain their list of clauses (i.e., the facts that they can draw upon). This means that regionck doesn't have to do anything "special" -- rather, the input to regionck will change from being a flat list of obligations, to obligations that can carry more environmental information.There is one complication here:
Actual steps
OK, I ran out of time for this part. =)