E3062

E3062 — A struct literal that writes its fields in an order other than the struct's declaration. The fields run in the order the source writes them, so P { y : f(), x : g() } would run f before g and store y before x. Write the fields in the order the struct declares them.

What the compiler reports

Error[E3062] at {{.*}}.vx:[[@LINE+1]]:11: the field `x` comes after `y`, but `Pair` declares `x` first. Write the fields in the order of the declaration: x, y
Error[E3062] at {{.*}}.vx:[[@LINE+1]]:11: the field `n` comes after `v`
Error[E3062] at {{.*}}.vx:[[@LINE+2]]:29: the field `r` comes after `n`
3 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
//
//
// A struct literal must write its fields in the order the struct declares them (E3062).
// The fields run in the order the source writes them, so a different order is easy to misread.

import std::vec;

struct Pair {
  x : i32,
  y : i32,
}

struct Moved {
  n : i32,
  v : Vec<i64>,
}

struct Holds {
  r : &i64,
  n : i32,
}

fn grow(v : &mut Vec<i64>) -> i32 {
  v.push(2i64);
  return v.len();
}

fn main() -> i32 {
  let mut a = Vec<i64>::with_capacity(1);
  a.push(1i64);
  let p = Pair {
    y : 1, x : 2
  };
  let b = Vec<i64>::new();
  let m = Moved {
    v : b, n : 0
  };
  // `grow` runs first, and then the borrow of `a`.
  let h = Holds {
    n : grow(&mut a), r : a.get_ref(0)
  };
  println!("{} {} {}", p.x, m.n, h.n);
  return 0;
}

From tests/frontend/fail/struct_literal_fields_out_of_declaration_order.vx, which asserts this diagnostic on every commit.

Related