-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
More flexible coherence rules that permit overlap #1053
Comments
A discussion with niko today revealed that a naive specialization feature could cause the drop check rule (RFC 769) to break. In particular, if we allow one to:
Then one could end up in a situation where the |
Hi. I think negative bounds as discussed in RFC #586 would be very valuable, with the following modification to avoid the problem of backwards incompatibility: Doing this would limit the usefulness of negative bounds somewhat (because It might be worth doing, also, that if there exists a Types defined in std should negatively implement various traits where a backwards compatible commitment to not implementing that trait exists. This is a backwards compatible change. Adding negative bounds to traits which should not logically cohere (e.g. Some sort of specification system would be useful in addition to this for a lot of the use cases you've highlighted, but this alone would open up a lot of more straightforward cases, such as enabling new traits to 'piggyback' on standardized or otherwise commonly imported traits without violating coherence rules (e.g. the trait |
Here's an interesting case: trait Foo { }
trait Bar {
type Baz;
}
impl<T> Foo for T where T: Bar<Baz=u32> { }
impl<T> Foo for T where T: Bar<Baz=i32> { } This is currently incoherent, because the coherence rules do not allow us to infer that the intersection between
In my own use case for this, I want to provide blanket impls for functions that return one of two different types. |
cc #2451. |
but would be cool coherent backtrace implementation for Compat<failure::Error>
I am really really new to Rust and somehow navigated myself to this issue. It seems to have remained open for a few years. I'm still learning the ins and outs of Rust's trait system, but I am already interested in how this rfc will turn out. Any updates? |
@ThomasKagan note that this is an issue, not an actual RFC. I'm not aware of any active proposals in this space (it certainly doesn't fit with the 2019 Roadmap). For an unofficial attempt to summarize in one coherent and novice-friendly place why this is such a hard problem and all the seemingly obvious answers don't actually work, see https://github.com/Ixrec/rust-orphan-rules |
Thanks for the link! Definitely curious to see how it pans out |
Sorry to "ping" on this, just wanted to share another concrete use case. I would find it very useful to use num-traits so that I can implement something like this:
or something like:
I believe these are each not really possible at the moment, which leads to a lot of macro usage From the peanut gallery, it seems like if the more general problem in this issue is hard to make progress on in ~8 years, maybe it would be worth reopening the (seemingly simpler) #1148? (I appreciate that it may in fact not be simpler!) |
This was the most destructive yet? Ran into problems with associated types and blanket generics (in particular, cannot have negative trait bounds, which makes it not possible to disambiguate which `BottomUpBuilder` impl to use; see rust-lang/rfcs#1053).
This was the most destructive yet? Ran into problems with associated types and blanket generics (in particular, cannot have negative trait bounds, which makes it not possible to disambiguate which `BottomUpBuilder` impl to use; see rust-lang/rfcs#1053).
So, I see three aspects to this issue:
Aside: coherence is well defined here. In short, assuring that each type has at most one impl of each trait, and the addition of a new impl upstream cannot cause breaking changes downstream (at least, not through multiple impls of the same type-trait pair). Points 2 and 3 are about solving the same problem from different directions. It is difficult to argue which approach is better or more appropriate for Rust; although the language does have a tradition of a complex and rigid error checking system, there are other areas that Rust doesn't even try to prevent semver breakage (e.g. by allowing glob imports). Point 1 (specialization) is, as best I can tell, a completely unrelated problem (unless the scope changes significantly from the merged RFC), and thus should not be a blocker to progress on this issue: more flexible coherence rules that permit overlap. (Also, in my biased opinion, specialisation is the less important of the two issues.) How can we progress this issue? |
There is a need for more flexible coherence rules, and in particular a way to permit overlap in some cases. There are numerous proposals for how to go about achieving that. Here is a summary:
Note that a prime concern here is forwards compatibility. See RFC #1023 (and this internals thread) for details.
RFCs and other links:
The text was updated successfully, but these errors were encountered: