Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 17 pull requests #37604

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f89ba5d
Fix some mistakes in HRTB docs
mbrubeck Oct 18, 2016
942f909
Add missing urls for ErrorKind's variants
GuillaumeGomez Nov 2, 2016
50ecee2
Add feature gate for Self and associated types in struct expressions …
petrochenkov Sep 14, 2016
7d06bdd
set frame pointer elimination attribute for main
dinfuehr Nov 3, 2016
dc138b3
use DefId's in const eval for cross-crate const fn's
TimNN Nov 3, 2016
ed0230e
Peekable::peek(): Use Option::as_ref()
mglagla Nov 3, 2016
d5f72d2
Fix ICE when querying DefId on Def::Err.
Mark-Simulacrum Nov 3, 2016
6a34feb
Set RUSTC_BOOTSTRAP to some value.
brson Nov 3, 2016
1e40c80
Fix issues with the Add/AddAssign impls for Cow<str>
ollie27 Nov 4, 2016
9366ba3
Reorder `hir::Expr` fields.
nnethercote Nov 3, 2016
43452a3
Shrink `Expr_::ExprStruct`.
nnethercote Nov 4, 2016
a5f6aa1
reference full path `DefaultHasher`
liigo Nov 4, 2016
94e655e
Add -Zhir-stats for collecting statistics on HIR and AST
michaelwoerister Nov 4, 2016
3e4bd88
Change Into<Vec<u8>> for String and Into<OsString> for PathBuf to Fro…
leoyvens Nov 4, 2016
a6cf777
fix #37559: update compiler-rt
TimNN Nov 4, 2016
775d399
Remove recursive call from Cow::to_mut
ollie27 Nov 4, 2016
fe953dc
std: Track change to cprng syscall signature (Fuchsia)
raphlinus Nov 4, 2016
ecd79a1
Add error when proc_macro_derive is used not on functions
est31 Nov 4, 2016
05c5c02
Rollup merge of #37255 - mbrubeck:doc-edit, r=steveklabnik
Nov 5, 2016
eecc5bf
Rollup merge of #37537 - GuillaumeGomez:error_kind_doc, r=steveklabnik
Nov 5, 2016
c8ff041
Rollup merge of #37547 - petrochenkov:selfgate, r=nikomatsakis
Nov 5, 2016
ebfb0cc
Rollup merge of #37556 - dinfuehr:main_frame_pointer, r=eddyb
Nov 5, 2016
9296ed9
Rollup merge of #37557 - TimNN:fix-36954, r=eddyb
Nov 5, 2016
113a2b4
Rollup merge of #37564 - Mark-Simulacrum:sized-ice, r=eddyb
Nov 5, 2016
4ed092b
Rollup merge of #37565 - mglagla:peek_use_as_ref, r=alexcrichton
Nov 5, 2016
52d9afa
Rollup merge of #37566 - brson:env, r=alexcrichton
Nov 5, 2016
f6a65b9
Rollup merge of #37574 - ollie27:cow_add, r=alexcrichton
Nov 5, 2016
12f814e
Rollup merge of #37577 - nnethercote:shrink-Expr-slightly, r=eddyb
Nov 5, 2016
c6bd7fe
Rollup merge of #37579 - liigo:defaulthasher, r=alexcrichton
Nov 5, 2016
c4507f4
Rollup merge of #37583 - michaelwoerister:hir-stats, r=alexcrichton
Nov 5, 2016
a11a94c
Rollup merge of #37585 - leodasvacas:change_into_to_from, r=alexcrichton
Nov 5, 2016
d687d1d
Rollup merge of #37586 - TimNN:fix-37559, r=alexcrichton
Nov 5, 2016
c5a8dd3
Rollup merge of #37587 - ollie27:to_mut, r=alexcrichton
Nov 5, 2016
8f0b3b1
Rollup merge of #37589 - raphlinus:fuchsia_random, r=alexcrichton
Nov 5, 2016
14e8f9f
Rollup merge of #37596 - est31:master, r=alexcrichton
Nov 5, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mk/main.mk
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ CFG_INFO := $(info cfg: disabling unstable features (CFG_DISABLE_UNSTABLE_FEATUR
# Turn on feature-staging
export CFG_DISABLE_UNSTABLE_FEATURES
# Subvert unstable feature lints to do the self-build
export RUSTC_BOOTSTRAP
export RUSTC_BOOTSTRAP=1
endif
ifdef CFG_MUSL_ROOT
export CFG_MUSL_ROOT
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ impl Build {

/// Adds the compiler's bootstrap key to the environment of `cmd`.
fn add_bootstrap_key(&self, cmd: &mut Command) {
cmd.env("RUSTC_BOOTSTRAP", "");
cmd.env("RUSTC_BOOTSTRAP", "1");
// FIXME: Transitionary measure to bootstrap using the old bootstrap logic.
// Remove this once the bootstrap compiler uses the new login in Issue #36548.
cmd.env("RUSTC_BOOTSTRAP_KEY", "62b3e239");
Expand Down
2 changes: 1 addition & 1 deletion src/compiler-rt
19 changes: 10 additions & 9 deletions src/doc/book/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ that takes a reference like so:
fn call_with_ref<F>(some_closure:F) -> i32
where F: Fn(&i32) -> i32 {

let mut value = 0;
let value = 0;
some_closure(&value)
}
```
Expand All @@ -340,14 +340,15 @@ fn call_with_ref<'a, F>(some_closure:F) -> i32
where F: Fn(&'a i32) -> i32 {
```

However this presents a problem in our case. When you specify the explicit
lifetime on a function it binds that lifetime to the *entire* scope of the function
instead of just the invocation scope of our closure. This means that the borrow checker
will see a mutable reference in the same lifetime as our immutable reference and fail
to compile.
However, this presents a problem in our case. When a function has an explicit
lifetime parameter, that lifetime must be at least as long as the *entire*
call to that function. The borrow checker will complain that `value` doesn't
live long enough, because it is only in scope after its declaration inside the
function body.

In order to say that we only need the lifetime to be valid for the invocation scope
of the closure we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:
What we need is a closure that can borrow its argument only for its own
invocation scope, not for the outer function's scope. In order to say that,
we can use Higher-Ranked Trait Bounds with the `for<...>` syntax:

```ignore
fn call_with_ref<F>(some_closure:F) -> i32
Expand All @@ -362,7 +363,7 @@ expect.
fn call_with_ref<F>(some_closure:F) -> i32
where F: for<'a> Fn(&'a i32) -> i32 {

let mut value = 0;
let value = 0;
some_closure(&value)
}
```
Expand Down
66 changes: 41 additions & 25 deletions src/libcollections/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use core::hash::{Hash, Hasher};
use core::ops::{Add, AddAssign, Deref};

use fmt;
use string::String;

use self::Cow::*;

Expand Down Expand Up @@ -159,7 +160,10 @@ impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
match *self {
Borrowed(borrowed) => {
*self = Owned(borrowed.to_owned());
self.to_mut()
match *self {
Borrowed(..) => unreachable!(),
Owned(ref mut owned) => owned,
}
}
Owned(ref mut owned) => owned,
}
Expand Down Expand Up @@ -284,48 +288,60 @@ impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> {
}
}

#[stable(feature = "cow_add", since = "1.13.0")]
#[stable(feature = "cow_add", since = "1.14.0")]
impl<'a> Add<&'a str> for Cow<'a, str> {
type Output = Cow<'a, str>;

fn add(self, rhs: &'a str) -> Self {
if self == "" {
Cow::Borrowed(rhs)
} else if rhs == "" {
self
} else {
Cow::Owned(self.into_owned() + rhs)
}
#[inline]
fn add(mut self, rhs: &'a str) -> Self::Output {
self += rhs;
self
}
}

#[stable(feature = "cow_add", since = "1.13.0")]
#[stable(feature = "cow_add", since = "1.14.0")]
impl<'a> Add<Cow<'a, str>> for Cow<'a, str> {
type Output = Cow<'a, str>;

fn add(self, rhs: Cow<'a, str>) -> Self {
if self == "" {
rhs
} else if rhs == "" {
self
} else {
Cow::Owned(self.into_owned() + rhs.borrow())
}
#[inline]
fn add(mut self, rhs: Cow<'a, str>) -> Self::Output {
self += rhs;
self
}
}

#[stable(feature = "cow_add", since = "1.13.0")]
#[stable(feature = "cow_add", since = "1.14.0")]
impl<'a> AddAssign<&'a str> for Cow<'a, str> {
fn add_assign(&mut self, rhs: &'a str) {
if rhs == "" { return; }
self.to_mut().push_str(rhs);
if self.is_empty() {
*self = Cow::Borrowed(rhs)
} else if rhs.is_empty() {
return;
} else {
if let Cow::Borrowed(lhs) = *self {
let mut s = String::with_capacity(lhs.len() + rhs.len());
s.push_str(lhs);
*self = Cow::Owned(s);
}
self.to_mut().push_str(rhs);
}
}
}

#[stable(feature = "cow_add", since = "1.13.0")]
#[stable(feature = "cow_add", since = "1.14.0")]
impl<'a> AddAssign<Cow<'a, str>> for Cow<'a, str> {
fn add_assign(&mut self, rhs: Cow<'a, str>) {
if rhs == "" { return; }
self.to_mut().push_str(rhs.borrow());
if self.is_empty() {
*self = rhs
} else if rhs.is_empty() {
return;
} else {
if let Cow::Borrowed(lhs) = *self {
let mut s = String::with_capacity(lhs.len() + rhs.len());
s.push_str(lhs);
*self = Cow::Owned(s);
}
self.to_mut().push_str(&rhs);
}
}
}
8 changes: 4 additions & 4 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1904,10 +1904,10 @@ impl<'a> FromIterator<String> for Cow<'a, str> {
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Into<Vec<u8>> for String {
fn into(self) -> Vec<u8> {
self.into_bytes()
#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
impl From<String> for Vec<u8> {
fn from(string : String) -> Vec<u8> {
string.into_bytes()
}
}

Expand Down
134 changes: 105 additions & 29 deletions src/libcollectionstest/cow_str.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012-2013-2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -12,54 +12,130 @@ use std::borrow::Cow;

// check that Cow<'a, str> implements addition
#[test]
fn check_cow_add() {
borrowed1 = Cow::Borrowed("Hello, ");
borrowed2 = Cow::Borrowed("World!");
borrow_empty = Cow::Borrowed("");
fn check_cow_add_cow() {
let borrowed1 = Cow::Borrowed("Hello, ");
let borrowed2 = Cow::Borrowed("World!");
let borrow_empty = Cow::Borrowed("");

owned1 = Cow::Owned("Hi, ".into());
owned2 = Cow::Owned("Rustaceans!".into());
owned_empty = Cow::Owned("".into());
let owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
let owned_empty: Cow<str> = Cow::Owned(String::new());

assert_eq!("Hello, World!", borrowed1 + borrowed2);
assert_eq!("Hello, Rustaceans!", borrowed1 + owned2);
assert_eq!("Hello, World!", borrowed1.clone() + borrowed2.clone());
assert_eq!("Hello, Rustaceans!", borrowed1.clone() + owned2.clone());

assert_eq!("Hello, World!", owned1 + borrowed2);
assert_eq!("Hello, Rustaceans!", owned1 + owned2);
assert_eq!("Hi, World!", owned1.clone() + borrowed2.clone());
assert_eq!("Hi, Rustaceans!", owned1.clone() + owned2.clone());

if let Cow::Owned(_) = borrowed1 + borrow_empty {
if let Cow::Owned(_) = borrowed1.clone() + borrow_empty.clone() {
panic!("Adding empty strings to a borrow should note allocate");
}
if let Cow::Owned(_) = borrow_empty + borrowed1 {
if let Cow::Owned(_) = borrow_empty.clone() + borrowed1.clone() {
panic!("Adding empty strings to a borrow should note allocate");
}
if let Cow::Owned(_) = borrowed1 + owned_empty {
if let Cow::Owned(_) = borrowed1.clone() + owned_empty.clone() {
panic!("Adding empty strings to a borrow should note allocate");
}
if let Cow::Owned(_) = owned_empty + borrowed1 {
if let Cow::Owned(_) = owned_empty.clone() + borrowed1.clone() {
panic!("Adding empty strings to a borrow should note allocate");
}
}

fn check_cow_add_assign() {
borrowed1 = Cow::Borrowed("Hello, ");
borrowed2 = Cow::Borrowed("World!");
borrow_empty = Cow::Borrowed("");
#[test]
fn check_cow_add_str() {
let borrowed = Cow::Borrowed("Hello, ");
let borrow_empty = Cow::Borrowed("");

let owned: Cow<str> = Cow::Owned(String::from("Hi, "));
let owned_empty: Cow<str> = Cow::Owned(String::new());

owned1 = Cow::Owned("Hi, ".into());
owned2 = Cow::Owned("Rustaceans!".into());
owned_empty = Cow::Owned("".into());
assert_eq!("Hello, World!", borrowed.clone() + "World!");

let borrowed1clone = borrowed1.clone();
borrowed1clone += borrow_empty;
assert_eq!((&borrowed1clone).as_ptr(), (&borrowed1).as_ptr());
assert_eq!("Hi, World!", owned.clone() + "World!");

borrowed1clone += owned_empty;
assert_eq!((&borrowed1clone).as_ptr(), (&borrowed1).as_ptr());
if let Cow::Owned(_) = borrowed.clone() + "" {
panic!("Adding empty strings to a borrow should note allocate");
}
if let Cow::Owned(_) = borrow_empty.clone() + "Hello, " {
panic!("Adding empty strings to a borrow should note allocate");
}
if let Cow::Owned(_) = owned_empty.clone() + "Hello, " {
panic!("Adding empty strings to a borrow should note allocate");
}
}

#[test]
fn check_cow_add_assign_cow() {
let mut borrowed1 = Cow::Borrowed("Hello, ");
let borrowed2 = Cow::Borrowed("World!");
let borrow_empty = Cow::Borrowed("");

let mut owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
let owned_empty: Cow<str> = Cow::Owned(String::new());

let mut s = borrowed1.clone();
s += borrow_empty.clone();
assert_eq!("Hello, ", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}
let mut s = borrow_empty.clone();
s += borrowed1.clone();
assert_eq!("Hello, ", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}
let mut s = borrowed1.clone();
s += owned_empty.clone();
assert_eq!("Hello, ", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}
let mut s = owned_empty.clone();
s += borrowed1.clone();
assert_eq!("Hello, ", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}

owned1 += borrowed2;
borrowed1 += owned2;

assert_eq!("Hello, World!", owned1);
assert_eq!("Hi, World!", owned1);
assert_eq!("Hello, Rustaceans!", borrowed1);
}

#[test]
fn check_cow_add_assign_str() {
let mut borrowed = Cow::Borrowed("Hello, ");
let borrow_empty = Cow::Borrowed("");

let mut owned: Cow<str> = Cow::Owned(String::from("Hi, "));
let owned_empty: Cow<str> = Cow::Owned(String::new());

let mut s = borrowed.clone();
s += "";
assert_eq!("Hello, ", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}
let mut s = borrow_empty.clone();
s += "World!";
assert_eq!("World!", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}
let mut s = owned_empty.clone();
s += "World!";
assert_eq!("World!", s);
if let Cow::Owned(_) = s {
panic!("Adding empty strings to a borrow should note allocate");
}

owned += "World!";
borrowed += "World!";

assert_eq!("Hi, World!", owned);
assert_eq!("Hello, World!", borrowed);
}
1 change: 1 addition & 0 deletions src/libcollectionstest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mod bench;

mod binary_heap;
mod btree;
mod cow_str;
mod enum_set;
mod fmt;
mod linked_list;
Expand Down
Loading