You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a problem exclusively for when there is a const RUNTIME: bool param added to all const traits.
Suppose we have the following function:
constfnfoo<T: ~constAdd>(a:T,b:T) -> T::Output{ a + b }
We'd expect this to pass compilation, but if Add has a runtime parameter, T::Output needs to exclusively refer to the not-const version of the trait for backwards compatibility, which means this code would not compile. In fact, it is required to write the function like so, if traits had booleans attached to them:
constfnfoo<T: ~constAdd>(a:T,b:T) -> <Tas ~constAdd>::Output{ a + b }
This can add a lot of surface syntax noise as people, expectedly, use projections a lot. And constifying functions would lead to these projections all having to specify which context they are in:
T::Output for non-const
<T as ~const Add>::Output for binding constness to context (in const fns)
<T as const Add>::Output for always-const (in consts and etc.)
But we shouldn't need to do this! We can always be sure that the same type T implementing a trait Foo will always have <T as Foo>::X == <T as const Foo>::X if they do implement both the non-const and always-const version of the trait. This is due to the fact that we always store the "which context this type is in" in types themselves, leading to them being locked to a specific context.
For example, let's say in the future const closures are implemented. We always know which context this closure is in based on its type. (Note that closures will never implement both non-const and always-const, only exactly one context, see rust-lang/rust#119718.) That means the same closure (suppose we bind its constness to a generic param, such that it will eventually figure out what constness it is) used in a const context and in a non-const context will be two different types (imagine one with <true> attached to it and the other with <false>, therefore we never have to worry about different kinds of projections giving us different types.
The text was updated successfully, but these errors were encountered:
On second thought, my last two paragraphs could be wrong. There are types that are not locked to specific contexts like u32 and trait impls for them could easily project to different types should we start allowing things like function pointers to be specified as always const or not:
I believe this is also finished? Since fee1-dead's rewrite to use associated consts, effects are fully "late-bound", so this problem doesn't matter anymore.
I do think we should open a follow-up issue about WTF to do with ~const fn(), b/c that comes with its own set of really weird problems (also because it would be a distinct type from fn(), and that has tons of ecosystem implications).
This is a problem exclusively for when there is a
const RUNTIME: bool
param added to all const traits.Suppose we have the following function:
We'd expect this to pass compilation, but if
Add
has a runtime parameter,T::Output
needs to exclusively refer to the not-const version of the trait for backwards compatibility, which means this code would not compile. In fact, it is required to write the function like so, if traits had booleans attached to them:This can add a lot of surface syntax noise as people, expectedly, use projections a lot. And constifying functions would lead to these projections all having to specify which context they are in:
T::Output
for non-const<T as ~const Add>::Output
for binding constness to context (inconst fn
s)<T as const Add>::Output
for always-const (inconst
s and etc.)But we shouldn't need to do this! We can always be sure that the same type
T
implementing a traitFoo
will always have<T as Foo>::X == <T as const Foo>::X
if they do implement both the non-const and always-const version of the trait. This is due to the fact that we always store the "which context this type is in" in types themselves, leading to them being locked to a specific context.For example, let's say in the future const closures are implemented. We always know which context this closure is in based on its type. (Note that closures will never implement both non-const and always-const, only exactly one context, see rust-lang/rust#119718.) That means the same closure (suppose we bind its constness to a generic param, such that it will eventually figure out what constness it is) used in a const context and in a non-const context will be two different types (imagine one with
<true>
attached to it and the other with<false>
, therefore we never have to worry about different kinds of projections giving us different types.The text was updated successfully, but these errors were encountered: