Background
In RFC 1268 we introduced a notion that traits with zero items in them can be implemented many times and permit overlap because they lack computational content and therefore it is not a violation of coherence (also see Quantified class constraints, section 3.4, with pdf).
Later, concerns were noted that the mechanism proposed in the was automatic rather than opt-in:
@cramertj Agreed; the discussion seems to have decided that this needs to be opt-in on the trait, not something that just happens. Iâve started a PR towards doing so: #53693 - @scottmcm
It was suggested that we should use an opt-in mechanism with an attribute #[marker]
.
For example, you would write:
#[marker] pub trait Copy: Clone {}
This change was then implemented.
However, with respect to the naming of the attribute, concerns have been raised that the name is sub-optimal. In particular, the attribute name does not suggest what effect it has on the trait (permitting overlap). Furthermore, if we permitted defaulted items which are not overridable, with for example:
#[marker] unsafe trait SafeToZero: Sized {
fn zeroed() -> Self { unsafe { MaybeUninit::zeroed() } }
}
then SafeToZero
would no longer fit the description of being a marker trait.
The brainstorm
Me and @scottmcm have already done some bikeshedding over at Discord and we came up with the following list of possible names:
-
#[incoherent]
â this is not really appropriate because it is inaccurate per the meaning of coherence and it also sounds quite bad. -
#[overlappable]
â this naming paints an accurate description, but misses the fact that the implementations can overlap and not the trait itself. Perhaps that is hard to capture? The attribute name is also twice as long (12 characters) asmarker
(6 characters). We do not tend to use the-able
suffix on traits; but we do have instances of paths with-able
in the name. For example: Peekable and unreachable neither of which are traits. -
#[overlap]
â this is shorter and based on the same root word, but it isnât an adjective. -
#[mixin]
â this is possibly vague and also perhaps a synonym oftrait
? -
#[permit_impl_overlap]
â these names are possibly too long but they are quite descriptive as to the effect. -
#[allow_impl_overlap]
â the word allow might have more precedent here due to#[allow(..)]
but perhaps the connotation with lints is not something we wish to impart here. -
#[impl_overlap]
â Here we simply omit âallowâ and leave it inferred; the main benefit of doing so is brevity which matters if the attribute is used a lot (and we donât really know if it will or wonâtâŚ). -
#[allow_overlapping_impls]
â this is just a rewording that may read better? -
#[permit_overlap]
â this one doesnât communicate about implementations but does state explicitly that we are permitting something. -
#[fact]
â the idea is that we are stating a fact, but this may not work so well because all trait implementations are really proof witnesses about a (type, trait). -
#[multiple_impls]
â this states clearly that multiple implementations are allowed, but it leaves out the important qualifier that multiple impls are allowed for the same type which might not be understood as people may think multiple impls of the same trait is referred to.
The collective bikeshed
In the previous section Iâve outlined some names that we thought of; some of these are not serious contenders and are merely provided for completeness and to avoid repetition of dead ends. Other names are more serious; for example, I think that #[overlappable]
is not too shabby.
Finally, we would like your help in determining the best name.
- What do you think about the various names above?
- Do you have any preference?
- Are there names which we have yet to consider and what is the rationale for those?
- Should we use an attribute for this at all, or should this be a contextual keyword?
Let the bikeshed begin =P