-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
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: