Hello, I'm new rustacean here and just learning the language using leetcode problems as a practice.
TL;DR; Introducing use std::borrow::BorrowMut; use std::borrow::Borrow;
breaks .borrow()
method for Rc<RefCell<T>>
type. But it works if I write .as_ref().borrow()
.
Last couple of days daily leetcode has Trees. And I'm strugling with Rust more than with the problems since I still don't know many of concepts and do not understand borrowing fully.
One of my struggles was an LSP's auto import of std::borrow::Borrow
. Every time it happens, part of my code breaks.
Below is one of my functions:
pub fn sum_of_left_leaves_without_copy(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut result = 0;
fn go_deeper(root: &Option<Rc<RefCell<TreeNode>>>, is_left: bool, result: &mut i32) {
if root.is_some() {
let root = root.clone().unwrap();
let borrowed_root = root.borrow();
match (&borrowed_root.left, &borrowed_root.right) {
(None, None) if is_left => *result += borrowed_root.val,
(None, None) => {}
(Some(_), None) => {
go_deeper(&borrowed_root.left, true, result);
}
(None, Some(_)) => {
go_deeper(&borrowed_root.right, false, result);
}
(Some(_), Some(_)) => {
go_deeper(&borrowed_root.left, true, result);
go_deeper(&borrowed_root.right, false, result);
}
}
}
}
go_deeper(&root, false, &mut result);
result
}
It works fine as is. But if I introduce
use std::borrow::BorrowMut;
There will be next errors:
error[E0282]: type annotations needed for `&Borrowed`
--> src\trees.rs:70:17
|
70 | let borrowed_root = root.borrow();
| ^^^^^^^^^^^^^
71 |
72 | match (&borrowed_root.left, &borrowed_root.right) {
| ------------------ type must be known at this point
|
help: consider giving `borrowed_root` an explicit type, where the type for type parameter `Borrowed` is specified
|
70 | let borrowed_root: &Borrowed = root.borrow();
| +++++++++++
error[E0609]: no field `left` on type `&_`
--> src\trees.rs:72:35
|
72 | match (&borrowed_root.left, &borrowed_root.right) {
| ^^^^ unknown field
I tried to define type as first error suggested but I can't do it at all. RefCell<TreeNode>
doesn't work and other variations that I could think of too.
But surprisingly introducing as_ref()
fixes the issue.
So the line
let borrowed_root = root.as_ref().borrow();
It works as expected, and there is no error.
So I have the next question:
- Why does
use std::borrow::Borrow;
break the code with errors listed above? - Why using
as_ref()
fixes the issue? - Is it possible to prevent LSP from suggesting options that lead to an import of a trait when autocompliting method?
Big thanks to everyone who read it all and will answer here. I will also be very grateful if you point out any useful further reading for me.