-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Allow incoherent trait implementations #150652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This commit adds two new attributes to rustc: * `#[rustc_has_incoherent_trait_impls]` * `#[rustc_allow_incoherent_trait_impl]` They are intended to behave similar to the `#[rustc_has_incoherent_inherent_impls]` pedants and serve the purpose to allow the implementation of incoherent trait implementations in the standard library. According to the Rust reference, "a trait is considered incoherent if either the orphan rules check fails or there are overlapping implementation instances". For now, this patch only circumvents orphan rule checks, hence why it is still a draft and because to my understanding, the problem of overlapping implementation instances is a larger one (see specializations). Of course, circumventing the orphan rule is generally a **bad idea**, as it is to circumvent the coherence for inherent implementations. But just like the incoherence for inherent implementations, there are valid use-cases in the hacking with the standard library that would justify its use. Personally, my motivation for this patch stems from rust-lang/libs-team#519, which describes a proposal for moving `ToOwned` from `alloc` to `core` and was theoretically accepted by libs team but ultimately dropped due to `ToOwned` implementations for types defined in `core` with associated types defined in `alloc`, thereby making it effectively impossible. I would like to keep continue working on this, but for this, a modification to `rustc` would probably be necessary.
|
See also: cvengler@943fc34 For a demonstration of this in conjunction to moving |
Arbitrary overlap of implementations where there is no clear specializing impl is not going to work. Which trait impl something gets resolved to needs to be consistent between crates. Otherwise you are likely to get an ICE due to type mismatches during codegen or const eval when typeck in one crate and codegen or const eval in another crate have a different view of which trait impl applies. I think only bypassing the orphan rule should ever be allowed. Maybe not necessary in the initial implementation, but I've been thinking about having coherence domains. All crates within a coherence domain will apply the orphan rule as if they are the same crate. And once you have compiled all crates in a coherence domain you did let rustc check that there are no overlapping impls between the crates and produce a file as proof of this that you need to present when compiling dependent crates. With this you could have the entire standard library be in a single coherence domain and for example all crates of Rust for Linux be another coherence domain and similar for any other project that is developed as a single unit. |
|
You will need T-types sign off before adding such an exception to the language even unstabley |
Does this process involve opening an external ticket/RFC, similar to libs-team with their ACP system? |
That is what I would have thought too.
I like the idea in theory but I feel it is a bit like a hypothetical Regarding stability: To my understanding, all |
Yes, all attributes whose name starts with the string Still, we don't want to add internal attributes willy-nilly since they would still need to be maintained. |
|
This sounds like it could maybe worsen the issue in #149347 |
This pull request does not touch any parts related to |
|
It does have the same issue as |
|
Indeed, this would lead to a similar situation as in #149347 unfortunately. 🙁 I am still very new in contributing to the compiler but from what I understand so far, it is probably not the attributes "causing" the problem but rather the code trying to resolve the symbols which treats everything as it finds as being part of a global scope – basically what others have already mentioned. Now the question is on how to proceed here. |
This commit adds two new attributes to rustc:
#[rustc_has_incoherent_trait_impls]#[rustc_allow_incoherent_trait_impl]They are intended to behave similar to the
#[rustc_has_incoherent_inherent_impls]pedants and serve the purpose to allow the implementation of incoherent trait implementations in the standard library.According to the Rust reference, "a trait is considered incoherent if either the orphan rules check fails or there are overlapping implementation instances".
For now, this patch only circumvents orphan rule checks, hence why it is still a draft and because to my understanding, the problem of overlapping implementation instances is a larger one (see specializations).
Of course, circumventing the orphan rule is generally a bad idea, as it is to circumvent the coherence for inherent implementations. But just like the incoherence for inherent implementations, there are valid use-cases in the hacking with the standard library that would justify its use.
Personally, my motivation for this patch stems from rust-lang/libs-team#519, which describes a proposal for moving
ToOwnedfromalloctocoreand was theoretically accepted by libs team but ultimately dropped due toToOwnedimplementations for types defined incorewith associated types defined inalloc, thereby making it effectively impossible. I would like to keep continue working on this, but for this, a modification torustcwould probably be necessary.