Reputation: 43
In this code:
#![allow(dead_code)]
use std::ops::Add;
struct Foo(i32);
const X: i32 = 1;
const Y: i32 = X + X;
const A: Foo = Foo(1);
const B: Foo = A + A;
impl Add for Foo {
type Output = Foo;
fn add(self, rhs: Foo) -> Foo {
Foo(self.0 + rhs.0)
}
}
The compiler says:
error[E0015]: calls in constants are limited to struct and enum constructors
--> src/main.rs:8:16
|
8 | const B: Foo = A + A;
| ^^^^^
|
note: a limited form of compile-time function evaluation is available on a nightly compiler via `const fn`
--> src/main.rs:8:16
|
8 | const B: Foo = A + A;
| ^^^^^
What is the best substitution?
Upvotes: 4
Views: 1245
Reputation: 431669
No, you cannot. Namely, the implementation of add
could do literally anything that Rust can do, including panicking, printing output, reading files, allocating memory, etc.
You will need to construct your constant "by hand":
const B: Foo = Foo(2);
You could also utilize a build script which would generate Rust code that you then can include back into your program.
As the error message says:
note: a limited form of compile-time function evaluation is available on a nightly compiler via
const fn
However, that won't help you here and now as trait methods cannot currently be made const
, and I doubt that Add::add
(or any other operator trait) will be marked const
as that would be overly restrictive — preventing implementations of Add
from using all the features listed above. I don't know how specialization / subtyping will work with const functions.
Upvotes: 2