Quick concept. There's a number of constants (e.g. UNICODE_VERSION
) where the value is constant for any specific library version and target/configuration combination, but changing one of those is allowed to change the value of the constant. As such, introducing these constants into the type system via const generics is a potential footgun.
It'd be nice if we could mark such constant items as "fickle" and have the compiler warn when using them in a context which isn't itself marked as fickle. This would be granular; it's an accepted usage if the function or const
item definition it appears in is marked as fickle. Using a fickle const as a const generic would be marked with #[allow]
to acknowledge the lint and that this use is deliberate and handles the potential variance. Use outside the type system (i.e. in non-const
expressions) would of course remain non linted. (I'm unsure on whether inline const
blocks should lint fickle consts.)
There should probably be some looseness around "universal" usage, so e.g. all the usage of [u8; mem::size_of<T>]
doesn't suddenly lint everywhere, since that's probably nonproblematic usage. The "full smart" analysis would be the lack of any non-universally-quantified impls on the type, but that's unfortunately a very global question, and an open one at that, since crates can add new trait impls. (More precise but also significantly more complicated would be only linting once a bounded obligation is required. Also deliberately ignores post-mono filtering of the const, since that's, well, post-mono[1].)
This could be extended to traits where removing an impl shouldn't be considered breaking. Currently stable, I think that's only Drop
, but IIRC a primary reason Freeze
is still private (despite technically being publicly observable via const restrictions) is that whether a type is Freeze
(contains any shared mutable state before indirection) isn't considered API-stable information, and documenting it could give the impression that it is. Having a clear marker that it's fickle mitigates that somewhat. I also vaguely recall some other potential const fn
type introspection in the vein of mem::needs_drop
that haven't been provided for similar concerns.
I suppose this technically falls under the general category of the portability lint group.
-
const
panic triggered post-mono errors might potentially be moved up earlier in the pipeline to "post instantiation" but pre codegen to eliminate build/optimization-dependence. Don't quote me on this. See recent discussion w.r.t. the stabilization ofinline_const
for the context. ↩︎