-
Notifications
You must be signed in to change notification settings - Fork 13k
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
"left.extend_from_slice(right.strip_prefix(&mut left[n..]).unwrap())" doesn't compile #110362
Comments
That doesn't seem to be correct |
@TadaHrd , what you mean? Algorithm for vector merging is wrong? Or my code violates some Rust invariants? |
I don't think this is a bug. Your code: (with comments removed) let mut left = vec![0, 1, 2];
let right = vec![1, 2, 3];
let duplicate_part = &mut left[n..];
left.extend_from_slice(right.strip_prefix(duplicate_part).unwrap()); Due to argument evaluation order, I believe the last line expands to something like: {
let extend_receiver = &mut left; // (*)
let arg = right.strip_prefix(duplicate_part).unwrap();
extend_receiver.extend_from_slice(arg);
} Now the lifetime error should be obvious, as (*) More precisely, the method receiver is taken as a two-phase borrow, which is why the code would compile if |
@quaternic Is there a reason why two-phase doesn't allow exclusive borrows in the arguments? For example in this code, if the lifetime of the borrow in the argument outlives the method call it would be wrong for shared borrows as well as exclusive borrows, but only the exclusive borrow is a compiler error. struct Foo;
impl Foo {
fn bar(&mut self, _: ()) {}
}
fn main() {
let mut foo = Foo;
foo.bar(drop(&foo)); // OK
foo.bar(drop(&mut foo)); // ERROR
} |
The two-phase functions like a shared borrow until its activation point (when the call is actually made), and exclusive from then on. See the link for details (bottom of the page). URLO would be a much better medium for asking questions about the language. The issue tracker really isn't the place. |
@safinaskar, I think you need to implement it yourself if you need special functionality. |
The line In other words, I think the compiler should try all possible evaluation order strategies, which are equivalent to order specified in the reference (from side-effects point of view), until the compiler finds evaluation order, which satisfies borrow checker.
You mean writing patch for rustc? I simply want this bug to stay opened for a long time. Until someone will eventually (possibly after several years) fix it. I. e. similarly to how bug #47680 (comment) (and similar bugs) eventually led to creation of Polonius. I don't even ask to fix this bug. Just keep this report opened |
Here is simplified version of my code from actual production code base:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=99a751acd113949b2a77fa251e33f955 (rustc 1.68.2)
The code doesn't compile, but the code is correct, and it should compile. Yes, I can do the same task easier, but the code is still correct.
-Zpolonius
doesn't change anything, i. e. this bug is not fixed by Polonius.@rustbot label +A-lifetimes +T-compiler +A-borrow-checker +NLL-polonius +A-NLL
The text was updated successfully, but these errors were encountered: