Description
Per this comment, the current system for handling outlives obligations relies on an "approximate" match for outlives relations that is actually kind of flawed in some edge cases, which can lead to us overconstraining inference:
It's not really meant to be conservative in "two dimensions". That is,
projection_approx_declared_bounds_from_env
ought to return anything that might potentially be useful. I suspect this is not presently true, though, around bound regions and a few other edge cases (e.g., I think we by and large ignore things likefor<'a> T::Proj<'a>: 'a
, which is really a bug, although a pre-existing one; we also are too conservative I think around equality of types likefor<'a> fn(&'a u32)
vsfor<'b> fn(&'b u32)
. Also a pre-existing bug.)I might be able to fix those cases where we are "overly" conservative though via a more thorough erasure. I think erasing regions today preserves the lifetime bounds, but we would ideally look for an "equality" check that just completely ignores region equality (even around binders). I was working towards that but never finished it.
Originally, I had intended to fix this by using the "type relation" code from the NLL type checker, but in a mode where it ignored all the outlives relations. I introduced the idea of an "outlives delegate" and so forth in preparation for that but then never took the last step, since "erasing obligations" seemed simpler and sufficient for the moment.