First, if Tile is a small object, consider making it a Copy type (#[derive(Copy)]), so it will be easy to work with. Instead of "can't move out of borrowed context" error, the compiler will copy it.
Swap can be used, but there's a catch. The borrow checker doesn't understand that vec[0] and vec[1] are different! So when you borrow both, it just sees vec borrowed twice and complains. The solution to this is
let (left, right) = vec.split_at_mut(position);
split_at_mut gives you two separate slices pointing into two non-overlapping areas in the same vector or slice.
BTW: there's no 2D vector in Rust. What you have is a "jagged array" where every row is allowed to have a different dimension. If your grid has a fixed size, then 2D array may work ([[Tile; width]; height]). There's imgref crate that gets close to being a 2D vector by adding 2D addressing to a 1D vectors. It's designed for images, but would work with other types.