Skip to content

Commit a12cefb

Browse files
committed
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.)
1 parent eabef06 commit a12cefb

File tree

4 files changed

+143
-136
lines changed

4 files changed

+143
-136
lines changed

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc::middle::mem_categorization::Categorization;
1414
use rustc::middle::mem_categorization::NoteClosureEnv;
1515
use rustc::middle::mem_categorization::InteriorOffsetKind as Kind;
1616
use rustc::ty;
17+
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
1718
use syntax::ast;
1819
use syntax_pos;
1920
use errors::DiagnosticBuilder;
@@ -134,24 +135,17 @@ fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
134135
}
135136

136137
// (keep in sync with gather_moves::check_and_get_illegal_move_origin )
137-
fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
138+
fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
138139
move_from: mc::cmt<'tcx>)
139140
-> DiagnosticBuilder<'a> {
140141
match move_from.cat {
141142
Categorization::Deref(_, mc::BorrowedPtr(..)) |
142143
Categorization::Deref(_, mc::Implicit(..)) |
143144
Categorization::Deref(_, mc::UnsafePtr(..)) |
144145
Categorization::StaticItem => {
145-
let mut err = struct_span_err!(bccx, move_from.span, E0507,
146-
"cannot move out of {}",
147-
move_from.descriptive_string(bccx.tcx));
148-
err.span_label(
149-
move_from.span,
150-
format!("cannot move out of {}", move_from.descriptive_string(bccx.tcx))
151-
);
152-
err
146+
bccx.cannot_move_out_of(
147+
move_from.span, &move_from.descriptive_string(bccx.tcx), Origin::Ast)
153148
}
154-
155149
Categorization::Interior(ref b, mc::InteriorElement(ik)) => {
156150
let type_name = match (&b.ty.sty, ik) {
157151
(&ty::TyArray(_, _), Kind::Index) => "array",

src/librustc_borrowck/diagnostics.rs

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -317,132 +317,6 @@ fn main() {
317317
```
318318
"##,
319319

320-
E0507: r##"
321-
You tried to move out of a value which was borrowed. Erroneous code example:
322-
323-
```compile_fail,E0507
324-
use std::cell::RefCell;
325-
326-
struct TheDarkKnight;
327-
328-
impl TheDarkKnight {
329-
fn nothing_is_true(self) {}
330-
}
331-
332-
fn main() {
333-
let x = RefCell::new(TheDarkKnight);
334-
335-
x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
336-
}
337-
```
338-
339-
Here, the `nothing_is_true` method takes the ownership of `self`. However,
340-
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
341-
which is a borrow of the content owned by the `RefCell`. To fix this error,
342-
you have three choices:
343-
344-
* Try to avoid moving the variable.
345-
* Somehow reclaim the ownership.
346-
* Implement the `Copy` trait on the type.
347-
348-
Examples:
349-
350-
```
351-
use std::cell::RefCell;
352-
353-
struct TheDarkKnight;
354-
355-
impl TheDarkKnight {
356-
fn nothing_is_true(&self) {} // First case, we don't take ownership
357-
}
358-
359-
fn main() {
360-
let x = RefCell::new(TheDarkKnight);
361-
362-
x.borrow().nothing_is_true(); // ok!
363-
}
364-
```
365-
366-
Or:
367-
368-
```
369-
use std::cell::RefCell;
370-
371-
struct TheDarkKnight;
372-
373-
impl TheDarkKnight {
374-
fn nothing_is_true(self) {}
375-
}
376-
377-
fn main() {
378-
let x = RefCell::new(TheDarkKnight);
379-
let x = x.into_inner(); // we get back ownership
380-
381-
x.nothing_is_true(); // ok!
382-
}
383-
```
384-
385-
Or:
386-
387-
```
388-
use std::cell::RefCell;
389-
390-
#[derive(Clone, Copy)] // we implement the Copy trait
391-
struct TheDarkKnight;
392-
393-
impl TheDarkKnight {
394-
fn nothing_is_true(self) {}
395-
}
396-
397-
fn main() {
398-
let x = RefCell::new(TheDarkKnight);
399-
400-
x.borrow().nothing_is_true(); // ok!
401-
}
402-
```
403-
404-
Moving a member out of a mutably borrowed struct will also cause E0507 error:
405-
406-
```compile_fail,E0507
407-
struct TheDarkKnight;
408-
409-
impl TheDarkKnight {
410-
fn nothing_is_true(self) {}
411-
}
412-
413-
struct Batcave {
414-
knight: TheDarkKnight
415-
}
416-
417-
fn main() {
418-
let mut cave = Batcave {
419-
knight: TheDarkKnight
420-
};
421-
let borrowed = &mut cave;
422-
423-
borrowed.knight.nothing_is_true(); // E0507
424-
}
425-
```
426-
427-
It is fine only if you put something back. `mem::replace` can be used for that:
428-
429-
```
430-
# struct TheDarkKnight;
431-
# impl TheDarkKnight { fn nothing_is_true(self) {} }
432-
# struct Batcave { knight: TheDarkKnight }
433-
use std::mem;
434-
435-
let mut cave = Batcave {
436-
knight: TheDarkKnight
437-
};
438-
let borrowed = &mut cave;
439-
440-
mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
441-
```
442-
443-
You can find more information about borrowing in the rust-book:
444-
http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html
445-
"##,
446320

447321
E0508: r##"
448322
A value was moved out of a non-copy fixed-size array.

src/librustc_mir/diagnostics.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,133 @@ fn print_fancy_ref(fancy_ref: &FancyNum){
999999
```
10001000
"##,
10011001

1002+
E0507: r##"
1003+
You tried to move out of a value which was borrowed. Erroneous code example:
1004+
1005+
```compile_fail,E0507
1006+
use std::cell::RefCell;
1007+
1008+
struct TheDarkKnight;
1009+
1010+
impl TheDarkKnight {
1011+
fn nothing_is_true(self) {}
1012+
}
1013+
1014+
fn main() {
1015+
let x = RefCell::new(TheDarkKnight);
1016+
1017+
x.borrow().nothing_is_true(); // error: cannot move out of borrowed content
1018+
}
1019+
```
1020+
1021+
Here, the `nothing_is_true` method takes the ownership of `self`. However,
1022+
`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,
1023+
which is a borrow of the content owned by the `RefCell`. To fix this error,
1024+
you have three choices:
1025+
1026+
* Try to avoid moving the variable.
1027+
* Somehow reclaim the ownership.
1028+
* Implement the `Copy` trait on the type.
1029+
1030+
Examples:
1031+
1032+
```
1033+
use std::cell::RefCell;
1034+
1035+
struct TheDarkKnight;
1036+
1037+
impl TheDarkKnight {
1038+
fn nothing_is_true(&self) {} // First case, we don't take ownership
1039+
}
1040+
1041+
fn main() {
1042+
let x = RefCell::new(TheDarkKnight);
1043+
1044+
x.borrow().nothing_is_true(); // ok!
1045+
}
1046+
```
1047+
1048+
Or:
1049+
1050+
```
1051+
use std::cell::RefCell;
1052+
1053+
struct TheDarkKnight;
1054+
1055+
impl TheDarkKnight {
1056+
fn nothing_is_true(self) {}
1057+
}
1058+
1059+
fn main() {
1060+
let x = RefCell::new(TheDarkKnight);
1061+
let x = x.into_inner(); // we get back ownership
1062+
1063+
x.nothing_is_true(); // ok!
1064+
}
1065+
```
1066+
1067+
Or:
1068+
1069+
```
1070+
use std::cell::RefCell;
1071+
1072+
#[derive(Clone, Copy)] // we implement the Copy trait
1073+
struct TheDarkKnight;
1074+
1075+
impl TheDarkKnight {
1076+
fn nothing_is_true(self) {}
1077+
}
1078+
1079+
fn main() {
1080+
let x = RefCell::new(TheDarkKnight);
1081+
1082+
x.borrow().nothing_is_true(); // ok!
1083+
}
1084+
```
1085+
1086+
Moving a member out of a mutably borrowed struct will also cause E0507 error:
1087+
1088+
```compile_fail,E0507
1089+
struct TheDarkKnight;
1090+
1091+
impl TheDarkKnight {
1092+
fn nothing_is_true(self) {}
1093+
}
1094+
1095+
struct Batcave {
1096+
knight: TheDarkKnight
1097+
}
1098+
1099+
fn main() {
1100+
let mut cave = Batcave {
1101+
knight: TheDarkKnight
1102+
};
1103+
let borrowed = &mut cave;
1104+
1105+
borrowed.knight.nothing_is_true(); // E0507
1106+
}
1107+
```
1108+
1109+
It is fine only if you put something back. `mem::replace` can be used for that:
1110+
1111+
```
1112+
# struct TheDarkKnight;
1113+
# impl TheDarkKnight { fn nothing_is_true(self) {} }
1114+
# struct Batcave { knight: TheDarkKnight }
1115+
use std::mem;
1116+
1117+
let mut cave = Batcave {
1118+
knight: TheDarkKnight
1119+
};
1120+
let borrowed = &mut cave;
1121+
1122+
mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!
1123+
```
1124+
1125+
You can find more information about borrowing in the rust-book:
1126+
http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html
1127+
"##,
1128+
10021129
}
10031130

10041131
register_diagnostics! {

src/librustc_mir/util/borrowck_errors.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ pub trait BorrowckErrors {
191191
{
192192
self.cannot_assign(span, &format!("immutable static item `{}`", desc), o)
193193
}
194+
195+
fn cannot_move_out_of(&self, move_from_span: Span, move_from_desc: &str, o: Origin)
196+
-> DiagnosticBuilder
197+
{
198+
let mut err = struct_span_err!(self, move_from_span, E0507,
199+
"cannot move out of {}{OGN}",
200+
move_from_desc, OGN=o);
201+
err.span_label(
202+
move_from_span,
203+
format!("cannot move out of {}", move_from_desc));
204+
err
205+
}
194206
}
195207

196208
impl<'b, 'tcx, 'gcx> BorrowckErrors for TyCtxt<'b, 'tcx, 'gcx> {

0 commit comments

Comments
 (0)