-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
NLL breaks usage of AddAssign #48129
Comments
I'd like to work on this. |
Oddly enough, the precise syntax used to invoke #![feature(nll)]
use std::ops::*;
#[derive(Copy, Clone)]
struct Foo;
impl AddAssign for Foo {
fn add_assign(&mut self, _rhs: Foo) {
panic!()
}
}
fn bar() {
let mut a = Foo;
a += a;
a.add_assign(a);
}
fn main() {} |
I happened to run this with a slightly outdated nightly build. It seems that this is a regression: the last snippet worked on |
Upon further investigation, this appears to be intentional: https://github.com/rust-lang/rust/pull/47489/files#diff-b3d7798e2a3c43eca68203216e36de65R544 However, this ends up breaking existing code in @pnkfelix: Seeing as this was your PR, do you think it makes sense to extend two-phase borrows to overloaded operators in order to preserve compatibility with existing code? |
I ran into this as well. I have some code like the following that suddenly stopped compiling with the latest nightly: #![feature(nll)]
use std::num::Wrapping;
fn main() {
let mut x = Wrapping(1234u32);
x ^= x >> 2;
println!("{}", x);
} It does compile and runs fine without the |
I think extending two-phase borrows to cover this case seems reasonable. |
The use_self isn't necessary to show that this is a regression, see #48175 #![feature(nll)]
use std::ops::*;
#[derive(Copy, Clone)]
struct Au(u32);
impl Add<Au> for Au {
type Output = Au;
fn add(self, other: Au) -> Au {
Au(self.0 + other.0)
}
}
impl AddAssign<Au> for Au {
fn add_assign(&mut self, other: Au) {
*self = Au(self.0 + other.0)
}
}
fn main() {
let mut foo = vec![Au(4), Au(5), Au(6)];
foo[2] += foo[2];
} (playpen) |
We need two-phase borrows of ops to be in the initial NLL release since without them lots of existing code will break. Fixes rust-lang#48129
…, r=nikomatsakis Allow two-phase borrows of &mut self in ops We need two-phase borrows of ops to be in the initial NLL release since without them lots of existing code will break. Fixes rust-lang#48129. CC @pnkfelix and @nikomatsakis r? @pnkfelix
…, r=nikomatsakis Allow two-phase borrows of &mut self in ops We need two-phase borrows of ops to be in the initial NLL release since without them lots of existing code will break. Fixes rust-lang#48129. CC @pnkfelix and @nikomatsakis r? @pnkfelix
When trying to reproduce #48071, I came across another issue in
libcompiler_builtins
. The original errors were:I managed to reduce the second error to this example (playground):
which fails to compile with this error:
As expected, removing
#![feature(nll)]
causesa += a
to compile, butb.use_self(b);
to fail with this error:I assume that this last error is due to the lack of two-phase borrows on ast-borrowck, and is not something that will be fixed. However, I expect NLL to compile both the operator and 'desuraged operator' version.
The text was updated successfully, but these errors were encountered: