Skip to content

Commit fdd7d13

Browse files
committed
Move E0509 diagnostic into mod borrowck_errors shared between ast- and mir-borrowck.
1 parent a995b56 commit fdd7d13

File tree

4 files changed

+111
-102
lines changed

4 files changed

+111
-102
lines changed

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,9 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
155155
Categorization::Interior(ref b, mc::InteriorField(_)) => {
156156
match b.ty.sty {
157157
ty::TyAdt(def, _) if def.has_dtor(bccx.tcx) => {
158-
let mut err = struct_span_err!(bccx, move_from.span, E0509,
159-
"cannot move out of type `{}`, \
160-
which implements the `Drop` trait",
161-
b.ty);
162-
err.span_label(move_from.span, "cannot move out of here");
163-
err
164-
},
158+
bccx.cannot_move_out_of_interior_of_drop(
159+
move_from.span, b.ty, Origin::Ast)
160+
}
165161
_ => {
166162
span_bug!(move_from.span, "this path should not cause illegal move");
167163
}

src/librustc_borrowck/diagnostics.rs

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

320-
E0509: r##"
321-
This error occurs when an attempt is made to move out of a value whose type
322-
implements the `Drop` trait.
323-
324-
Example of erroneous code:
325-
326-
```compile_fail,E0509
327-
struct FancyNum {
328-
num: usize
329-
}
330-
331-
struct DropStruct {
332-
fancy: FancyNum
333-
}
334-
335-
impl Drop for DropStruct {
336-
fn drop(&mut self) {
337-
// Destruct DropStruct, possibly using FancyNum
338-
}
339-
}
340-
341-
fn main() {
342-
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
343-
let fancy_field = drop_struct.fancy; // Error E0509
344-
println!("Fancy: {}", fancy_field.num);
345-
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
346-
}
347-
```
348-
349-
Here, we tried to move a field out of a struct of type `DropStruct` which
350-
implements the `Drop` trait. However, a struct cannot be dropped if one or
351-
more of its fields have been moved.
352-
353-
Structs implementing the `Drop` trait have an implicit destructor that gets
354-
called when they go out of scope. This destructor may use the fields of the
355-
struct, so moving out of the struct could make it impossible to run the
356-
destructor. Therefore, we must think of all values whose type implements the
357-
`Drop` trait as single units whose fields cannot be moved.
358-
359-
This error can be fixed by creating a reference to the fields of a struct,
360-
enum, or tuple using the `ref` keyword:
361-
362-
```
363-
struct FancyNum {
364-
num: usize
365-
}
366-
367-
struct DropStruct {
368-
fancy: FancyNum
369-
}
370-
371-
impl Drop for DropStruct {
372-
fn drop(&mut self) {
373-
// Destruct DropStruct, possibly using FancyNum
374-
}
375-
}
376-
377-
fn main() {
378-
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
379-
let ref fancy_field = drop_struct.fancy; // No more errors!
380-
println!("Fancy: {}", fancy_field.num);
381-
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
382-
}
383-
```
384-
385-
Note that this technique can also be used in the arms of a match expression:
386-
387-
```
388-
struct FancyNum {
389-
num: usize
390-
}
391-
392-
enum DropEnum {
393-
Fancy(FancyNum)
394-
}
395-
396-
impl Drop for DropEnum {
397-
fn drop(&mut self) {
398-
// Destruct DropEnum, possibly using FancyNum
399-
}
400-
}
401-
402-
fn main() {
403-
// Creates and enum of type `DropEnum`, which implements `Drop`
404-
let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
405-
match drop_enum {
406-
// Creates a reference to the inside of `DropEnum::Fancy`
407-
DropEnum::Fancy(ref fancy_field) => // No error!
408-
println!("It was fancy-- {}!", fancy_field.num),
409-
}
410-
// implicit call to `drop_enum.drop()` as drop_enum goes out of scope
411-
}
412-
```
413-
"##,
414-
415320
E0595: r##"
416321
Closures cannot mutate immutable captured variables.
417322

src/librustc_mir/diagnostics.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,100 @@ fn main() {
11701170
```
11711171
"##,
11721172

1173+
E0509: r##"
1174+
This error occurs when an attempt is made to move out of a value whose type
1175+
implements the `Drop` trait.
1176+
1177+
Example of erroneous code:
1178+
1179+
```compile_fail,E0509
1180+
struct FancyNum {
1181+
num: usize
1182+
}
1183+
1184+
struct DropStruct {
1185+
fancy: FancyNum
1186+
}
1187+
1188+
impl Drop for DropStruct {
1189+
fn drop(&mut self) {
1190+
// Destruct DropStruct, possibly using FancyNum
1191+
}
1192+
}
1193+
1194+
fn main() {
1195+
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
1196+
let fancy_field = drop_struct.fancy; // Error E0509
1197+
println!("Fancy: {}", fancy_field.num);
1198+
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
1199+
}
1200+
```
1201+
1202+
Here, we tried to move a field out of a struct of type `DropStruct` which
1203+
implements the `Drop` trait. However, a struct cannot be dropped if one or
1204+
more of its fields have been moved.
1205+
1206+
Structs implementing the `Drop` trait have an implicit destructor that gets
1207+
called when they go out of scope. This destructor may use the fields of the
1208+
struct, so moving out of the struct could make it impossible to run the
1209+
destructor. Therefore, we must think of all values whose type implements the
1210+
`Drop` trait as single units whose fields cannot be moved.
1211+
1212+
This error can be fixed by creating a reference to the fields of a struct,
1213+
enum, or tuple using the `ref` keyword:
1214+
1215+
```
1216+
struct FancyNum {
1217+
num: usize
1218+
}
1219+
1220+
struct DropStruct {
1221+
fancy: FancyNum
1222+
}
1223+
1224+
impl Drop for DropStruct {
1225+
fn drop(&mut self) {
1226+
// Destruct DropStruct, possibly using FancyNum
1227+
}
1228+
}
1229+
1230+
fn main() {
1231+
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
1232+
let ref fancy_field = drop_struct.fancy; // No more errors!
1233+
println!("Fancy: {}", fancy_field.num);
1234+
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
1235+
}
1236+
```
1237+
1238+
Note that this technique can also be used in the arms of a match expression:
1239+
1240+
```
1241+
struct FancyNum {
1242+
num: usize
1243+
}
1244+
1245+
enum DropEnum {
1246+
Fancy(FancyNum)
1247+
}
1248+
1249+
impl Drop for DropEnum {
1250+
fn drop(&mut self) {
1251+
// Destruct DropEnum, possibly using FancyNum
1252+
}
1253+
}
1254+
1255+
fn main() {
1256+
// Creates and enum of type `DropEnum`, which implements `Drop`
1257+
let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
1258+
match drop_enum {
1259+
// Creates a reference to the inside of `DropEnum::Fancy`
1260+
DropEnum::Fancy(ref fancy_field) => // No error!
1261+
println!("It was fancy-- {}!", fancy_field.num),
1262+
}
1263+
// implicit call to `drop_enum.drop()` as drop_enum goes out of scope
1264+
}
1265+
```
1266+
"##,
11731267

11741268
}
11751269

src/librustc_mir/util/borrowck_errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,20 @@ pub trait BorrowckErrors {
223223
err.span_label(move_from_span, "cannot move out of here");
224224
err
225225
}
226+
227+
fn cannot_move_out_of_interior_of_drop(&self,
228+
move_from_span: Span,
229+
container_ty: ty::Ty,
230+
o: Origin)
231+
-> DiagnosticBuilder
232+
{
233+
let mut err = struct_span_err!(self, move_from_span, E0509,
234+
"cannot move out of type `{}`, \
235+
which implements the `Drop` trait{OGN}",
236+
container_ty, OGN=o);
237+
err.span_label(move_from_span, "cannot move out of here");
238+
err
239+
}
226240
}
227241

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

0 commit comments

Comments
 (0)