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
What is allowed/disallowed with proc-macros and macro_rules?
Soundness fixes.
Changes to unsafe.
Go through attributes and figure out which ones matter for adding/removing/changing.
The stability RFC says any "non-trivial" change to a trait item signature, but doesn't define what a "trivial" change is.
Changes to function front-matter.
Adding "const" should be ok? Removing "const" is not.
Fundamental types, adding blanket trait impls, and the re-rebalancing RFC. There is a section on fundamental types that has changed as part of RFC 1023 and RFC 2451 that I don't fully understand. See also niko's blog.
Major: Adding or removing some trait implementations. For example, Drop, Copy, Send, Sync, etc. I think removing any public trait is a breaking change? I believe adding Drop is a major change, not sure what the rules are there.
Add "adding a defaulted const generic parameter", and discuss how that prevents adding a defaulted type parameter in the future.
Adding a viarant to a non_exhaustive enum if the enum is fieldless (can no longer cast it, etc).
Making a semver-major change to a dependency whose types (or other entities or impls) are publicly exported. This can cause a version incompatibility hazard.
Changing panic behavior (adding or removing a panic from a function for example).
Mention that changes that affect lints are always allowed? Or should there be any nuance there? Add semver rule for lints #11596
Adding or removing private fields of a struct can be a breaking change if those fields change the auto traits.
Removing private fields of a struct can be a breaking change if those fields are leaked through some other means. For example, if using serde with #[derive(Serialize)], private fields will leak in the serialized output.
this demonstrates an interesting failure with a change to a private field. struct B<T> { x: Box<T> } with a user having struct A { b: B<A> }. Change Box<T> to just T causes A to be infinitely sized.
To what degree are inference changes a breaking change? For example, I think maybe generic-generalize-identical or fn-generalize-compatible could potentially have inference issues (needs investigation, I believe struct and fn inference work differently).
Removing a feature from a dependency. This has some subtle impacts due to unification. Package A → Package B, removes the feature "f1" from B. Package C → Package A and B, and only builds correctly if Package B has "f1" enabled, but does not explicitly state that. Removing "f1" now causes Package C to fail to build when it does an update of A. I'm not really sure how this should be handled.
Removing a cargo target. For example, if you remove the [lib] target, that would break anything depending on that package. This will be more important with artifact-dependencies.
Maybe have a catch-all rule about changing the signature of an item or type is not allowed unless explicitly allowed by some other rule? Otherwise, would need to enumerate all examples, which could be quite a lot. For example, changing the arity of a tuple, or the size of an array, changing from a u16 to a u8, changing from one type to another, etc.
SemVer compatibility downgrade: If you have a dependency, say with a req 1.5.2, and then you later publish a version that depends on 1.5.0, is that a breaking change? I think unlikely unless you re-export the dependency, in which case it then becomes an interesting question. Let's say 1.5.2 had a new item or type that wasn't in 1.5.0. It would be a breaking change because users could be trying to access those entities through the re-export, and they may be using something like minimal-versions which would break.
This is a dump of some elements that I considered adding to the SemVer compatibility chapter, but didn't have time or knowledge to finish.
--no-default-featuresexplicitly.SomeType<'static>tofn some<'a>(i: &'a str) -> SomeType<'a>.impl traitvs generic parameters. Converting betweenfoo(x: impl Trait)andfoo<T: Trait>(x: T).impl traitand generics conversion here: Remove outdated info about impl Trait in parameters and generics in the same function reference#1495-> impl traitreturn value converted to a concrete type-> FooDrop,Copy,Send,Sync, etc. I think removing any public trait is a breaking change? I believe addingDropis a major change, not sure what the rules are there.constcan be a breaking change (https://internals.rust-lang.org/t/should-we-be-more-strict-with-const-and-semver/14302).#[derive(Serialize)], private fields will leak in the serialized output.struct B<T> { x: Box<T> }with a user havingstruct A { b: B<A> }. ChangeBox<T>to justTcausesAto be infinitely sized.[lib]target, that would break anything depending on that package. This will be more important with artifact-dependencies.repr(packed)type. See Handling of packed fields causes semver hazard: layout details from other crates affect type-checking rust#115305 (comment) and closure field capturing: don't depend on alignment of packed fields rust#115315.use<>) can be a breaking change. discussionAs an alternative to documentation, we could make these lints in a tool like cargo-crate-api