RFC Draft - Const trait methods - Redux

I wasn't satisfied by the syntax proposed by RFC 3762, and judging by the comments, neither was the author. I took oli-obk's RFC and wrote my own version based off of it, with different syntax choices and the rationale for them, but the same semantics.

Rendered.

Fully contained example:

const trait Default {
    const fn default() -> Self;
}

impl const Default for () {
    const fn default() {}
}

struct Thing<T>(T);

impl<T: const Default> const Default for Thing<T> {
    const fn default() -> Self { Self(T::default()) }
}

const fn default<T: const Default>() -> T {
    T::default()
}

fn compile_time_default<T: const(always) Default>() -> T {
    const { T::default() }
}

const _: () = Default::default();

fn main() {
    let () = default();
    let () = compile_time_default();
    let () = Default::default();
}
5 Likes

I actually mostly like the syntax RFC 3762 has landed on; my only major disagreement is that I prefer ~const to (const). However, I have a completely different mental model for why it’s good, compared to the lang team. I describe this model at length here: const traits model - HackMD

TLDR: const Trait can be thought of as an alias for a refined version of Trait.

2 Likes

Lang team hat on: so do I.

Many, many rationales, but among them, impl (Trait) means the same thing impl Trait does, so impl (const) Trait shouldn't mean something different than impl const Trait. (x) and x are the same thing.

5 Likes

I think the mental model of ~const Trait is a lot easier to follow, and I also like the potential of being able to maybe have ~const fn in the future.

1 Like

What would you expect this to mean?

To me it would be a function that can be const depending on its parameters. For example, ~const fn f(t: impl ~const MaybeConstTrait) -> u64 can be const if t is, but not otherwise. But I haven't dug into the RFC (which may also be a useful data point separate from those more steeped in the history here).

1 Like

There are a few reasons the design in my HackMD I linked above doesn’t work that way, and writes that const fn f(t: impl ~const MaybeConstTrait) -> u64 instead:

  • The relationship between const in const fn and ~const in ~const MaybeConstTrait is asymmetric. The former depends on the latter. So the syntax should be asymmetric also.
  • You can think of all const fns as “conditionally const”, it’s just that up to now the condition was always true.
  • The HackMD uses ~const fn to mean something different: it’s used in the methods of const Traits, to indicate that the constness of the trait depends on the constness of the method.
2 Likes