Skip to content

Rollup of 8 pull requests #41237

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

Merged
merged 29 commits into from
Apr 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f6e5661
Implement Manually Drop
nagisa Mar 22, 2017
3871312
Move away from the ad-hoc NoDrop unions
nagisa Mar 22, 2017
c94b3f1
Replace the `forget` intrinsic with ManuallyDrop
nagisa Apr 2, 2017
4863455
into_inner to associated function
nagisa Apr 2, 2017
c337b99
Fix test failures
nagisa Apr 2, 2017
d4aecf5
Fix block code headers parsing
GuillaumeGomez Apr 9, 2017
1c3f34d
Convert HashMap to BTree in build-manifest
brson Apr 10, 2017
b9d662a
Fixes incorrect formatting in array's documentation.
Apr 10, 2017
f297767
Make sccache a bit quieter
aidanhs Apr 10, 2017
63ebf08
Initial attempt at implementing optimization fuel and re-enabling str…
ahicks92 Mar 8, 2017
4db9c7a
Make a comment better.
ahicks92 Mar 9, 2017
9125999
Tests for -Z fuel=foo=n
ahicks92 Mar 10, 2017
8b00837
UI test for -Z print-fuel=foo
ahicks92 Mar 10, 2017
98eb121
We have to use u16 to test field reordering because u64's alignment c…
ahicks92 Mar 20, 2017
0931e20
Initial attempt at implementing optimization fuel and re-enabling str…
ahicks92 Mar 8, 2017
d821e98
Make a comment better.
ahicks92 Mar 9, 2017
a384f13
Fix handling of closure arguments
nagisa Apr 11, 2017
e18c59f
Fix some nits
nagisa Apr 11, 2017
143f7be
Remove strings fulfilled with whitespaces in code block headers
GuillaumeGomez Apr 10, 2017
316af60
Clarify Iterator::position doc
shahn Apr 11, 2017
56503dd
use correct vault url
TimNN Apr 11, 2017
4f6f4eb
Rollup merge of #40377 - camlorn:optimization_fuel, r=eddyb
frewsxcv Apr 11, 2017
acb43ce
Rollup merge of #40559 - nagisa:manually-drop, r=alexcrichton
frewsxcv Apr 11, 2017
b72c30a
Rollup merge of #41173 - GuillaumeGomez:fix-rustdoc-code-block-parsin…
frewsxcv Apr 11, 2017
c03061d
Rollup merge of #41202 - brson:btree, r=nikomatsakis
frewsxcv Apr 11, 2017
704cbad
Rollup merge of #41204 - remexre:master, r=steveklabnik
frewsxcv Apr 11, 2017
828ed96
Rollup merge of #41209 - aidanhs:aphs-quiet-sccache, r=alexcrichton
frewsxcv Apr 11, 2017
3ebeaf6
Rollup merge of #41216 - shahn:iter_pos, r=steveklabnik
frewsxcv Apr 11, 2017
72538de
Rollup merge of #41231 - TimNN:fix-centos, r=frewsxcv
frewsxcv Apr 11, 2017
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 src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub fn llvm(build: &Build, target: &str) {
}

if env::var_os("SCCACHE_ERROR_LOG").is_some() {
cfg.env("RUST_LOG", "sccache=debug");
cfg.env("RUST_LOG", "sccache=info");
}

// FIXME: we don't actually need to build all LLVM tools and all LLVM
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/dist-i686-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ WORKDIR /build
# to http://vault.centos.org/
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
RUN sed -i 's/mirrorlist/#mirrorlist/' /etc/yum.repos.d/*.repo
RUN sed -i 's/#\(baseurl.*\)mirror.centos.org/\1107.158.252.35/' /etc/yum.repos.d/*.repo
RUN sed -i 's|#\(baseurl.*\)mirror.centos.org/centos/$releasever|\1vault.centos.org/5.11|' /etc/yum.repos.d/*.repo

RUN yum upgrade -y && yum install -y \
curl \
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/dist-x86_64-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ WORKDIR /build
# to http://vault.centos.org/
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf
RUN sed -i 's/mirrorlist/#mirrorlist/' /etc/yum.repos.d/*.repo
RUN sed -i 's/#\(baseurl.*\)mirror.centos.org/\1107.158.252.35/' /etc/yum.repos.d/*.repo
RUN sed -i 's|#\(baseurl.*\)mirror.centos.org/centos/$releasever|\1vault.centos.org/5.11|' /etc/yum.repos.d/*.repo

RUN yum upgrade -y && yum install -y \
curl \
Expand Down
1 change: 0 additions & 1 deletion src/ci/docker/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ if [ "$SCCACHE_BUCKET" != "" ]; then
args="$args --env AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID"
args="$args --env AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY"
args="$args --env SCCACHE_ERROR_LOG=/tmp/sccache/sccache.log"
args="$args --env SCCACHE_LOG_LEVEL=debug"
args="$args --volume $objdir/tmp:/tmp/sccache"
else
mkdir -p $HOME/.cache/sccache
Expand Down
1 change: 1 addition & 0 deletions src/doc/unstable-book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
- [loop_break_value](loop-break-value.md)
- [macro_reexport](macro-reexport.md)
- [main](main.md)
- [manually_drop](manually-drop.md)
- [map_entry_recover_keys](map-entry-recover-keys.md)
- [mpsc_select](mpsc-select.md)
- [n16](n16.md)
Expand Down
Empty file.
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#![feature(heap_api)]
#![feature(inclusive_range)]
#![feature(lang_items)]
#![feature(manually_drop)]
#![feature(nonzero)]
#![feature(pattern)]
#![feature(placement_in)]
Expand Down
12 changes: 3 additions & 9 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
// performance than with the 2nd method.
//
// All methods were benchmarked, and the 3rd showed best results. So we chose that one.
let mut tmp = NoDrop { value: ptr::read(&v[0]) };
let mut tmp = mem::ManuallyDrop::new(ptr::read(&v[0]));

// Intermediate state of the insertion process is always tracked by `hole`, which
// serves two purposes:
Expand All @@ -1571,13 +1571,13 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
// fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it
// initially held exactly once.
let mut hole = InsertionHole {
src: &mut tmp.value,
src: &mut *tmp,
dest: &mut v[1],
};
ptr::copy_nonoverlapping(&v[1], &mut v[0], 1);

for i in 2..v.len() {
if !is_less(&v[i], &tmp.value) {
if !is_less(&v[i], &*tmp) {
break;
}
ptr::copy_nonoverlapping(&v[i], &mut v[i - 1], 1);
Expand All @@ -1587,12 +1587,6 @@ fn insert_head<T, F>(v: &mut [T], is_less: &mut F)
}
}

// Holds a value, but never drops it.
#[allow(unions_with_drop_fields)]
union NoDrop<T> {
value: T
}

// When dropped, copies from `src` into `dest`.
struct InsertionHole<T> {
src: *mut T,
Expand Down
3 changes: 0 additions & 3 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,6 @@ extern "rust-intrinsic" {
/// initialize memory previous set to the result of `uninit`.
pub fn uninit<T>() -> T;

/// Moves a value out of scope without running drop glue.
pub fn forget<T>(_: T) -> ();

/// Reinterprets the bits of a value of one type as another type.
///
/// Both types must have the same size. Neither the original, nor the result,
Expand Down
8 changes: 6 additions & 2 deletions src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,14 +1532,18 @@ pub trait Iterator {
/// Stopping at the first `true`:
///
/// ```
/// let a = [1, 2, 3];
/// let a = [1, 2, 3, 4];
///
/// let mut iter = a.iter();
///
/// assert_eq!(iter.position(|&x| x == 2), Some(1));
/// assert_eq!(iter.position(|&x| x >= 2), Some(1));
///
/// // we can still use `iter`, as there are more elements.
/// assert_eq!(iter.next(), Some(&3));
///
/// // The returned index depends on iterator state
/// assert_eq!(iter.position(|&x| x == 4), Some(0));
///
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
120 changes: 119 additions & 1 deletion src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub use intrinsics::transmute;
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn forget<T>(t: T) {
unsafe { intrinsics::forget(t) }
ManuallyDrop::new(t);
}

/// Returns the size of a type in bytes.
Expand Down Expand Up @@ -736,3 +736,121 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
}
}


/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
///
/// This wrapper is 0-cost.
///
/// # Examples
///
/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
/// the type:
///
/// ```rust
/// # #![feature(manually_drop)]
/// use std::mem::ManuallyDrop;
/// struct Peach;
/// struct Banana;
/// struct Melon;
/// struct FruitBox {
/// // Immediately clear there’s something non-trivial going on with these fields.
/// peach: ManuallyDrop<Peach>,
/// melon: Melon, // Field that’s independent of the other two.
/// banana: ManuallyDrop<Banana>,
/// }
///
/// impl Drop for FruitBox {
/// fn drop(&mut self) {
/// unsafe {
/// // Explicit ordering in which field destructors are run specified in the intuitive
/// // location – the destructor of the structure containing the fields.
/// // Moreover, one can now reorder fields within the struct however much they want.
/// ManuallyDrop::drop(&mut self.peach);
/// ManuallyDrop::drop(&mut self.banana);
/// }
/// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
/// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
/// }
/// }
/// ```
#[unstable(feature = "manually_drop", issue = "40673")]
#[allow(unions_with_drop_fields)]
pub union ManuallyDrop<T>{ value: T }

impl<T> ManuallyDrop<T> {
/// Wrap a value to be manually dropped.
///
/// # Examples
///
/// ```rust
/// # #![feature(manually_drop)]
/// use std::mem::ManuallyDrop;
/// ManuallyDrop::new(Box::new(()));
/// ```
#[unstable(feature = "manually_drop", issue = "40673")]
#[inline]
pub fn new(value: T) -> ManuallyDrop<T> {
ManuallyDrop { value: value }
}

/// Extract the value from the ManuallyDrop container.
///
/// # Examples
///
/// ```rust
/// # #![feature(manually_drop)]
/// use std::mem::ManuallyDrop;
/// let x = ManuallyDrop::new(Box::new(()));
/// let _: Box<()> = ManuallyDrop::into_inner(x);
/// ```
#[unstable(feature = "manually_drop", issue = "40673")]
#[inline]
pub fn into_inner(slot: ManuallyDrop<T>) -> T {
unsafe {
slot.value
}
}

/// Manually drops the contained value.
///
/// # Unsafety
///
/// This function runs the destructor of the contained value and thus the wrapped value
/// now represents uninitialized data. It is up to the user of this method to ensure the
/// uninitialized data is not actually used.
#[unstable(feature = "manually_drop", issue = "40673")]
#[inline]
pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
ptr::drop_in_place(&mut slot.value)
}
}

#[unstable(feature = "manually_drop", issue = "40673")]
impl<T> ::ops::Deref for ManuallyDrop<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe {
&self.value
}
}
}

#[unstable(feature = "manually_drop", issue = "40673")]
impl<T> ::ops::DerefMut for ManuallyDrop<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
&mut self.value
}
}
}

#[unstable(feature = "manually_drop", issue = "40673")]
impl<T: ::fmt::Debug> ::fmt::Debug for ManuallyDrop<T> {
fn fmt(&self, fmt: &mut ::fmt::Formatter) -> ::fmt::Result {
unsafe {
fmt.debug_tuple("ManuallyDrop").field(&self.value).finish()
}
}
}
30 changes: 12 additions & 18 deletions src/libcore/slice/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ use cmp;
use mem;
use ptr;

/// Holds a value, but never drops it.
#[allow(unions_with_drop_fields)]
union NoDrop<T> {
value: T
}

/// When dropped, copies from `src` into `dest`.
struct CopyOnDrop<T> {
src: *mut T,
Expand All @@ -49,15 +43,15 @@ fn shift_head<T, F>(v: &mut [T], is_less: &mut F)
// Read the first element into a stack-allocated variable. If a following comparison
// operation panics, `hole` will get dropped and automatically write the element back
// into the slice.
let mut tmp = NoDrop { value: ptr::read(v.get_unchecked(0)) };
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(0)));
let mut hole = CopyOnDrop {
src: &mut tmp.value,
src: &mut *tmp,
dest: v.get_unchecked_mut(1),
};
ptr::copy_nonoverlapping(v.get_unchecked(1), v.get_unchecked_mut(0), 1);

for i in 2..len {
if !is_less(v.get_unchecked(i), &tmp.value) {
if !is_less(v.get_unchecked(i), &*tmp) {
break;
}

Expand All @@ -81,15 +75,15 @@ fn shift_tail<T, F>(v: &mut [T], is_less: &mut F)
// Read the last element into a stack-allocated variable. If a following comparison
// operation panics, `hole` will get dropped and automatically write the element back
// into the slice.
let mut tmp = NoDrop { value: ptr::read(v.get_unchecked(len - 1)) };
let mut tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(len - 1)));
let mut hole = CopyOnDrop {
src: &mut tmp.value,
src: &mut *tmp,
dest: v.get_unchecked_mut(len - 2),
};
ptr::copy_nonoverlapping(v.get_unchecked(len - 2), v.get_unchecked_mut(len - 1), 1);

for i in (0..len-2).rev() {
if !is_less(&tmp.value, v.get_unchecked(i)) {
if !is_less(&*tmp, v.get_unchecked(i)) {
break;
}

Expand Down Expand Up @@ -403,12 +397,12 @@ fn partition<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> (usize, bool)

// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
// operation panics, the pivot will be automatically written back into the slice.
let mut tmp = NoDrop { value: unsafe { ptr::read(pivot) } };
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
let _pivot_guard = CopyOnDrop {
src: unsafe { &mut tmp.value },
src: &mut *tmp,
dest: pivot,
};
let pivot = unsafe { &tmp.value };
let pivot = &*tmp;

// Find the first pair of out-of-order elements.
let mut l = 0;
Expand Down Expand Up @@ -452,12 +446,12 @@ fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize

// Read the pivot into a stack-allocated variable for efficiency. If a following comparison
// operation panics, the pivot will be automatically written back into the slice.
let mut tmp = NoDrop { value: unsafe { ptr::read(pivot) } };
let mut tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) });
let _pivot_guard = CopyOnDrop {
src: unsafe { &mut tmp.value },
src: &mut *tmp,
dest: pivot,
};
let pivot = unsafe { &tmp.value };
let pivot = &*tmp;

// Now partition the slice.
let mut l = 0;
Expand Down
24 changes: 24 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,8 @@ macro_rules! options {
Some("one of: `address`, `leak`, `memory` or `thread`");
pub const parse_linker_flavor: Option<&'static str> =
Some(::rustc_back::LinkerFlavor::one_of());
pub const parse_optimization_fuel: Option<&'static str> =
Some("crate=integer");
}

#[allow(dead_code)]
Expand Down Expand Up @@ -787,6 +789,21 @@ macro_rules! options {
}
true
}

fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) -> bool {
match v {
None => false,
Some(s) => {
let parts = s.split('=').collect::<Vec<_>>();
if parts.len() != 2 { return false; }
let crate_name = parts[0].to_string();
let fuel = parts[1].parse::<u64>();
if fuel.is_err() { return false; }
*slot = Some((crate_name, fuel.unwrap()));
true
}
}
}
}
) }

Expand Down Expand Up @@ -991,6 +1008,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"Use a sanitizer"),
linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
"Linker flavor"),
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
"Set the optimization fuel quota for a crate."),
print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
"Make Rustc print the total optimization fuel used by a crate."),
}

pub fn default_lib_output() -> CrateType {
Expand Down Expand Up @@ -1784,11 +1805,13 @@ mod dep_tracking {

impl_dep_tracking_hash_via_hash!(bool);
impl_dep_tracking_hash_via_hash!(usize);
impl_dep_tracking_hash_via_hash!(u64);
impl_dep_tracking_hash_via_hash!(String);
impl_dep_tracking_hash_via_hash!(lint::Level);
impl_dep_tracking_hash_via_hash!(Option<bool>);
impl_dep_tracking_hash_via_hash!(Option<usize>);
impl_dep_tracking_hash_via_hash!(Option<String>);
impl_dep_tracking_hash_via_hash!(Option<(String, u64)>);
impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
Expand All @@ -1810,6 +1833,7 @@ mod dep_tracking {
impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>,
Option<cstore::NativeLibraryKind>));
impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
impl DepTrackingHash for SearchPaths {
fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
let mut elems: Vec<_> = self
Expand Down
Loading