E4006
E4006 — An assignment through a shared reference:*r = v,r.f = vorr[i] = vwhereris a&T. A shared reference only reads; writing needs a&mut T.
What the compiler reports
Error[E4006] at 30:3: this assigns through `p`
Error[E4006] at 37:3: this assigns through `r`
Error[E4006] at 38:3: this assigns through `r`
Error[E4006] at 44:5: this assigns through `h`
Error[E4006] at 47:4: this assigns through `t`
Error[E4006] at 49:3: this assigns through `w`
Error[E4006] at 53:5: this assigns through `x`
7 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
//
//
// Each assignment writes through a shared reference (`&`), which can only be read through:
// `*r = ..`, `*r += ..`, a field, an element, a `&mut` field reached through a `&`, a
// parameter, and the `&i64` items of `v.iter()`.
import core::iter;
import std::vec;
struct Holder {
n : i64,
m : &mut i64,
}
fn set(p : &i64) -> i32 {
*p = 1i64;
return 0;
}
fn main() -> i32 {
let a : i64 = 1i64;
let r : &i64 = &a;
*r = 5i64;
*r += 1i64;
let mut b : i64 = 2i64;
let hv = Holder {
n : 1i64, m : &mut b
};
let h : &Holder = &hv;
h.n = 3i64;
let arr : Tensor<i64, [2]> = [ 1i64, 2i64 ];
let t : &Tensor<i64, [2]> = &arr;
t[0] = 4i64;
let w : &Holder = &hv;
*w.m = 9i64;
let mut v = Vec<i64>::new();
v.push(40i64);
for x in v.iter() {
*x = 7i64;
}
return 0;
}
From tests/frontend/fail/write_through_a_shared_reference.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.
E4005A value that points into this function's stack frame would outlive the function: a reference to a local, or a closure that uses one, returned (on its own or inside a struct), stored through a reference, or passed to a call that could store it there. What it points at is gone once the function returns. The same holds inside a function for a block: a variable declared outside a block cannot be given a value that points at a variable declared inside it.