Description
Right now the ParameterEnvironment
is a kind of grab bag of things. The most important thing, however, is the list of "caller bounds". In more Prolog-y terms, these are the clauses in the environment -- that is, they are the where-clauses that are in scope, and hence which we can assume to be true. If you look in the librustc/traits
code, you'll see that in fact the only thing which gets used from the ParameterEnvironment
is this caller_bounds
field.
Eventually, I think we want to move the caller_bounds
out into the obligations themselves. That is, in chalk, an obligation is not just the thing to be proven but also the environment in which it should be proven -- and this environment can grow and get new clauses as we go (this will be important for checking higher-ranked trait bounds like for<T: Foo> Vec<T>: Bar
).
To this end, a first step (this issue) is to refactor caller_bounds
so that they are an interned, lightweight pointer. (The whole setup around ParameterEnvironment
is, in fact, kind of a mess, but let's start simple). I envision a struct Environment<'tcx>
:
pub struct Environment<'tcx> {
clauses: &'tcx [ty::Predicate<'tcx>]
}
where the clauses list is interned. This struct will eventually be part of every Obligation
, so it's important that it be cheap to copy. It will also eventually be hashed for cache keys, so having an interned list of predicates makes that cheap. It will also grow an additional field (universe_index: usize
), and hence it's convenient for it to be a named struct.
We might want to pick a less overloaded name than Environment<'tcx>
. I'm not sure what to use though, that's really the most common name for this sort of thing.