Skip to content

Commit

Permalink
alloc: Add Borrow impls for &String, &mut String, &Vec, and &mut Vec
Browse files Browse the repository at this point in the history
This patch addresses a small papercut, where the auto-ref/deref
does not work well with generic types. One small example of this
is:

```rust
use std::borrow::Borrow;

fn foo<T: Borrow<[usize]>>(x: T) {
    println!("{:?}", x.borrow());
}

fn main() {
    let x = vec![1, 2, 3];
    foo(&x);
}
```

Without this patch, rust will error with:

```
error[E0277]: the trait bound `&std::vec::Vec<{integer}>: std::borrow::Borrow<[usize]>` is not satisfied
 --> foo.rs:9:5
  |
9 |     foo(&x);
  |     ^^^ the trait `std::borrow::Borrow<[usize]>` is not implemented for `&std::vec::Vec<{integer}>`
  |
  = help: the following implementations were found:
            <std::vec::Vec<T> as std::borrow::Borrow<[T]>>
  = note: required by `foo`

error: aborting due to previous error
```

This forces users to use `x.as_slice()` to get the code to compile.
This patch then implements the following to cut down on unnecessary
line noise:

* `Borrow<str>` for `&String`, `&mut String`
* `BorrowMut<str>` for `String` and `&mut String`
* `Borrow<[T]>` for `&Vec<T>` and `&mut Vec<T>`
* `BorrowMut<[T]>` for `&mut Vec<T>`
  • Loading branch information
erickt committed Nov 6, 2017
1 parent 74be072 commit 830ed13
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
21 changes: 21 additions & 0 deletions src/liballoc/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1830,13 +1830,34 @@ impl<T> Borrow<[T]> for Vec<T> {
}
}

#[unstable(feature = "borrow_ref_vec", issue = "45808")]
impl<'a, T> Borrow<[T]> for &'a Vec<T> {
fn borrow(&self) -> &[T] {
&self[..]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> BorrowMut<[T]> for Vec<T> {
fn borrow_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}

#[unstable(feature = "borrow_ref_vec", issue = "45808")]
impl<'a, T> Borrow<[T]> for &'a mut Vec<T> {
fn borrow(&self) -> &[T] {
&self[..]
}
}

#[unstable(feature = "borrow_ref_vec", issue = "45808")]
impl<'a, T> BorrowMut<[T]> for &'a mut Vec<T> {
fn borrow_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> ToOwned for [T] {
type Owned = Vec<T>;
Expand Down
34 changes: 33 additions & 1 deletion src/liballoc/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use core::iter::FusedIterator;
use std_unicode::str::{UnicodeStr, Utf16Encoder};

use vec_deque::VecDeque;
use borrow::{Borrow, ToOwned};
use borrow::{Borrow, BorrowMut, ToOwned};
use string::String;
use std_unicode;
use vec::Vec;
Expand Down Expand Up @@ -182,6 +182,38 @@ impl Borrow<str> for String {
}
}

#[unstable(feature = "borrow_mut_string", issue = "45808")]
impl<'a> BorrowMut<str> for String {
#[inline]
fn borrow_mut(&mut self) -> &mut str {
&mut self[..]
}
}

#[unstable(feature = "borrow_ref_string", issue = "45808")]
impl<'a> Borrow<str> for &'a String {
#[inline]
fn borrow(&self) -> &str {
&self[..]
}
}

#[unstable(feature = "borrow_ref_string", issue = "45808")]
impl<'a> Borrow<str> for &'a mut String {
#[inline]
fn borrow(&self) -> &str {
&self[..]
}
}

#[unstable(feature = "borrow_ref_string", issue = "45808")]
impl<'a> BorrowMut<str> for &'a mut String {
#[inline]
fn borrow_mut(&mut self) -> &mut str {
&mut self[..]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for str {
type Owned = String;
Expand Down

0 comments on commit 830ed13

Please sign in to comment.