ethereum / fe

Emerging smart contract language for the Ethereum blockchain.
https://fe-lang.org
Other
1.6k stars 179 forks source link

Const ty #945

Closed Y-Nak closed 7 months ago

Y-Nak commented 10 months ago

This PR introduces basic const types. Currently, there are some restrictions on the usage of const types, which will be mitigated when a type checker is implemented.

Usage

ADTs, functions, and traits can be declared with const type parameters. The basic example would be

pub struct S<const N: u32> {
    N: u32
}

pub fn f<const N: u32>() {}

pub trait Trait<const B: bool> {}

Const type parameters can treated in the same way as normal type parameters in trait or method implementation. e.g.,

pub trait Trait<const N: u32> {}
pub struct S<const N: u32> {}

impl<const N: u32> S<N> {
     // `foo` is defined for S with all `N`(0..u32::MAX)     
    pub fn foo(self) {}
}

// `Trait<1>` is implemented for `S<1>`, `Trait<2>` is implemented for `S<2>` respectively.
impl<const N: u32> Trait<N> for S<N> {}

// It's also possible to implement specialized traits for specialized types.
impl Trait<2> for S<1> {}

impl S<1> {
    // `bar` is defined only for `S<1>`
    fn bar(self) {}
}

Limitations

There are two major restrictions on the type system.

  1. Only bool and integral types(e.g., u8, u16, ...) are allowed for a const type.
  2. Only literals are allowed as a const type argument.

These limitations will be mitigated when we redesign type system.

MIsc

Replace fxhash with rustc_hash in parser2.

sbillig commented 7 months ago

@Y-Nak Will we allow dependent functions, with a return type that depends on the value of an argument? Eg

pub struct X<const N: u8> {}

pub fn bar(n: u8) -> X {
  return X<n>{}
}

In the current implementation, should the syntax of -> X be allowed, or should there be an error? (There currently isn't an error)

Y-Nak commented 7 months ago

This PR is pretty restrictive so that we can introduce the basic const generics. I should've titled this PR as basic const generics rather than dependent types(I couldn't make up my mind whether I should continue implementing a genuine dependent type system in this PR when I implemented this PR, then forgot to rename this in my mind). So, for now, your example should be an error(I fixed this bug).

I'm trying to design a more sophisticated type system now in the separate PR, which will allow the snippet below.

pub struct X<const N: u8> {}

pub fn bar(n: u8) -> X<n> {
  return X<n>{}
}