about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2022-08-26 14:08:43 +0200
committerGitHub <noreply@github.com>2022-08-26 14:08:43 +0200
commite3148dc7c48e1c96b05c85f57394308a6e46c1ed (patch)
tree919f2245d6ed3c5ac0570e18be950643dee707a0
parent983f4daddf238d114c4adc4751c5528fc6695a5a (diff)
parentea4e5c27a9fe52d175f6cdf5af4d2079660a5540 (diff)
downloadrust-e3148dc7c48e1c96b05c85f57394308a6e46c1ed.tar.gz
rust-e3148dc7c48e1c96b05c85f57394308a6e46c1ed.zip
Rollup merge of #95005 - ssomers:btree_static_assert, r=thomcc
BTree: evaluate static type-related check at compile time

`assert`s like the ones replaced here would only go off when you run the right test cases, if the code were ever incorrectly changed such that rhey would trigger. But [inspired on a nice forum question](https://users.rust-lang.org/t/compile-time-const-generic-parameter-check/69202), they can be checked at compile time.
-rw-r--r--library/alloc/src/collections/btree/node.rs16
1 files changed, 9 insertions, 7 deletions
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index d831161bcb6..f1d2d3b30d9 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -318,7 +318,7 @@ impl<BorrowType: marker::BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type>
     pub fn ascend(
         self,
     ) -> Result<Handle<NodeRef<BorrowType, K, V, marker::Internal>, marker::Edge>, Self> {
-        assert!(BorrowType::PERMITS_TRAVERSAL);
+        let _ = BorrowType::TRAVERSAL_PERMIT;
         // We need to use raw pointers to nodes because, if BorrowType is marker::ValMut,
         // there might be outstanding mutable references to values that we must not invalidate.
         let leaf_ptr: *const _ = Self::as_leaf_ptr(&self);
@@ -1003,7 +1003,7 @@ impl<BorrowType: marker::BorrowType, K, V>
     /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should
     /// both, upon success, do nothing.
     pub fn descend(self) -> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
-        assert!(BorrowType::PERMITS_TRAVERSAL);
+        let _ = BorrowType::TRAVERSAL_PERMIT;
         // We need to use raw pointers to nodes because, if BorrowType is
         // marker::ValMut, there might be outstanding mutable references to
         // values that we must not invalidate. There's no worry accessing the
@@ -1666,15 +1666,17 @@ pub mod marker {
     pub struct ValMut<'a>(PhantomData<&'a mut ()>);
 
     pub trait BorrowType {
-        // Whether node references of this borrow type allow traversing
-        // to other nodes in the tree.
-        const PERMITS_TRAVERSAL: bool = true;
+        // If node references of this borrow type allow traversing to other
+        // nodes in the tree, this constant can be evaluated. Thus reading it
+        // serves as a compile-time assertion.
+        const TRAVERSAL_PERMIT: () = ();
     }
     impl BorrowType for Owned {
-        // Traversal isn't needed, it happens using the result of `borrow_mut`.
+        // Reject evaluation, because traversal isn't needed. Instead traversal
+        // happens using the result of `borrow_mut`.
         // By disabling traversal, and only creating new references to roots,
         // we know that every reference of the `Owned` type is to a root node.
-        const PERMITS_TRAVERSAL: bool = false;
+        const TRAVERSAL_PERMIT: () = panic!();
     }
     impl BorrowType for Dying {}
     impl<'a> BorrowType for Immut<'a> {}