Simply stated, this is an UB if you somehow transform immutable reference to a variable into mutable one. Clippy doesn't try to look at the function's body to determine whether it is the case or two references are unrelated, it just throws a warning in. And, so to say, your code in fact contains an UB: if some optimisation assumes that the object is immutable, but it was in fact mutated (through the reference acquired by this function), you'll easily can get anything wrong.
Even if you are using interior mutability, this is almost always UB.
Note: The only way to use interior mutability is by using UnsafeCell or types that use UnsafeCell, like Cell, Mutex, or Atomic*.
If we use UnsafeCell , there is also get function of UnsafeCell (UnsafeCell in std::cell - Rust), which doing the same thing.. So, what is the difference between doing manually or using UnsafeCell.
UnsafeCell is treated specially (more about it and the similar cases here). It is marked as the only thing which can be modified while being behind shared reference.
UnsafeCell is a language item. It is allowed to be modified under shared reference in the same sense as ManuallyDrop will not run destructor of its content.
Unsafe Rust is much more unsafe than unsafe C/++ as Rust restricts far much more things for the sake of performance. Those restrictions are automatically proven by compiler in safe context. But in unsafe { } it is you who has responsibility to guarantee ALL those restrictions. That's why I always (half-seriously) shout that the unsafe keyword should be renamed to unsafe_but_trust_me_i_know_what_im_doing_here