From c847d111dea18c42e209fed198fb2d0ff3d78c1a Mon Sep 17 00:00:00 2001 From: Lucas <81485821+ZillaZ@users.noreply.github.com> Date: Sat, 23 May 2026 07:52:40 -0300 Subject: [PATCH] datatypes: BSTree to_left and to_right fix (#27198) --- vlib/datatypes/bstree.v | 22 ++--- vlib/datatypes/bstree_test.v | 28 ++++++ .../tests/check_err_msg_with_generics.out | 96 +++++++++---------- 3 files changed, 84 insertions(+), 62 deletions(-) diff --git a/vlib/datatypes/bstree.v b/vlib/datatypes/bstree.v index 0a526e3f3..71fac7acd 100644 --- a/vlib/datatypes/bstree.v +++ b/vlib/datatypes/bstree.v @@ -249,13 +249,7 @@ fn (bst &BSTree[T]) get_node(node &BSTreeNode[T], value T) &BSTreeNode[T] { return bst.get_node(node.left, value) } -// to_left returns the value of the node to the left of the node with `value` specified if it exists, -// otherwise the a false value is returned. -// -// An example of usage can be the following one -//```v -// left_value, exist := bst.to_left(10) -//``` +// to_left returns the value of the node to the left of the node with `value` specified if it exists pub fn (bst &BSTree[T]) to_left(value T) !T { if bst.is_empty() { return error('BSTree is empty') @@ -265,16 +259,13 @@ pub fn (bst &BSTree[T]) to_left(value T) !T { return error('BSTree is not initialized') } left_node := node.left + if unsafe { left_node == 0 } || !left_node.is_init { + return error('No left node exists for the given value') + } return left_node.value } -// to_right return the value of the element to the right of the node with `value` specified, if exist -// otherwise, the boolean value is false -// An example of usage can be the following one -// -//```v -// left_value, exist := bst.to_right(10) -//``` +// to_right returns the value of the node to the right of the node with `value` specified if it exists pub fn (bst &BSTree[T]) to_right(value T) !T { if bst.is_empty() { return error('BSTree is empty') @@ -284,6 +275,9 @@ pub fn (bst &BSTree[T]) to_right(value T) !T { return error('BSTree is not initialized') } right_node := node.right + if unsafe { right_node == 0 } || !right_node.is_init { + return error('No right node exists for the given value') + } return right_node.value } diff --git a/vlib/datatypes/bstree_test.v b/vlib/datatypes/bstree_test.v index 483d32bda..f7ab04057 100644 --- a/vlib/datatypes/bstree_test.v +++ b/vlib/datatypes/bstree_test.v @@ -85,6 +85,34 @@ fn test_get_left_on_empty_bst() { assert right_val == -1 } +// Check if accessing the left node of the leftmost non root node panics +fn test_to_left_on_leftmost_nonroot() { + mut bst := BSTree[int]{} + + assert bst.insert(20) + assert bst.insert(10) + assert bst.insert(30) + + min := bst.min() or { -1 } + assert min == 10 + left_val := bst.to_left(min) or { -1 } + assert left_val == -1 +} + +// Check if accessing the right node of the rightmost non root node panics +fn test_to_right_on_rightmost_nonroot() { + mut bst := BSTree[int]{} + + assert bst.insert(20) + assert bst.insert(10) + assert bst.insert(30) + + max := bst.max() or { -1 } + assert max == 30 + right_val := bst.to_right(max) or { -1 } + assert right_val == -1 +} + // Check the remove operation if it is able to remove // all elements required, and maintains the BST propriety. fn test_remove_from_bst_one() { diff --git a/vlib/v/checker/tests/check_err_msg_with_generics.out b/vlib/v/checker/tests/check_err_msg_with_generics.out index 45c228546..9107f70ca 100644 --- a/vlib/v/checker/tests/check_err_msg_with_generics.out +++ b/vlib/v/checker/tests/check_err_msg_with_generics.out @@ -294,67 +294,67 @@ Did you mean `Ok[[]Token]`? | ^ 250 | } 251 | -vlib/datatypes/bstree.v:260:17: error: unknown type `Token`. +vlib/datatypes/bstree.v:254:17: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 258 | //``` - 259 | pub fn (bst &BSTree[T]) to_left(value T) !T { - 260 | if bst.is_empty() { + 252 | // to_left returns the value of the node to the left of the node with `value` specified if it exists + 253 | pub fn (bst &BSTree[T]) to_left(value T) !T { + 254 | if bst.is_empty() { | ^ - 261 | return error('BSTree is empty') - 262 | } -vlib/datatypes/bstree.v:263:22: error: unknown type `Token`. + 255 | return error('BSTree is empty') + 256 | } +vlib/datatypes/bstree.v:257:22: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 261 | return error('BSTree is empty') - 262 | } - 263 | node := bst.get_node(bst.root, value) + 255 | return error('BSTree is empty') + 256 | } + 257 | node := bst.get_node(bst.root, value) | ^ - 264 | if !node.is_init { - 265 | return error('BSTree is not initialized') -vlib/datatypes/bstree.v:279:17: error: unknown type `Token`. + 258 | if !node.is_init { + 259 | return error('BSTree is not initialized') +vlib/datatypes/bstree.v:270:17: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 277 | //``` - 278 | pub fn (bst &BSTree[T]) to_right(value T) !T { - 279 | if bst.is_empty() { + 268 | // to_right returns the value of the node to the right of the node with `value` specified if it exists + 269 | pub fn (bst &BSTree[T]) to_right(value T) !T { + 270 | if bst.is_empty() { | ^ - 280 | return error('BSTree is empty') - 281 | } -vlib/datatypes/bstree.v:282:22: error: unknown type `Token`. + 271 | return error('BSTree is empty') + 272 | } +vlib/datatypes/bstree.v:273:22: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 280 | return error('BSTree is empty') - 281 | } - 282 | node := bst.get_node(bst.root, value) + 271 | return error('BSTree is empty') + 272 | } + 273 | node := bst.get_node(bst.root, value) | ^ - 283 | if !node.is_init { - 284 | return error('BSTree is not initialized') -vlib/datatypes/bstree.v:293:17: error: unknown type `Token`. + 274 | if !node.is_init { + 275 | return error('BSTree is not initialized') +vlib/datatypes/bstree.v:287:17: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 291 | // Time complexity O(N) if the BST is not balanced - 292 | pub fn (bst &BSTree[T]) max() !T { - 293 | if bst.is_empty() { + 285 | // Time complexity O(N) if the BST is not balanced + 286 | pub fn (bst &BSTree[T]) max() !T { + 287 | if bst.is_empty() { | ^ - 294 | return error('BSTree is empty') - 295 | } -vlib/datatypes/bstree.v:296:31: error: unknown type `Token`. + 288 | return error('BSTree is empty') + 289 | } +vlib/datatypes/bstree.v:290:31: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 294 | return error('BSTree is empty') - 295 | } - 296 | max := bst.get_max_from_right(bst.root) + 288 | return error('BSTree is empty') + 289 | } + 290 | max := bst.get_max_from_right(bst.root) | ^ - 297 | if !max.is_init { - 298 | return error('BSTree is not initialized') -vlib/datatypes/bstree.v:306:17: error: unknown type `Token`. + 291 | if !max.is_init { + 292 | return error('BSTree is not initialized') +vlib/datatypes/bstree.v:300:17: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 304 | // Time complexity O(N) if the BST is not balanced. - 305 | pub fn (bst &BSTree[T]) min() !T { - 306 | if bst.is_empty() { + 298 | // Time complexity O(N) if the BST is not balanced. + 299 | pub fn (bst &BSTree[T]) min() !T { + 300 | if bst.is_empty() { | ^ - 307 | return error('BSTree is empty') - 308 | } -vlib/datatypes/bstree.v:309:30: error: unknown type `Token`. + 301 | return error('BSTree is empty') + 302 | } +vlib/datatypes/bstree.v:303:30: error: unknown type `Token`. Did you mean `Ok[[]Token]`? - 307 | return error('BSTree is empty') - 308 | } - 309 | min := bst.get_min_from_left(bst.root) + 301 | return error('BSTree is empty') + 302 | } + 303 | min := bst.get_min_from_left(bst.root) | ^ - 310 | if !min.is_init { - 311 | return error('BSTree is not initialized') + 304 | if !min.is_init { + 305 | return error('BSTree is not initialized') -- 2.39.5