I wonder which of the variants 1 through 5 is the best way to go?
I feel like variant 1 is the most idiomatic one to use because it won't (force) unnecessary creation of Arcs. But it does feel somewhat unergonomic due to the extra Arc::new and Arc::clone needed when calling the foo method:
let x_manual_arc = Arc::new(X::new_x().await);
x_manual_arc.clone().foo1().await;
I'd also say that making the Arc creation explicit is the better option, not because it's explicit, but because it doesn't force an unwrapping operation in the case when you need ownership of the value (without the Arc), increasing type safety (since Arc-unwrapping is fallible).
Taking the Arc by-value is also the more expressive option in that it shows clearly that ownership of the Arc is needed (and it can also avoid an unnecessary clone, although cloning Arc is cheap so this is not the foremost reason).
Take time to code as not to need Arc and spawn_blocking.
Assuming the above isn't chosen;
Consider what method will cause least breakage if code refactored in future. Hiding the Arc internally generally will do so; but I have no idea if Arc is needed outside to be used in other parts of code.
Maybe I should consider this to be an (ugly) implementation detail and go for variant 5. But in the particular case, it will be a private module, so I don't need to care for a clean/stable API.
Anyway, I believe that in Rust it's usualluy idiomatic to expose the question whether an Arc is needed/consumed/created to the user of an API.