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.)
The error message
Section titled “The error message”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}What it means
Section titled “What it means”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.
Why Rust does this
Section titled “Why Rust does this”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.
How to fix it
Section titled “How to fix it”Fix 1: Use the number directly
Section titled “Fix 1: Use the number directly”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:
33Not 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() -> u32returns an order id, and thenorder.totalfails becauseorderis au32. - A
HashMap<&str, u32>stores only scores, and thenscores["ana"].scorefails because each value is au32, not aPlayer.
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 numberfn 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 centsana: score 10, level 2If a number is all you need, keep the u32 and just drop the .field part. See Structs and HashMaps.
Fix 3: Remove the extra .0
Section titled “Fix 3: Remove the extra .0”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 = 342 mend y = 4Count 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.
Where you’ll usually see it
Section titled “Where you’ll usually see it”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.
Related errors
Section titled “Related errors”- E0609: no field
xon typeT: the type has no field with that name. You get this one (not E0610) for references like&u32. - E0615: attempted to take value of method: you wrote
price.roundinstead ofprice.round(). E0689: can't call method on ambiguous numeric type: a method on a number whose type isn’t picked yet. Add a type likei32.- E0599: no method named x found: the method version, for example a method that numbers don’t have.
- E0308: mismatched types: often appears next to E0610 when a function returns a number but you expected a struct.
- All compiler errors explained
Quick check
Section titled “Quick check”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
Read more
Section titled “Read more”- E0610 — Rust error codes index: the official explanation of this error.
- Data Types — The Rust Book: scalar types (integers, floats,
bool,char) and compound types (tuples, arrays). - Tuple Structs — The Rust Book: wrapper types like
Meters(u32)and how.0works on them. - Primitives — Rust by Example: the built-in types, with runnable examples.
i32— Rust standard library: every method an integer has (and you’ll see they’re all called with()).