# Future Direction: Const Generics and Dispatching

**URL:** https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283
**Category:** Uncategorized
**Created:** [October 27, 2020, 4:54pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283 "2020-10-27T16:54:48Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@sighoya](https://internals.rust-lang.org/u/sighoya)
#### Post date: [October 27, 2020, 4:54pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/1 "2020-10-27T16:54:49Z")

</div>

At momentum, the stabilizing (not yet) feature of const generics seem to exclude const equality/const ordering or at least allows them to some minor extent, for good reasons.

My interest would go after this as described by the RFC Section [Specialization on Const Parameters](https://rust-lang.github.io/rfcs/2000-const-generics.html#specialization-on-const-parameters)

Although the mentioned example is quite interesting, generalizing to include the full semantic of equality and order leads to undecidable type checking, for example:

```rust
fn fun<T:Comparable>(x:T, y:T) where x<y
fn fun<T:Comparable>(x:T, y:T) where x<=y

```

To get the former method preferred when applying fun to x,y, you are required to compare `<=`, `<` either by traversing all relation members (this is undecidable for T with infinite members) or you prove the code given the where signatures.

The latter requires understanding semantics usually expressed over higher order logic (HOL), e.g. for describing reflexivity, symmetry and transitivity.

Beside that some cases are decidable and could be inferred in reasonable time, others are not, i.e. typechecking becomes undecidable.

So what is the future direction to go with specialization?

I've heard from @oli-obk that specialization is disregarded at momentum for const generics, i.e. two trait methods with the signature except for different const value expressions are deemed to be (possibly) equal resulting into an error?

Is the target to allow const expr in trait methods with decidable semantic specialization or is it generally possible to formulate undecidable problems. When, how to tackle them in the right way? Writing own proofs or change the dispatch behavior in the undecidable case and when is a const expr known to be undecidable regarding order, i.e. how many scenarios have to be enumerated to exclude any undecidable case?

Another approach coming from [D](https://dlang.org/) is to treat relations of any kind (this includes all operators, functions too) as simple propositions such that `==(x,x^2+1)` becomes substituted to `==(x,y)`, the former known to be false for every x, the latter may include the possibility that `x==y` because we have no semantic meaning of ops like `^`,`+ `.

It means these two functions are possibly equal:

```rust
fn fun<T:Comparable>(x:T, y:T) where x<y
fn fun<T:Comparable>(x:T, y:T) where x<=y

```

Therefore, it will be rejected by the compiler considering only propositions. It can, however, be alleviated with the following rewrite:

```rust
fn fun<T:Comparable>(x:T, y:T) where x<y
fn fun<T:Comparable>(x:T, y:T) where x<=y && not(x<y)

```

Is a bit more nasty to write that and it doesn't scale that much, but it is at least manually possible and you can control the way it dispatches. Imagine that semantic dispatching even when decidable can take a while to compute, dispatching over propositions is much faster and has the advantage to be decidable.

Would this be a reasonable approach for Rust, too or can we expect a mix of semantic vs propositional dispatching.

---

<div class="post-metadata">

### Author: ![lcnr](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lcnr/32/6794_2.png) [@lcnr](https://internals.rust-lang.org/u/lcnr)
#### Post date: [October 27, 2020, 7:42pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/2 "2020-10-27T19:42:36Z")

</div>

```rust
default fn fun<T:Comparable>(x:T, y:T) where x<=y
fn fun<T:Comparable>(x:T, y:T) where x<=y && not(x==y)

```

seems the most likely to me and is something which I expect to be somewhat straightforward.

I personally would maybe allow reasoning about inductive datatypes, meaning that

`(3, U)` can specialize `(T, U)` and `Foo { v: 3, u: N + 1 }` can specialize `Foo { v: M, u: N + 1 }`

This would also allow for the following:

```rust
trait Foo<const V: Option<usize>> { fn test() {} }

impl<const N: usize> Foo<{ Some(N) }> for () {}

imp Foo<None> for () {
    fn test() {
        println!("I am none");
    }
}

```

Also, like I said on github, I am mostly concerned with getting the simple version to work correctly before I even think to deeply about any of this though.

---

<div class="post-metadata">

### Author: ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)
#### Post date: [October 27, 2020, 9:40pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/3 "2020-10-27T21:40:22Z")

</div>

A solution based on specialization has a lot of problems:

- It's highly nonintuitive, especially if there are more cases than two.
- In some cases we may want to use associated types, but `default type` prevents the compiler from resolving associated type projections to concrete types in some cases – an unnecessary limitation.
- Also, specialization currently has no path to stabilization at all, except for min\_specialization, which would not work for this.

I wish we had something like `if constexpr`...

---

<div class="post-metadata">

### Author: ![sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@sighoya](https://internals.rust-lang.org/u/sighoya)
#### Post date: [October 28, 2020, 8:09am UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/4 "2020-10-28T08:09:49Z")

</div>

> [@comex](#):
>
> I wish we had something like `if constexpr`

Did you suggest some kind of `static if` or to what exactly did you refer to?

---

<div class="post-metadata">

### Author: ![lcnr](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lcnr/32/6794_2.png) [@lcnr](https://internals.rust-lang.org/u/lcnr)
#### Post date: [October 28, 2020, 8:23am UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/5 "2020-10-28T08:23:53Z")

</div>

```rust
default fn fun<T:Comparable>(x:T, y:T) where x<=y
fn fun<T:Comparable>(x:T, y:T) where x<=y && not(x==y)

```

Note that stuff like this should probably get written as

```rust
fn fun<T:Comparable>(x:T, y:T) where x<=y`{
    if x == y {
        // whatever
    } else {
        // whatever
    }
}

```

you can specialize on const expressions by branching on their value.

---

<div class="post-metadata">

### Author: ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)
#### Post date: [October 28, 2020, 7:18pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/6 "2020-10-28T19:18:43Z")

</div>

> [@comex](#):
>
> I wish we had something like `if constexpr`

Is this not

```rust
#![feature(inline_const)]

if const { true } {
    ...
}

```

> <https://github.com/ecstatic-morse/rfcs/blob/inline-const/text/0000-inline-const.md>

> <https://github.com/rust-lang/rust/issues/76001>
>
> This is a tracking issue for the RFC "Inline \`const\` expressions and patterns" (…rust-lang/rfcs#2920).
> The feature gate for the issue is \`#!\[feature(inline\_const)\]\`.
> 
> \### About tracking issues
> 
> Tracking issues are used to record the overall progress of implementation.
> They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions.
> A tracking issue is however \*not\* meant for large scale discussion, questions, or bug reports about a feature.
> Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
> 
> \### Steps
> \<!--
> Include each step required to complete the feature. Typically this is a PR
> implementing a feature, followed by a PR that stabilises the feature. However
> for larger features an implementation could be broken up into multiple PRs.
> \--\>
> 
> \- \[x\] Implement the RFC (#77124 does most of it, modulo some bugs around range patterns that should be fixed in #78116)
> \- \[x\] Adjust documentation (\[see instructions on rustc-dev-guide\]\[doc-guide\]) \[Unstable Book docs in #78250\]
> \- \[\] Handle inner attributes. https://github.com/rust-lang/rust/pull/94985
> \- \[\] resolve expr fragment specifier issue (#86730)
> \- \[\] Stabilization PR (\[see instructions on rustc-dev-guide\]\[stabilization-guide\])
> 
> \[stabilization-guide\]: https://rustc-dev-guide.rust-lang.org/stabilization\_guide.html#stabilization-pr
> \[doc-guide\]: https://rustc-dev-guide.rust-lang.org/stabilization\_guide.html#documentation-prs
> 
> \### Unresolved Questions
> 
> \* Naming: "inline const", "const block", or "anonymous const"?
> \* Lint about \`&const { 4 }\` vs \`const { &4 }\`?
> \* How should this work for the special has-block syntax rules? \<https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/const.20blocks.20differ.20from.20normal.20and.20from.20unsafe.20blocks/near/290229453\>
> 
> \### Implementation history
> 
> \<!--
> Include a list of all the PRs that were involved in implementing the feature.
> \--\>
> 
> \- Primary implementation PR: #77124
> \- Unstable Book documentation: #78250
> \- \`FnDef\` type is disallowed in patterns: #114668

---

<div class="post-metadata">

### Author: ![bovine\_buddha](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bovine_buddha/32/8877_2.png) [@bovine\_buddha](https://internals.rust-lang.org/u/bovine_buddha)
#### Post date: [October 28, 2020, 7:55pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/7 "2020-10-28T19:55:40Z")

</div>

Isn't `if constexpr` in C++ a way to make the compiler discard one of the branches depending on the condition, to enable weird duck-typing conditional compilation based on the template arguments? I don't think this can apply in any way to Rust code.

The proposed `if consteval` in C++ which would allow conditional compilation depending on if we are currently executing in a const context or not could be feasible, but... that is also a real can of worms.

---

<div class="post-metadata">

### Author: ![sighoya](https://avatars.discourse-cdn.com/v4/letter/s/a87d85/32.png) [@sighoya](https://internals.rust-lang.org/u/sighoya)
#### Post date: [October 29, 2020, 3:48pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/8 "2020-10-29T15:48:40Z")

</div>

Other question: Would it be possible to call/instantiate C++ templates constrained by [concepts and constraints](https://en.cppreference.com/w/cpp/language/constraints) in a safe/compatible manner? I mean, additionally calling C++ logic over the ABI, it could also be possible to use C++ logic over the ASI (Application Source Interface) / or ATI (Application Template Interface), don't know.

---

<div class="post-metadata">

### Author: ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)
#### Post date: [October 29, 2020, 5:33pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/9 "2020-10-29T17:33:42Z")

</div>

While I'd love to see a project to integrate rustc with a C++ compiler for better FFI, it's definitely not on topic in this thread.

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [January 27, 2021, 5:33pm UTC](https://internals.rust-lang.org/t/future-direction-const-generics-and-dispatching/13283/10 "2021-01-27T17:33:44Z")

</div>

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