From 830ed13802488cd0de1b46501a6c080dffdb08f3 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 6 Mar 2017 09:38:35 -0800 Subject: [PATCH] alloc: Add Borrow impls for &String, &mut String, &Vec, and &mut Vec 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>(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: 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` for `&String`, `&mut String` * `BorrowMut` for `String` and `&mut String` * `Borrow<[T]>` for `&Vec` and `&mut Vec` * `BorrowMut<[T]>` for `&mut Vec` --- src/liballoc/slice.rs | 21 +++++++++++++++++++++ src/liballoc/str.rs | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index b41cb912fe798..328a26ac5037f 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1830,6 +1830,13 @@ impl Borrow<[T]> for Vec { } } +#[unstable(feature = "borrow_ref_vec", issue = "45808")] +impl<'a, T> Borrow<[T]> for &'a Vec { + fn borrow(&self) -> &[T] { + &self[..] + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl BorrowMut<[T]> for Vec { fn borrow_mut(&mut self) -> &mut [T] { @@ -1837,6 +1844,20 @@ impl BorrowMut<[T]> for Vec { } } +#[unstable(feature = "borrow_ref_vec", issue = "45808")] +impl<'a, T> Borrow<[T]> for &'a mut Vec { + fn borrow(&self) -> &[T] { + &self[..] + } +} + +#[unstable(feature = "borrow_ref_vec", issue = "45808")] +impl<'a, T> BorrowMut<[T]> for &'a mut Vec { + fn borrow_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for [T] { type Owned = Vec; diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 5f0b4088fc07e..4c13905fb98f9 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -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; @@ -182,6 +182,38 @@ impl Borrow for String { } } +#[unstable(feature = "borrow_mut_string", issue = "45808")] +impl<'a> BorrowMut for String { + #[inline] + fn borrow_mut(&mut self) -> &mut str { + &mut self[..] + } +} + +#[unstable(feature = "borrow_ref_string", issue = "45808")] +impl<'a> Borrow for &'a String { + #[inline] + fn borrow(&self) -> &str { + &self[..] + } +} + +#[unstable(feature = "borrow_ref_string", issue = "45808")] +impl<'a> Borrow for &'a mut String { + #[inline] + fn borrow(&self) -> &str { + &self[..] + } +} + +#[unstable(feature = "borrow_ref_string", issue = "45808")] +impl<'a> BorrowMut 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;