From bdb805b640ebdea7463c91f930e7c4f82ddd652c Mon Sep 17 00:00:00 2001 From: George Burton Date: Mon, 12 Feb 2018 17:30:53 +0000 Subject: [PATCH 1/6] Add a generic impl of From> for Cow --- src/liballoc/borrow.rs | 11 +++++++++ src/liballoc/string.rs | 8 ------- src/liballoc/tests/borrow.rs | 44 ++++++++++++++++++++++++++++++++++++ src/liballoc/tests/lib.rs | 1 + src/liballoc/vec.rs | 7 ------ src/libstd/path.rs | 8 ------- 6 files changed, 56 insertions(+), 23 deletions(-) create mode 100644 src/liballoc/tests/borrow.rs diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index acae0daa86b6b..051f6f89156e9 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -361,6 +361,17 @@ impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { } } +#[unstable(feature = "generic_cow_from", reason = "recently added", issue = "0000")] +impl<'a, B, T> From<&'a B> for Cow<'a, T> +where + B: ?Sized + Borrow, + T: ?Sized + ToOwned, +{ + fn from(b: &'a B) -> Self { + Cow::Borrowed(b.borrow()) + } +} + #[stable(feature = "cow_add", since = "1.14.0")] impl<'a> Add<&'a str> for Cow<'a, str> { type Output = Cow<'a, str>; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 8d99d0bc8f4dc..e7f4e36873d33 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -2128,14 +2128,6 @@ impl<'a> From> for String { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a> From<&'a str> for Cow<'a, str> { - #[inline] - fn from(s: &'a str) -> Cow<'a, str> { - Cow::Borrowed(s) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl<'a> From for Cow<'a, str> { #[inline] diff --git a/src/liballoc/tests/borrow.rs b/src/liballoc/tests/borrow.rs new file mode 100644 index 0000000000000..42215718a593b --- /dev/null +++ b/src/liballoc/tests/borrow.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::borrow::Cow; +use std::path::PathBuf; +use std::ffi::{CStr, CString, OSStr, OSString}; + +#[test] +fn test_cow_from() { + const MSG: &'static str = "Hello, World"; + let s = MSG.to_string(); + assert_eq!(Cow::from(&s), Cow::Borrowed(MSG)); + assert_eq!(Cow::from(s.as_str()), Cow::Borrowed(MSG)); + assert_eq!(Cow::from(s), Cow::Owned(MSG.to_string())); + + const VALUES: &'static [u8] = [1u8, 2, 3, 4, 5, 6, 7, 8]; + let v = VALUES.iter().collect::>(); + assert_eq!(Cow::from(&v), Cow::Borrowed(VALUES)); + assert_eq!(Cow::from(v.as_slice()), Cow::Borrowed(VALUES)); + assert_eq!(Cow::from(v), Cow::Owned(VALUES.iter().collect::>())); + + let p = PathBuf::new(); + assert_eq!(Cow::from(&p), Cow::Borrowed(p.as_path())); + assert_eq!(Cow::from(v.as_path()), Cow::Borrowed(p.as_path())); + + let cstring = CString::new(MSG); + let cstr = { + const MSG_NULL_TERMINATED: &'static str = "Hello, World\0"; + CStr::from_bytes_with_nul(MSG_NULL_TERMINATED).unwrap() + }; + assert_eq(Cow::from(&cstring), Cow::Borrowed(cstr)); + assert_eq(Cow::from(cstring.as_c_str()), Cow::Borrowed(cstr)); + + let s = OSString::from(MSG.into()); + assert_eq!(Cow::from(&s), Cow::Borrowed(OSStr::new(msg))); + assert_eq!(Cow::from(s.as_os_str()), Cow::Borrowed(OSStr::new(msg))); +} diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 427a7adcbded1..c5cc17357eb73 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -40,6 +40,7 @@ use std::collections::hash_map::DefaultHasher; mod binary_heap; mod btree; +mod borrow; mod cow_str; mod fmt; mod heap; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b26979c7f6d8c..7b20fd9739b9b 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2233,13 +2233,6 @@ impl<'a> From<&'a str> for Vec { // Clone-on-write //////////////////////////////////////////////////////////////////////////////// -#[stable(feature = "cow_from_vec", since = "1.8.0")] -impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> { - fn from(s: &'a [T]) -> Cow<'a, [T]> { - Cow::Borrowed(s) - } -} - #[stable(feature = "cow_from_vec", since = "1.8.0")] impl<'a, T: Clone> From> for Cow<'a, [T]> { fn from(v: Vec) -> Cow<'a, [T]> { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index ed102c2949ede..4ebb849bfa30f 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1445,14 +1445,6 @@ impl Default for PathBuf { } } -#[stable(feature = "cow_from_path", since = "1.6.0")] -impl<'a> From<&'a Path> for Cow<'a, Path> { - #[inline] - fn from(s: &'a Path) -> Cow<'a, Path> { - Cow::Borrowed(s) - } -} - #[stable(feature = "cow_from_path", since = "1.6.0")] impl<'a> From for Cow<'a, Path> { #[inline] From a8f5236cf34433fcf36b84aa7d885e58964000b9 Mon Sep 17 00:00:00 2001 From: George Burton Date: Mon, 12 Feb 2018 19:45:42 +0000 Subject: [PATCH 2/6] Fix some issues --- src/liballoc/tests/borrow.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/liballoc/tests/borrow.rs b/src/liballoc/tests/borrow.rs index 42215718a593b..e07930c7bcb1d 100644 --- a/src/liballoc/tests/borrow.rs +++ b/src/liballoc/tests/borrow.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::borrow::Cow; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::ffi::{CStr, CString, OSStr, OSString}; #[test] @@ -27,8 +27,8 @@ fn test_cow_from() { assert_eq!(Cow::from(v), Cow::Owned(VALUES.iter().collect::>())); let p = PathBuf::new(); - assert_eq!(Cow::from(&p), Cow::Borrowed(p.as_path())); - assert_eq!(Cow::from(v.as_path()), Cow::Borrowed(p.as_path())); + assert_eq!(Cow::from(&p), Cow::Borrowed(Path::new(""))); + assert_eq!(Cow::from(p.as_path()), Cow::Borrowed(Path::new(""))); let cstring = CString::new(MSG); let cstr = { From 5c0011f8cba1330ea5aa62a6abd78de1ca54167d Mon Sep 17 00:00:00 2001 From: George Burton Date: Tue, 13 Feb 2018 18:49:33 +0000 Subject: [PATCH 3/6] Fix tests, and add a test for a generic From --- src/liballoc/tests/borrow.rs | 61 +++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/src/liballoc/tests/borrow.rs b/src/liballoc/tests/borrow.rs index e07930c7bcb1d..bce92c5ffea94 100644 --- a/src/liballoc/tests/borrow.rs +++ b/src/liballoc/tests/borrow.rs @@ -10,35 +10,66 @@ use std::borrow::Cow; use std::path::{Path, PathBuf}; -use std::ffi::{CStr, CString, OSStr, OSString}; +use std::ffi::{CStr, CString, OsStr, OsString}; #[test] +#[ignore] fn test_cow_from() { const MSG: &'static str = "Hello, World"; let s = MSG.to_string(); - assert_eq!(Cow::from(&s), Cow::Borrowed(MSG)); + assert_eq!(Cow::::from(&s), Cow::Borrowed(MSG)); assert_eq!(Cow::from(s.as_str()), Cow::Borrowed(MSG)); - assert_eq!(Cow::from(s), Cow::Owned(MSG.to_string())); + assert_eq!( + Cow::from(s), + || -> Cow { Cow::Owned(MSG.to_string()) }() + ); - const VALUES: &'static [u8] = [1u8, 2, 3, 4, 5, 6, 7, 8]; - let v = VALUES.iter().collect::>(); - assert_eq!(Cow::from(&v), Cow::Borrowed(VALUES)); + const VALUES: &[u8] = &[1u8, 2, 3, 4, 5, 6, 7, 8]; + let v = VALUES.iter().map(|b| *b).collect::>(); + assert_eq!(Cow::<[u8]>::from(&v), Cow::Borrowed(VALUES)); assert_eq!(Cow::from(v.as_slice()), Cow::Borrowed(VALUES)); - assert_eq!(Cow::from(v), Cow::Owned(VALUES.iter().collect::>())); + assert_eq!( + Cow::from(v), + || -> Cow<[u8]> { Cow::Owned(VALUES.iter().map(|b| *b).collect::>() )}() + ); let p = PathBuf::new(); - assert_eq!(Cow::from(&p), Cow::Borrowed(Path::new(""))); + assert_eq!(Cow::::from(&p), Cow::Borrowed(Path::new(""))); assert_eq!(Cow::from(p.as_path()), Cow::Borrowed(Path::new(""))); + assert_eq!( + Cow::from(p), + || -> Cow { Cow::Owned(PathBuf::new()) }() + ); - let cstring = CString::new(MSG); + let cstring = CString::new(MSG).unwrap(); let cstr = { const MSG_NULL_TERMINATED: &'static str = "Hello, World\0"; - CStr::from_bytes_with_nul(MSG_NULL_TERMINATED).unwrap() + CStr::from_bytes_with_nul(MSG_NULL_TERMINATED.as_bytes()).unwrap() }; - assert_eq(Cow::from(&cstring), Cow::Borrowed(cstr)); - assert_eq(Cow::from(cstring.as_c_str()), Cow::Borrowed(cstr)); + assert_eq!(Cow::::from(&cstring), Cow::Borrowed(cstr)); + assert_eq!(Cow::from(cstring.as_c_str()), Cow::Borrowed(cstr)); - let s = OSString::from(MSG.into()); - assert_eq!(Cow::from(&s), Cow::Borrowed(OSStr::new(msg))); - assert_eq!(Cow::from(s.as_os_str()), Cow::Borrowed(OSStr::new(msg))); + let s = OsString::from(MSG.to_string()); + assert_eq!(Cow::::from(&s), Cow::Borrowed(OsStr::new(MSG))); + assert_eq!(Cow::from(s.as_os_str()), Cow::Borrowed(OsStr::new(MSG))); +} + +#[test] +fn test_generic_cow_from() { + struct VecWrapper { + _inner: Vec, + } + + impl VecWrapper { + fn new<'a, T: Into>>(val: T) -> Self { + VecWrapper { + _inner: val.into().into_owned(), + } + } + } + + let ints = vec![0i32, 1, 2, 3, 4, 5]; + let _vw0 = VecWrapper::new(ints.as_slice()); + let _vw1 = VecWrapper::new(&ints); + let _vw2 = VecWrapper::new(ints); } From 4f3b723d9f571cb79cd3e139c68c9f40d1723631 Mon Sep 17 00:00:00 2001 From: George Burton Date: Tue, 13 Feb 2018 19:38:55 +0000 Subject: [PATCH 4/6] Remove trailing whitespace --- src/liballoc/tests/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/tests/borrow.rs b/src/liballoc/tests/borrow.rs index bce92c5ffea94..da5ce28c38833 100644 --- a/src/liballoc/tests/borrow.rs +++ b/src/liballoc/tests/borrow.rs @@ -65,7 +65,7 @@ fn test_generic_cow_from() { VecWrapper { _inner: val.into().into_owned(), } - } + } } let ints = vec![0i32, 1, 2, 3, 4, 5]; From 75bf333719555011edbba82e2bd587b8aff1818a Mon Sep 17 00:00:00 2001 From: George Burton Date: Tue, 13 Feb 2018 22:32:00 +0000 Subject: [PATCH 5/6] Stabilise "generic_cow_from" change --- src/liballoc/borrow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index 051f6f89156e9..f90c7b71559b7 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -361,7 +361,7 @@ impl<'a, T: ?Sized + ToOwned> AsRef for Cow<'a, T> { } } -#[unstable(feature = "generic_cow_from", reason = "recently added", issue = "0000")] +#[stable(feature = "generic_cow_from", since = "1.24.0")] impl<'a, B, T> From<&'a B> for Cow<'a, T> where B: ?Sized + Borrow, From 54df5ce72c1bbc1d8d9ebfa65ffd1126fa1b084b Mon Sep 17 00:00:00 2001 From: George Burton Date: Tue, 27 Feb 2018 20:01:09 +0000 Subject: [PATCH 6/6] Remove ignore annotation from test_cow_from --- src/liballoc/tests/borrow.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/liballoc/tests/borrow.rs b/src/liballoc/tests/borrow.rs index bce92c5ffea94..afa33f6340d4c 100644 --- a/src/liballoc/tests/borrow.rs +++ b/src/liballoc/tests/borrow.rs @@ -13,7 +13,6 @@ use std::path::{Path, PathBuf}; use std::ffi::{CStr, CString, OsStr, OsString}; #[test] -#[ignore] fn test_cow_from() { const MSG: &'static str = "Hello, World"; let s = MSG.to_string();