E4013
E4013 — A field moved out of a value that must keep it:let x = p.awherep's type implementsDrop, whosedropneeds every field, orlet x = make().a, where the value has no name and drops all its fields at the end of the statement. Borrow the field (&p.a), clone it, or bind the value to a variable first.
What the compiler reports
Error[E4013] at [[@LINE+1]]:18: this field cannot be moved out of a value with no name
Error[E4008] at [[@LINE+1]]:16: this field cannot be moved out through a reference
2 error(s) emitted
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// Reading a field that has something to drop moves it out of its struct. Two such moves are
// refused, because nothing could stop the field being dropped twice: one out of a value with no
// name (E4013), which drops all its fields at the end of the statement, and one through a
// reference (E4008), which does not own the field.
import core::ops;
struct Noisy {
id : i32,
}
impl Drop for Noisy {
fn drop(self : &mut Noisy) -> void {
print(self.id);
}
}
struct Pair {
a : Noisy,
b : Noisy,
}
fn make() -> Pair {
return Pair {
a : Noisy {
id : 1
},
b : Noisy {
id : 2
}
};
}
fn field_of_a_call_result() -> i32 {
let x = make().a;
return x.id;
}
fn field_through_a_reference(r : &Pair) -> i32 {
let x = (*r).a;
return x.id;
}
fn main() -> i32 {
return 0;
}
From tests/frontend/fail/field_with_something_to_drop_moved_out_of_its_struct.vx, which asserts this diagnostic on every commit.
Related
Ownership and borrowingThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E4012A call to the
drop method of a Drop impl by hand: x.drop(). drop runs when the value is dropped, so calling it as well would run it twice. Write drop(x), from core::mem, to drop a value early.