For the Rc+RefCell version, cursors i tryied includes
&mut ListNode // from_array20, not work
Rc<RefCell<ListNode>> // from_array21
&Rc<RefCell<ListNode>> // from_array22, not work
Option<Rc<RefCell<ListNode>>> // from_array23
&Option<Rc<RefCell<ListNode>>> // from_array24, not work
What I most wonder is why &mut Box<ListNode> work but &Rc<RefCell<ListNode>> don't.
let mut tail = &head;
for &i in arr.iter().skip(1) {
let node = Rc::new(RefCell::new(ListNode2 { val: i, next: None }));
tail.as_ref().unwrap().as_ref().borrow_mut().next = Some(node.clone());
let tmp = tail.as_ref().unwrap().as_ref().borrow().next.clone();
tail = &tmp;
} // tmp dropped here at the end of the iteration
let tmp = tail.as_ref().unwrap().as_ref().borrow().next.clone(); creates a new instance of Rc<RefCell<ListNode>>, which is dropped at the end of the iteration of your loop in which tmp is created. You can't hold on to a reference to the Rc instance for longer than the instance lives, as this would be a dangling pointer. Why are you trying to pass references to Rc anyway? Rc is a smart pointer already, there is really no need to put it behind a shared reference. If you need to share the Rc you can just clone it to increase its reference count and pass the clone (as you are doing in from_array21 and from_array23).
You mentioned leetcode in a previous topic, so probably they suggested or dictated the datatype. Leetcode exercises aren't necessarily a good fit for Rust code, because the problems have generally just been ported from other domains with GC or the like, where sea-of-pointer data structures don't cause lots of complications like they do with Rust's ownership-based approach. (More generally I doubt any site that generalizes over 1-2 dozen langauges can do a great job.)
There are some other practice site recommendations in this thread and others.