Make intrusive_adapter generated constructor function const
penberg opened this issue · comments
Pekka Enberg commented
I have an adapter defined with the intrusive_adapter
macro as follows:
intrusive_adapter!(pub ProcessAdapter = Rc<Process>: Process { link: LinkedListLink });
However, I am unable to construct a linked list with it for a static
variable:
static mut RUNQUEUE: LinkedList<ProcessAdapter> = LinkedList::new(ProcessAdapter::new());
because the ProcessAdapter::new()
function is not const:
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
The following patch fixes the problem for me:
diff --git a/src/adapter.rs b/src/adapter.rs
index ccb0349..3b98873 100644
--- a/src/adapter.rs
+++ b/src/adapter.rs
@@ -175,6 +175,11 @@ macro_rules! intrusive_adapter {
#[allow(dead_code)]
impl<$($args $(: ?$bound)*),*> $name<$($args),*> $($where_)* {
pub const NEW: Self = $name($crate::__core::marker::PhantomData);
+ #[cfg(feature = "nightly")]
+ pub const fn new() -> Self {
+ Self::NEW
+ }
+ #[cfg(not(feature = "nightly"))]
pub fn new() -> Self {
Self::NEW
}
However, it cause the following compilation warning:
warning: outlives requirements can be inferred
--> src/rbtree.rs:1456:43
|
1456 | pub enum Entry<'a, A: Adapter<Link = Link> + 'a> {
| ^^^^^ help: remove this bound
|
note: lint level defined here
--> src/lib.rs:275:9
|
275 | #![warn(rust_2018_idioms)]
| ^^^^^^^^^^^^^^^^
= note: `#[warn(explicit_outlives_requirements)]` implied by `#[warn(rust_2018_idioms)]`
which I am not sure how to fix, which is why I am submitting this as an issue rather than a pull request.
Amanieu d'Antras commented
There's issues with const fn
and generic bounds. You should just use ::NEW
when you need a const constructor, that's what it is for.
Pekka Enberg commented
@Amanieu Aah, thanks! I didn't see ::NEW
mentioned in the API documentation, but perhaps I didn't look closely enough.