Opaque concrete constants #39
Labels
A-unification
Unifying constants in the type system
C-design-docs
Category: This is part of our design documentation
K-behavior
Document Kind: regarding user visible behavior
P-optional
Priority: not strictly required
S-active
What is this
This is a design document for const generics. Any discussions about its content should be on zulip. The conclusions of these discussions should then be edited back into this issue. Please do not post any comments directly in this issue.
Content
adapted from a summary by @PoignardAzur.
Quite a lot of functions might not want their exact output to be part of their stability guarantees. A good example for this is
mem::size_of::<T>()
.With const generics, changing the return value of such functions can however end up being a breaking change.
While this is already an issue today, it may get even worse with the addition of complex generic constants, e.g:
Current stability guidelines
Looking at the SemVer Compatibility doc this is somewhat under-documented.
Should we worry about this?
Currently any breakage tends to be fairly explicit, as it mostly happens by unifying an array, where the length is the result of a function call, with some array of a concrete length. This means that places where breakage may occur tend to be fairly obvious.
This may change in the future however. By using a bound like
N > 4
for trait implementations it will be less clear whether one currently depends on the concrete return value of such a function. It will also make it less obvious what actually went wrong, making the resulting breakage more difficult to figure out.And in any case, the current situation isn't ideal. Stability guarantees should be better documented, and enforced by machine rules instead of doc comments.
How could we remedy this
The language could have an annotation to mark that a constants value isn't part of the stability guarantee, and therefore shouldn't be relied on.
This annotation would have no effect within a crate, but would prevent downstream crates from unifying the constant with its value, among other things.
For instance:
Opaqueness would be infectious:
Const functions could be declared as opaque as well, so that their output isn't a stability guarantee:
Arguably, some developers may even want opaqueness to be the default for functions. It's unclear how common opaque const functions would be. On one hand, library authors don't want to bump semver whenever they change internal code.
On the other hand, there are functions where it's absolutely clear the output is never expected to change, like
Vec::size
oriter::find
, even if their internal algorithm changes.The most notable function is
mem::size_of
. Its output is explicitly not part of Rusts stability guarantees but people still want to rely on the exact size of their structs. So while we won't be able to completely forbid that, we should consider to lint in these cases instead. @PoignardAzur discusses this in more detail.Next steps
While this is strongly related to const generics its actual design and implementation are mostly independent of it. I would expect us to take the following steps for this:
The text was updated successfully, but these errors were encountered: