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
One worthy goal would be to be able to perform compile-time size/alignment assertions for inline storage without changing the final api, and retaining the storage-agnostic goal of the final container objects. Heap storage should not do any assertions.
My approach is to use generic associated types as assertion objects and have the final create function perform the check using the assertion object directly. This way each associated assertion is a policy for the final create function. For all storages the assertion is performed as a trait requirement on create, the trick is to make the assertion always pass for Heap storages but possibly-fail for Inline storages.
Unfortunately having the check being part of the signature means that all call sites will need to propagate the constraint even if we know that eg on HeapStorage it will always pass. The compiler first checks the trait bounds and refuses to evaluate the bound itself. This means that if we attempt to make an alias with HeapStorage the constraint will have to leak to user code as well.
Eg a user can't write an external create function:
it would be nice if the compiler attempted to evaluate the trait first. The above should be able to reduce to:
[u8 ; {HeapStorage::Asserter<T>::VALUE as usize} - 1] : Sized =>
// At this point AlwaysTrueAsserter is parameterized but we can avoid it.
[u8 ; {AlwaysTrueAsserter::VALUE as usize} - 1] : Sized =>
[u8 ; {true as usize} - 1] : Sized =>
[u8 ; 0] : Sized
So the fact that I have to specify the bound seems a bit unneeded to me.
The text was updated successfully, but these errors were encountered:
I realized there's another fundamental difference between the inline storage and the heap storage. With the inline storage, it's known at compile-time whether the allocation will succeed, whether with the heap storage it's not known until one tries.
Hence, if we wanted to go all the way, we should also make it possible to specialize the error type in create. That is:
And the AllocError<T> should expand to either T if failure is possible or ! if it is not.
I must admit that I'm not ready to use the clunky [u8; X] : Sized work-around.
If at some point the compiler were to support value-based where clauses, such as where S::is_allocation_possible::<T>(), it would be one thing; but the goal here is to end up with a design fitting the std library, and I have some doubts that where [u8; X] : Sized will pass muster.
I do like exploring how far compile-time assertions can be pushed; I just want to be clear that I am not likely to act on any such exploration.
I understand this, I also wouldn't attempt to standarize this as is. Even if we had a better syntax for the assertion, I would expect the HeapStorage to completely remove the assertion for user code otherwise it would just be confusing. Currently trying to see if this is in the scope of the const_generics RFC.
One worthy goal would be to be able to perform compile-time size/alignment assertions for inline storage without changing the final api, and retaining the storage-agnostic goal of the final container objects. Heap storage should not do any assertions.
My approach is to use generic associated types as assertion objects and have the final create function perform the check using the assertion object directly. This way each associated assertion is a policy for the final create function. For all storages the assertion is performed as a trait requirement on create, the trick is to make the assertion always pass for Heap storages but possibly-fail for Inline storages.
Here is a POC of this.
Unfortunately having the check being part of the signature means that all call sites will need to propagate the constraint even if we know that eg on HeapStorage it will always pass. The compiler first checks the trait bounds and refuses to evaluate the bound itself. This means that if we attempt to make an alias with HeapStorage the constraint will have to leak to user code as well.
Eg a user can't write an external create function:
even though the trait is always valid. Instead they have to write the following:
it would be nice if the compiler attempted to evaluate the trait first. The above should be able to reduce to:
So the fact that I have to specify the bound seems a bit unneeded to me.
The text was updated successfully, but these errors were encountered: