Step 1 Move it to another thread
An `Rc` is a reference count kept with ordinary non-atomic arithmetic — correct and fast on one thread, and a data race on two. Nothing in the program mentions thread safety: the constraint is carried by the TYPE and checked wherever the type goes. Read the error code. It is the ordinary trait-bound error, the same one that reports a missing `Display`, pointed at a marker trait nobody writes an impl for.
error[E0277]: `Rc<i32>` cannot be sent between threads safely
31 | let handle = thread::spawn(move || {
| ^^^^^^^^^ `Rc<i32>` cannot be sent between threads safely
32 | println!("{moved}");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc<i32>` cannot be sent between threads safely
33 | });
| ^^^^^ `Rc<i32>` cannot be sent between threads safely
The error points at 2 further places. A trait bound is not violated at one line; it is required at a call and unsatisfied by a type, and both ends have to be named.
31 | let handle = thread::spawn(move || {
| ------- within this `{closure@src/main.rs:31:32: 31:39}`
31 | let handle = thread::spawn(move || {
| ------------- required by a bound introduced by this call
rustc offers no edit for this one, and there is nothing evasive about that: no change to any single line makes the type satisfy the bound. The fix is to use a type that does, which is what the last step shows.