Skip to content

Rust Error E0610: Primitive Type Doesn't Have Fields

E0610 means: you wrote something.field, but something is a plain number (or a bool or char), and those have no fields at all. It almost always means the variable isn’t what you think it is. Maybe you already took the number out of a struct, a function returned a number instead of a struct, or you wrote one .0 too many. The message tells you the exact type Rust sees, so you’re one step away from the fix. (This page is part of Rust compiler errors explained.)

error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
--> src/main.rs:3:22
|
3 | println!("{}", x.value); // ❌ x is a number, it has no `value` field
| ^^^^^

This is the program that produces it:

fn main() {
let x = 5;
println!("{}", x.value); // ❌ x is a number, it has no `value` field
}

The type in backticks is what Rust thinks your variable is. Here it’s `{integer}`, which means “some whole number, I haven’t decided which kind yet” (Rust picks i32 later if nothing else decides). You’ll also see `{float}` for decimals, or a concrete type like u32, usize, f64, bool or char.

The ^^^^^ points at the name after the dot. Rust isn’t saying “value is spelled wrong”. It’s saying “a number can’t have any field, whatever you call it”.

So the question to ask is: why is this variable a number? It’s like asking for “the price tag on 5”. A product has a price tag. The number 5 is just a number.

Primitive types like i32, u32, f64, bool and char are single values built into the language. They’re not structs, so there’s nothing inside them to reach with a dot and a name. See Data types.

They do have methods, though: x.abs(), x.pow(2), price.round(), c.is_alphabetic(). Methods are called with (). Fields are data stored inside a struct, and only structs, tuples and unions have them.

Because Rust checks every .field at compile time, this mix-up can never become a crash or a silent undefined at runtime. You find out right away, at the exact line.

Choose this when you already took the field out of the struct earlier. After let count = counter.value;, count is the number, so count.value asks for a field on a u32:

error[E0610]: `u32` is a primitive type and therefore doesn't have fields
--> src/main.rs:8:26
|
8 | println!("{}", count.value);
| ^^^^^

Either use the number as it is, or go back to the struct and read the field from there:

struct Counter {
value: u32,
}
fn main() {
let mut counter = Counter { value: 0 };
counter.value += 3;
let count = counter.value; // count is a plain u32 now
println!("{}", count); // ✅ use the number itself
println!("{}", counter.value); // ✅ or read the field from the struct
}

Output:

3
3
▶ Try it Yourself

Not sure what type a variable has? Hover over it in your editor (with rust-analyzer, see Rust tools). Or write let _: () = count; for a moment: rustc answers with expected `()`, found `usize` and tells you the real type. Delete the line afterwards.

Fix 2: Return or store the struct, not the number

Section titled “Fix 2: Return or store the struct, not the number”

Choose this when the value came from a function or a collection, and you expected a struct. Two common cases:

  • A function like fn find_order() -> u32 returns an order id, and then order.total fails because order is a u32.
  • A HashMap<&str, u32> stores only scores, and then scores["ana"].score fails because each value is a u32, not a Player.

Decide what you really want. If you need several pieces of data, change the return type or the value type to the struct:

use std::collections::HashMap;
struct Order {
id: u32,
total: u32, // in cents
}
// returns the whole Order, not just a number
fn new_order(id: u32, total: u32) -> Order {
Order { id, total }
}
struct Player {
score: u32,
level: u8,
}
fn main() {
let order = new_order(7, 1999);
println!("Order {} costs {} cents", order.id, order.total);
// the map stores whole Players, not just their scores
let mut players: HashMap<&str, Player> = HashMap::new();
players.insert("ana", Player { score: 10, level: 2 });
let ana = &players["ana"];
println!("ana: score {}, level {}", ana.score, ana.level);
}

Output:

Order 7 costs 1999 cents
ana: score 10, level 2
▶ Try it Yourself

If a number is all you need, keep the u32 and just drop the .field part. See Structs and HashMaps.

Choose this when the error points at a .0 or .1. Tuples and tuple structs use positions for their fields, and it’s easy to go one level too deep. After let x = point.0;, x is already the number, so x.0 gives `{integer}` is a primitive type. The same happens with a wrapper like struct Meters(u32);: one .0 gets the u32 out, and a second .0 fails.

struct Meters(u32);
fn main() {
let point = (3, 4);
let x = point.0; // x is already the number 3
println!("x = {}", x); // not x.0
let m = Meters(42);
println!("{} m", m.0); // one .0 takes the u32 out of the tuple struct
let line = ((0, 0), (3, 4)); // nested tuples: one position per level
println!("end y = {}", line.1.1);
}

Output:

x = 3
42 m
end y = 4
▶ Try it Yourself

Count the levels: each .0 or .1 goes one level into a tuple. When you reach a number, stop. If the positions get confusing, give them names with a struct instead. See Accessing elements by position and When to use a tuple vs a struct.

A method without (). price.round on an f64, or x.abs on an i32, is not E0610 but E0615, “attempted to take value of method”, because those names are methods. Fix: price.round(), x.abs(). One surprise: if the type is still {integer} (as in let x = -5;), even x.abs gives E0610, and x.abs() then gives E0689 “can’t call method abs on ambiguous numeric type {integer}”. Pick a type, let x: i32 = -5;, and x.abs() works.

A reference to a number. If the variable is a &u32 instead of a u32, the code changes to E0609: no field `value` on type `&u32`. A common place is a loop like for (name, score) in &players, where score is a &i32, and score.1 gives no field `1` on type `&{integer}`. Same cause, same fixes: score is already the number.

The result of len() or count(). let len = scores.len(); gives you a usize, so len.count fails with `usize` is a primitive type. Fix: use len directly.

Numbers with a unit. If you want price.cents or distance.meters, make a small struct: struct Price { cents: u64 }. Then price.cents works, and the type stops you from mixing up prices and other numbers. See Structs.

Quick check

1. After let total = cart.total; (where total is a u32 field), what does total.amount give?

2. What does {integer} mean in the message?

3. let x = point.0; then x.0 gives E0610. What's the fix?

Score: 0 / 3