diff --git a/Cargo.toml b/Cargo.toml index 6ceb7e2de9..718c198fda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["profile-rustflags"] + [workspace] members = [ "examples/basic", @@ -117,3 +119,8 @@ rev = "2a74b62c26724ff9c67e4e3ad05378a1af53f195" [profile.release] debug = true + +# FIXME: Work-around for undefined symbol errors that occur with the +# combination of `-Zbuild-std`, `opt-level = "s"`, and `lto = true` +# +rustflags = ["-Zshare-generics=off"] diff --git a/doc/toolchain_limitations.md b/doc/toolchain_limitations.md index 7fca80b49b..b8c100cd07 100644 --- a/doc/toolchain_limitations.md +++ b/doc/toolchain_limitations.md @@ -106,7 +106,7 @@ type Alias = Struct<{::N}>; ### `[tag:const_for]` `for` loops are unusable in `const fn` -Technically it's available under the compiler feature `const_for`, but the lack of essential trait implementations (e.g., `[ref:range_const_iterator]`, `[ref:const_slice_iter]`) and above all the inability of implementing `const Iterator` (`[ref:iterator_const_default]`) make it unusable. +Technically it's available under the compiler feature `const_for`, but the lack of essential trait implementations (e.g., `[ref:range_const_iterator]`, `[ref:const_slice_iter]`) makes it unusable in many cases. ### `[tag:const_static_item_ref]` `const`s and `const fn`s can't refer to `static`s @@ -430,23 +430,6 @@ const _: () = assert!(PartialEq::eq(&(A..A), &(A..A))); ``` -### `[tag:type_id_partial_eq]` `TypeId: !const PartialEq` - -The standard library doesn't provide a `const` trait implementation of `PartialEq` for `core::any::TypeId`. - -```rust -use core::any::TypeId; -assert!(TypeId::of::<()>() == TypeId::of::<()>()); -``` - -```rust,compile_fail,E0277 -#![feature(const_type_id)] -use core::any::TypeId; -// error[E0277]: can't compare `TypeId` with `_` in const contexts -const _: () = assert!(TypeId::of::<()>() == TypeId::of::<()>()); -``` - - ### `[tag:range_const_iterator]` `Range: !~const Iterator` The standard library doesn't provide a `const` trait implementation of `Range: Iterator`. @@ -466,25 +449,6 @@ const _: () = assert!(matches!((2..4).next(), Some(2))); ``` -### `[tag:iterator_const_default]` `Iterator` lack `#[const_trait]` - -```rust,compile_fail -#![feature(const_trait_impl)] -#![feature(const_mut_refs)] - -struct MyIterator; - -// error: const `impl` for trait `Iterator` which is not marked with `#[const_trait]` -impl const Iterator for MyIterator { - type Item = u32; - - fn next(&mut self) -> Option { - Some(42) - } -} -``` - - ### `[tag:const_assert_eq]` `assert_eq!` and similar macros are unusable in `const fn` ```rust,compile_fail,E0015 diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 839028b20a..95b4b200c3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-01-10" +channel = "nightly-2023-03-18" components = ["rustfmt", "rust-src", "clippy"] diff --git a/src/r3_core/src/bag.rs b/src/r3_core/src/bag.rs index 01261efb61..9c56e6d512 100644 --- a/src/r3_core/src/bag.rs +++ b/src/r3_core/src/bag.rs @@ -1,5 +1,5 @@ //! A heterogeneous collection to store property values. -use core::mem::transmute; +use core::{any::TypeId, mem::transmute}; /// A heterogeneous collection to store property values. #[const_trait] @@ -88,40 +88,3 @@ mod private { impl const Sealed for super::List {} impl const Sealed for super::Either {} } - -// `TypeId` doesn't implement `const PartialEq` [ref:type_id_partial_eq] -/// A wrapper of [`core::any::TypeId`] that is usable in a constant context. -struct TypeId { - inner: core::any::TypeId, -} - -impl TypeId { - #[inline] - const fn of() -> Self { - Self { - inner: core::any::TypeId::of::(), - } - } - - #[inline] - const fn eq(&self, other: &Self) -> bool { - // This relies on the implementation details of `TypeId`, but I think - // we're are okay judging by the fact that WebRender is doing the same - // - unsafe { - type TypeIdBytes = [u8; core::mem::size_of::()]; - let x: TypeIdBytes = transmute(self.inner); - let y: TypeIdBytes = transmute(other.inner); - // Can't just do `x == y` due to [ref:array_const_partial_eq]. - // A non-idiomatic loop must be used due to [ref:const_for]. - let mut i = 0; - while i < x.len() { - if x[i] != y[i] { - return false; - } - i += 1; - } - true - } - } -} diff --git a/src/r3_core/src/bind/sorter.rs b/src/r3_core/src/bind/sorter.rs index 3535d4b008..c48ab6a093 100644 --- a/src/r3_core/src/bind/sorter.rs +++ b/src/r3_core/src/bind/sorter.rs @@ -318,7 +318,7 @@ pub(super) const fn sort_bindings( End, } - impl const MyIterator for VertexIter<'_> { + impl const Iterator for VertexIter<'_> { type Item = Vertex; fn next(&mut self) -> Option { @@ -369,7 +369,7 @@ pub(super) const fn sort_bindings( End, } - impl const MyIterator for SuccessorIter<'_, Callback> + impl const Iterator for SuccessorIter<'_, Callback> where Callback: ~const SorterCallback, { @@ -533,23 +533,14 @@ pub(super) const fn sort_bindings( // Helper traits // -------------------------------------------------------------------------- -// `const Iterator` is currently very hard to implement -// [ref:iterator_const_default] -/// An [`Iterator`][] usable in `const fn`. -#[const_trait] -trait MyIterator { - type Item; - fn next(&mut self) -> Option; -} - #[const_trait] trait GraphAccess { - type VertexIter<'a>: ~const MyIterator + ~const Destruct + 'a + type VertexIter<'a>: ~const Iterator + ~const Destruct + 'a where Self: 'a; fn vertices(&self) -> Self::VertexIter<'_>; - type SuccessorIter<'a>: ~const MyIterator + ~const Destruct + 'a + type SuccessorIter<'a>: ~const Iterator + ~const Destruct + 'a where Self: 'a; fn successors(&self, v: &VertexRef) -> Self::SuccessorIter<'_>; diff --git a/src/r3_kernel/src/lib.rs b/src/r3_kernel/src/lib.rs index 982336a4de..67729e2d0d 100644 --- a/src/r3_kernel/src/lib.rs +++ b/src/r3_kernel/src/lib.rs @@ -27,7 +27,6 @@ #![feature(const_swap)] #![feature(never_type)] // `!` #![feature(decl_macro)] -#![feature(pin_macro)] #![feature(doc_cfg)] // `#[doc(cfg(...))]` #![deny(unsafe_op_in_unsafe_fn)] #![cfg_attr( diff --git a/src/r3_kernel/src/utils/ctz.rs b/src/r3_kernel/src/utils/ctz.rs index 400b3bf474..7264ad8816 100644 --- a/src/r3_kernel/src/utils/ctz.rs +++ b/src/r3_kernel/src/utils/ctz.rs @@ -314,7 +314,7 @@ mod tests { } else { let low = i & 31; let high = i >> 5; - low | (high << (bits - 5)) + low | high.checked_shl((bits - 5) as u32).unwrap() } as usize; let got = $func(in_value); diff --git a/src/r3_port_std/src/lib.rs b/src/r3_port_std/src/lib.rs index c4f8e67006..12e6bfe65a 100644 --- a/src/r3_port_std/src/lib.rs +++ b/src/r3_port_std/src/lib.rs @@ -1,5 +1,4 @@ #![feature(cfg_target_has_atomic)] // `#[cfg(target_has_atomic_load_store)]` -#![feature(atomic_mut_ptr)] #![feature(thread_local)] #![feature(deadline_api)] #![feature(once_cell)] diff --git a/src/r3_port_std/src/threading_windows.rs b/src/r3_port_std/src/threading_windows.rs index 3da7f0c72a..36f77998b0 100644 --- a/src/r3_port_std/src/threading_windows.rs +++ b/src/r3_port_std/src/threading_windows.rs @@ -91,7 +91,7 @@ pub fn park() { while token_count < 0 { unsafe { synchapi::WaitOnAddress( - token_count_cell.as_mut_ptr().cast(), // location to watch + token_count_cell.as_ptr().cast(), // location to watch addr_of!(token_count).cast_mut().cast(), // undesired value std::mem::size_of::(), // value size INFINITE, // timeout @@ -116,7 +116,7 @@ impl Thread { let _guard = self.data.remote_op_mutex.lock().unwrap(); let token_count_cell = &self.data.token_count; if token_count_cell.fetch_add(1, Ordering::Relaxed) == -1 { - unsafe { synchapi::WakeByAddressAll(token_count_cell.as_mut_ptr().cast()) }; + unsafe { synchapi::WakeByAddressAll(token_count_cell.as_ptr().cast()) }; unsafe { processthreadsapi::ResumeThread(self.data.hthread) }; } } @@ -256,7 +256,7 @@ mod mutex { { unsafe { synchapi::WaitOnAddress( - self.locked.as_mut_ptr().cast(), // location to watch + self.locked.as_ptr().cast(), // location to watch [true].as_ptr().cast_mut().cast(), // undesired value std::mem::size_of::(), // value size INFINITE, // timeout @@ -283,7 +283,7 @@ mod mutex { #[inline] fn drop(&mut self) { self.locked.store(false, Ordering::Release); - unsafe { synchapi::WakeByAddressSingle(self.locked.as_mut_ptr().cast()) }; + unsafe { synchapi::WakeByAddressSingle(self.locked.as_ptr().cast()) }; } } diff --git a/src/r3_test_runner/src/main.rs b/src/r3_test_runner/src/main.rs index d8ed90c2c7..2777252d4c 100644 --- a/src/r3_test_runner/src/main.rs +++ b/src/r3_test_runner/src/main.rs @@ -4,7 +4,6 @@ #![feature(lint_reasons)] #![feature(decl_macro)] // `macro` #![feature(once_cell)] -#![feature(pin_macro)] // `core::pin::pin!` #![warn(must_not_suspend)] use anyhow::{bail, Context}; use clap::Parser;