TECH Signal 396
Restricting trait implementability and field mutability
RFC 3323 adds compile-time restrictions for where traits can be implemented and where struct fields may be mutated.
The restrictions let library authors express intent directly in the type definition, removing the need for auxiliary sealed traits and manual getter/setter patterns. Compilers will emit precise errors when code violates the declared scope, helping maintain invariants across crate boundaries. Adoption requires enabling nightly feature flags and may break downstream code that relied on unrestricted implementations or mutations.
Written by elseif from the cluster below · every claim links back to a sourceThe three things worth knowing
impl_restriction lets a crate declare a trait as implementable only within a specific module hierarchy.
mut_restriction lets a crate declare that a field can be mutated only from a designated scope, while remaining readable elsewhere.
Both features enforce the restrictions at compile time and prohibit struct literals that would create values with uninitialised restricted fields.
THE READ
What the cluster adds up to.
The compiler team has prepared two language extensions that let developers annotate the visibility of implementations and mutations. One annotation governs trait implementation scopes, while the other governs field-mutation scopes. Both are gated behind nightly feature flags and are described in RFC 3323.
The implementation-restriction annotation works like a visibility modifier for traits: a trait can be marked as crate-only, super-module only, or limited to an arbitrary path. This replaces the common sealed-trait idiom, which required a private marker trait and extra boilerplate. By expressing the restriction directly, the compiler can point to the exact location of the violation when an external crate attempts an illegal impl.
The mutation-restriction annotation applies to individual struct, enum, or union fields, allowing read access everywhere but limiting write access to a chosen scope. This gives library authors a finer-grained tool than public getters, and the borrow checker can still track independent borrows of unrestricted fields. Attempting to assign to a restricted field outside its allowed scope triggers a clear compile-time error.
A notable side effect is that struct literals are disallowed when they contain fields that cannot be mutated from the current location, preventing callers from bypassing validation logic. This rule applies to any field annotated with a mutation restriction that the constructing code cannot write to, ensuring invariants are preserved at construction time.
To use these annotations, developers must opt-in with the appropriate feature flags and adjust existing code that previously relied on unrestricted impls or field writes. Downstream crates that previously provided their own implementations of a now-restricted trait will see compilation failures, and code that mutates a field from outside its declared scope will need to be refactored or moved into the allowed module. The changes are compile-time only and do not affect runtime behavior, but they impose a migration cost for libraries that expose extensible APIs.
Written by elseif from the cluster below · checked for specifics the sources never containedTHE CLUSTER
↗