Auto merge of #42130 - Mark-Simulacrum:rollup, r=Mark-Simulacrum

Rollup of 6 pull requests

- Successful merges: #41892, #42062, #42091, #42093, #42098, #42127
- Failed merges:
This commit is contained in:
bors 2017-05-21 01:53:20 +00:00
commit 7ac844ffb8
22 changed files with 129 additions and 54 deletions

View File

@ -0,0 +1,7 @@
# `needs_drop`
The tracking issue for this feature is: [#41890]
[#41890]: https://github.com/rust-lang/rust/issues/41890
------------------------

View File

@ -32,6 +32,7 @@
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(generic_param_attrs)]
#![feature(needs_drop)]
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(test, feature(test))]
@ -82,7 +83,7 @@ impl<T> TypedArenaChunk<T> {
unsafe fn destroy(&mut self, len: usize) {
// The branch on needs_drop() is an -O1 performance optimization.
// Without the branch, dropping TypedArena<u8> takes linear time.
if intrinsics::needs_drop::<T>() {
if mem::needs_drop::<T>() {
let mut start = self.start();
// Destroy all allocated objects.
for _ in 0..len {
@ -350,7 +351,7 @@ impl DroplessArena {
#[inline]
pub fn alloc<T>(&self, object: T) -> &mut T {
unsafe {
assert!(!intrinsics::needs_drop::<T>());
assert!(!mem::needs_drop::<T>());
assert!(mem::size_of::<T>() != 0);
self.align_for::<T>();
@ -379,9 +380,7 @@ impl DroplessArena {
#[inline]
pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
where T: Copy {
unsafe {
assert!(!intrinsics::needs_drop::<T>());
}
assert!(!mem::needs_drop::<T>());
assert!(mem::size_of::<T>() != 0);
assert!(slice.len() != 0);
self.align_for::<T>();

View File

@ -302,6 +302,58 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
unsafe { intrinsics::min_align_of_val(val) }
}
/// Returns whether dropping values of type `T` matters.
///
/// This is purely an optimization hint, and may be implemented conservatively.
/// For instance, always returning `true` would be a valid implementation of
/// this function.
///
/// Low level implementations of things like collections, which need to manually
/// drop their data, should use this function to avoid unnecessarily
/// trying to drop all their contents when they are destroyed. This might not
/// make a difference in release builds (where a loop that has no side-effects
/// is easily detected and eliminated), but is often a big win for debug builds.
///
/// Note that `ptr::drop_in_place` already performs this check, so if your workload
/// can be reduced to some small number of drop_in_place calls, using this is
/// unnecessary. In particular note that you can drop_in_place a slice, and that
/// will do a single needs_drop check for all the values.
///
/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
/// needs_drop explicitly. Types like HashMap, on the other hand, have to drop
/// values one at a time and should use this API.
///
///
/// # Examples
///
/// Here's an example of how a collection might make use of needs_drop:
///
/// ```ignore
/// #![feature(needs_drop)]
/// use std::{mem, ptr};
///
/// pub struct MyCollection<T> { /* ... */ }
///
/// impl<T> Drop for MyCollection<T> {
/// fn drop(&mut self) {
/// unsafe {
/// // drop the data
/// if mem::needs_drop::<T>() {
/// for x in self.iter_mut() {
/// ptr::drop_in_place(x);
/// }
/// }
/// self.free_buffer();
/// }
/// }
/// }
/// ```
#[inline]
#[unstable(feature = "needs_drop", issue = "41890")]
pub fn needs_drop<T>() -> bool {
unsafe { intrinsics::needs_drop::<T>() }
}
/// Creates a value whose bytes are all zero.
///
/// This has the same effect as allocating space with

View File

@ -918,6 +918,7 @@ impl<T> AtomicPtr<T> {
}
}
#[cfg(target_has_atomic = "ptr")]
macro_rules! atomic_int {
($stable:meta,
$stable_cxchg:meta,

View File

@ -113,7 +113,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
heading: &str, span: Span)
-> (String, Option<Span>) {
let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1),
Some(span))
}

View File

@ -192,8 +192,8 @@ impl<'a> Debug for DiagnosticBuilder<'a> {
}
}
/// Destructor bomb - a DiagnosticBuilder must be either emitted or cancelled or
/// we emit a bug.
/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled
/// or we emit a bug.
impl<'a> Drop for DiagnosticBuilder<'a> {
fn drop(&mut self) {
if !panicking() && !self.cancelled() {

View File

@ -1296,10 +1296,8 @@ impl Write for BufferedWriter {
}
fn flush(&mut self) -> io::Result<()> {
let mut stderr = io::stderr();
let result = (|| {
stderr.write_all(&self.buffer)?;
stderr.flush()
})();
let result = stderr.write_all(&self.buffer)
.and_then(|_| stderr.flush());
self.buffer.clear();
result
}

View File

@ -383,7 +383,7 @@ impl Handler {
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
self.emit(&sp.into(), msg, Fatal);
self.panic_if_treat_err_as_bug();
return FatalError;
FatalError
}
pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self,
sp: S,
@ -392,7 +392,7 @@ impl Handler {
-> FatalError {
self.emit_with_code(&sp.into(), msg, code, Fatal);
self.panic_if_treat_err_as_bug();
return FatalError;
FatalError
}
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
self.emit(&sp.into(), msg, Error);

View File

@ -12,9 +12,8 @@ use alloc::heap::{allocate, deallocate};
use cmp;
use hash::{BuildHasher, Hash, Hasher};
use intrinsics::needs_drop;
use marker;
use mem::{align_of, size_of};
use mem::{align_of, size_of, needs_drop};
use mem;
use ops::{Deref, DerefMut};
use ptr::{self, Unique, Shared};

View File

@ -13,6 +13,13 @@
//! This module contains functions to inspect various aspects such as
//! environment variables, process arguments, the current directory, and various
//! other important directories.
//!
//! There are several functions and structs in this module that have a
//! counterpart ending in `os`. Those ending in `os` will return an [`OsString`]
//! and those without will be returning a [`String`].
//!
//! [`OsString`]: ../../std/ffi/struct.OsString.html
//! [`String`]: ../string/struct.String.html
#![stable(feature = "env", since = "1.0.0")]
@ -74,7 +81,8 @@ pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// An iterator over a snapshot of the environment variables of this process.
///
/// This structure is created through the [`std::env::vars`] function.
/// This structure is created by the [`std::env::vars`] function. See its
/// documentation for more.
///
/// [`std::env::vars`]: fn.vars.html
#[stable(feature = "env", since = "1.0.0")]
@ -82,7 +90,8 @@ pub struct Vars { inner: VarsOs }
/// An iterator over a snapshot of the environment variables of this process.
///
/// This structure is created through the [`std::env::vars_os`] function.
/// This structure is created by the [`std::env::vars_os`] function. See
/// its documentation for more.
///
/// [`std::env::vars_os`]: fn.vars_os.html
#[stable(feature = "env", since = "1.0.0")]
@ -176,12 +185,10 @@ impl fmt::Debug for VarsOs {
/// Fetches the environment variable `key` from the current process.
///
/// The returned result is [`Ok(s)`] if the environment variable is present and is
/// valid unicode. If the environment variable is not present, or it is not
/// valid unicode, then [`VarError`] will be returned.
/// # Errors
///
/// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok
/// [`VarError`]: enum.VarError.html
/// * Environment variable is not present
/// * Environment variable is not valid unicode
///
/// # Examples
///
@ -233,7 +240,8 @@ fn _var_os(key: &OsStr) -> Option<OsString> {
})
}
/// Possible errors from the [`env::var`] function.
/// The error type for operations interacting with environment variables.
/// Possibly returned from the [`env::var`] function.
///
/// [`env::var`]: fn.var.html
#[derive(Debug, PartialEq, Eq, Clone)]
@ -356,10 +364,13 @@ fn _remove_var(k: &OsStr) {
})
}
/// An iterator over `PathBuf` instances for parsing an environment variable
/// according to platform-specific conventions.
/// An iterator that splits an environment variable into paths according to
/// platform-specific conventions.
///
/// This structure is returned from `std::env::split_paths`.
/// This structure is created by the [`std::env::split_paths`] function See its
/// documentation for more.
///
/// [`std::env::split_paths`]: fn.split_paths.html
#[stable(feature = "env", since = "1.0.0")]
pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
@ -402,8 +413,10 @@ impl<'a> fmt::Debug for SplitPaths<'a> {
}
}
/// Error type returned from `std::env::join_paths` when paths fail to be
/// joined.
/// The error type for operations on the `PATH` variable. Possibly returned from
/// the [`env::join_paths`] function.
///
/// [`env::join_paths`]: fn.join_paths.html
#[derive(Debug)]
#[stable(feature = "env", since = "1.0.0")]
pub struct JoinPathsError {
@ -413,7 +426,7 @@ pub struct JoinPathsError {
/// Joins a collection of [`Path`]s appropriately for the `PATH`
/// environment variable.
///
/// Returns an [`OsString`] on success.
/// # Errors
///
/// Returns an [`Err`][err] (containing an error message) if one of the input
/// [`Path`]s contains an invalid character for constructing the `PATH`
@ -493,12 +506,16 @@ pub fn home_dir() -> Option<PathBuf> {
/// Returns the path of a temporary directory.
///
/// On Unix, returns the value of the `TMPDIR` environment variable if it is
/// # Unix
///
/// Returns the value of the `TMPDIR` environment variable if it is
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
/// is no global temporary folder (it is usually allocated per-app), it returns
/// `/data/local/tmp`.
///
/// On Windows, returns the value of, in order, the `TMP`, `TEMP`,
/// # Windows
///
/// Returns the value of, in order, the `TMP`, `TEMP`,
/// `USERPROFILE` environment variable if any are set and not the empty
/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
/// This behavior is identical to that of [`GetTempPath`][msdn], which this

View File

@ -530,7 +530,7 @@ impl<'a> From<&'a OsStr> for Box<OsStr> {
}
#[stable(feature = "os_string_from_box", since = "1.18.0")]
impl<'a> From<Box<OsStr>> for OsString {
impl From<Box<OsStr>> for OsString {
fn from(boxed: Box<OsStr>) -> OsString {
boxed.into_os_string()
}

View File

@ -281,6 +281,7 @@
#![feature(linkage)]
#![feature(macro_reexport)]
#![feature(needs_panic_runtime)]
#![feature(needs_drop)]
#![feature(never_type)]
#![feature(num_bits_bytes)]
#![feature(old_wrapping)]

View File

@ -1342,7 +1342,7 @@ impl<'a> From<&'a Path> for Box<Path> {
}
#[stable(feature = "path_buf_from_box", since = "1.18.0")]
impl<'a> From<Box<Path>> for PathBuf {
impl From<Box<Path>> for PathBuf {
fn from(boxed: Box<Path>) -> PathBuf {
boxed.into_path_buf()
}

View File

@ -12,9 +12,10 @@
#![unstable(feature = "thread_local_internals", issue = "0")]
use cell::{Cell, UnsafeCell};
use intrinsics;
use mem;
use ptr;
pub struct Key<T> {
inner: UnsafeCell<Option<T>>,
@ -37,7 +38,7 @@ impl<T> Key<T> {
pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
unsafe {
if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
if mem::needs_drop::<T>() && self.dtor_running.get() {
return None
}
self.register_dtor();
@ -46,7 +47,7 @@ impl<T> Key<T> {
}
unsafe fn register_dtor(&self) {
if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
if !mem::needs_drop::<T>() || self.dtor_registered.get() {
return
}

View File

@ -13,7 +13,7 @@
use cell::{Cell, UnsafeCell};
use fmt;
use intrinsics;
use mem;
use ptr;
pub struct Key<T> {
@ -44,7 +44,7 @@ impl<T> Key<T> {
pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
unsafe {
if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
if mem::needs_drop::<T>() && self.dtor_running.get() {
return None
}
self.register_dtor();
@ -53,7 +53,7 @@ impl<T> Key<T> {
}
unsafe fn register_dtor(&self) {
if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
if !mem::needs_drop::<T>() || self.dtor_registered.get() {
return
}

View File

@ -11,7 +11,7 @@
pub trait Resources<'a> {}
pub trait Buffer<'a, R: Resources<'a>> {
//~^ NOTE the lifetime 'a as defined on the trait at 13:0...
//~^ NOTE the lifetime 'a as defined on the trait at 13:1...
//~| NOTE ...does not necessarily outlive the lifetime 'a as defined on the trait
fn select(&self) -> BufferViewHandle<R>;
@ -22,7 +22,7 @@ pub trait Buffer<'a, R: Resources<'a>> {
//~| ERROR mismatched types
//~| lifetime mismatch
//~| NOTE expected type `Resources<'_>`
//~| NOTE the anonymous lifetime #1 defined on the method body at 17:4...
//~| NOTE the anonymous lifetime #1 defined on the method body at 17:5...
}
pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R);

View File

@ -4,14 +4,14 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content...
12 | if x > y { x } else { y }
| ^
|
note: ...the reference is valid for the lifetime 'a as defined on the function body at 11:0...
note: ...the reference is valid for the lifetime 'a as defined on the function body at 11:1...
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:1
|
11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
12 | | if x > y { x } else { y }
13 | | }
| |_^
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the function body at 11:0
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the function body at 11:1
--> $DIR/ex1-return-one-existing-name-if-else.rs:11:1
|
11 | / fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {

View File

@ -6,14 +6,14 @@ error[E0308]: mismatched types
|
= note: expected type `Ref<'a, _>`
found type `Ref<'_, _>`
note: the anonymous lifetime #2 defined on the function body at 15:0...
note: the anonymous lifetime #2 defined on the function body at 15:1...
--> $DIR/ex2a-push-one-existing-name.rs:15:1
|
15 | / fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
16 | | x.push(y);
17 | | }
| |_^
note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 15:0
note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 15:1
--> $DIR/ex2a-push-one-existing-name.rs:15:1
|
15 | / fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {

View File

@ -6,14 +6,14 @@ error[E0308]: mismatched types
|
= note: expected type `Ref<'_, _>`
found type `Ref<'_, _>`
note: the anonymous lifetime #3 defined on the function body at 15:0...
note: the anonymous lifetime #3 defined on the function body at 15:1...
--> $DIR/ex2b-push-no-existing-names.rs:15:1
|
15 | / fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
16 | | x.push(y);
17 | | }
| |_^
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 15:0
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the function body at 15:1
--> $DIR/ex2b-push-no-existing-names.rs:15:1
|
15 | / fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {

View File

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
16 | let z = Ref { data: y.data };
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:1...
--> $DIR/ex2c-push-inference-variable.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
@ -17,7 +17,7 @@ note: ...so that reference does not outlive borrowed content
|
16 | let z = Ref { data: y.data };
| ^^^^^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:1...
--> $DIR/ex2c-push-inference-variable.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {

View File

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
17 | let b = Ref { data: y.data };
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:1...
--> $DIR/ex2d-push-inference-variable-2.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
@ -18,7 +18,7 @@ note: ...so that reference does not outlive borrowed content
|
17 | let b = Ref { data: y.data };
| ^^^^^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:1...
--> $DIR/ex2d-push-inference-variable-2.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {

View File

@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
17 | let b = Ref { data: y.data };
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:0...
note: first, the lifetime cannot outlive the lifetime 'c as defined on the function body at 15:1...
--> $DIR/ex2e-push-inference-variable-3.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
@ -18,7 +18,7 @@ note: ...so that reference does not outlive borrowed content
|
17 | let b = Ref { data: y.data };
| ^^^^^^
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:0...
note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 15:1...
--> $DIR/ex2e-push-inference-variable-3.rs:15:1
|
15 | / fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {