Change the root node in a binary tree - rust

I wrote a binary tree of i32. I want to change its root node to left node. But always failed. How to do it?
fn left(&mut self) -> Result<(), Error> {
match self.root.as_mut() {
Some(root) => match root.left {
Some(left) => {
self.root = Some(left); // this line always failed
return Ok(());
}
None => {
return Err(Error::NotFound);
}
},
None => {
return Err(Error::EmptyTree);
}
}
}
self.root = Some(left) I think it is easy to do this, but always failed.
error[E0507]: cannot move out of `root.left.0` which is behind a mutable reference
--> src/main.rs:120:33
|
120 | Some(root) => match root.left {
| ^^^^^^^^^ help: consider borrowing here: `&root.left`
121 | Some(left) => {
| ----
| |
| data moved here
| move occurs because `left` has type `Box<Node>`, which does not implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
playground

You can use std::mem::take, which allows taking things out of a mutable reference to them (replacing the pointed value with the default value of that type). That is, your function left can be rewritten:
use std::mem::take;
fn left(&mut self) -> Result<(), Error> {
let root = self.root.as_mut().ok_or(Error::EmptyTree)?;
let left = take(&mut root.left).ok_or(Error::NotFound)?;
*root = left;
Ok(())
}
Edit: turns out there is a method that does exactly that. I'll leave my first snippet so that you understand what happens, but the following is probably more suitable in real code.
fn left(&mut self) -> Result<(), Error> {
let root = self.root.as_mut().ok_or(Error::EmptyTree)?;
let left = root.left.take().ok_or(Error::NotFound)?;
*root = left;
Ok(())
}

Related

Rust "use of moved value" error with map_err and '?' operator but not with match return

I am trying to use the '?' operator and map_err to help flatten code that has a lot of simple matches that return on errors. The following is a code snippet to reproduce the compiler error I have been getting. I was wondering if anyone knows why compiler_error results in a 'use of moved value' error when no_compiler_error do not. They seem to have similar control flow and the function in map_err and after_test will never both be called, but there is clearly something I am missing.
fn main() {
no_compiler_error_1();
no_compiler_error_2();
compiler_error();
}
fn no_compiler_error_1() -> Result<(), String> {
let outer = String::from("Outer Error");
match test() {
Ok(()) => (),
Err(inner) => return Err(error_test(inner, outer))
};
after_test(outer);
Ok(())
}
fn no_compiler_error_2() -> Result<(), String> {
let outer = String::from("Outer Error");
test()?;
after_test(outer);
Ok(())
}
fn compiler_error() -> Result<(), String> {
let outer = String::from("Outer Error");
test().map_err(|inner| error_test(inner, outer))?;
after_test(outer);
Ok(())
}
fn test() -> Result<(), String> {
Err(String::from("Inner Error"))
}
fn error_test(inner: String, outer: String) -> String {
format!("{}:{}", inner, outer)
}
fn after_test(outer: String) {
format!("{} did not happen", outer);
}
error[E0382]: use of moved value: `outer`
--> src\main.rs:27:16
|
25 | let outer = String::from("Outer Error");
| ----- move occurs because `outer` has type `String`, which does not implement the `Copy` trait
26 | test().map_err(|inner| error_test(inner, outer))?;
| ------- ----- variable moved due to use in closure
| |
| value moved into closure here
27 | after_test(outer);
| ^^^^^ value used here after move
For more information about this error, try `rustc --explain E0382`.

Cannot infer an appropriate lifetime due to conflicting requirements

I am new to rust and I am building a TUI app using rust-tui to practice and understand the concepts of rust. I have this code:
// the widgets that can be renderd on the screen
#[derive(Clone)]
pub enum Widgets<'a> {
ResList(ResList<'a>),
ListResults(ListResults<'a>),
Input(Input),
}
pub struct Screen<'a> {
renders_done: u32,
tx: Sender<Result<Event, crossterm::ErrorKind>>,
rx: Receiver<Result<Event, crossterm::ErrorKind>>,
main_screen: Widgets<'a>,
}
impl Screen<'_> {
pub async fn handle_events(&mut self) {
let event = self
.rx
.recv()
.expect("Err while recievent the events in the reciever")
.unwrap();
let new_screen: Option<Widgets> = match &mut self.main_screen {
Widgets::ResList(res_list) => {
match event {
Event::Key(event) => match event.code {
KeyCode::Esc => {
Screen::exit_app();
None
}
_ => None,
}
}
Widgets::Input(input) => input.handle_events(event).await, <-- the problem comes when I add this
_ => None,
};
match new_screen {
Some(screen) => self.main_screen = screen,
None => {}
}
}
}
impl Input {
async fn handle_events(&mut self, event: Event) -> Option<Widgets> {
None
}
}
The idea is that if a sub-module returns a widget the main screen should be changed to that new widget. For texting purposes for now I never return a widget.
But when I try and build the code the compiler complains:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the method body at 84:32...
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^
note: ...so that the expression is assignable
--> src/model/tui/screen.rs:84:32
|
84 | pub async fn handle_events(&mut self) {
| ^^^^^^^^^
= note: expected `&mut Screen<'_>`
found `&mut Screen<'_>`
note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 45:13...
--> src/model/tui/screen.rs:45:13
|
45 | impl Screen<'_> {
| ^^
note: ...so that the expression is assignable
--> src/model/tui/screen.rs:126:52
|
126 | Some(mut screen) => self.main_screen = screen,
| ^^^^^^
= note: expected `Widgets<'_>`
found `Widgets<'_>`
error: aborting due to previous error; 8 warnings emitted
For more information about this error, try `rustc --explain E0495`.
From what I understand the lifetimes are not living enough to be saved in the struct but I am not using references anywhere they are all owned values. Can someone help me understand what am I missing?
Specify the lifetimes explicitly on the widget returned and create an explicit lifetime of the object:
impl<'screen> Screen<'screen> {
pub async fn handle_events<'c>(&'cmut self) {
let event = self
.rx
.recv()
.expect("Err while recievent the events in the reciever")
.unwrap();
let new_screen: Option<Widgets<'screen>> = match &mut self.main_screen {
Widgets::ResList(res_list) => {
match event {
Event::Key(event) => match event.code {
KeyCode::Esc => {
Screen::exit_app();
None
}
_ => None,
}
}
Widgets::Input(input) => input.handle_events(event).await,
_ => None,
};
match new_screen {
Some(screen) => self.main_screen = screen,
None => {}
}
}
}
Also add the lifetime explicitly when returning a Widget from inside a function

Iterate through a whole file one character at a time

I'm new to Rust and I'm struggle with the concept of lifetimes. I want to make a struct that iterates through a file a character at a time, but I'm running into issues where I need lifetimes. I've tried to add them where I thought they should be but the compiler isn't happy. Here's my code:
struct Advancer<'a> {
line_iter: Lines<BufReader<File>>,
char_iter: Chars<'a>,
current: Option<char>,
peek: Option<char>,
}
impl<'a> Advancer<'a> {
pub fn new(file: BufReader<File>) -> Result<Self, Error> {
let mut line_iter = file.lines();
if let Some(Ok(line)) = line_iter.next() {
let char_iter = line.chars();
let mut advancer = Advancer {
line_iter,
char_iter,
current: None,
peek: None,
};
// Prime the pump. Populate peek so the next call to advance returns the first char
let _ = advancer.next();
Ok(advancer)
} else {
Err(anyhow!("Failed reading an empty file."))
}
}
pub fn next(&mut self) -> Option<char> {
self.current = self.peek;
if let Some(char) = self.char_iter.next() {
self.peek = Some(char);
} else {
if let Some(Ok(line)) = self.line_iter.next() {
self.char_iter = line.chars();
self.peek = Some('\n');
} else {
self.peek = None;
}
}
self.current
}
pub fn current(&self) -> Option<char> {
self.current
}
pub fn peek(&self) -> Option<char> {
self.peek
}
}
fn main() -> Result<(), Error> {
let file = File::open("input_file.txt")?;
let file_buf = BufReader::new(file);
let mut advancer = Advancer::new(file_buf)?;
while let Some(char) = advancer.next() {
print!("{}", char);
}
Ok(())
}
And here's what the compiler is telling me:
error[E0515]: cannot return value referencing local variable `line`
--> src/main.rs:37:13
|
25 | let char_iter = line.chars();
| ---- `line` is borrowed here
...
37 | Ok(advancer)
| ^^^^^^^^^^^^ returns a value referencing data owned by the current function
error[E0597]: `line` does not live long enough
--> src/main.rs:49:34
|
21 | impl<'a> Advancer<'a> {
| -- lifetime `'a` defined here
...
49 | self.char_iter = line.chars();
| -----------------^^^^--------
| | |
| | borrowed value does not live long enough
| assignment requires that `line` is borrowed for `'a`
50 | self.peek = Some('\n');
51 | } else {
| - `line` dropped here while still borrowed
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0515, E0597.
For more information about an error, try `rustc --explain E0515`.
error: could not compile `advancer`.
Some notes:
The Chars iterator borrows from the String it was created from. So you can't drop the String while the iterator is alive. But that's what happens in your new() method, the line variable owning the String disappears while the iterator referencing it is stored in the struct.
You could also try storing the current line in the struct, then it would live long enough, but that's not an option – a struct cannot hold a reference to itself.
Can you make a char iterator on a String that doesn't store a reference into the String? Yes, probably, for instance by storing the current position in the string as an integer – it shouldn't be the index of the char, because chars can be more than one byte long, so you'd need to deal with the underlying bytes yourself (using e.g. is_char_boundary() to take the next bunch of bytes starting from your current index that form a char).
Is there an easier way? Yes, if performance is not of highest importance, one solution is to make use of Vec's IntoIterator instance (which uses unsafe magic to create an object that hands out parts of itself) :
let char_iter = file_buf.lines().flat_map(|line_res| {
let line = line_res.unwrap_or(String::new());
line.chars().collect::<Vec<_>>()
});
Note that just returning line.chars() would have the same problem as the first point.
You might think that String should have a similar IntoIterator instance, and I wouldn't disagree.

Borrowed value does not live long enough when adding to a binary tree built on RefCell

I tried to implement an add operation in a binary tree:
use std::cell::RefCell;
use std::cmp::PartialOrd;
type Link<T> = RefCell<Option<Box<Node<T>>>>;
struct Node<T> {
key: T,
left: Link<T>,
right: Link<T>,
}
struct Tree<T> {
root: Link<T>,
}
impl<T> Node<T> {
fn new(val: T) -> Self {
Node {
key: val,
left: RefCell::new(None),
right: RefCell::new(None),
}
}
}
impl<T: PartialOrd> Tree<T> {
fn new() -> Self {
Tree {
root: RefCell::new(None),
}
}
fn add(&self, val: T) {
let mut next = self.root.borrow();
let node = Box::new(Node::new(val));
match next.as_ref() {
None => {
self.root.replace(Some(node));
()
}
Some(root_ref) => {
let mut prev = root_ref;
let mut cur: Option<&Box<Node<T>>> = Some(root_ref);
while let Some(node_ref) = cur {
prev = node_ref;
if node.key < node_ref.key {
next = node_ref.left.borrow();
} else {
next = node_ref.right.borrow();
}
cur = next.as_ref();
}
if node.key < prev.key {
prev.left.replace(Some(node));
} else {
prev.right.replace(Some(node));
}
}
}
}
}
fn main() {}
I don't understand why the next variable doesn't live long enough:
error[E0597]: `next` does not live long enough
--> src/main.rs:36:15
|
36 | match next.as_ref() {
| ^^^^ borrowed value does not live long enough
...
60 | }
| - `next` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error[E0597]: `next` does not live long enough
--> src/main.rs:51:27
|
51 | cur = next.as_ref();
| ^^^^ borrowed value does not live long enough
...
60 | }
| - `next` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
next lives for the entire scope of the add function and, in my opinion, other variables containing references to it are dropped before next has dropped.
The compiler says that "values in a scope are dropped in the opposite order they are created", suggesting that there is another way to declare variables and to solve this problem, but I don't know how.
The problem I see is that in order to update a leaf node of your tree you have to hold a reference to each intermediate step, not only its parent, because all the links up to the root node must be kept alive while you are updating the value. And Rust lifetimes just cannot do that.
That is, Rust cannot do that in a loop, but it can do that in a recursive function, and a tree is best implemented with a recursive function.
Naturally, your recursive struct is Node, not Tree, but something like this could work (there are many ways to get the borrows to work):
impl<T: PartialOrd> Node<T> {
fn add(&self, val: T) {
let mut branch = if val < self.key {
self.left.borrow_mut()
} else {
self.right.borrow_mut()
};
if let Some(next) = &*branch {
next.add(val);
return;
}
//Separated from the if let so that branch is not borrowed.
*branch = Some(Box::new(Node::new(val)));
}
}
And then, in impl Tree just relay the work to this one.
The code may be simplified a bit if, as other people noted, you get rid of the Tree vs Node and the RefCell...

Iterating through a recursive structure using mutable references and returning the last valid reference

I'm trying to recurse down a structure of nodes, modifying them, and then returning the last Node that I get to. I solved the problems with mutable references in the loop using an example in the non-lexical lifetimes RFC. If I try to return the mutable reference to the last Node, I get a use of moved value error:
#[derive(Debug)]
struct Node {
children: Vec<Node>,
}
impl Node {
fn new(children: Vec<Self>) -> Self {
Self { children }
}
fn get_last(&mut self) -> Option<&mut Node> {
self.children.last_mut()
}
}
fn main() {
let mut root = Node::new(vec![Node::new(vec![])]);
let current = &mut root;
println!("Final: {:?}", get_last(current));
}
fn get_last(mut current: &mut Node) -> &mut Node {
loop {
let temp = current;
println!("{:?}", temp);
match temp.get_last() {
Some(child) => { current = child },
None => break,
}
}
current
}
Gives this error
error[E0382]: use of moved value: `*current`
--> test.rs:51:5
|
40 | let temp = current;
| ---- value moved here
...
51 | current
| ^^^^^^^ value used here after move
|
= note: move occurs because `current` has type `&mut Node`, which does not implement the `Copy` trait
If I return the temporary value instead of breaking, I get the error cannot borrow as mutable more than once.
fn get_last(mut current: &mut Node) -> &mut Node {
loop {
let temp = current;
println!("{:?}", temp);
match temp.get_last() {
Some(child) => { current = child },
None => return temp,
}
}
}
error[E0499]: cannot borrow `*temp` as mutable more than once at a time
--> test.rs:47:28
|
43 | match temp.get_last() {
| ---- first mutable borrow occurs here
...
47 | None => return temp,
| ^^^^ second mutable borrow occurs here
48 | }
49 | }
| - first borrow ends here
How can I iterate through the structure with mutable references and return the last Node? I've searched, but I haven't found any solutions for this specific problem.
I can't use Obtaining a mutable reference by iterating a recursive structure because it gives me a borrowing more than once error:
fn get_last(mut current: &mut Node) -> &mut Node {
loop {
let temp = current;
println!("{:?}", temp);
match temp.get_last() {
Some(child) => current = child,
None => current = temp,
}
}
current
}
This is indeed different from Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time. If we look at the answer there, modified a bit, we can see that it matches on a value and is able to return the value that was matched on in the terminal case. That is, the return value is an Option:
fn back(&mut self) -> &mut Option<Box<Node>> {
let mut anchor = &mut self.root;
loop {
match {anchor} {
&mut Some(ref mut node) => anchor = &mut node.next,
other => return other, // transferred ownership to here
}
}
}
Your case is complicated by two aspects:
The lack of non-lexical lifetimes.
The fact that you want to take a mutable reference and "give it up" in one case (there are children) and not in the other (no children). This is conceptually the same as this:
fn maybe_identity<T>(_: T) -> Option<T> { None }
fn main() {
let name = String::from("vivian");
match maybe_identity(name) {
Some(x) => println!("{}", x),
None => println!("{}", name),
}
}
The compiler cannot tell that the None case could (very theoretically) continue to use name.
The straight-forward solution is to encode this "get it back" action explicitly. We create an enum that returns the &mut self in the case of no children, a helper method that returns that enum, and rewrite the primary method to use the helper:
enum LastOrNot<'a> {
Last(&'a mut Node),
NotLast(&'a mut Node),
}
impl Node {
fn get_last_or_self(&mut self) -> LastOrNot<'_> {
match self.children.is_empty() {
false => LastOrNot::Last(self.children.last_mut().unwrap()),
true => LastOrNot::NotLast(self),
}
}
fn get_last(mut current: &mut Node) -> &mut Node {
loop {
match { current }.get_last_or_self() {
LastOrNot::Last(child) => current = child,
LastOrNot::NotLast(end) => return end,
}
}
}
}
Note that we are using all of the techniques exposed in both Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in? and Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time.
With an in-progress reimplementation of NLL, we can simplify get_last_or_self a bit to avoid the boolean:
fn get_last_or_self(&mut self) -> LastOrNot<'_> {
match self.children.last_mut() {
Some(l) => LastOrNot::Last(l),
None => LastOrNot::NotLast(self),
}
}
The final version of Polonius should allow reducing the entire problem to a very simple form:
fn get_last(mut current: &mut Node) -> &mut Node {
while let Some(child) = current.get_last() {
current = child;
}
current
}
See also:
Returning a reference from a HashMap or Vec causes a borrow to last beyond the scope it's in?
Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time

Resources