Should we be more strict with const and SemVer

With const generics approaching, will const and const fn values be an unexpected part of the semantic versioning of a crate? Consider this code, split across two crates at version 1.0.

// crate a
const VAL_A: usize = 1;
const VAL_B: usize = 2;
// crate b
struct Foobar<const N: usize> { inner: [(); N] } ;
impl Eq for Foobar<{a::VAL_A}> {}
impl Eq for Foobar<{a::VAL_B}> {}

Now crate a is within its (current) SemVer rights to publish 1.1 with:

const VAL_A: usize = 2; //!!
const VAL_B: usize = 2;

However this breaks crate b since the two impls of Eq will now overlap. This can of course already be a problem without const genericss since [T; N] is a stable type that can use a constant generic parameter. This wasn't a very common problem, however, since it existed only for directly use of arrays. However, with const generics and const fn I would expect this to be more common, in particular with the expansion beyond min-const-generics.

Are there any interface guidelines for the case? Should we adopt API-markers where values can be relied upon?


Is there something specific about constants within Rust's SemVer guarantees that isn't obvious?

To me it seems like changing an exported constant would always be a SemVer major changes.

It's contextual. There was some semver conversation in the tracking issue.

1 Like

I think this case is similar:

struct Foo<const N: u32> { /* ... */ }
impl Eq for Foo<{u32::BITS}> {}
impl Eq for Foo<{usize::BITS}> {}

Once BITS is stabilized, this would compile on target_pointer_width = "64" and fail to compile on target_pointer_width = "32".