Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Borrow checker error: borrow occurs due to deref coercion
Hi, I am facing borrow checker errors when mutating a vector consisting of borrowed FstNode<'a>
s. Here is a shorter version of the code (playground link):
// Uses the `fst` crate. `fst = "0.4.7"`
use std::collections::{HashMap, HashSet};
use fst::raw::{Builder, Fst, Node};
pub struct FstTree {
fst: Fst<Vec<u8>>,
}
impl FstTree {
pub fn new(mut set: Vec<&str>) -> Self {
todo!()
}
pub fn match_longest_common_prefix<'a>(&self, prefix: &'a str) -> (&'a str, &'a str, bool) {
todo!()
}
pub fn matching_node<'a>(&'a self, word: &'a str) -> Option<FstNode<'a>> {
todo!()
}
}
pub struct FstNode<'a> {
fst: &'a Fst<Vec<u8>>,
node: Node<'a>,
word: String,
}
impl FstNode<'_> {
pub fn get_matching_node(&self, suffix: &str) -> Option<FstNode<'_>> {
todo!()
}
pub fn get_word(&self) -> Option<&str> {
todo!()
}
}
pub struct Block {
pub transliterate: Vec<String>,
pub entire_block_optional: Option<bool>,
}
pub struct Suggest {
patterns: HashMap<String, Block>,
patterns_trie: FstTree,
words: FstTree,
common_suffixes: Vec<String>,
}
impl Suggest {
pub fn new() -> Self {
let patterns: HashMap<String, Block> = todo!();
let patterns_trie: FstTree = todo!();
let words: FstTree = todo!();
let common_suffixes = todo!();
Suggest {
patterns,
patterns_trie,
words,
common_suffixes,
}
}
pub fn suggest(&self, input: &str) -> Vec<String> {
let (matched, mut remaining, _) = self.patterns_trie.match_longest_common_prefix(&input);
let matched_patterns = &self.patterns.get(matched).unwrap().transliterate;
let mut matched_nodes = matched_patterns
.iter()
.filter_map(|p| self.words.matching_node(p))
.collect::<Vec<_>>();
let additional_nodes = matched_nodes
.iter()
.flat_map(|node| {
self.common_suffixes
.iter()
.filter_map(|suffix| node.get_matching_node(suffix))
})
.collect::<Vec<_>>();
matched_nodes.extend(additional_nodes);
while !remaining.is_empty() {
let (mut new_matched, mut new_remaining, mut complete) =
self.patterns_trie.match_longest_common_prefix(&remaining);
if !complete {
for i in (0..remaining.len()).rev() {
(new_matched, new_remaining, complete) = self
.patterns_trie
.match_longest_common_prefix(&remaining[..i]);
if complete {
remaining = &remaining[i..];
break;
}
}
} else {
remaining = new_remaining;
}
let new_matched_patterns = &self.patterns.get(new_matched).unwrap().transliterate;
let new_matched_nodes = new_matched_patterns
.iter()
.flat_map(|p| {
matched_nodes
.iter()
.filter_map(|node| node.get_matching_node(p))
})
.collect::<Vec<_>>();
if self
.patterns
.get(new_matched)
.unwrap()
.entire_block_optional
.is_some()
{
// Entirely optional patterns like "([ওোঅ]|(অ্য)|(য়ো?))?" may not yield any result
matched_nodes.extend(new_matched_nodes);
} else {
matched_nodes = new_matched_nodes;
}
let additional_matched_nodes = matched_nodes
.iter()
.flat_map(|node| {
self.common_suffixes
.iter()
.filter_map(|suffix| node.get_matching_node(suffix))
})
.collect::<Vec<_>>();
matched_nodes.extend(additional_matched_nodes);
}
let suggestions: HashSet<_> = matched_nodes.iter().filter_map(|n| n.get_word()).collect();
suggestions.into_iter().map(|s| s.to_string()).collect()
}
}
The issue seems that the borrow of FstNode<'a>
is being spilled out. Here is the borrow checker error:
error[E0502]: cannot borrow `matched_nodes` as mutable because it is also borrowed as immutable
--> src/lib.rs:82:9
|
74 | let additional_nodes = matched_nodes
| ------------- immutable borrow occurs here
...
82 | matched_nodes.extend(additional_nodes);
| ^^^^^^^^^^^^^^------^^^^^^^^^^^^^^^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
error[E0502]: cannot borrow `matched_nodes` as mutable because it is also borrowed as immutable
--> src/lib.rs:121:17
|
74 | let additional_nodes = matched_nodes
| ------------- immutable borrow occurs here
...
121 | matched_nodes.extend(new_matched_nodes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
126 | let additional_matched_nodes = matched_nodes
| ------------- immutable borrow later used here
error[E0506]: cannot assign to `matched_nodes` because it is borrowed
--> src/lib.rs:123:17
|
74 | let additional_nodes = matched_nodes
| ------------- `matched_nodes` is borrowed here
...
123 | matched_nodes = new_matched_nodes;
| ^^^^^^^^^^^^^
| |
| `matched_nodes` is assigned to here but it was already borrowed
| borrow later used here
|
= note: borrow occurs due to deref coercion to `[FstNode<'_>]`
note: deref defined here
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3287:5
|
3287 | type Target = [T];
| ^^^^^^^^^^^
error[E0502]: cannot borrow `matched_nodes` as mutable because it is also borrowed as immutable
--> src/lib.rs:134:13
|
74 | let additional_nodes = matched_nodes
| ------------- immutable borrow occurs here
...
134 | matched_nodes.extend(additional_matched_nodes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
137 | let suggestions: HashSet<_> = matched_nodes.iter().filter_map(|n| n.get_word()).collect();
| ------------- immutable borrow later used here
I think the important part is:
= note: borrow occurs due to deref coercion to `[FstNode<'_>]`
note: deref defined here
--> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3287:5
|
3287 | type Target = [T];
| ^^^^^^^^^^^
How can I fix this issue or there any workarounds available?
Thanks in advance!
4 posts - 2 participants
🏷️ rust_feed