[Feature request] Allow destructuring patterns in `const` and `static`

Hi! I'm trying to move a bulk of computation into compile time and I have the following pattern:

const fn expensive_computation<T, U, V>() -> (T, U, V);

So, few values (three tables of different types and sizes) are being computed at the same time and depend on each other. And then I want to declare the constants:

const (A, B, C): (T, U, V) = expensive_computation();

The problem is that this syntax is not valid in Rust. The workaround I have is

const A: T = expensive_computation().0;
const B: U = expensive_computation().1;
const C: V = expensive_computation().2;

But this is both not elegant and slows down the compilation by a significant margin because now I have to compute the same set of values three times instead of just one. It would be awesome if the tuple destructuring syntax was available for constants: the compile-time evaluation and syntax would get much cleaner.

More context of how I encountered this and real-world case for this feature: long running const eval unusable in practice · Issue #93481 · rust-lang/rust · GitHub

7 Likes

Is the performance just as bad if the whole computation is first assigned to one const?

E.g.

const ABC: (T, U, V) = expensive_computation();
const A = ABC.0;
const B = ABC.1;
const C = ABC.2;

Edit: Some quick test on my laptop makes it seem as if introducing another const like this does improve performance significantly.

4 Likes

I think the way to do this would not make tuples special, but allow all destructuring patterns. That is, const and static are currently defined to take only identifiers:

Constant items:

ConstantItem : const ( IDENTIFIER | _ ) : Type ( = Expression )? ;

Static items:

StaticItem : static mut ? IDENTIFIER : Type ( = Expression )? ;

But perhaps they could take a pattern like let statements:

LetStatement : OuterAttribute * let PatternNoTopAlt ( : Type )? ( = Expression )? ;

7 Likes

Seems reasonable to allow any irrefutable pattern.

6 Likes

Out of curiosity, why can't (doesn't) the compiler cache the result of a const function?

Is there any reason not to allow irrefutable patterns? It seems like an obvious thing to do here — I don't think anyone would dispute its usefulness.

4 Likes

I suppose it could memoize it. But right now I think it just does that with const items.

Good point, thanks! That would kind of solve my problem but the larger problem would still be there, so I think it'll be valuable to allow destructuring patterns in consts in general.

Good point, I will update the title!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.