-
Notifications
You must be signed in to change notification settings - Fork 13.3k
consider expanding two-phase borrows *just a bit more* #48598
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
Comments
I encountered this example attempting to bootstrap rustc. |
Also, that error message is ungreat. |
I had suggested a rule where that happens only if there are no constraints on the lifetime of the reference. Considering that's probably difficult to implement, we could use a syntactical rule which is a subset of that: We may auto-ref method arguments whenever the lifetime of the argument is elided. |
@leodasvacas
Remind me, why does that matter? We don't have an analogous restriction on the |
Nevemind, I got confused and thought this was about general auto-refing. |
cc @bobtwinkles -- what do you think about trying to implement this change? cc @pnkfelix -- do you object to this expansion? |
I should be able to take a stab at this sometime this week. It might end up being as easy as switching an |
OK, so some notes (mostly for myself but perhaps useful to those interested in how I'm progressing).
|
A collection of tricky cases: struct Foo<'a> {
x: &'a u32,
}
struct Bar<'a, 'b: 'a> {
x: &'a mut Foo<'b>
}
impl<'a> Foo<'a> {
fn method(&mut self, value: &u32) {
}
}
fn trick1() {
let mut f = &mut Foo { x: &22 };
let z = Bar {x: f};
// This is hard because we need to look "through" a projection to figure out where the borrow came from
Foo::method(z.x, z.x.x)
}
fn trick2() {
let mut b = &mut Foo { x: &7 };
let mb = b;
// similarly, there is more than one assignment we would have to consider
Foo::method(mb, mb.x);
} |
I don't understand why there is a problem with the original example. Is it because &22 has static lifetime? Otherwise, with a small change the example creates aliasing---isn't that exactly what Rust should protect from? There is a problem if x is a u32 instead of a &u32. The borrow checker still complains because it applies the checks to the borrows needed to evaluate the arguments, rather than to the borrows needed to make the call after argument evaluation. |
Extend two-phase borrows to apply to method receiver autorefs Fixes #48598 by permitting two-phase borrows on the autorefs created when functions and methods.
At first, I thought this was a bug in two-phase borrows, but I realize now that this example does not fall into the subset that @pnkfelix and I identified. That said, I wonder if it should? Try it on play:
This gives:
I wonder if we should expand to auto-refs on any method argument? I think they all have the same character as
self.foo()
, and those would preserve theself.foo(..)
=>Foo::foo(self, ..)
transformation more faithfully.cc @rust-lang/wg-compiler-nll
The text was updated successfully, but these errors were encountered: