Move E0509 diagnostic into mod borrowck_errors shared between ast- and mir-borrowck.
This commit is contained in:
parent
a995b56a5e
commit
fdd7d13c24
4 changed files with 111 additions and 102 deletions
|
|
@ -155,13 +155,9 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
|||
Categorization::Interior(ref b, mc::InteriorField(_)) => {
|
||||
match b.ty.sty {
|
||||
ty::TyAdt(def, _) if def.has_dtor(bccx.tcx) => {
|
||||
let mut err = struct_span_err!(bccx, move_from.span, E0509,
|
||||
"cannot move out of type `{}`, \
|
||||
which implements the `Drop` trait",
|
||||
b.ty);
|
||||
err.span_label(move_from.span, "cannot move out of here");
|
||||
err
|
||||
},
|
||||
bccx.cannot_move_out_of_interior_of_drop(
|
||||
move_from.span, b.ty, Origin::Ast)
|
||||
}
|
||||
_ => {
|
||||
span_bug!(move_from.span, "this path should not cause illegal move");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,101 +317,6 @@ fn main() {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0509: r##"
|
||||
This error occurs when an attempt is made to move out of a value whose type
|
||||
implements the `Drop` trait.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0509
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let fancy_field = drop_struct.fancy; // Error E0509
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Here, we tried to move a field out of a struct of type `DropStruct` which
|
||||
implements the `Drop` trait. However, a struct cannot be dropped if one or
|
||||
more of its fields have been moved.
|
||||
|
||||
Structs implementing the `Drop` trait have an implicit destructor that gets
|
||||
called when they go out of scope. This destructor may use the fields of the
|
||||
struct, so moving out of the struct could make it impossible to run the
|
||||
destructor. Therefore, we must think of all values whose type implements the
|
||||
`Drop` trait as single units whose fields cannot be moved.
|
||||
|
||||
This error can be fixed by creating a reference to the fields of a struct,
|
||||
enum, or tuple using the `ref` keyword:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let ref fancy_field = drop_struct.fancy; // No more errors!
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Note that this technique can also be used in the arms of a match expression:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
enum DropEnum {
|
||||
Fancy(FancyNum)
|
||||
}
|
||||
|
||||
impl Drop for DropEnum {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropEnum, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Creates and enum of type `DropEnum`, which implements `Drop`
|
||||
let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
|
||||
match drop_enum {
|
||||
// Creates a reference to the inside of `DropEnum::Fancy`
|
||||
DropEnum::Fancy(ref fancy_field) => // No error!
|
||||
println!("It was fancy-- {}!", fancy_field.num),
|
||||
}
|
||||
// implicit call to `drop_enum.drop()` as drop_enum goes out of scope
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0595: r##"
|
||||
Closures cannot mutate immutable captured variables.
|
||||
|
||||
|
|
|
|||
|
|
@ -1170,6 +1170,100 @@ fn main() {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0509: r##"
|
||||
This error occurs when an attempt is made to move out of a value whose type
|
||||
implements the `Drop` trait.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0509
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let fancy_field = drop_struct.fancy; // Error E0509
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Here, we tried to move a field out of a struct of type `DropStruct` which
|
||||
implements the `Drop` trait. However, a struct cannot be dropped if one or
|
||||
more of its fields have been moved.
|
||||
|
||||
Structs implementing the `Drop` trait have an implicit destructor that gets
|
||||
called when they go out of scope. This destructor may use the fields of the
|
||||
struct, so moving out of the struct could make it impossible to run the
|
||||
destructor. Therefore, we must think of all values whose type implements the
|
||||
`Drop` trait as single units whose fields cannot be moved.
|
||||
|
||||
This error can be fixed by creating a reference to the fields of a struct,
|
||||
enum, or tuple using the `ref` keyword:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
struct DropStruct {
|
||||
fancy: FancyNum
|
||||
}
|
||||
|
||||
impl Drop for DropStruct {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropStruct, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let drop_struct = DropStruct{fancy: FancyNum{num: 5}};
|
||||
let ref fancy_field = drop_struct.fancy; // No more errors!
|
||||
println!("Fancy: {}", fancy_field.num);
|
||||
// implicit call to `drop_struct.drop()` as drop_struct goes out of scope
|
||||
}
|
||||
```
|
||||
|
||||
Note that this technique can also be used in the arms of a match expression:
|
||||
|
||||
```
|
||||
struct FancyNum {
|
||||
num: usize
|
||||
}
|
||||
|
||||
enum DropEnum {
|
||||
Fancy(FancyNum)
|
||||
}
|
||||
|
||||
impl Drop for DropEnum {
|
||||
fn drop(&mut self) {
|
||||
// Destruct DropEnum, possibly using FancyNum
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Creates and enum of type `DropEnum`, which implements `Drop`
|
||||
let drop_enum = DropEnum::Fancy(FancyNum{num: 10});
|
||||
match drop_enum {
|
||||
// Creates a reference to the inside of `DropEnum::Fancy`
|
||||
DropEnum::Fancy(ref fancy_field) => // No error!
|
||||
println!("It was fancy-- {}!", fancy_field.num),
|
||||
}
|
||||
// implicit call to `drop_enum.drop()` as drop_enum goes out of scope
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,6 +223,20 @@ pub trait BorrowckErrors {
|
|||
err.span_label(move_from_span, "cannot move out of here");
|
||||
err
|
||||
}
|
||||
|
||||
fn cannot_move_out_of_interior_of_drop(&self,
|
||||
move_from_span: Span,
|
||||
container_ty: ty::Ty,
|
||||
o: Origin)
|
||||
-> DiagnosticBuilder
|
||||
{
|
||||
let mut err = struct_span_err!(self, move_from_span, E0509,
|
||||
"cannot move out of type `{}`, \
|
||||
which implements the `Drop` trait{OGN}",
|
||||
container_ty, OGN=o);
|
||||
err.span_label(move_from_span, "cannot move out of here");
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'tcx, 'gcx> BorrowckErrors for TyCtxt<'b, 'tcx, 'gcx> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue