Currently, I am working to implement the phase one of the functionality. There is no implementation yet besides of the code below:
#[derive(Debug, PartialEq, Default, Clone)]
pub enum ScopeType {
#[default]
SelfImpl,
TraitFor,
Trait,
}
pub trait Clear {
fn clear(&mut self);
}
#[derive(Debug, Default)]
pub struct Scope<'a> {
pub name: String,
pub name_for: Option<&'a mut String>,
pub type_of_scope: ScopeType,
//name_for_cache: String,
}
impl Clear for Scope<'_> {
fn clear(&mut self) {
self.name.clear();
self.name_for.as_mut().map(|string| string.clear());
self.name_for = None;
self.type_of_scope = Default::default();
}
}
fn main() {
let mut scope: Scope = Default::default();
let mut name_for_cache = String::new();
//let mut name_for_cache2 = String::new();
scope.name.push_str("Ab");
scope.name.push('b');
scope.name_for = Some(&mut name_for_cache);
if let Some(ref mut name_for) = scope.name_for {
name_for.push('C');
name_for.push('d');
}
if let Some(ref mut name_for) = scope.name_for {
name_for.push_str("Zx");
}
println!(
"scope {} {:?}",
scope.name,
scope.name_for.as_ref().unwrap()
);
scope.clear();
scope.name.push('E');
scope.name.push('f');
scope.name_for = Some(&mut name_for_cache);
//name_for_cache.push('y');
println!(
"scope {} {:?}",
scope.name,
//scope.name,
scope.name_for.as_ref(),
//&name_for_cache
);
}
I do not understand why I am getting the error:
error[E0499]: cannot borrow `name_for_cache` as mutable more than once at a time
--> /media/exhdd/Dev/modu/trait1/test.rs:82:27
|
64 | scope.name_for = Some(&mut name_for_cache);
| ------------------- first mutable borrow occurs here
...
82 | scope.name_for = Some(&mut name_for_cache);
| ----------------------^^^^^^^^^^^^^^^^^^^-
| | |
| | second mutable borrow occurs here
| first borrow later used here
error: aborting due to 1 previous error
In my understanding, the mutable borrow should be dropped after clear. Since, Rust borrow checker works at compilation time, it may not detect clear. But in the case, second Some assignment should drop the previous one, however it doesn't happen. Why? More likely, I will end with a work around as (String,bool) instead of Option<String>. Anyway, if I missed something, you can educate me. Regarding that Rust identifiers limited to 64 bytes, and I can use just 64 bytes array instead of the dynamic string. The scanner, I work on, should work for any arbitrary language including those that have no length limitation of identifiers.