about summary refs log tree commit diff
path: root/src/test/ui/thinlto
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-04-04 01:49:08 +0200
committerGitHub <noreply@github.com>2019-04-04 01:49:08 +0200
commitb78cbe6dddc5065c0dba1808e82f4bd17a453036 (patch)
treece496b2a6dae0f290f28aaca0354626c52001b7c /src/test/ui/thinlto
parentdcccab56bab29439fd154fd8114a3679a1ed5b3d (diff)
parent1cfed0d452d739b502c73904d61a1f4496b1acf5 (diff)
downloadrust-b78cbe6dddc5065c0dba1808e82f4bd17a453036.tar.gz
rust-b78cbe6dddc5065c0dba1808e82f4bd17a453036.zip
Rollup merge of #59663 - matklad:borrow, r=dtolnay
Be more direct about borrow contract

I always was confused by the difference between Borrow and AsRef, despite the fact that I've read all available docs at least a dozen of times.

I finally grokked the difference between the two when I realized the Borrow invariant:

> If you implement Borrow, you **must** make sure that Eq, Ord and Hash implementations are equivalent for borrowed and owned data

My problem was that this invariant is not stated explicitly in documentation, and instead some  vague and philosophical notions are used.

So I suggest to mention the requirements of `Borrow` very explicitly: instead of "use Borrow when X and use AsRef when Y", let's phrase this as `Borrow` differs from `AsRef` in `W`, so that's why `Borrow` is for `X` and `AsRef` is for `Y`.

Note that this change could be seen as tightening contract of the Borrow. Let's say Alice has written the following code:

```rust
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)]
struct Person {
    first_name: String,
    last_name: String,
}

impl Borrow<str> for Person {
      fn borrow(&self) -> &str { self.first_name.as_str() }
}
```

Now Bob uses this `Person` struct, puts it into `HashMap` and tries to look it up using `&str` for the first name. Bob's code naturally fails.

The question is, who is to blame: Alice, who has written the impl, or Bob, who uses the HashMap. If I read the current docs literally, I would say that `Bob` is to blame: `Eq` and `Hash` bounds appear on HashMap, so it is the HashMap which requires that they are consistent. By using a type for which the `Borrow` impl does not yield well-behaved `Eq`, Bob is violating contract of HashMap.

If, as this PR proposes, we unconditionally require that Eq & friends for borrow should be valid, then the blame shifts to Alice, which I think is more reasonable.

closes https://github.com/rust-lang/rust/issues/44868
Diffstat (limited to 'src/test/ui/thinlto')
0 files changed, 0 insertions, 0 deletions