# \[Pre-RFC\] Genericity over static values

**URL:** <https://internals.rust-lang.org/t/pre-rfc-genericity-over-static-values/1538>\
**Category:** internals\
**Created:** [February 4, 2015, 11:49am UTC](https://internals.rust-lang.org/t/pre-rfc-genericity-over-static-values/1538 "2015-02-04T11:49:37Z")\
**Posts on this page:** 1\
**Showing post:** 26

<div class="post-metadata">

**Author:** ![quantheory](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quantheory/32/480_2.png) [@quantheory](https://internals.rust-lang.org/u/quantheory)\
**Post date:** [February 12, 2015, 8:26pm UTC](https://internals.rust-lang.org/t/pre-rfc-genericity-over-static-values/1538/26 "2015-02-12T20:26:54Z")

</div>

> [@glaebhoerl](#):
>
> At the term level, when someone writes `1>>2`, we don't have any difficulty with determining whether the expression ends at `1` or also encompasses the `>>2`.

The simple answer to your question is that if you write `let x = 1 >> 2;` the parser knows that the expression continues as soon as it hits the `>>`, purely by knowing that no type context has been established, without needing any other context at all, whereas in a parameter list it would have to look ahead to see if whatever is farther to the right is an expression or something that can follow a type. (A similar kind of difficulty is why we have to write `Vec::<usize>::new()` instead of `Vec<usize>::new()`.)

My understanding is that right now the rustc parser expects to be able to tell whether it's in an expression or type context without having to do lookahead. This is admittedly a property of the current reference compiler that sometimes seems to be too restrictive, and could change, but it does have its good points (besides the reference compiler, other parsing tools are easier to create if the language is designed this way).

Regarding your "austere" solution, I don't think that allowing only literals and named constants will give you the same expressiveness, because there would be no way to translate something like this:

```rust
trait SomeTrait {
    fn do_stuff<const N: usize>(x: Foo<N>) -> Foo<{N-1}>;
}

```

I will think about `where` clauses and your comments some more tonight. It occurs to me that the ability of match patterns to overlap might not be such a big deal after all. What's important for coherence checks is that it has to be _possible_ to give some kind of verdict on whether two constraints can overlap, whether or not match patterns do the same thing. Furthermore, we could recover something approximating the fuller match pattern semantics if negative bounds eventually become possible:

```rust
// Don't worry about the syntax for this example.
// The point is that you can define overlapping impls, then make them compatible by giving one a negative bound that handles it.
impl<const N: usize> SomeTrait<N> for Foo<5>
      where const N: 5...7 {/* ... */}
impl<const N: usize> SomeTrait<N> for Foo<N>
      where const !N: 5...7, const N: 2...10 { /* ... */ }

```

---

_[View the full topic](https://internals.rust-lang.org/t/pre-rfc-genericity-over-static-values/1538)._
