-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking issue for future-incompatibility lint coherence_leak_check
#56105
Comments
Oh hey, this one again. This breaking change is the exact opposite of another breaking change from August 2017 made in #43880 and discussed FCP’ed in #44224. Like before, Servo is affected. The fix is to remove the generic trait impl for In the abstract, the behavior now in Nightly makes more sense to be. However, it doesn’t feel good that we pushed the ecosystem through a breakage (even if it might only affect a small fraction of the code out there) with lengthy technical arguments (that I don’t entirely understand) in #44224 to justify it, only to change our mind a couple years later and cause breakage again. Do those arguments no longer apply? Did something change, or were they not good arguments in the first place? What is the confidence that this time, reverting is the right decision?
As far as I can find, the issue description says what the change is but not why it was made.
I’m worried that we rely on Crater so much for this kind of decision. It can only test a sample of all the Rust code that exists in the world, and that sample likely has a heavy selection bias toward (relatively) small libraries rather than large applications. How much of https://www.rust-lang.org/production/users is tested by crater? |
Upgrade to rustc 1.33.0-nightly (c0bbc3927 2019-01-03) This deals with a breaking change in the language that affect stable code, in the exact opposite way from a previous breaking change from August 2017. See rust-lang/rust#56105 (comment) <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22612) <!-- Reviewable:end -->
OK, so, due to the All Hands etc, this issue wound up somewhat neglected for too long. But @aturon and I have been digging into it lately and I wanted to summarize current thinking Perhaps the TL;DR is that I am considering trying to land #58592, which kind of "reimplements" the old check we used to do, but using the infrastructure of the newer system. The reason for this is not because the old behavior was more correct, but to give us time to explore the new behavior in more depth, as there are concerns that it may interact in unsound ways with other parts of the system which would have to be corrected. However, I am not sure if this is a good idea. The new behavior has not yet hit stable, but it's been on nightly for some time. Crater runs did not show major disruption (though there have been a few bugs reported since). Nightly apps, like servo, have adapted (more on that in a bit). Moreover, as far as we know, the new higher-ranked code is basically correct -- we are mostly concerns that there may be interactions with other parts of the system that will require further adjustments, and hence there is reason to want to tread cautiously here (e.g., maybe we would want to update those other parts of the system before adopting the new universe system). Let me review briefly what was affected. Subtyping, type equality, and A side-effect of this change is #46989: an This change to subtyping and equality seems "correct" on its own. However, there are two concerns:
impl<A> Foo for fn(A) {
type Output = A;
} and now if you have Meanwhile, we have #57639 -- this regression is different. It is a pre-existing bug in the trait solver (#21974), but one that is now affecting more code. We think we have plans to solve this too, but some experimentation is warranted, particularly when it comes to the older trait solve (the chalk solver would require a different approach). Finally, Servo has been affected here by two independent changes that interact. First, we modified method resolution to use the trait checking code rather than "rolling its own" checks. The trait solver code however was too conservative, and thus wound up assuming that an impl for |
Thanks @nikomatsakis for the writeup and the PR. FWIW, it seems wisest to me to go ahead and land the leak check just to keep our options maximally open, and to explore these issues without time pressure. |
Servo can adapt one way or another, and we already have to deal with worse breakage on Nightly. Don’t worry about us. But Servo might be the canary in the coal mine. What I’m worried about is projects who might be using similar code on Stable: impl<A, B> MyTrait for fn(A) -> B {}
impl<'a, A, B> MyTrait fn(&'a A) -> B {} Some time in 2017, this project updated their compiler and had to add the second impl: #44224 I think intuitively that this second impl shouldn’t be necessary (all types that it covers should already be covered by the first one through simple substitution). But that’s perhaps less important than the fact that any breakage on Stable weakens or “stability without stagnation” promise. But maybe fixing something was worth it in this case, we (the Rust project) do occasionally make minor breaking changes when they are justified. #55517 landed in the 1.33 cycle, which reaches the Stable channel in 9 days. As it is, this hypothetical project will experience another breaking change when they upgrade to 1.33. Maybe that’s not what’s happening, but the perception is that we were wrong to make the change in 2017 and the whole thing could have been avoided. To someone who hasn’t been following multiple long in-depth discussions, it might even look frivolous or careless. Now we are talking about temporarily reverting the reversal. If this lands in 1.34 or later, affected project who thought they could rely on stability might have to change their code up to four times, worsening this perception even further. So please strongly consider backporting to 1.33 beta this [temporary reversal of the reversal] so that #55517 does not reach the Stable channel, or not doing it at all. But time is getting very short. @rust-lang/release given that builds are made a few days in advance, how much time before the planned release date should a backport land in the |
To clarify, that is the ultimate intent of the PR, and the reason we are scrambling to get it together. |
The promotion from beta to stable happens on Monday, so by Sunday it should be at least |
Nominating for the release team meeting this evening. |
Discussed this a bit in the release meeting, we're willing to delay beta -> stable promotion a bit if this doesn't make it in. |
@rustbot label C-future-compatibility |
instantiate higher ranked goals outside of candidate selection, remove the `coherence_leak_check` future compat lint - rust-lang#59490 - rust-lang#56105 --- and adapt the old solver to not rely on universe errors for higher ranked goals to impact candidate selection. This matches the behavior of the new solver: rust-lang/trait-system-refactor-initiative#34. See https://hackmd.io/gstwC83ORaG7V29w54nMdA for more details about this change r? `@nikomatsakis`
instantiate higher ranked goals outside of candidate selection, remove the `coherence_leak_check` future compat lint - rust-lang#59490 - rust-lang#56105 --- and adapt the old solver to not rely on universe errors for higher ranked goals to impact candidate selection. This matches the behavior of the new solver: rust-lang/trait-system-refactor-initiative#34. See https://hackmd.io/gstwC83ORaG7V29w54nMdA for more details about this change r? `@nikomatsakis`
instantiate higher ranked goals outside of candidate selection, remove the `coherence_leak_check` future compat lint - rust-lang#59490 - rust-lang#56105 --- and adapt the old solver to not rely on universe errors for higher ranked goals to impact candidate selection. This matches the behavior of the new solver: rust-lang/trait-system-refactor-initiative#34. See https://hackmd.io/gstwC83ORaG7V29w54nMdA for more details about this change r? `@nikomatsakis`
instantiate higher ranked goals outside of candidate selection, remove the `coherence_leak_check` future compat lint - rust-lang#59490 - rust-lang#56105 --- and adapt the old solver to not rely on universe errors for higher ranked goals to impact candidate selection. This matches the behavior of the new solver: rust-lang/trait-system-refactor-initiative#34. See https://hackmd.io/gstwC83ORaG7V29w54nMdA for more details about this change r? `@nikomatsakis`
instantiate higher ranked goals outside of candidate selection, remove the `coherence_leak_check` future compat lint - rust-lang#59490 - rust-lang#56105 --- and adapt the old solver to not rely on universe errors for higher ranked goals to impact candidate selection. This matches the behavior of the new solver: rust-lang/trait-system-refactor-initiative#34. See https://hackmd.io/gstwC83ORaG7V29w54nMdA for more details about this change r? `@nikomatsakis`
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
Add a test for rust-lang#107975 The int is zero. But also not zero. This is so much fun. This is a part of rust-lang#105107. Initially I was going to just rebase rust-lang#108445, but quite a few things changed since then: * The [mcve](rust-lang#105787 (comment)) used for rust-lang#105787 got fixed.[^upd2] * You can't just `a ?= b` for rust-lang#107975 anymore. Now you have to `a-b ?= 0`. This is what this PR does. As an additional flex, it show that three ways of converting a pointer to its address have this issue: 1. `as usize` 2. `.expose_provenance()` 3. `.addr()` * rust-lang#108425 simply got fixed. Yay. As an aside, the naming for `addr_of!` is quite unfortunate in context of provenance APIs. Because `addr_of!` gives you a pointer, but what provenance APIs refer to as "address" is the `usize` value. Oh well. UPD1: GitHub is incapable of parsing rust-lang#107975 in the PR name, so let's add it here. [^upd2]: UPD2: [The other mcve](rust-lang#105787 (comment)) does not work anymore either, saying "this behavior recently changed as a result of a bug fix; see rust-lang#56105 for details."
coherence_leak_check
This is the tracking issue for the "universe transition". The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around bug fixes that affect existing code, see our breaking change policy guidelines.
What was the change and what code is affected?
This change (introduced in #55517) fixed a number of bugs (e.g., #32330) in how the Rust compiler handled higher-ranked types (e.g.,
fn(&u8)
or -- more explicitly --for<'a> fn(&'a u8)
) and trait bounds (e.g.,for<'a> T: Trait<'a>
). One of these changes could however affect existing code. In particular, the compiler in the past would accept trait implementations for identical functions that differed only in where the lifetime binder appeared:We no longer accept both of these impls. Code relying on this pattern would now have to introduce "newtypes", like
struct Foo(for<'a> fn(&'a u8))
.History of this change
This change was first made in #55517 without a "warning period". This was done because (a) it would be challenging to issue precise warnings for affected code and (b) a crater run found zero regressions.
However, the change was subsequently backed out in #58592, owing to concerns about unintended side-effects.
The change was re-added in #65232, but this time with a warning period. We are currently completing the implementation and trying to figure out how to draw the line in terms of what should become a hard error.
Affected crates and patterns
This section is for collecting patterns and examples to look into or other related issues.
The text was updated successfully, but these errors were encountered: