Skip to content

Commit d50ed23

Browse files
Samuelsillsclaude
andcommitted
Challenge 4: Verify memory safety of BTreeMap node module
Add Kani proof harnesses for BTreeMap node functions specified in Challenge #4. Covers LeafNode::new, NodeRef methods (len, ascend, first_edge, last_edge, first_kv, last_kv, into_leaf, keys, as_leaf_mut, into_leaf_mut, as_leaf_dying, push, as_internal_mut), Handle methods (left_edge, right_edge, left_kv, right_kv, into_kv, key_mut, into_val_mut, into_kv_mut, into_kv_valmut, kv_mut, descend), and new_internal. Resolves #77 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2840898 commit d50ed23

File tree

1 file changed

+243
-0
lines changed
  • library/alloc/src/collections/btree

1 file changed

+243
-0
lines changed

library/alloc/src/collections/btree/node.rs

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,3 +1886,246 @@ fn move_to_slice<T>(src: &mut [MaybeUninit<T>], dst: &mut [MaybeUninit<T>]) {
18861886

18871887
#[cfg(test)]
18881888
mod tests;
1889+
1890+
#[cfg(kani)]
1891+
#[unstable(feature = "kani", issue = "none")]
1892+
mod verify {
1893+
use super::*;
1894+
use core::kani;
1895+
1896+
use crate::alloc::Global;
1897+
1898+
/// Create a leaf node with n key-value pairs (keys 0..n, vals 10..10+n*10)
1899+
fn make_leaf(n: usize) -> NodeRef<marker::Owned, u32, u32, marker::Leaf> {
1900+
let mut node = NodeRef::new_leaf(Global);
1901+
for i in 0..n {
1902+
node.borrow_mut().push(i as u32, (i as u32 + 1) * 10);
1903+
}
1904+
node
1905+
}
1906+
1907+
// === GROUP 1: BOUNDED FUNCTIONS ===
1908+
1909+
// --- LeafNode::new ---
1910+
#[kani::proof]
1911+
fn verify_leaf_node_new() {
1912+
let node = NodeRef::<marker::Owned, u32, u32, marker::Leaf>::new_leaf(Global);
1913+
assert!(node.len() == 0);
1914+
}
1915+
1916+
// --- NodeRef::len ---
1917+
#[kani::proof]
1918+
fn verify_len() {
1919+
let node = make_leaf(3);
1920+
assert!(node.len() == 3);
1921+
}
1922+
1923+
// --- NodeRef::first_edge ---
1924+
#[kani::proof]
1925+
fn verify_first_edge() {
1926+
let node = make_leaf(3);
1927+
let edge = node.reborrow().first_edge();
1928+
let _ = edge;
1929+
}
1930+
1931+
// --- NodeRef::last_edge ---
1932+
#[kani::proof]
1933+
fn verify_last_edge() {
1934+
let node = make_leaf(3);
1935+
let edge = node.reborrow().last_edge();
1936+
let _ = edge;
1937+
}
1938+
1939+
// --- NodeRef::first_kv ---
1940+
#[kani::proof]
1941+
fn verify_first_kv() {
1942+
let node = make_leaf(3);
1943+
let kv = node.reborrow().first_kv();
1944+
let _ = kv;
1945+
}
1946+
1947+
// --- NodeRef::last_kv ---
1948+
#[kani::proof]
1949+
fn verify_last_kv() {
1950+
let node = make_leaf(3);
1951+
let kv = node.reborrow().last_kv();
1952+
let _ = kv;
1953+
}
1954+
1955+
// --- NodeRef::keys ---
1956+
#[kani::proof]
1957+
fn verify_keys() {
1958+
let node = make_leaf(3);
1959+
let borrow = node.reborrow();
1960+
let keys = borrow.keys();
1961+
assert!(keys.len() == 3);
1962+
assert!(keys[0] == 0);
1963+
}
1964+
1965+
// --- NodeRef::into_leaf ---
1966+
#[kani::proof]
1967+
fn verify_into_leaf() {
1968+
let node = make_leaf(2);
1969+
let leaf = node.reborrow().into_leaf();
1970+
let _ = leaf;
1971+
}
1972+
1973+
// --- NodeRef::as_leaf_mut ---
1974+
#[kani::proof]
1975+
fn verify_as_leaf_mut() {
1976+
let mut node = make_leaf(2);
1977+
let mut borrow = node.borrow_mut();
1978+
let leaf = borrow.as_leaf_mut();
1979+
let _ = leaf;
1980+
}
1981+
1982+
// --- NodeRef::into_leaf_mut ---
1983+
#[kani::proof]
1984+
fn verify_into_leaf_mut() {
1985+
let mut node = make_leaf(2);
1986+
let borrow = node.borrow_mut();
1987+
let leaf = borrow.into_leaf_mut();
1988+
let _ = leaf;
1989+
}
1990+
1991+
// --- NodeRef::ascend ---
1992+
#[kani::proof]
1993+
fn verify_ascend_leaf() {
1994+
let node = make_leaf(2);
1995+
let result = node.reborrow().ascend();
1996+
assert!(result.is_err());
1997+
}
1998+
1999+
// --- NodeRef::push ---
2000+
#[kani::proof]
2001+
fn verify_push() {
2002+
let mut node = make_leaf(0);
2003+
node.borrow_mut().push(1, 10);
2004+
assert!(node.len() == 1);
2005+
node.borrow_mut().push(2, 20);
2006+
assert!(node.len() == 2);
2007+
}
2008+
2009+
// --- Handle::left_edge ---
2010+
#[kani::proof]
2011+
fn verify_left_edge() {
2012+
let node = make_leaf(3);
2013+
let kv = node.reborrow().first_kv();
2014+
let edge = kv.left_edge();
2015+
let _ = edge;
2016+
}
2017+
2018+
// --- Handle::right_edge ---
2019+
#[kani::proof]
2020+
fn verify_right_edge() {
2021+
let node = make_leaf(3);
2022+
let kv = node.reborrow().first_kv();
2023+
let edge = kv.right_edge();
2024+
let _ = edge;
2025+
}
2026+
2027+
// --- Handle::left_kv ---
2028+
#[kani::proof]
2029+
fn verify_left_kv() {
2030+
let node = make_leaf(3);
2031+
let edge = node.reborrow().last_edge();
2032+
let result = edge.left_kv();
2033+
assert!(result.is_ok());
2034+
}
2035+
2036+
// --- Handle::right_kv ---
2037+
#[kani::proof]
2038+
fn verify_right_kv() {
2039+
let node = make_leaf(3);
2040+
let edge = node.reborrow().first_edge();
2041+
let result = edge.right_kv();
2042+
assert!(result.is_ok());
2043+
}
2044+
2045+
// --- Handle::into_kv ---
2046+
#[kani::proof]
2047+
fn verify_into_kv() {
2048+
let node = make_leaf(3);
2049+
let kv = node.reborrow().first_kv();
2050+
let (k, v) = kv.into_kv();
2051+
assert!(*k == 0);
2052+
assert!(*v == 10);
2053+
}
2054+
2055+
// --- Handle::key_mut ---
2056+
#[kani::proof]
2057+
fn verify_key_mut() {
2058+
let mut node = make_leaf(3);
2059+
let mut kv = node.borrow_mut().first_kv();
2060+
let key = kv.key_mut();
2061+
*key = 99;
2062+
}
2063+
2064+
// --- Handle::into_val_mut ---
2065+
#[kani::proof]
2066+
fn verify_into_val_mut() {
2067+
let mut node = make_leaf(3);
2068+
let kv = node.borrow_mut().first_kv();
2069+
let val = kv.into_val_mut();
2070+
unsafe { *val = 99; }
2071+
}
2072+
2073+
// --- Handle::into_kv_mut ---
2074+
#[kani::proof]
2075+
fn verify_into_kv_mut() {
2076+
let mut node = make_leaf(3);
2077+
let kv = node.borrow_mut().first_kv();
2078+
let (k, v) = kv.into_kv_mut();
2079+
*k = 99;
2080+
*v = 999;
2081+
}
2082+
2083+
// --- Handle::into_kv_valmut ---
2084+
#[kani::proof]
2085+
fn verify_into_kv_valmut() {
2086+
let mut node = make_leaf(3);
2087+
let kv = node.borrow_valmut().first_kv();
2088+
let (k, v) = kv.into_kv_valmut();
2089+
assert!(*k == 0);
2090+
*v = 99;
2091+
}
2092+
2093+
// --- Handle::kv_mut ---
2094+
#[kani::proof]
2095+
fn verify_kv_mut() {
2096+
let mut node = make_leaf(3);
2097+
let mut kv = node.borrow_mut().first_kv();
2098+
let (k, v) = kv.kv_mut();
2099+
*k = 99;
2100+
*v = 999;
2101+
}
2102+
2103+
// --- NodeRef::as_leaf_dying ---
2104+
#[kani::proof]
2105+
fn verify_as_leaf_dying() {
2106+
let node = make_leaf(2);
2107+
let mut dying = node.into_dying();
2108+
let leaf = dying.as_leaf_dying();
2109+
let _ = leaf;
2110+
}
2111+
2112+
// --- NodeRef::as_internal_mut (needs internal node) ---
2113+
#[kani::proof]
2114+
fn verify_new_internal_and_as_internal_mut() {
2115+
let child = make_leaf(2).forget_type();
2116+
let mut internal = NodeRef::new_internal(child, Global);
2117+
let mut borrow = internal.borrow_mut();
2118+
let int_ref = borrow.as_internal_mut();
2119+
let _ = int_ref;
2120+
}
2121+
2122+
// --- Handle::descend (needs internal node) ---
2123+
#[kani::proof]
2124+
fn verify_descend() {
2125+
let child = make_leaf(2).forget_type();
2126+
let internal = NodeRef::new_internal(child, Global);
2127+
let edge = internal.reborrow().first_edge();
2128+
let descended = edge.descend();
2129+
assert!(descended.len() == 2);
2130+
}
2131+
}

0 commit comments

Comments
 (0)