Move E0507 diagnostic into mod borrowck_errors shared between ast- and mir-borrowck.
(Had to modify signature of `report_cannot_move_out_of` slightly to satisfy requirements of newly added `fn cannot_move_out_of` method.)
This commit is contained in:
parent
eabef0608b
commit
a12cefb497
4 changed files with 143 additions and 136 deletions
|
@ -14,6 +14,7 @@ use rustc::middle::mem_categorization::Categorization;
|
|||
use rustc::middle::mem_categorization::NoteClosureEnv;
|
||||
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
|
||||
use rustc::ty;
|
||||
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
|
||||
use syntax::ast;
|
||||
use syntax_pos;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
@ -134,7 +135,7 @@ fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
|
|||
}
|
||||
|
||||
// (keep in sync with gather_moves::check_and_get_illegal_move_origin )
|
||||
fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
||||
move_from: mc::cmt<'tcx>)
|
||||
-> DiagnosticBuilder<'a> {
|
||||
match move_from.cat {
|
||||
|
@ -142,16 +143,9 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
|||
Categorization::Deref(_, mc::Implicit(..)) |
|
||||
Categorization::Deref(_, mc::UnsafePtr(..)) |
|
||||
Categorization::StaticItem => {
|
||||
let mut err = struct_span_err!(bccx, move_from.span, E0507,
|
||||
"cannot move out of {}",
|
||||
move_from.descriptive_string(bccx.tcx));
|
||||
err.span_label(
|
||||
move_from.span,
|
||||
format!("cannot move out of {}", move_from.descriptive_string(bccx.tcx))
|
||||
);
|
||||
err
|
||||
bccx.cannot_move_out_of(
|
||||
move_from.span, &move_from.descriptive_string(bccx.tcx), Origin::Ast)
|
||||
}
|
||||
|
||||
Categorization::Interior(ref b, mc::InteriorElement(ik)) => {
|
||||
let type_name = match (&b.ty.sty, ik) {
|
||||
(&ty::TyArray(_, _), Kind::Index) => "array",
|
||||
|
|
|
@ -317,132 +317,6 @@ fn main() {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0507: r##"
|
||||
You tried to move out of a value which was borrowed. Erroneous code example:
|
||||
|
||||
```compile_fail,E0507
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `nothing_is_true` method takes the ownership of `self`. However,
|
||||
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
|
||||
which is a borrow of the content owned by the `RefCell`. To fix this error,
|
||||
you have three choices:
|
||||
|
||||
* Try to avoid moving the variable.
|
||||
* Somehow reclaim the ownership.
|
||||
* Implement the `Copy` trait on the type.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(&self) {} // First case, we don't take ownership
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
let x = x.into_inner(); // we get back ownership
|
||||
|
||||
x.nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(Clone, Copy)] // we implement the Copy trait
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Moving a member out of a mutably borrowed struct will also cause E0507 error:
|
||||
|
||||
```compile_fail,E0507
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
struct Batcave {
|
||||
knight: TheDarkKnight
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut cave = Batcave {
|
||||
knight: TheDarkKnight
|
||||
};
|
||||
let borrowed = &mut cave;
|
||||
|
||||
borrowed.knight.nothing_is_true(); // E0507
|
||||
}
|
||||
```
|
||||
|
||||
It is fine only if you put something back. `mem::replace` can be used for that:
|
||||
|
||||
```
|
||||
# struct TheDarkKnight;
|
||||
# impl TheDarkKnight { fn nothing_is_true(self) {} }
|
||||
# struct Batcave { knight: TheDarkKnight }
|
||||
use std::mem;
|
||||
|
||||
let mut cave = Batcave {
|
||||
knight: TheDarkKnight
|
||||
};
|
||||
let borrowed = &mut cave;
|
||||
|
||||
mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
|
||||
```
|
||||
|
||||
You can find more information about borrowing in the rust-book:
|
||||
http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html
|
||||
"##,
|
||||
|
||||
E0508: r##"
|
||||
A value was moved out of a non-copy fixed-size array.
|
||||
|
|
|
@ -999,6 +999,133 @@ fn print_fancy_ref(fancy_ref: &FancyNum){
|
|||
```
|
||||
"##,
|
||||
|
||||
E0507: r##"
|
||||
You tried to move out of a value which was borrowed. Erroneous code example:
|
||||
|
||||
```compile_fail,E0507
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `nothing_is_true` method takes the ownership of `self`. However,
|
||||
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
|
||||
which is a borrow of the content owned by the `RefCell`. To fix this error,
|
||||
you have three choices:
|
||||
|
||||
* Try to avoid moving the variable.
|
||||
* Somehow reclaim the ownership.
|
||||
* Implement the `Copy` trait on the type.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(&self) {} // First case, we don't take ownership
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
let x = x.into_inner(); // we get back ownership
|
||||
|
||||
x.nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(Clone, Copy)] // we implement the Copy trait
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = RefCell::new(TheDarkKnight);
|
||||
|
||||
x.borrow().nothing_is_true(); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Moving a member out of a mutably borrowed struct will also cause E0507 error:
|
||||
|
||||
```compile_fail,E0507
|
||||
struct TheDarkKnight;
|
||||
|
||||
impl TheDarkKnight {
|
||||
fn nothing_is_true(self) {}
|
||||
}
|
||||
|
||||
struct Batcave {
|
||||
knight: TheDarkKnight
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut cave = Batcave {
|
||||
knight: TheDarkKnight
|
||||
};
|
||||
let borrowed = &mut cave;
|
||||
|
||||
borrowed.knight.nothing_is_true(); // E0507
|
||||
}
|
||||
```
|
||||
|
||||
It is fine only if you put something back. `mem::replace` can be used for that:
|
||||
|
||||
```
|
||||
# struct TheDarkKnight;
|
||||
# impl TheDarkKnight { fn nothing_is_true(self) {} }
|
||||
# struct Batcave { knight: TheDarkKnight }
|
||||
use std::mem;
|
||||
|
||||
let mut cave = Batcave {
|
||||
knight: TheDarkKnight
|
||||
};
|
||||
let borrowed = &mut cave;
|
||||
|
||||
mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
|
||||
```
|
||||
|
||||
You can find more information about borrowing in the rust-book:
|
||||
http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
register_diagnostics! {
|
||||
|
|
|
@ -191,6 +191,18 @@ pub trait BorrowckErrors {
|
|||
{
|
||||
self.cannot_assign(span, &format!("immutable static item `{}`", desc), o)
|
||||
}
|
||||
|
||||
fn cannot_move_out_of(&self, move_from_span: Span, move_from_desc: &str, o: Origin)
|
||||
-> DiagnosticBuilder
|
||||
{
|
||||
let mut err = struct_span_err!(self, move_from_span, E0507,
|
||||
"cannot move out of {}{OGN}",
|
||||
move_from_desc, OGN=o);
|
||||
err.span_label(
|
||||
move_from_span,
|
||||
format!("cannot move out of {}", move_from_desc));
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'tcx, 'gcx> BorrowckErrors for TyCtxt<'b, 'tcx, 'gcx> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue