This error occurs because you are trying to pass a string slice (&str) where a string value (String) is required, or vice versa, without an explicit conversion. Rust does not automatically coerce between these types in all contexts, so you must manually convert the slice to an owned string using .to_string() or .to_owned(), or change the function signature to accept a generic string type.
If your function expects a String but you have a &str (like a string literal), convert the slice to an owned String before passing it. This allocates a new heap buffer containing the string data.
fn process_data(name: String) {
println!("Processing: {}", name);
}
fn main() {
let literal: &str = "Alice";
// Fix: Convert &str to String
process_data(literal.to_string());
// Alternatively, if you own the String already, you can move it
let owned = String::from("Bob");
process_data(owned);
}
If you are defining a function and don't actually need ownership of the string, it is often better to change the function signature to accept &str. This avoids unnecessary allocations and allows the function to work with both string literals and slices of owned strings.
// Better: Accept a string slice to avoid allocation
fn process_data(name: &str) {
println!("Processing: {}", name);
}
fn main() {
let literal: &str = "Alice";
let owned = String::from("Bob");
// Both work without conversion
process_data(literal);
process_data(&owned);
}
For more complex scenarios where you want to accept either String or &str without writing two separate functions, use the AsRef<str> trait. This is the idiomatic Rust approach for generic string handling.
fn process_data<T: AsRef<str>>(name: T) {
println!("Processing: {}", name.as_ref());
}
fn main() {
process_data("Alice"); // &str
process_data(String::from("Bob")); // String
}
Choose the fix based on your needs: use .to_string() if the caller must own the data, change the signature to &str if borrowing is sufficient, or use AsRef<str> for maximum flexibility.