diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf4d6b8e2..ad837b69d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,6 +88,20 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo miri test -p rune-alloc --all-features + rune_nightly: + runs-on: ubuntu-latest + needs: basics + env: + RUSTFLAGS: -D warnings --cfg rune_nightly + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: miri + - uses: Swatinem/rust-cache@v2 + - run: cargo build --all-features + - run: cargo build --tests --all-features + no_default_features: runs-on: ubuntu-latest needs: basics diff --git a/crates/rune-alloc/Cargo.toml b/crates/rune-alloc/Cargo.toml index fff13f285..2795d21c6 100644 --- a/crates/rune-alloc/Cargo.toml +++ b/crates/rune-alloc/Cargo.toml @@ -17,6 +17,8 @@ categories = ["parser-implementations"] default = ["std", "serde"] std = ["alloc", "ahash/std", "serde?/std"] alloc = [] +inline-more = [] +raw = [] [dependencies] rune-alloc-macros = { version = "=0.14.0", path = "../rune-alloc-macros" } diff --git a/crates/rune-alloc/src/boxed.rs b/crates/rune-alloc/src/boxed.rs index c54099cec..b25743a36 100644 --- a/crates/rune-alloc/src/boxed.rs +++ b/crates/rune-alloc/src/boxed.rs @@ -320,14 +320,6 @@ impl Box { unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } - /// Converts a `Box` into a `Box<[T]>` - /// - /// This conversion does not allocate on the heap and happens in place. - pub(crate) fn into_boxed_slice(boxed: Self) -> Box<[T], A> { - let (raw, alloc) = Box::into_raw_with_allocator(boxed); - unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } - } - /// Consumes the `Box`, returning the wrapped value. #[inline] pub fn into_inner(boxed: Self) -> T { diff --git a/crates/rune-alloc/src/btree/borrow.rs b/crates/rune-alloc/src/btree/borrow.rs index d1bafb9c0..a728e64cc 100644 --- a/crates/rune-alloc/src/btree/borrow.rs +++ b/crates/rune-alloc/src/btree/borrow.rs @@ -59,15 +59,4 @@ impl<'a, T> DormantMutRef<'a, T> { // SAFETY: our own safety conditions imply this reference is again unique. unsafe { &mut *self.ptr.as_ptr() } } - - /// Borrows a new shared reference from the unique borrow initially captured. - /// - /// # Safety - /// - /// The reborrow must have ended, i.e., the reference returned by `new` and - /// all pointers and references derived from it, must not be used anymore. - pub(crate) unsafe fn reborrow_shared(&self) -> &'a T { - // SAFETY: our own safety conditions imply this reference is again unique. - unsafe { &*self.ptr.as_ptr() } - } } diff --git a/crates/rune-alloc/src/btree/map.rs b/crates/rune-alloc/src/btree/map.rs index 887319193..2892f88f5 100644 --- a/crates/rune-alloc/src/btree/map.rs +++ b/crates/rune-alloc/src/btree/map.rs @@ -3156,8 +3156,11 @@ impl Debug for Cursor<'_, K, V> { /// methods. pub struct CursorMut<'a, K: 'a, V: 'a, A = Global> { current: Option, K, V, marker::LeafOrInternal>, marker::KV>>, + #[cfg_attr(not(test), allow(unused))] root: DormantMutRef<'a, Option>>, + #[cfg_attr(not(test), allow(unused))] length: &'a mut usize, + #[cfg_attr(not(test), allow(unused))] alloc: &'a mut A, } @@ -3173,6 +3176,7 @@ impl<'a, K, V> Cursor<'a, K, V> { /// If the cursor is pointing to the "ghost" non-element then this will move it to /// the first element of the `BTreeMap`. If it is pointing to the last /// element of the `BTreeMap` then this will move it to the "ghost" non-element. + #[cfg(test)] pub(crate) fn move_next(&mut self) { match self.current.take() { None => { @@ -3195,6 +3199,7 @@ impl<'a, K, V> Cursor<'a, K, V> { /// If the cursor is pointing to the "ghost" non-element then this will move it to /// the last element of the `BTreeMap`. If it is pointing to the first /// element of the `BTreeMap` then this will move it to the "ghost" non-element. + #[cfg(test)] pub(crate) fn move_prev(&mut self) { match self.current.take() { None => { @@ -3244,6 +3249,7 @@ impl<'a, K, V> Cursor<'a, K, V> { /// If the cursor is pointing to the "ghost" non-element then this returns /// the first element of the `BTreeMap`. If it is pointing to the last /// element of the `BTreeMap` then this returns `None`. + #[cfg(test)] pub(crate) fn peek_next(&self) -> Option<(&'a K, &'a V)> { let mut next = self.clone(); next.move_next(); @@ -3255,6 +3261,7 @@ impl<'a, K, V> Cursor<'a, K, V> { /// If the cursor is pointing to the "ghost" non-element then this returns /// the last element of the `BTreeMap`. If it is pointing to the first /// element of the `BTreeMap` then this returns `None`. + #[cfg(test)] pub(crate) fn peek_prev(&self) -> Option<(&'a K, &'a V)> { let mut prev = self.clone(); prev.move_prev(); @@ -3268,6 +3275,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { /// If the cursor is pointing to the "ghost" non-element then this will move it to /// the first element of the `BTreeMap`. If it is pointing to the last /// element of the `BTreeMap` then this will move it to the "ghost" non-element. + #[cfg(test)] pub(crate) fn move_next(&mut self) { match self.current.take() { None => { @@ -3286,29 +3294,6 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { } } - /// Moves the cursor to the previous element of the `BTreeMap`. - /// - /// If the cursor is pointing to the "ghost" non-element then this will move it to - /// the last element of the `BTreeMap`. If it is pointing to the first - /// element of the `BTreeMap` then this will move it to the "ghost" non-element. - pub(crate) fn move_prev(&mut self) { - match self.current.take() { - None => { - // SAFETY: The previous borrow of root has ended. - self.current = unsafe { self.root.reborrow() }.as_mut().and_then(|root| { - root.borrow_mut() - .last_leaf_edge() - .forget_node_type() - .left_kv() - .ok() - }); - } - Some(current) => { - self.current = current.next_back_leaf_edge().next_back_kv().ok(); - } - } - } - /// Returns a reference to the key of the element that the cursor is /// currently pointing to. /// @@ -3363,29 +3348,12 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { }) } - /// Returns a mutable reference to the key of the element that the cursor is - /// currently pointing to. - /// - /// This returns `None` if the cursor is currently pointing to the - /// "ghost" non-element. - /// - /// # Safety - /// - /// This can be used to modify the key, but you must ensure that the - /// `BTreeMap` invariants are maintained. Specifically: - /// - /// * The key must remain unique within the tree. - /// * The key must remain in sorted order with regards to other elements in - /// the tree. - pub(crate) unsafe fn key_mut_unchecked(&mut self) -> Option<&mut K> { - self.current.as_mut().map(|current| current.kv_mut().0) - } - /// Returns a reference to the key and value of the next element. /// /// If the cursor is pointing to the "ghost" non-element then this returns /// the first element of the `BTreeMap`. If it is pointing to the last /// element of the `BTreeMap` then this returns `None`. + #[cfg(test)] pub(crate) fn peek_next(&mut self) -> Option<(&K, &mut V)> { let (k, v) = match self.current { None => { @@ -3413,6 +3381,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { /// If the cursor is pointing to the "ghost" non-element then this returns /// the last element of the `BTreeMap`. If it is pointing to the first /// element of the `BTreeMap` then this returns `None`. + #[cfg(test)] pub(crate) fn peek_prev(&mut self) -> Option<(&K, &mut V)> { let (k, v) = match self.current.as_mut() { None => { @@ -3436,19 +3405,6 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { }; Some((k, v)) } - - /// Returns a read-only cursor pointing to the current element. - /// - /// The lifetime of the returned `Cursor` is bound to that of the - /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the - /// `CursorMut` is frozen for the lifetime of the `Cursor`. - pub(crate) fn as_cursor(&self) -> Cursor<'_, K, V> { - Cursor { - // SAFETY: The tree is immutable while the cursor exists. - root: unsafe { self.root.reborrow_shared().as_ref() }, - current: self.current.as_ref().map(|current| current.reborrow()), - } - } } // Now the tree editing operations @@ -3465,6 +3421,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// /// * The key of the newly inserted element must be unique in the tree. /// * All keys in the tree must remain in sorted order. + #[cfg(test)] pub(crate) unsafe fn try_insert_after_unchecked( &mut self, key: K, @@ -3514,6 +3471,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// /// * The key of the newly inserted element must be unique in the tree. /// * All keys in the tree must remain in sorted order. + #[cfg(test)] pub(crate) unsafe fn try_insert_before_unchecked( &mut self, key: K, @@ -3563,6 +3521,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// any). /// - the given key compares greater than or equal to the next element (if /// any). + #[cfg(test)] pub(crate) fn try_insert_after(&mut self, key: K, value: V) -> Result<(), AllocError> { if let Some(current) = self.key() { if &key <= current { @@ -3597,6 +3556,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// (if any). /// - the given key compares less than or equal to the previous element (if /// any). + #[cfg(test)] pub(crate) fn try_insert_before(&mut self, key: K, value: V) -> Result<(), AllocError> { if let Some(current) = self.key() { if &key >= current { @@ -3626,6 +3586,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// /// If the cursor is currently pointing to the "ghost" non-element then no element /// is removed and `None` is returned. The cursor is not moved in this case. + #[cfg(test)] pub(crate) fn remove_current(&mut self) -> Option<(K, V)> { let current = self.current.take()?; let mut emptied_internal_root = false; @@ -3648,6 +3609,7 @@ impl<'a, K: Ord, V, A: Allocator> CursorMut<'a, K, V, A> { /// /// If the cursor is currently pointing to the "ghost" non-element then no element /// is removed and `None` is returned. The cursor is not moved in this case. + #[cfg(test)] pub(crate) fn remove_current_and_move_back(&mut self) -> Option<(K, V)> { let current = self.current.take()?; let mut emptied_internal_root = false; diff --git a/crates/rune-alloc/src/btree/navigate.rs b/crates/rune-alloc/src/btree/navigate.rs index 2e6f2077b..8ee73416d 100644 --- a/crates/rune-alloc/src/btree/navigate.rs +++ b/crates/rune-alloc/src/btree/navigate.rs @@ -773,7 +773,7 @@ impl NodeRef { Leaf(NodeRef), Internal(NodeRef), - InternalKV(Handle, marker::KV>), + InternalKV(#[allow(unused)] Handle, marker::KV>), } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { diff --git a/crates/rune-alloc/src/btree/node.rs b/crates/rune-alloc/src/btree/node.rs index d75542077..a682a11ef 100644 --- a/crates/rune-alloc/src/btree/node.rs +++ b/crates/rune-alloc/src/btree/node.rs @@ -1285,6 +1285,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> unsafe { leaf.vals.get_unchecked_mut(self.idx).assume_init_mut() } } + #[cfg(test)] pub(crate) fn into_kv_valmut(self) -> (&'a K, &'a mut V) { debug_assert!(self.idx < self.node.len()); let leaf = self.node.into_leaf_mut(); diff --git a/crates/rune-alloc/src/btree/set/tests.rs b/crates/rune-alloc/src/btree/set/tests.rs index d7f9acccb..a6898c47d 100644 --- a/crates/rune-alloc/src/btree/set/tests.rs +++ b/crates/rune-alloc/src/btree/set/tests.rs @@ -553,7 +553,7 @@ fn test_extend_ref() { #[test] fn test_recovery() { #[derive(Debug)] - struct Foo(&'static str, i32); + struct Foo(&'static str, #[allow(unused)] i32); impl PartialEq for Foo { fn eq(&self, other: &Self) -> bool { diff --git a/crates/rune-alloc/src/hashbrown/raw/mod.rs b/crates/rune-alloc/src/hashbrown/raw/mod.rs index ea85ff38d..97ad670fa 100644 --- a/crates/rune-alloc/src/hashbrown/raw/mod.rs +++ b/crates/rune-alloc/src/hashbrown/raw/mod.rs @@ -1205,7 +1205,7 @@ impl RawTable { /// /// This does not check if the given element already exists in the table. #[cfg_attr(feature = "inline-more", inline)] - #[cfg(any(feature = "raw", feature = "rustc-internal-api"))] + #[cfg(feature = "raw")] pub unsafe fn insert_no_grow(&mut self, hash: u64, value: T) -> Bucket { let (index, old_ctrl) = self.table.prepare_insert_slot(hash); let bucket = self.table.bucket(index); diff --git a/crates/rune-alloc/src/hashbrown/set.rs b/crates/rune-alloc/src/hashbrown/set.rs index 9fb0543ef..ec3395672 100644 --- a/crates/rune-alloc/src/hashbrown/set.rs +++ b/crates/rune-alloc/src/hashbrown/set.rs @@ -2764,7 +2764,7 @@ mod test_set { use core::hash; #[derive(Debug)] - struct Foo(&'static str, i32); + struct Foo(&'static str, #[allow(unused)] i32); impl PartialEq for Foo { fn eq(&self, other: &Self) -> bool { diff --git a/crates/rune-alloc/src/lib.rs b/crates/rune-alloc/src/lib.rs index 343e2ee95..61acb5d37 100644 --- a/crates/rune-alloc/src/lib.rs +++ b/crates/rune-alloc/src/lib.rs @@ -34,25 +34,20 @@ // may not be copied, modified, or distributed except according to those terms. #![no_std] -// TODO: get rid of this once we've evaluated what we want to have public. -#![allow(dead_code)] +#![allow(unexpected_cfgs)] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_doc_tests)] -#![cfg_attr(rune_nightly, feature(rustdoc_missing_doc_code_examples))] #![cfg_attr(rune_nightly, deny(rustdoc::missing_doc_code_examples))] +#![cfg_attr(rune_nightly, allow(internal_features))] +#![cfg_attr(rune_nightly, feature(fmt_internals))] +#![cfg_attr(rune_nightly, feature(rustdoc_missing_doc_code_examples))] #![cfg_attr(rune_nightly, feature(core_intrinsics))] #![cfg_attr(rune_nightly, feature(dropck_eyepatch))] #![cfg_attr(rune_nightly, feature(min_specialization))] #![cfg_attr(rune_nightly, feature(ptr_sub_ptr))] #![cfg_attr(rune_nightly, feature(set_ptr_value))] -#![cfg_attr(rune_nightly, feature(slice_ptr_len))] #![cfg_attr(rune_nightly, feature(slice_range))] #![cfg_attr(rune_nightly, feature(strict_provenance))] -#![cfg_attr(rune_nightly, feature(saturating_int_impl))] -#![cfg_attr(rune_nightly, feature(inline_const))] -#![cfg_attr(rune_nightly, feature(const_maybe_uninit_zeroed))] -// The only feature we use is `rustc_specialization_trait`. -#![cfg_attr(rune_nightly, allow(internal_features))] #![cfg_attr(rune_nightly, feature(rustc_attrs))] #![allow(clippy::comparison_chain)] #![allow(clippy::manual_map)] diff --git a/crates/rune-alloc/src/raw_vec.rs b/crates/rune-alloc/src/raw_vec.rs index 94841955e..d5a3d87cd 100644 --- a/crates/rune-alloc/src/raw_vec.rs +++ b/crates/rune-alloc/src/raw_vec.rs @@ -13,6 +13,7 @@ enum AllocInit { /// The contents of the new memory are uninitialized. Uninitialized, /// The new memory is guaranteed to be zeroed. + #[cfg(rune_nightly)] Zeroed, } @@ -99,6 +100,7 @@ impl RawVec { /// Like `with_capacity_zeroed`, but parameterized over the choice /// of allocator for the returned `RawVec`. #[inline] + #[cfg(rune_nightly)] pub(crate) fn try_with_capacity_zeroed_in(capacity: usize, alloc: A) -> Result { Self::try_allocate_in(capacity, AllocInit::Zeroed, alloc) } @@ -146,6 +148,7 @@ impl RawVec { } let ptr = match init { AllocInit::Uninitialized => alloc.allocate(layout)?, + #[cfg(rune_nightly)] AllocInit::Zeroed => alloc.allocate_zeroed(layout)?, }; diff --git a/crates/rune-alloc/src/vec/into_iter.rs b/crates/rune-alloc/src/vec/into_iter.rs index a9f1c5093..71f26bcc3 100644 --- a/crates/rune-alloc/src/vec/into_iter.rs +++ b/crates/rune-alloc/src/vec/into_iter.rs @@ -178,13 +178,6 @@ where } } -#[doc(hidden)] -pub trait NonDrop {} - -// T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr -// and thus we can't implement drop-handling -impl NonDrop for T {} - #[cfg(rune_nightly)] unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { fn drop(&mut self) { diff --git a/crates/rune-alloc/src/vec_deque/into_iter.rs b/crates/rune-alloc/src/vec_deque/into_iter.rs index 812906666..5e8de292b 100644 --- a/crates/rune-alloc/src/vec_deque/into_iter.rs +++ b/crates/rune-alloc/src/vec_deque/into_iter.rs @@ -39,10 +39,6 @@ impl IntoIter { pub(super) fn new(inner: VecDeque) -> Self { IntoIter { inner } } - - pub(super) fn into_vecdeque(self) -> VecDeque { - self.inner - } } impl fmt::Debug for IntoIter { diff --git a/crates/rune-alloc/src/vec_deque/mod.rs b/crates/rune-alloc/src/vec_deque/mod.rs index a6742bf8e..d2409f6d5 100644 --- a/crates/rune-alloc/src/vec_deque/mod.rs +++ b/crates/rune-alloc/src/vec_deque/mod.rs @@ -429,25 +429,6 @@ impl VecDeque { } } - /// Writes all values from `iter` to `dst`. - /// - /// # Safety - /// - /// Assumes no wrapping around happens. - /// Assumes capacity is sufficient. - #[inline] - unsafe fn write_iter( - &mut self, - dst: usize, - iter: impl Iterator, - written: &mut usize, - ) { - iter.enumerate().for_each(|(i, element)| unsafe { - self.buffer_write(dst + i, element); - *written += 1; - }); - } - /// Frobs the head and tail sections around to handle the fact that we /// just reallocated. Unsafe because it trusts old_capacity. #[inline] @@ -569,38 +550,6 @@ impl VecDeque { }) } - /// Creates a `VecDeque` from a raw allocation, when the initialized part of - /// that allocation forms a *contiguous* subslice thereof. - /// - /// For use by `vec::IntoIter::into_vecdeque` - /// - /// # Safety - /// - /// All the usual requirements on the allocated memory like in - /// `Vec::from_raw_parts_in`, but takes a *range* of elements that are - /// initialized rather than only supporting `0..len`. Requires that - /// `initialized.start` ≤ `initialized.end` ≤ `capacity`. - #[inline] - pub(crate) unsafe fn from_contiguous_raw_parts_in( - ptr: *mut T, - initialized: Range, - capacity: usize, - alloc: A, - ) -> Self { - debug_assert!(initialized.start <= initialized.end); - debug_assert!(initialized.end <= capacity); - - // SAFETY: Our safety precondition guarantees the range length won't wrap, - // and that the allocation is valid for use in `RawVec`. - unsafe { - VecDeque { - head: initialized.start, - len: initialized.end.wrapping_sub(initialized.start), - buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), - } - } - } - /// Provides a reference to the element at the given index. /// /// Element at index 0 is the front of the queue. diff --git a/crates/rune-core/src/lib.rs b/crates/rune-core/src/lib.rs index d56e3dd93..e25efb672 100644 --- a/crates/rune-core/src/lib.rs +++ b/crates/rune-core/src/lib.rs @@ -23,6 +23,7 @@ //! **YOU ARE NOT** supposed to depend on this directly. Doing so might cause //! dependency errors since its API is not stable. +#![allow(unexpected_cfgs)] #![allow(clippy::module_inception)] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_doc_tests)] diff --git a/crates/rune-modules/Cargo.toml b/crates/rune-modules/Cargo.toml index e6ece219c..df71224f4 100644 --- a/crates/rune-modules/Cargo.toml +++ b/crates/rune-modules/Cargo.toml @@ -28,6 +28,7 @@ test = [] core = [] io = [] fmt = [] +macros = [] [dependencies] reqwest = { version = "0.11.17", optional = true, default-features = false, features = ["rustls-tls", "gzip", "json"] } diff --git a/crates/rune/src/lib.rs b/crates/rune/src/lib.rs index 0ea5379f1..14825da95 100644 --- a/crates/rune/src/lib.rs +++ b/crates/rune/src/lib.rs @@ -133,6 +133,7 @@ #![deny(rustdoc::private_doc_tests)] #![cfg_attr(rune_nightly, feature(rustdoc_missing_doc_code_examples))] #![cfg_attr(rune_nightly, deny(rustdoc::missing_doc_code_examples))] +#![allow(unexpected_cfgs)] #![allow(clippy::enum_variant_names)] #![allow(clippy::needless_doctest_main)] #![allow(clippy::too_many_arguments)]