-
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
permit negative impls for non-auto traits #68004
Conversation
Some changes occurred in diagnostic error codes |
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
@nikomatsakis: How does this relate to reservation impls? |
This comment has been minimized.
This comment has been minimized.
A negative impl is a semver commitment never to implement the given trait for the given type. It should eventually mean that you can rely on the impl not existing for the purposes of negative reasoning in coherence, though this PR doesn't implement that. What this PR does is simply require that no negative and positive impls (for the same trait) can overlap. This means that you can rely on an impl not existing for the purpose of proving soundness, and in particular for proving A reservation impl is...something harder to express. It is considered a kind of "ambiguous" impl -- it doesn't exist yet, but it might exist in the future. This prevents people from assuming negatively that it would never exist. But it doesn't prevent you from writing overlapping impls. |
e3a0b47
to
e16b360
Compare
This comment has been minimized.
This comment has been minimized.
e16b360
to
c6875fd
Compare
@comex do you think you could provide me with "clean, minimized versions" of your exploits? The code in this playground is rather complex .. I'd prefer to have three or four simple tests I can add for regression tests. They don't have to be fully weaponized necessarily, either -- something like what @withoutboats did would be perfect. (In particular, I believe we need a negative |
c6875fd
to
e2a82fa
Compare
@nikomatsakis I can provide minimal examples for both DerefMut and Clone. Here they are: DerefMut for shared reference: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7d0c6cef76960efecd8e9afd3a851443 Clone for mutable reference: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=55430b595a04fa05c52fb6abe024d5e8 (You'll notice these work almost exactly the same way.) For CoerceUnsized I don't have a sample ready, but I think fixing CoerceUnsized should be tracked separately, possibly even opening a separate issue from #66544 |
Yea I think it'd be better to track the coerceunsized problem as "we added an unchecked invariant to implementing coerceunsized but didnt mark the trait unsafe," just separate from this coherence hole issue. |
This comment has been minimized.
This comment has been minimized.
e2a82fa
to
83d1c33
Compare
This comment has been minimized.
This comment has been minimized.
fa21734
to
a10769a
Compare
I've removed the WIP, I think this PR is roughly ready to land, though I think it merits an FCP and a more detailed write-up of (a) the semantics of what is happening I can try to get to that in a bit. |
a10769a
to
4663d8f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation looks good. The diagnostics around negative trait bounds in general could be improved, but that can be left as a follow up.
src/test/ui/traits/negative-impls/pin-unsound-issue-66544-clone.stderr
Outdated
Show resolved
Hide resolved
It might also be worth putting negative impls for non-auto traits behind a separate feature flag to |
Ah yeah, I meant to add "new feature flag" to the checklist |
The "stable" version number should be 1.41 or whenever this actually gets to stable. This might sound silly to say but sometimes version strings like this have gone unnoticed so I thought i'd just throw in a reminder. |
Do we want to do a crater run for this? On one hand, I would be shocked if anyone ever wrote this kind of bizarre impl in real code. On the other hand, if someone did write such an impl, it would be good to know that there exists code in the wild that will be permanently broken by this. |
1515754
to
011215b
Compare
@bors r=varkor |
📌 Commit 0d07026 has been approved by |
⌛ Testing commit 0d07026 with merge 8599f89a0f86493bfe6d12bc1a1f0a09d86818eb... |
@bors retry |
Rollup of 5 pull requests Successful merges: - rust-lang#68004 (permit negative impls for non-auto traits) - rust-lang#70385 (Miri nits: comment and var name improvement) - rust-lang#70411 (Fix for rust-lang#62691: use the largest niche across all fields) - rust-lang#70417 (parser: recover on `...` as a pattern, suggesting `..`) - rust-lang#70424 (simplify match stmt) Failed merges: r? @ghost
#![feature(optin_builtin_traits)] | ||
|
||
struct TestType; | ||
|
||
trait TestTrait { | ||
fn dummy(&self) { } | ||
} | ||
|
||
impl !TestTrait for TestType {} | ||
//~^ ERROR invalid negative impl | ||
|
||
fn main() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't a test for this without the feature flag remain?
This is a prototype impl that extends
impl !Trait
beyond auto traits. It is not integrated with coherence or anything else, and hence only serves to prevent downstream impls (but not to allow downstream crates to rely on the absence of such impls for coherence purposes).Fixes #66544
TODO:
Clone
in order to fully fixPin
is unsound due to rogue Deref/DerefMut implementations #66544CoerceUnsized
unsafe? -- that problem is now split out intoPin
is unsound due to transitive effects ofCoerceUnsized
#68015