MIRI error, with `intrusive_collections` crate
⚓ Rust 📅 2025-11-06 👤 surdeus 👁️ 7I am not good at English. Sorry if there are any funny expressions.
MIRI reports an error in the code where it uses RBTree from intrusive_collections crate.
If I use the standard BTreeMap instead of RBTree, it doesn't cause an error.
I'm confused because it doesn't seem that whether it's intrusive or not affects error occurrence.
(I usually can't handle unsafe properly...
)
Please give me some advice.
Code
This code has been minimized for error reproduction.
Datas are generated and dropped immediately.
So, it's not actually doing meaningful work.
/src/lib.rs
#![allow(dead_code)]
mod map_adapter;
mod test_rbtree;
mod test_btree_map;
/src/test_rbtree.rs
use intrusive_collections::{*, rbtree::*};
use crate::map_adapter::*;
#[test]
fn test_rbtree() {
let mut map = RBTree::new(MapAdapter::new());
drop(MyType::new(&mut map));
}
struct MyType<'a> {
iter: Option<Iter<'a, MapAdapter>>,
map: *mut RBTree<MapAdapter>,
}
impl<'a> MyType<'a> {
pub fn new(map: &'a mut RBTree<MapAdapter>) -> Self {
Self {
map: map as *mut _,
iter: Some(map.iter()),
}
}
}
impl Drop for MyType<'_> {
fn drop(&mut self) {
self.iter.take();
let _ = unsafe { &mut *self.map }; // ❌ MIRI Error!
}
}
/src/test_btree_map.rs
use std::collections::btree_map::{BTreeMap, Iter};
#[test]
fn test1() {
let mut map = BTreeMap::<usize, i32>::new();
drop(MyType::new(&mut map));
}
struct MyType<'a> {
iter: Option<Iter<'a, usize, i32>>,
map: *mut BTreeMap<usize, i32>,
}
impl<'a> MyType<'a> {
pub fn new(map: &'a mut BTreeMap<usize, i32>) -> Self {
Self {
map: map as *mut _,
iter: Some(map.iter()),
}
}
}
impl Drop for MyType<'_> {
fn drop(&mut self) {
self.iter.take();
let _ = unsafe { &mut *self.map }; // 🤔 No MIRI Error!
}
}
/src/map_adapter.rs
use intrusive_collections::*;
intrusive_adapter!(
pub MapAdapter = Box<Node>: Node {
link: RBTreeLink
}
);
impl<'a> KeyAdapter<'a> for MapAdapter {
type Key = usize;
fn get_key(&self, x: &'a Node) -> usize {
*x.key()
}
}
pub struct Node {
key: usize,
_val: i32,
pub(crate) link: RBTreeLink,
}
impl Node {
pub fn key(&self) -> &usize {
&self.key
}
}
Error excerpt
test test_btree_map::test1 ... ok
test test_rbtree::test_rbtree ... error: Undefined Behavior: not granting access to tag <168217> because that would remove [SharedReadOnly for <168240>] which is strongly protected
--> src\test_rbtree.rs:27:26
|
27 | let _ = unsafe { &mut *self.map };
| ^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <168217> was created by a SharedReadWrite retag at offsets [0x0..0x8]
--> src\test_rbtree.rs:18:18
|
18 | map: map as *mut _,
| ^^^
help: <168240> is this argument
--> src\test_rbtree.rs:7:5
|
7 | drop(MyType::new(&mut map));
7 posts - 3 participants
🏷️ Rust_feed