This code gives an error:
#[derive(Default)]
struct A {
b: Option<()>,
c: Option<()>,
}
const a: A = A {
b: None,
..Default::default()
};
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src/lib.rs:9:7
|
9 | ..Default::default()
| ^^^^^^^^^^^^^^^^^^
In this small example it's not a big problem, but if I have a struct composed by multiple structs that implement the Default
trait, not being able to use it becomes at minimum an inconvenience.
While I could write this, it wouldn't have the flexibility that Default
provides:
impl A {
const fn new(b: Option<()>) -> Self {
A { b, c: None }
}
}
const a: A = A::new(None);
Is there any way to avoid doing that?
The ..Default::default()
syntax is not restricted to Default::default()
, so you can write a const fn
default-like function and use that inside of a constant:
struct A {
b: Option<()>,
c: Option<()>,
}
impl A {
const fn new() -> A {
A {
b: None,
c: None,
}
}
}
impl Default for A {
fn default() -> A {
// implementing using new() instead of #[derive]
// to avoid diverging implementations
A::new()
}
}
const a: A = A {
b: None,
..A::new()
};
Run in Playground
No, it is not possible to use traits in a constant context. This is still being discussed in RFC #2632 — Calling methods on generic parameters of const fns.
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With