Skip to content

Commit

Permalink
Rollup merge of rust-lang#66566 - robamler:issue-66476, r=rkruppe
Browse files Browse the repository at this point in the history
Document pitfall with `impl PartialEq<B> for A`

Fixes rust-lang#66476 by turning the violating example into an explicit
counterexample.
  • Loading branch information
pietroalbini authored Nov 22, 2019
2 parents 564f2d3 + 5028fd8 commit 203c906
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,23 @@ use self::Ordering::*;
/// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
/// we allow `BookFormat`s to be compared with `Book`s.
///
/// You can also combine these implementations to let the `==` operator work with
/// two different types:
///
/// ```
/// A comparison like the one above, which ignores some fields of the struct,
/// can be dangerous. It can easily lead to an unintended violation of the
/// requirements for a partial equivalence relation. For example, if we kept
/// the above implementation of `PartialEq<Book>` for `BookFormat` and added an
/// implementation of `PartialEq<Book>` for `Book` (either via a `#[derive]` or
/// via the manual implementation from the first example) then the result would
/// violate transitivity:
///
/// ```should_panic
/// #[derive(PartialEq)]
/// enum BookFormat {
/// Paperback,
/// Hardback,
/// Ebook,
/// }
///
/// #[derive(PartialEq)]
/// struct Book {
/// isbn: i32,
/// format: BookFormat,
Expand All @@ -163,18 +169,16 @@ use self::Ordering::*;
/// }
/// }
///
/// impl PartialEq for Book {
/// fn eq(&self, other: &Book) -> bool {
/// self.isbn == other.isbn
/// }
/// }
/// fn main() {
/// let b1 = Book { isbn: 1, format: BookFormat::Paperback };
/// let b2 = Book { isbn: 2, format: BookFormat::Paperback };
///
/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
/// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
/// assert!(b1 == BookFormat::Paperback);
/// assert!(BookFormat::Paperback == b2);
///
/// assert!(b1 == BookFormat::Paperback);
/// assert!(BookFormat::Ebook != b1);
/// assert!(b1 == b2);
/// // The following should hold by transitivity but doesn't.
/// assert!(b1 == b2); // <-- PANICS
/// }
/// ```
///
/// # Examples
Expand Down

0 comments on commit 203c906

Please sign in to comment.