Why does quoting a use statement cause a variable type to change?

play ground

Please forgive me, I don't know what title is best.

Question:
Why when I introduce the use statement in the first line,
the type of v here is not RefCell<String>,
but something else?

Method resolution when you use . on T proceeds like so:

Look for a receiver with type...

  • T, then &T, then &mut T. Next try...
  • *T, &*T, &mut *T. (Note that &*T may not be T thanks to Deref coercion.)
  • **T, &**T, &mut **T
  • ...etc until it finds one or can't dereference...
  • finally if an unsized coercion applies at the end resulting in U, try:
    • U, &U, &mut U

The search stops once an receiver is found. Inherant methods and trait methods are considered when looking for the receivers. A trait has to be in scope to be considered. Some are "always" in scope (in typical Rust) because of the prelude.

In the case of ties between inherent methods and traits, the inherent method wins. In the case of ties between multiple traits, you have to be explicit.


So what's going on in your code? Method resolution isn't finding a borrow_mut on your Arc at all, so it dereferences it; this finds the RefCell. RefCell has an inherent borrow_mut method, and that is what gets chosen.

But when you uncomment the use, it brings the BorrowMut<_> trait into scope. That trait has a blanket implementation that applies to Arc (and everything else). So now method resolution finds a receiver for the Arc before it tries dereferencing to the RefCell underneath.

What to do if you need the RefCell version while the BorrowMut trait is in scope? You can dereference past the Arc.

            let mut v = (*s).borrow_mut();
            let mut v = RefCell::borrow_mut(&*s);
4 Likes

Let me summarize:

The specific reasons are:

use std::borrow::BorrowMut; will cause the function called by s.borrow_mut to actually be borrow_mut in BorrowMut,

You can jump to the definition through the IDE to see the specific source code.

Thank you very much, this forum helped me with many questions.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.