-
Notifications
You must be signed in to change notification settings - Fork 74
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
Check constraints arising from higher-rank trait bounds (HRTBs) #172
Comments
Sprint 2021-07-30 NotesAfter a day to reflect, I've written up a summary of the conversation I had with Niko about HRTBs and Polonius. Personal notes are italicized. HRTBs and PoloniusAfter some background discussion about universes, Niko gave the following example to illustrate how HRTBs can become entangled in borrow-checking function bodies: fn foo<'a>(x: &'a u32) where for<'b> 'a: 'b { } // Pseudo-Rust ('b <: 'a -> 'a = 'static)
// The equivalent (I think) in actual Rust.
/*
trait Outlives<'a, 'b> {}
impl<'a: 'b, 'b> Outlives<'a, 'b> for () {}
fn foo<'a>(x: &'a u32) where for<'b> (): Outlives<'a, 'b> {}
*/
fn bar() {
let x = 22;
let y/*: &'y i32*/ = &22
foo(y);
} In the example, I'm still a bit confused as to where the boundary between trait selection, type checking, and borrow checking (Polonius) lies exactly. Most of the HRTBs tests for fn foo<'a>(a: &'a u32) where for<'b> 'b: 'a { }
fn bar<'x>(x: &'x u32) {
foo(x);
} But A digression on subset errors vs. loan invalidationNiko briefly discussed an alternate approach to generating errors for borrows of stack variables that escape the function body. For example, fn foo() -> &'static u32 {
let x = 22;
&/*'x*/ x
} Currently, Polonius would emit an error when it sees that the loan created in Niko also gave the example following example involving a deref projection. fn foo<'a>(x: &'a u32) -> &'a u32 {
let y = &*x; // loan L0
y // here, 'a contains loan L0, but that's ok
} Back to HRTBsNiko returned to discussing the
I was a bit confused by this, since in my framework (see the second example), this type of constraint is immediately unsatisfiable, so maybe we could handle this type of thing a different way? Unfortunately I didn't realize this in the moment (I blame the literal catfight). He then gave the following example of a place where this kind of constraint might arise: trait TheTrait { }
impl<'a> TheTrait for fn(&'a u32) { }
fn take<X: TheTrait>() { }
fn main() {
take::<fn(&u32)>();
} Ultimately, Niko concluded,
I'm not as convinced, but everything was moving pretty fast at this point. My blog post was all about how all universally quantified trait bounds are either unsatisfiable (as in the second point) or can be reduced to a bound on Next StepsThe conversation ended here. The good news is that we might be close to replicating the existing borrow checker as far as HRTBs go. However, there's some open soundness holes (Niko mentions issue 25860), that might need a more advanced approach. Unfortunately I don't have any insight into these, and my understanding of universes and region inferences is lacking, so I'll need to do quite a bit of studying to get up to speed. |
This issue tracks error compatibility with the current version of
rustc
for functions involving HRTBs. This is one of the major features missing from Polonius.Currently,
rustc
uses the concept of Universes (described in detail here to reason about HRTBs. Previously, it used something called the leak check, which I believe still exists in some form.rustc
implementation history (possibly incomplete):'empty
combined with universes rust#70950Relevant test cases (definitely incomplete):
Currently, Polonius cannot handle quantified constraints arising from HRTBs. One possible framework, hereditary-harrop predicates, were explored in Niko's blog post. I discussed the implications of allowing a reduced set of these (just the quantifiers) in a later post.
For now, the goal is simply to reach feature parity with current versions of
rustc
, but therustc
borrow-checker has some shortcomings around HRTBs, where it needs to represent constraints likefor <'a, 'b: 'a>
, and there are some upcoming features that may complicate things further:The text was updated successfully, but these errors were encountered: