Rust Error E0615: Attempted to Take Value of Method
E0615 means: you wrote value.something without parentheses, but something is a method, not a field. In Rust, a method only runs when you call it with (), even when it takes no arguments. This one is very common if you come from C#, JavaScript or Python, where .Count, .length or a property look like plain fields. The fix is almost always two characters long. (This page is part of Rust compiler errors explained.)
The error message
Section titled “The error message”error[E0615]: attempted to take value of method `len` on type `String` --> src/main.rs:3:46 |3 | println!("{} has {} letters", name, name.len); // ❌ `len` is a method | ^^^ method, not a field |help: use parentheses to call the method |3 | println!("{} has {} letters", name, name.len()); // ❌ `len` is a method | ++This is the program that produces it:
fn main() { let name = String::from("Ferris"); println!("{} has {} letters", name, name.len); // ❌ `len` is a method}What it means
Section titled “What it means”Read the headline from the end: on type String is the type Rust looked at, and method len is what it found there. So Rust did find len. It just isn’t a value you can read like a field. It’s a piece of code that has to run.
The label method, not a field and the ++ under () in the help say exactly that: add the parentheses and you’re done.
Think of a vending machine. A field is a label printed on the machine (“Machine #12”): you just read it. A method is a button (“Show my change”): nothing happens until you press it. name.len points at the button. name.len() presses it.
Why Rust does this
Section titled “Why Rust does this”Rust keeps fields and methods strictly apart. A field is data stored inside the struct. A method is a function defined in an impl block that takes self. You read a field with value.field and call a method with value.method(). See Adding behavior with methods.
Many languages blur this line with properties: list.Count in C# or text.length in JavaScript look like fields but run code behind the scenes. Rust doesn’t have properties on purpose. When you see (), you know code runs and may take time; when you don’t, you know it’s a plain read of stored data. Nothing is hidden.
A struct can even have a field and a method with the same name, like a private balance field and a public balance() method. That’s only possible because Rust never guesses which one you meant: no parentheses means the field, parentheses means the method.
How to fix it
Section titled “How to fix it”Fix 1: Add the parentheses
Section titled “Fix 1: Add the parentheses”Choose this almost every time. Follow the help: line and call the method. This works the same for your own methods (like total on a shopping cart) and for standard ones like len, is_empty, trim and count:
struct Item { price: u32, // in cents qty: u32,}
struct Cart { items: Vec<Item>,}
impl Cart { fn total(&self) -> u32 { self.items.iter().map(|i| i.price * i.qty).sum() }}
fn main() { let name = String::from("Ferris"); println!("{} has {} letters", name, name.len()); // ✅ called
let cart = Cart { items: vec![Item { price: 250, qty: 2 }, Item { price: 100, qty: 1 }], }; if !cart.items.is_empty() { println!("Total: {} cents", cart.total()); // ✅ called }}Output:
Ferris has 6 lettersTotal: 600 centsIf the method needs arguments, rustc shows where they go with a _ placeholder. For s.contains the help reads s.contains(_): fill in what you’re looking for, such as s.contains("world"). If you’re not sure what a method needs, rustc’s next error (E0061) will tell you how many arguments it takes.
Fix 2: Pass the method as a function, not value.method
Section titled “Fix 2: Pass the method as a function, not value.method”Choose this when you didn’t want to call the method right now, but hand it to something else, like .map() or sort_by_key. Writing .map(words[0].len) gives E0615 too. You have two good options: a short closure that calls the method, or the method’s full path, String::len, which works like a function name:
fn main() { let words = vec![String::from("crab"), String::from("ferris"), String::from("rust")];
// a closure that calls the method on each item let lengths: Vec<usize> = words.iter().map(|w| w.len()).collect(); println!("{:?}", lengths);
// the method's path works like a function name let same: Vec<usize> = words.iter().map(String::len).collect(); println!("{:?}", same);
let mut sorted = words.clone(); sorted.sort_by_key(|w| w.len()); println!("{:?}", sorted);}Output:
[4, 6, 4][4, 6, 4]["crab", "rust", "ferris"]String::len works here because iter() gives you &String items, and String::len takes a &String. When the types don’t line up exactly, the closure |w| w.len() is the easy choice that always works.
Fix 3: Make it a field, if it really is stored data
Section titled “Fix 3: Make it a field, if it really is stored data”Choose this when the error is in your own struct and you realize the value should just be stored. This is a design question: field or method?
- Make it a field when the value is given once and doesn’t depend on anything else: an
id, aname, acreated_atdate. - Make it a method when the value is worked out from other data: a
totalfrom the items, anareafrom width and height, alenfrom the contents.
A stored total field would go out of date the moment someone adds an item and forgets to update it. A total() method is calculated fresh every time, so it can never be wrong. Here id is a field and total is a method, and you can see the method stays correct as the order changes:
mod shop { pub struct Order { pub id: u32, // stored: set once, read with order.id prices: Vec<u32>, // private: only changed through methods }
impl Order { pub fn new(id: u32) -> Self { Order { id, prices: Vec::new() } }
pub fn add(&mut self, price: u32) { self.prices.push(price); }
// computed: always matches the prices, can't go stale pub fn total(&self) -> u32 { self.prices.iter().sum() }
pub fn item_count(&self) -> usize { self.prices.len() } }}
use shop::Order;
fn main() { let mut order = Order::new(17); order.add(250); order.add(100); println!("Order {}: {} items, {} cents", order.id, order.item_count(), order.total());
order.add(50); println!("Order {}: {} items, {} cents", order.id, order.item_count(), order.total());}Output:
Order 17: 2 items, 350 centsOrder 17: 3 items, 400 centsThere’s a middle way you’ll see in many libraries: a private field plus a public method with the same name (a “getter”). Other code can read the value with acc.balance() but can’t change it directly. Writing acc.balance from outside the module then gives a slightly different error, E0616 “field balance of struct Account is private”, with the hint a method `balance` also exists, call it with parentheses. Same fix: add (). See Everything is private by default.
Where you’ll usually see it
Section titled “Where you’ll usually see it”Habits from other languages. name.len, list.is_empty, text.trim, words.iter().count all give E0615. Every one of them is a method in Rust, so every one needs (). Fix: name.len(), list.is_empty(), and so on. See Useful string methods.
len on a Vec. scores.len is the one exception to the message: you get E0616, “field len of struct Vec is private”, because Vec really has a hidden field called len. rustc still adds help: a method `len` also exists, call it with parentheses. Fix: scores.len(). (scores.is_empty gives the normal E0615.) See Vectors.
A method that changes something. counter.increment; on its own line gives E0615 as well, even though you didn’t want a value. Without () nothing runs. Fix: counter.increment();.
The reverse: calling a field like a method. If name is a field, user.name() gives E0599 with the label field, not a method and help: remove the arguments. Fix: user.name. And if the field holds a closure, like on_click: Box<dyn Fn() -> String>, rustc says surround the field access with parentheses: write (button.on_click)() to call it.
Related errors
Section titled “Related errors”- E0609: no field
xon typeT: the name after the dot isn’t a field or a method of that type. Usually a typo or anOptionthat needs unwrapping. - E0599: no method named x found: the opposite direction,
user.name()whennameis a field, or a method that doesn’t exist. - E0616: field is private:
scores.lenon aVec, or a private field with a public getter of the same name. Call the method instead. - E0061: wrong number of arguments: you added the
(), but the method needs arguments. - E0610: primitive type doesn’t have fields:
.somethingon a number,boolorchar. - All compiler errors explained
Quick check
Section titled “Quick check”Quick check
1. You get "attempted to take value of method is_empty on type String". What's the fix?
2. Which one should usually be a method instead of a stored field?
3. You want the length of every word: words.iter().map(???). What works?
Score: 0 / 3
Read more
Section titled “Read more”- E0615 — Rust error codes index: the official explanation of this error.
- Method Syntax — The Rust Book: how methods are defined and called, and getters that share a name with a field.
- Defining and Instantiating Structs — The Rust Book: fields, and how to read them with dot notation.
- Method call expressions — The Rust Reference: the exact rules for
value.method(). - Methods — Rust by Example: short, runnable examples of methods and associated functions.