-
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
Two MUTABLE borrows to local var, by pushing closures into RefCell'd Vec through a trait. #18783
Comments
Reduced a bit further: use std::cell::RefCell;
fn main() {
let c = RefCell::new(vec![]);
let mut y = 1u;
c.push(|| y = 0);
c.push(|| y = 0);
// confliciting borrow detected when not going through trait
// c.borrow_mut().push(|| y = 0);
// c.borrow_mut().push(|| y = 0);
}
trait Push<'c> {
fn push<'f: 'c>(&self, push: ||:'f -> ());
}
impl<'c> Push<'c> for RefCell<Vec<||:'c>> {
fn push<'f: 'c>(&self, fun: ||:'f -> ()) {
self.borrow_mut().push(fun)
}
} This is a regression from 0.12. cc @nikomatsakis |
git bisect shows this came in with #18121 |
I tried #18694 on a hunch, and it fixes this issue. |
P-backcompat-lang, 1.0. |
This is not entirely fixed by #18694, there is another guise. Here is a revised test: // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::cell::RefCell;
fn main() {
let c = RefCell::new(vec![]);
let mut y = 1u;
c.push(|| y = 0);
c.push(|| y = 0);
// confliciting borrow detected when not going through trait
// c.borrow_mut().push(|| y = 0);
// c.borrow_mut().push(|| y = 0);
}
fn ufcs() {
let c = RefCell::new(vec![]);
let mut y = 1u;
Push::push(&c, || y = 0);
Push::push(&c, || y = 0);
}
trait Push<'c> {
fn push<'f: 'c>(&self, push: ||:'f -> ());
}
impl<'c> Push<'c> for RefCell<Vec<||:'c>> {
fn push<'f: 'c>(&self, fun: ||:'f -> ()) {
self.borrow_mut().push(fun)
}
} the second set of calls using UFCS form passes. |
(I suspect though this second form is a dup of #18899) |
Ah, no, I think what is happening is that the |
(I presume the problem is that the variance inference must take the |
I'll take care of this. |
Closes rust-lang#5988. Closes rust-lang#10176. Closes rust-lang#10456. Closes rust-lang#12744. Closes rust-lang#13264. Closes rust-lang#13324. Closes rust-lang#14182. Closes rust-lang#15381. Closes rust-lang#15444. Closes rust-lang#15480. Closes rust-lang#15756. Closes rust-lang#16822. Closes rust-lang#16966. Closes rust-lang#17351. Closes rust-lang#17503. Closes rust-lang#17545. Closes rust-lang#17771. Closes rust-lang#17816. Closes rust-lang#17897. Closes rust-lang#17905. Closes rust-lang#18188. Closes rust-lang#18232. Closes rust-lang#18345. Closes rust-lang#18389. Closes rust-lang#18400. Closes rust-lang#18502. Closes rust-lang#18611. Closes rust-lang#18783. Closes rust-lang#19009. Closes rust-lang#19081. Closes rust-lang#19098. Closes rust-lang#19127. Closes rust-lang#19135.
Closes rust-lang#5988. Closes rust-lang#10176. Closes rust-lang#10456. Closes rust-lang#12744. Closes rust-lang#13264. Closes rust-lang#13324. Closes rust-lang#14182. Closes rust-lang#15381. Closes rust-lang#15444. Closes rust-lang#15480. Closes rust-lang#15756. Closes rust-lang#16822. Closes rust-lang#16966. Closes rust-lang#17351. Closes rust-lang#17503. Closes rust-lang#17545. Closes rust-lang#17771. Closes rust-lang#17816. Closes rust-lang#17897. Closes rust-lang#17905. Closes rust-lang#18188. Closes rust-lang#18232. Closes rust-lang#18345. Closes rust-lang#18389. Closes rust-lang#18400. Closes rust-lang#18502. Closes rust-lang#18611. Closes rust-lang#18783. Closes rust-lang#19009. Closes rust-lang#19081. Closes rust-lang#19098. Closes rust-lang#19127. Closes rust-lang#19135.
Closes #5988. Closes #10176. Closes #10456. Closes #12744. Closes #13264. Closes #13324. Closes #14182. Closes #15381. Closes #15444. Closes #15480. Closes #15756. Closes #16822. Closes #16966. Closes #17351. Closes #17503. Closes #17545. Closes #17771. Closes #17816. Closes #17897. Closes #17905. Closes #18188. Closes #18232. Closes #18345. Closes #18389. Closes #18400. Closes #18502. Closes #18611. Closes #18783. Closes #19009. Closes #19081. Closes #19098. Closes #19127. Closes #19135.
Looks like a bug in the borrow checker:
Playpen
This compiles and runs fine. It also compiles when using unboxed closures instead (using type param F: FnOnce<(), ()>+'c and F members). Using the non-trait impl, however, causes compilation to fail correctly:
The text was updated successfully, but these errors were encountered: