rfc-proposal

This is roughly what is described in the RFC.

TL;DR

  • Traits can be declared as const, in which case all methods are "maybe-const" (depending on the impl)
  • Impl can decide whether it is implementing const Trait (const or maybe-const methods)

Design axioms

Default trait and impl

Equivalent of default trait and impl:

#![allow(unused)]
fn main() {
const trait Default {
    fn default() -> Self;
}

struct Wrapper<T> {
    value: T
}

impl<T> const Default for Wrapper<T>
where
    T: ~const Default,
{
    fn default() -> Self {
        Wrapper {
            value: T::default()
        }
    }
}

const fn get_me<T>(x: Option<Wrapper<T>>) -> Wrapper<T>
where
    T: ~const Default,
{
    match x {
        None => <Wrapper<T>>::default(),
        Some(v) => v,
    }
}
}

Potential user confusion

If I write this...

#![allow(unused)]
fn main() {
const fn foo() {}
}

I have a function that can be used in or out of a const block. But if I put that const keyword on a generic bound...

#![allow(unused)]
fn main() {
const fn foo<T: const Default>() {

}
}

...I have a function that requires a const impl, which can be surprising (although it makes sense when you think about it, since trait bounds are declaring things that can be used by foo, not things that it does). However, it is backwards compatible to remove the const here. (It's not backwards compatible to add it.)