-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Two MUTABLE borrows to local var, by pushing closures into RefCell'd Vec through a trait. #18783
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
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: