What's wrong with this line and why?

fn main() {
   
   let name = String::from("hello");

   let (name, len) = calc_len(name);

   println!("{name} : {len}");
    
}
fn calc_len(name:String)->(String,usize) {
    (name,name.len()) // this one ????
}





you're transfering ownership of the 'name' and in the same time you want to access it

but i think tuple should be evaluted first then return /transfer

or in some diff way process is going on??

...and in this process of evaluation, name will be moved into its first element, before evaluation comes to the second one. Swapping the order of the fields works.

There's no "build the tuple, then transfer" step. Building (a, b) is evaluating a and moving it into slot 0, then evaluating b and moving it into slot 1 - left to right. So name is already moved by the time name.len() runs, and you get E0382.

Proof it's purely ordering: (name.len(), name) compiles fine.

In other words, (<some-expr-x>, <some-expr-y>) is evaluated as:

let tuple_0 = <some-expr-x>;
let tuple_1 = <some-expr-y>;
(tuple_0, tuple_1)

So (name, name.len()) is equivalent to:

let tuple_0 = name; // moves `name`
let tuple_1 = name.len(); // `name` already moved
(tuple_0, tuple_1)

For the sake of completion, it's worth mentioning that in Rust you'll usually create temporary ad-hoc variables particularly to get around this problem:

fn calc_len(name:String)->(String,usize) {
    let len = name.len();

    (name,len)
}