Auto merge of #39563 - frewsxcv:rollup, r=frewsxcv

Rollup of 19 pull requests

- Successful merges: #38518, #38921, #38959, #38983, #39009, #39107, #39193, #39289, #39312, #39393, #39442, #39443, #39453, #39454, #39471, #39477, #39478, #39527, #39552
- Failed merges:
This commit is contained in:
bors 2017-02-05 14:15:18 +00:00
commit 9c8cdb2923
139 changed files with 1345 additions and 577 deletions

View file

@ -11,8 +11,8 @@
//! rustbuild, the Rust build system
//!
//! This is the entry point for the build system used to compile the `rustc`
//! compiler. Lots of documentation can be found in the `README.md` file next to
//! this file, and otherwise documentation can be found throughout the `build`
//! compiler. Lots of documentation can be found in the `README.md` file in the
//! parent directory, and otherwise documentation can be found throughout the `build`
//! directory in each respective module.
#![deny(warnings)]

View file

@ -438,14 +438,14 @@ def main():
rb.use_vendored_sources = '\nvendor = true' in rb.config_toml or \
'CFG_ENABLE_VENDOR' in rb.config_mk
if 'SUDO_USER' in os.environ:
if os.environ['USER'] != os.environ['SUDO_USER']:
if 'SUDO_USER' in os.environ and not rb.use_vendored_sources:
if os.environ.get('USER') != os.environ['SUDO_USER']:
rb.use_vendored_sources = True
print('info: looks like you are running this command under `sudo`')
print(' and so in order to preserve your $HOME this will now')
print(' use vendored sources by default. Note that if this')
print(' does not work you should run a normal build first')
print(' before running a command like `sudo make intall`')
print(' before running a command like `sudo make install`')
if rb.use_vendored_sources:
if not os.path.exists('.cargo'):

View file

@ -381,7 +381,8 @@ pub fn rust_src(build: &Build) {
"README.md",
"RELEASES.md",
"configure",
"Makefile.in"
"Makefile.in",
"x.py",
];
let src_dirs = [
"man",

View file

@ -1088,7 +1088,7 @@ fn is_empty(&self) -> bool {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, T: 'a> FusedIterator for Drain<'a, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
fn from(vec: Vec<T>) -> BinaryHeap<T> {
let mut heap = BinaryHeap { data: vec };
@ -1097,7 +1097,7 @@ fn from(vec: Vec<T>) -> BinaryHeap<T> {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
impl<T> From<BinaryHeap<T>> for Vec<T> {
fn from(heap: BinaryHeap<T>) -> Vec<T> {
heap.data

View file

@ -588,7 +588,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeUnicode {}
#[stable(feature = "char_struct_display", since = "1.17.0")]
#[stable(feature = "char_struct_display", since = "1.16.0")]
impl fmt::Display for EscapeUnicode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for c in self.clone() {
@ -701,7 +701,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}
#[stable(feature = "char_struct_display", since = "1.17.0")]
#[stable(feature = "char_struct_display", since = "1.16.0")]
impl fmt::Display for EscapeDefault {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for c in self.clone() {
@ -735,7 +735,7 @@ impl ExactSizeIterator for EscapeDebug { }
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDebug {}
#[stable(feature = "char_struct_display", since = "1.17.0")]
#[unstable(feature = "char_escape_debug", issue = "35068")]
impl fmt::Display for EscapeDebug {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)

View file

@ -225,7 +225,7 @@ pub trait TryFrom<T>: Sized {
type Err;
/// Performs the conversion.
fn try_from(T) -> Result<Self, Self::Err>;
fn try_from(value: T) -> Result<Self, Self::Err>;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -13,7 +13,11 @@
// based on "op T" where T is expected to be `Copy`able
macro_rules! forward_ref_unop {
(impl $imp:ident, $method:ident for $t:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
forward_ref_unop!(impl $imp, $method for $t,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp for &'a $t {
type Output = <$t as $imp>::Output;
@ -29,7 +33,11 @@ fn $method(self) -> <$t as $imp>::Output {
// based on "T op U" where T and U are expected to be `Copy`able
macro_rules! forward_ref_binop {
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
forward_ref_binop!(impl $imp, $method for $t, $u,
#[stable(feature = "rust1", since = "1.0.0")]);
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<$u> for &'a $t {
type Output = <$t as $imp<$u>>::Output;
@ -39,7 +47,7 @@ fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[$attr]
impl<'a> $imp<&'a $u> for $t {
type Output = <$t as $imp<$u>>::Output;
@ -49,7 +57,7 @@ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[$attr]
impl<'a, 'b> $imp<&'a $u> for &'b $t {
type Output = <$t as $imp<$u>>::Output;

View file

@ -1086,7 +1086,7 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
#[inline]
fn next(&mut self) -> Option<I::Item> {
for x in self.iter.by_ref() {
for x in &mut self.iter {
if (self.predicate)(&x) {
return Some(x);
}
@ -1099,6 +1099,26 @@ fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper) // can't know a lower bound, due to the predicate
}
// this special case allows the compiler to make `.filter(_).count()`
// branchless. Barring perfect branch prediction (which is unattainable in
// the general case), this will be much faster in >90% of cases (containing
// virtually all real workloads) and only a tiny bit slower in the rest.
//
// Having this specialization thus allows us to write `.filter(p).count()`
// where we would otherwise write `.map(|x| p(x) as usize).sum()`, which is
// less readable and also less backwards-compatible to Rust before 1.10.
//
// Using the branchless version will also simplify the LLVM byte code, thus
// leaving more budget for LLVM optimizations.
#[inline]
fn count(mut self) -> usize {
let mut count = 0;
for x in &mut self.iter {
count += (self.predicate)(&x) as usize;
}
count
}
}
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -661,29 +661,29 @@ pub trait Product<A = Self>: Sized {
// NB: explicitly use Add and Mul here to inherit overflow checks
macro_rules! integer_sum_product {
(@impls $zero:expr, $one:expr, $($a:ty)*) => ($(
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
(@impls $zero:expr, $one:expr, #[$attr:meta], $($a:ty)*) => ($(
#[$attr]
impl Sum for $a {
fn sum<I: Iterator<Item=$a>>(iter: I) -> $a {
iter.fold($zero, Add::add)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
#[$attr]
impl Product for $a {
fn product<I: Iterator<Item=$a>>(iter: I) -> $a {
iter.fold($one, Mul::mul)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
#[$attr]
impl<'a> Sum<&'a $a> for $a {
fn sum<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
iter.fold($zero, Add::add)
}
}
#[stable(feature = "iter_arith_traits", since = "1.12.0")]
#[$attr]
impl<'a> Product<&'a $a> for $a {
fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
iter.fold($one, Mul::mul)
@ -691,8 +691,12 @@ fn product<I: Iterator<Item=&'a $a>>(iter: I) -> $a {
}
)*);
($($a:ty)*) => (
integer_sum_product!(@impls 0, 1, $($a)+);
integer_sum_product!(@impls Wrapping(0), Wrapping(1), $(Wrapping<$a>)+);
integer_sum_product!(@impls 0, 1,
#[stable(feature = "iter_arith_traits", since = "1.12.0")],
$($a)+);
integer_sum_product!(@impls Wrapping(0), Wrapping(1),
#[stable(feature = "wrapping_iter_arith", since = "1.14.0")],
$(Wrapping<$a>)+);
);
}

View file

@ -12,12 +12,12 @@
macro_rules! int_module {
($T:ident) => (int_module!($T, #[stable(feature = "rust1", since = "1.0.0")]););
($T:ident, $($attr: tt)*) => (
($T:ident, #[$attr:meta]) => (
/// The smallest value that can be represented by this integer type.
$($attr)*
#[$attr]
pub const MIN: $T = $T::min_value();
/// The largest value that can be represented by this integer type.
$($attr)*
#[$attr]
pub const MAX: $T = $T::max_value();
)
}

View file

@ -12,12 +12,12 @@
macro_rules! uint_module {
($T:ident) => (uint_module!($T, #[stable(feature = "rust1", since = "1.0.0")]););
($T:ident, $($attr: tt)*) => (
($T:ident, #[$attr:meta]) => (
/// The smallest value that can be represented by this integer type.
$($attr)*
#[$attr]
pub const MIN: $T = $T::min_value();
/// The largest value that can be represented by this integer type.
$($attr)*
#[$attr]
pub const MAX: $T = $T::max_value();
)
}

View file

@ -131,7 +131,8 @@ fn add(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0.wrapping_add(other.0))
}
}
forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl AddAssign for Wrapping<$t> {
@ -150,7 +151,8 @@ fn sub(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0.wrapping_sub(other.0))
}
}
forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl SubAssign for Wrapping<$t> {
@ -169,7 +171,8 @@ fn mul(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0.wrapping_mul(other.0))
}
}
forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl Mul, mul for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl MulAssign for Wrapping<$t> {
@ -188,7 +191,8 @@ fn div(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0.wrapping_div(other.0))
}
}
forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl DivAssign for Wrapping<$t> {
@ -207,7 +211,8 @@ fn rem(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0.wrapping_rem(other.0))
}
}
forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl RemAssign for Wrapping<$t> {
@ -226,7 +231,8 @@ fn not(self) -> Wrapping<$t> {
Wrapping(!self.0)
}
}
forward_ref_unop! { impl Not, not for Wrapping<$t> }
forward_ref_unop! { impl Not, not for Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "rust1", since = "1.0.0")]
impl BitXor for Wrapping<$t> {
@ -237,7 +243,8 @@ fn bitxor(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0 ^ other.0)
}
}
forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl BitXorAssign for Wrapping<$t> {
@ -256,7 +263,8 @@ fn bitor(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0 | other.0)
}
}
forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl BitOrAssign for Wrapping<$t> {
@ -275,7 +283,8 @@ fn bitand(self, other: Wrapping<$t>) -> Wrapping<$t> {
Wrapping(self.0 & other.0)
}
}
forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t> }
forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
#[stable(feature = "op_assign_traits", since = "1.8.0")]
impl BitAndAssign for Wrapping<$t> {
@ -293,7 +302,8 @@ fn neg(self) -> Self {
Wrapping(0) - self
}
}
forward_ref_unop! { impl Neg, neg for Wrapping<$t> }
forward_ref_unop! { impl Neg, neg for Wrapping<$t>,
#[stable(feature = "wrapping_ref", since = "1.14.0")] }
)*)
}

View file

@ -632,6 +632,76 @@ pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
}
}
/////////////////////////////////////////////////////////////////////////
// Entry-like operations to insert if None and return a reference
/////////////////////////////////////////////////////////////////////////
/// Inserts `v` into the option if it is `None`, then
/// returns a mutable reference to the contained value.
///
/// # Examples
///
/// ```
/// #![feature(option_entry)]
///
/// let mut x = None;
///
/// {
/// let y: &mut u32 = x.get_or_insert(5);
/// assert_eq!(y, &5);
///
/// *y = 7;
/// }
///
/// assert_eq!(x, Some(7));
/// ```
#[inline]
#[unstable(feature = "option_entry", issue = "39288")]
pub fn get_or_insert(&mut self, v: T) -> &mut T {
match *self {
None => *self = Some(v),
_ => (),
}
match *self {
Some(ref mut v) => v,
_ => unreachable!(),
}
}
/// Inserts a value computed from `f` into the option if it is `None`, then
/// returns a mutable reference to the contained value.
///
/// # Examples
///
/// ```
/// #![feature(option_entry)]
///
/// let mut x = None;
///
/// {
/// let y: &mut u32 = x.get_or_insert_with(|| 5);
/// assert_eq!(y, &5);
///
/// *y = 7;
/// }
///
/// assert_eq!(x, Some(7));
/// ```
#[inline]
#[unstable(feature = "option_entry", issue = "39288")]
pub fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
match *self {
None => *self = Some(f()),
_ => (),
}
match *self {
Some(ref mut v) => v,
_ => unreachable!(),
}
}
/////////////////////////////////////////////////////////////////////////
// Misc
/////////////////////////////////////////////////////////////////////////

View file

@ -616,7 +616,7 @@ pub trait SliceIndex<T> {
fn index_mut(self, slice: &mut [T]) -> &mut Self::Output;
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
impl<T> SliceIndex<T> for usize {
type Output = T;
@ -665,7 +665,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut T {
}
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
impl<T> SliceIndex<T> for ops::Range<usize> {
type Output = [T];
@ -726,7 +726,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
impl<T> SliceIndex<T> for ops::RangeTo<usize> {
type Output = [T];
@ -761,7 +761,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
impl<T> SliceIndex<T> for ops::RangeFrom<usize> {
type Output = [T];
@ -796,7 +796,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
impl<T> SliceIndex<T> for ops::RangeFull {
type Output = [T];
@ -832,7 +832,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> SliceIndex<T> for ops::RangeInclusive<usize> {
type Output = [T];
@ -895,7 +895,7 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
}
#[stable(feature = "slice-get-slice-impls", since = "1.13.0")]
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<T> SliceIndex<T> for ops::RangeToInclusive<usize> {
type Output = [T];

View file

@ -1318,6 +1318,24 @@ pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
unstable(feature = "integer_atomics", issue = "32976"),
u64 AtomicU64 ATOMIC_U64_INIT
}
#[cfg(not(stage0))]
#[cfg(target_has_atomic = "128")]
atomic_int! {
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
i128 AtomicI128 ATOMIC_I128_INIT
}
#[cfg(not(stage0))]
#[cfg(target_has_atomic = "128")]
atomic_int! {
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
unstable(feature = "i128", issue = "35118"),
u128 AtomicU128 ATOMIC_U128_INIT
}
#[cfg(target_has_atomic = "ptr")]
atomic_int!{
stable(feature = "rust1", since = "1.0.0"),

View file

@ -191,6 +191,12 @@ fn test_iterator_enumerate_count() {
assert_eq!(xs.iter().count(), 6);
}
#[test]
fn test_iterator_filter_count() {
let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8];
assert_eq!(xs.iter().filter(|&&x| x % 2 == 0).count(), 5);
}
#[test]
fn test_iterator_peekable() {
let xs = vec![0, 1, 2, 3, 4, 5];

@ -1 +1 @@
Subproject commit 7d57bdcdbb56540f37afe5a934ce12d33a6ca7fc
Subproject commit cb7f66732175e6171587ed69656b7aae7dd2e6ec

View file

@ -192,6 +192,13 @@
"lifetimes or labels named `'_` were erroneously allowed"
}
declare_lint! {
pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
Warn,
"attempt to resolve a trait on an expression whose type cannot be inferred but which \
currently defaults to ()"
}
declare_lint! {
pub SAFE_EXTERN_STATICS,
Warn,
@ -272,6 +279,7 @@ fn get_lints(&self) -> LintArray {
SUPER_OR_SELF_IN_GLOBAL_PATH,
HR_LIFETIME_IN_ASSOC_TYPE,
LIFETIME_UNDERSCORE,
RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
SAFE_EXTERN_STATICS,
PATTERNS_IN_FNS_WITHOUT_BODY,
EXTRA_REQUIREMENT_IN_IMPL,

View file

@ -1199,7 +1199,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &hir::Pat, op: &mut F) -> McResul
PatKind::Tuple(ref subpats, ddpos) => {
// (p1, ..., pN)
let expected_len = match self.pat_ty(&pat)?.sty {
ty::TyTuple(ref tys) => tys.len(),
ty::TyTuple(ref tys, _) => tys.len(),
ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {

View file

@ -163,7 +163,7 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Opti
let lhs_ty = lhs.ty(mir, tcx);
let rhs_ty = rhs.ty(mir, tcx);
let ty = op.ty(tcx, lhs_ty, rhs_ty);
let ty = tcx.intern_tup(&[ty, tcx.types.bool]);
let ty = tcx.intern_tup(&[ty, tcx.types.bool], false);
Some(ty)
}
&Rvalue::UnaryOp(_, ref operand) => {
@ -184,7 +184,8 @@ pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Opti
}
AggregateKind::Tuple => {
Some(tcx.mk_tup(
ops.iter().map(|op| op.ty(mir, tcx))
ops.iter().map(|op| op.ty(mir, tcx)),
false
))
}
AggregateKind::Adt(def, _, substs, _) => {

View file

@ -52,6 +52,7 @@
use std::rc::Rc;
use syntax::abi::Abi;
use hir;
use lint;
use util::nodemap::FxHashMap;
struct InferredObligationsSnapshotVecDelegate<'tcx> {
@ -407,19 +408,62 @@ pub fn select(&mut self, obligation: &TraitObligation<'tcx>)
debug!("select({:?})", obligation);
assert!(!obligation.predicate.has_escaping_regions());
let tcx = self.tcx();
let dep_node = obligation.predicate.dep_node();
let _task = self.tcx().dep_graph.in_task(dep_node);
let _task = tcx.dep_graph.in_task(dep_node);
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
match self.candidate_from_obligation(&stack)? {
None => Ok(None),
let ret = match self.candidate_from_obligation(&stack)? {
None => None,
Some(candidate) => {
let mut candidate = self.confirm_candidate(obligation, candidate)?;
let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
candidate.nested_obligations_mut().extend(inferred_obligations);
Ok(Some(candidate))
Some(candidate)
},
};
// Test whether this is a `()` which was produced by defaulting a
// diverging type variable with `!` disabled. If so, we may need
// to raise a warning.
if obligation.predicate.skip_binder().self_ty().is_defaulted_unit() {
let mut raise_warning = true;
// Don't raise a warning if the trait is implemented for ! and only
// permits a trivial implementation for !. This stops us warning
// about (for example) `(): Clone` becoming `!: Clone` because such
// a switch can't cause code to stop compiling or execute
// differently.
let mut never_obligation = obligation.clone();
let def_id = never_obligation.predicate.skip_binder().trait_ref.def_id;
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
// Swap out () with ! so we can check if the trait is impld for !
{
let mut trait_ref = &mut trait_pred.trait_ref;
let unit_substs = trait_ref.substs;
let mut never_substs = Vec::with_capacity(unit_substs.len());
never_substs.push(From::from(tcx.types.never));
never_substs.extend(&unit_substs[1..]);
trait_ref.substs = tcx.intern_substs(&never_substs);
}
trait_pred
});
if let Ok(Some(..)) = self.select(&never_obligation) {
if !tcx.trait_relevant_for_never(def_id) {
// The trait is also implemented for ! and the resulting
// implementation cannot actually be invoked in any way.
raise_warning = false;
}
}
if raise_warning {
tcx.sess.add_lint(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
obligation.cause.body_id,
obligation.cause.span,
format!("code relies on type inference rules which are likely \
to change"));
}
}
Ok(ret)
}
///////////////////////////////////////////////////////////////////////////
@ -1744,7 +1788,7 @@ fn sized_conditions(&mut self, obligation: &TraitObligation<'tcx>)
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) => Never,
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
Where(ty::Binder(tys.last().into_iter().cloned().collect()))
}
@ -1752,7 +1796,7 @@ fn sized_conditions(&mut self, obligation: &TraitObligation<'tcx>)
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(ty::Binder(match sized_crit.sty {
ty::TyTuple(tys) => tys.to_vec().subst(self.tcx(), substs),
ty::TyTuple(tys, _) => tys.to_vec().subst(self.tcx(), substs),
ty::TyBool => vec![],
_ => vec![sized_crit.subst(self.tcx(), substs)]
}))
@ -1799,7 +1843,7 @@ fn copy_conditions(&mut self, obligation: &TraitObligation<'tcx>)
Where(ty::Binder(vec![element_ty]))
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
// (*) binder moved here
Where(ty::Binder(tys.to_vec()))
}
@ -1874,7 +1918,7 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
vec![element_ty]
}
ty::TyTuple(ref tys) => {
ty::TyTuple(ref tys, _) => {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
tys.to_vec()
}

View file

@ -489,7 +489,7 @@ pub fn closure_trait_ref_and_return_type(self,
let arguments_tuple = match tuple_arguments {
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
TupleArgumentsFlag::Yes =>
self.intern_tup(sig.skip_binder().inputs()),
self.intern_tup(sig.skip_binder().inputs(), false),
};
let trait_ref = ty::TraitRef {
def_id: fn_trait_def_id,

View file

@ -201,7 +201,7 @@ fn tc_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|ty| tc_ty(tcx, &ty, cache))
}
ty::TyTuple(ref tys) => {
ty::TyTuple(ref tys, _) => {
TypeContents::union(&tys[..],
|ty| tc_ty(tcx, *ty, cache))
}

View file

@ -1384,23 +1384,24 @@ pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> {
self.mk_ty(TySlice(ty))
}
pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
self.mk_ty(TyTuple(self.intern_type_list(ts)))
pub fn intern_tup(self, ts: &[Ty<'tcx>], defaulted: bool) -> Ty<'tcx> {
self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted))
}
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts))))
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I,
defaulted: bool) -> I::Output {
iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted)))
}
pub fn mk_nil(self) -> Ty<'tcx> {
self.intern_tup(&[])
self.intern_tup(&[], false)
}
pub fn mk_diverging_default(self) -> Ty<'tcx> {
if self.sess.features.borrow().never_type {
self.types.never
} else {
self.mk_nil()
self.intern_tup(&[], true)
}
}

View file

@ -178,7 +178,7 @@ pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
match self.sty {
ty::TyBool | ty::TyChar | ty::TyInt(_) |
ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(),
ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(),
ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(),
ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
ty::TyArray(_, n) => format!("array of {} elements", n),
@ -209,7 +209,7 @@ pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
|p| format!("trait {}", tcx.item_path_str(p.def_id())))
}
ty::TyClosure(..) => "closure".to_string(),
ty::TyTuple(_) => "tuple".to_string(),
ty::TyTuple(..) => "tuple".to_string(),
ty::TyInfer(ty::TyVar(_)) => "inferred type".to_string(),
ty::TyInfer(ty::IntVar(_)) => "integral variable".to_string(),
ty::TyInfer(ty::FloatVar(_)) => "floating-point variable".to_string(),

View file

@ -72,7 +72,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
Some(ClosureSimplifiedType(def_id))
}
ty::TyNever => Some(NeverSimplifiedType),
ty::TyTuple(ref tys) => {
ty::TyTuple(ref tys, _) => {
Some(TupleSimplifiedType(tys.len()))
}
ty::TyFnDef(.., ref f) | ty::TyFnPtr(ref f) => {

View file

@ -151,7 +151,7 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
self.add_ty(m.ty);
}
&ty::TyTuple(ref ts) => {
&ty::TyTuple(ref ts, _) => {
self.add_tys(&ts[..]);
}

View file

@ -178,7 +178,7 @@ fn uninhabited_from_inner(
},
TyNever => DefIdForest::full(tcx),
TyTuple(ref tys) => {
TyTuple(ref tys, _) => {
DefIdForest::union(tcx, tys.iter().map(|ty| {
ty.uninhabited_from(visited, tcx)
}))

View file

@ -319,9 +319,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
ty::TyRawPtr(mt) |
ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty),
ty::TyTuple(ref tys) => tys.iter()
.filter_map(|ty| characteristic_def_id_of_type(ty))
.next(),
ty::TyTuple(ref tys, _) => tys.iter()
.filter_map(|ty| characteristic_def_id_of_type(ty))
.next(),
ty::TyFnDef(def_id, ..) |
ty::TyClosure(def_id, _) => Some(def_id),

View file

@ -791,7 +791,7 @@ fn non_zero_field_in_type(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
Some(&variant.memory_index[..]))
}
// Can we use one of the fields in this tuple?
(&Univariant { ref variant, .. }, &ty::TyTuple(tys)) => {
(&Univariant { ref variant, .. }, &ty::TyTuple(tys, _)) => {
Struct::non_zero_field_paths(infcx, tys.iter().cloned(),
Some(&variant.memory_index[..]))
}
@ -1157,7 +1157,7 @@ pub fn compute_uncached(ty: Ty<'gcx>,
Univariant { variant: st, non_zero: false }
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
// FIXME(camlorn): if we ever allow unsized tuples, this needs to be checked.
// See the univariant case below to learn how.
let st = Struct::new(dl,

View file

@ -197,6 +197,17 @@ pub fn def(&self) -> Def {
AssociatedKind::Type => Def::AssociatedTy(self.def_id),
}
}
/// Tests whether the associated item admits a non-trivial implementation
/// for !
pub fn relevant_for_never<'tcx>(&self) -> bool {
match self.kind {
AssociatedKind::Const => true,
AssociatedKind::Type => true,
// FIXME(canndrew): Be more thorough here, check if any argument is uninhabited.
AssociatedKind::Method => !self.method_has_self_argument,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
@ -1603,7 +1614,7 @@ fn calculate_sized_constraint_inner(&self,
_ if tys.references_error() => tcx.types.err,
0 => tcx.types.bool,
1 => tys[0],
_ => tcx.intern_tup(&tys[..])
_ => tcx.intern_tup(&tys[..], false)
};
let old = tcx.adt_sized_constraint.borrow().get(&self.did).cloned();
@ -1638,7 +1649,7 @@ fn sized_constraint_for_ty(&self,
vec![ty]
}
TyTuple(ref tys) => {
TyTuple(ref tys, _) => {
match tys.last() {
None => vec![],
Some(ty) => self.sized_constraint_for_ty(tcx, stack, ty)
@ -1652,7 +1663,7 @@ fn sized_constraint_for_ty(&self,
.subst(tcx, substs);
debug!("sized_constraint_for_ty({:?}) intermediate = {:?}",
ty, adt_ty);
if let ty::TyTuple(ref tys) = adt_ty.sty {
if let ty::TyTuple(ref tys, _) = adt_ty.sty {
tys.iter().flat_map(|ty| {
self.sized_constraint_for_ty(tcx, stack, ty)
}).collect()
@ -2010,6 +2021,12 @@ pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity {
}
}
pub fn trait_relevant_for_never(self, did: DefId) -> bool {
self.associated_items(did).any(|item| {
item.relevant_for_never()
})
}
pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized {
self.custom_coerce_unsized_kinds.memoize(did, || {
let (kind, src) = if did.krate != LOCAL_CRATE {

View file

@ -447,10 +447,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
Ok(tcx.mk_slice(t))
}
(&ty::TyTuple(as_), &ty::TyTuple(bs)) =>
(&ty::TyTuple(as_, a_defaulted), &ty::TyTuple(bs, b_defaulted)) =>
{
if as_.len() == bs.len() {
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?)
let defaulted = a_defaulted || b_defaulted;
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)), defaulted)?)
} else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize(
expected_found(relation, &as_.len(), &bs.len())))

View file

@ -474,7 +474,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
ty::TyDynamic(ref trait_ty, ref region) =>
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)),
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
ty::TyFnDef(def_id, substs, f) => {
ty::TyFnDef(def_id,
substs.fold_with(folder),
@ -511,7 +511,7 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
ty::TyAdt(_, substs) => substs.visit_with(visitor),
ty::TyDynamic(ref trait_ty, ref reg) =>
trait_ty.visit_with(visitor) || reg.visit_with(visitor),
ty::TyTuple(ts) => ts.visit_with(visitor),
ty::TyTuple(ts, _) => ts.visit_with(visitor),
ty::TyFnDef(_, substs, ref f) => {
substs.visit_with(visitor) || f.visit_with(visitor)
}

View file

@ -151,7 +151,11 @@ pub enum TypeVariants<'tcx> {
TyNever,
/// A tuple type. For example, `(i32, bool)`.
TyTuple(&'tcx Slice<Ty<'tcx>>),
/// The bool indicates whether this is a unit tuple and was created by
/// defaulting a diverging type variable with feature(never_type) disabled.
/// It's only purpose is for raising future-compatibility warnings for when
/// diverging type variables start defaulting to ! instead of ().
TyTuple(&'tcx Slice<Ty<'tcx>>, bool),
/// The projection of an associated type. For example,
/// `<T as Trait<..>>::N`.
@ -961,7 +965,7 @@ pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
pub fn is_nil(&self) -> bool {
match self.sty {
TyTuple(ref tys) => tys.is_empty(),
TyTuple(ref tys, _) => tys.is_empty(),
_ => false
}
}
@ -973,6 +977,15 @@ pub fn is_never(&self) -> bool {
}
}
// Test whether this is a `()` which was produced by defaulting a
// diverging type variable with feature(never_type) disabled.
pub fn is_defaulted_unit(&self) -> bool {
match self.sty {
TyTuple(_, true) => true,
_ => false,
}
}
/// Checks whether a type is visibly uninhabited from a particular module.
/// # Example
/// ```rust
@ -1355,7 +1368,7 @@ pub fn regions(&self) -> Vec<&'tcx ty::Region> {
TySlice(_) |
TyRawPtr(_) |
TyNever |
TyTuple(_) |
TyTuple(..) |
TyParam(_) |
TyInfer(_) |
TyError => {

View file

@ -207,7 +207,7 @@ pub fn positional_element_ty(self,
// Don't use `struct_variant`, this may be a univariant enum.
adt.variants[0].fields.get(i).map(|f| f.ty(self, substs))
}
(&TyTuple(ref v), None) => v.get(i).cloned(),
(&TyTuple(ref v, _), None) => v.get(i).cloned(),
_ => None
}
}
@ -466,8 +466,9 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
self.def_id(d);
}
}
TyTuple(tys) => {
TyTuple(tys, defaulted) => {
self.hash(tys.len());
self.hash(defaulted);
}
TyParam(p) => {
self.hash(p.idx);
@ -675,7 +676,7 @@ fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
-> Representability {
match ty.sty {
TyTuple(ref ts) => {
TyTuple(ref ts, _) => {
find_nonrepresentable(tcx, sp, seen, ts.iter().cloned())
}
// Fixed-length vectors.

View file

@ -112,7 +112,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty::TyClosure(_, ref substs) => {
stack.extend(substs.substs.types().rev());
}
ty::TyTuple(ts) => {
ty::TyTuple(ts, _) => {
stack.extend(ts.iter().cloned().rev());
}
ty::TyFnDef(_, substs, ref ft) => {

View file

@ -315,7 +315,7 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
self.require_sized(subty, traits::SliceOrArrayElem);
}
ty::TyTuple(ref tys) => {
ty::TyTuple(ref tys, _) => {
if let Some((_last, rest)) = tys.split_last() {
for elem in rest {
self.require_sized(elem, traits::TupleElem);

View file

@ -156,7 +156,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
let projection_ty = projections[0].ty;
if let TyTuple(ref args) = substs.type_at(1).sty {
if let TyTuple(ref args, _) = substs.type_at(1).sty {
return fn_sig(f, args, false, projection_ty);
}
}
@ -724,7 +724,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", tm)
}
TyNever => write!(f, "!"),
TyTuple(ref tys) => {
TyTuple(ref tys, _) => {
write!(f, "(")?;
let mut tys = tys.iter();
if let Some(&ty) = tys.next() {

View file

@ -22,6 +22,7 @@ pub fn target() -> Result<Target, String> {
linker_is_gnu: true,
allow_asm: false,
obj_is_bitcode: true,
is_like_emscripten: true,
max_atomic_width: Some(32),
post_link_args: vec!["-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],
target_family: Some("unix".to_string()),

View file

@ -330,6 +330,10 @@ pub struct TargetOptions {
/// Whether the target toolchain is like Android's. Only useful for compiling against Android.
/// Defaults to false.
pub is_like_android: bool,
/// Whether the target toolchain is like Emscripten's. Only useful for compiling with
/// Emscripten toolchain.
/// Defaults to false.
pub is_like_emscripten: bool,
/// Whether the linker support GNU-like arguments such as -O. Defaults to false.
pub linker_is_gnu: bool,
/// The MinGW toolchain has a known issue that prevents it from correctly
@ -428,6 +432,7 @@ fn default() -> TargetOptions {
is_like_solaris: false,
is_like_windows: false,
is_like_android: false,
is_like_emscripten: false,
is_like_msvc: false,
linker_is_gnu: false,
allows_weak_linkage: true,
@ -603,6 +608,7 @@ macro_rules! key {
key!(is_like_solaris, bool);
key!(is_like_windows, bool);
key!(is_like_msvc, bool);
key!(is_like_emscripten, bool);
key!(is_like_android, bool);
key!(linker_is_gnu, bool);
key!(allows_weak_linkage, bool);
@ -767,6 +773,7 @@ macro_rules! target_option_val {
target_option_val!(is_like_solaris);
target_option_val!(is_like_windows);
target_option_val!(is_like_msvc);
target_option_val!(is_like_emscripten);
target_option_val!(is_like_android);
target_option_val!(linker_is_gnu);
target_option_val!(allows_weak_linkage);

View file

@ -24,6 +24,7 @@ pub fn target() -> Result<Target, String> {
linker_is_gnu: true,
allow_asm: false,
obj_is_bitcode: true,
is_like_emscripten: true,
max_atomic_width: Some(32),
post_link_args: vec!["-s".to_string(), "BINARYEN=1".to_string(),
"-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],

View file

@ -423,7 +423,7 @@ fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>,
};
match parent_ty.sty {
ty::TyTuple(ref v) => {
ty::TyTuple(ref v, _) => {
let tuple_idx = match *origin_field_name {
mc::PositionalField(tuple_idx) => tuple_idx,
mc::NamedField(_) =>

View file

@ -713,7 +713,7 @@ fn open_drop<'a>(&mut self, c: &DropCtxt<'a, 'tcx>) -> BasicBlock {
let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx).collect();
self.open_drop_for_tuple(c, &tys)
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
self.open_drop_for_tuple(c, tys)
}
ty::TyAdt(def, _) if def.is_box() => {

View file

@ -721,7 +721,7 @@ fn pat_constructors(_cx: &mut MatchCheckCtxt,
fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> usize {
debug!("constructor_arity({:?}, {:?})", ctor, ty);
match ty.sty {
ty::TyTuple(ref fs) => fs.len(),
ty::TyTuple(ref fs, _) => fs.len(),
ty::TySlice(..) | ty::TyArray(..) => match *ctor {
Slice(length) => length,
ConstantValue(_) => 0,
@ -745,7 +745,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
{
debug!("constructor_sub_pattern_tys({:?}, {:?})", ctor, ty);
match ty.sty {
ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(),
ty::TyTuple(ref fs, _) => fs.into_iter().map(|t| *t).collect(),
ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor {
Slice(length) => repeat(ty).take(length).collect(),
ConstantValue(_) => vec![],

View file

@ -342,7 +342,7 @@ pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
PatKind::Tuple(ref subpatterns, ddpos) => {
let ty = self.tables.node_id_to_type(pat.id);
match ty.sty {
ty::TyTuple(ref tys) => {
ty::TyTuple(ref tys, _) => {
let subpatterns =
subpatterns.iter()
.enumerate_and_adjust(tys.len(), ddpos)

View file

@ -280,7 +280,7 @@ pub fn t_nil(&self) -> Ty<'tcx> {
}
pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
self.infcx.tcx.intern_tup(&[ty1, ty2])
self.infcx.tcx.intern_tup(&[ty1, ty2], false)
}
pub fn t_param(&self, index: u32) -> Ty<'tcx> {
@ -803,8 +803,8 @@ fn walk_ty() {
let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize;
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty], false);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty], false);
let walked: Vec<_> = tup2_ty.walk().collect();
assert_eq!(walked,
[tup2_ty, tup1_ty, int_ty, uint_ty, int_ty, uint_ty, tup1_ty, int_ty,
@ -818,8 +818,8 @@ fn walk_ty_skip_subtree() {
let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize;
let uint_ty = tcx.types.usize;
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty]);
let tup1_ty = tcx.intern_tup(&[int_ty, uint_ty, int_ty, uint_ty], false);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, uint_ty], false);
// types we expect to see (in order), plus a boolean saying
// whether to skip the subtree.

View file

@ -219,6 +219,10 @@ macro_rules! add_lint_group {
id: LintId::of(LIFETIME_UNDERSCORE),
reference: "issue #36892 <https://github.com/rust-lang/rust/issues/36892>",
},
FutureIncompatibleInfo {
id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
},
FutureIncompatibleInfo {
id: LintId::of(SAFE_EXTERN_STATICS),
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>",

View file

@ -532,7 +532,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
consider using a `*const libc::c_char`")
}
ty::TyTuple(_) => {
ty::TyTuple(..) => {
FfiUnsafe("found Rust tuple type in foreign module; \
consider using a struct instead")
}

View file

@ -141,7 +141,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
let t = cx.tables.expr_ty(&expr);
let warned = match t.sty {
ty::TyTuple(ref tys) if tys.is_empty() => return,
ty::TyTuple(ref tys, _) if tys.is_empty() => return,
ty::TyNever => return,
ty::TyBool => return,
ty::TyAdt(def, _) => {

View file

@ -584,7 +584,7 @@ fn load_derive_macros(&mut self, root: &CrateRoot, dylib: Option<PathBuf>, span:
use proc_macro::TokenStream;
use proc_macro::__internal::Registry;
use rustc_back::dynamic_lib::DynamicLibrary;
use syntax_ext::deriving::custom::CustomDerive;
use syntax_ext::deriving::custom::ProcMacroDerive;
use syntax_ext::proc_macro_impl::AttrProcMacro;
let path = match dylib {
@ -616,8 +616,8 @@ fn register_custom_derive(&mut self,
expand: fn(TokenStream) -> TokenStream,
attributes: &[&'static str]) {
let attrs = attributes.iter().cloned().map(Symbol::intern).collect();
let derive = SyntaxExtension::CustomDerive(
Box::new(CustomDerive::new(expand, attrs))
let derive = SyntaxExtension::ProcMacroDerive(
Box::new(ProcMacroDerive::new(expand, attrs))
);
self.0.push((Symbol::intern(trait_name), Rc::new(derive)));
}

View file

@ -257,7 +257,7 @@ pub fn build_binary_op(&mut self, mut block: BasicBlock,
let source_info = self.source_info(span);
let bool_ty = self.hir.bool_ty();
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty], false);
let result_value = self.temp(result_tup);
self.cfg.push_assign(block, source_info,

View file

@ -282,7 +282,7 @@ fn field_ty(&mut self,
})
}
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
return match tys.get(field.index()) {
Some(&ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange {

View file

@ -559,7 +559,7 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expa
"an `extern crate` loading macros must be at the crate root");
} else if !self.use_extern_macros && !used &&
self.session.cstore.dep_kind(module.def_id().unwrap().krate).macros_only() {
let msg = "custom derive crates and `#[no_link]` crates have no effect without \
let msg = "proc macro crates and `#[no_link]` crates have no effect without \
`#[macro_use]`";
self.session.span_warn(item.span, msg);
used = true; // Avoid the normal unused extern crate warning

View file

@ -250,6 +250,32 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
}
result
}
fn resolve_builtin_macro(&mut self, tname: Name) -> Result<Rc<SyntaxExtension>, Determinacy> {
match self.builtin_macros.get(&tname).cloned() {
Some(binding) => Ok(binding.get_macro(self)),
None => Err(Determinacy::Undetermined),
}
}
fn resolve_derive_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
-> Result<Rc<SyntaxExtension>, Determinacy> {
let ast::Path { span, .. } = *path;
match self.resolve_macro(scope, path, false) {
Ok(ext) => match *ext {
SyntaxExtension::BuiltinDerive(..) |
SyntaxExtension::ProcMacroDerive(..) => Ok(ext),
_ => Err(Determinacy::Determined),
},
Err(Determinacy::Undetermined) if force => {
let msg = format!("cannot find derive macro `{}` in this scope", path);
let mut err = self.session.struct_span_err(span, &msg);
err.emit();
Err(Determinacy::Determined)
},
Err(err) => Err(err),
}
}
}
impl<'a> Resolver<'a> {

View file

@ -639,7 +639,19 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
if *i == ident { return None; } // Never suggest the same name
match *resolution.borrow() {
NameResolution { binding: Some(_), .. } => Some(&i.name),
NameResolution { binding: Some(name_binding), .. } => {
match name_binding.kind {
NameBindingKind::Import { binding, .. } => {
match binding.kind {
// Never suggest the name that has binding error
// i.e. the name that cannot be previously resolved
NameBindingKind::Def(Def::Err) => return None,
_ => Some(&i.name),
}
},
_ => Some(&i.name),
}
},
NameResolution { single_imports: SingleImports::None, .. } => None,
_ => Some(&i.name),
}

View file

@ -1440,7 +1440,7 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
}.lower(self.tcx));
}
}
ty::TyTuple(_) => {}
ty::TyTuple(..) => {}
_ => span_bug!(ex.span,
"Expected struct or tuple type, found {:?}",
ty),

View file

@ -430,6 +430,9 @@ pub fn get_trait_ref_data(&self,
-> Option<TypeRefData> {
self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| {
let span = trait_ref.path.span;
if generated_code(span) {
return None;
}
let sub_span = self.span_utils.sub_span_for_type_name(span).or(Some(span));
filter!(self.span_utils, sub_span, span, None);
Some(TypeRefData {

View file

@ -367,7 +367,7 @@ pub fn unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
assert!(!sig.variadic && extra_args.is_empty());
match sig.inputs().last().unwrap().sty {
ty::TyTuple(ref tupled_arguments) => {
ty::TyTuple(ref tupled_arguments, _) => {
inputs = &sig.inputs()[0..sig.inputs().len() - 1];
&tupled_arguments[..]
}

View file

@ -72,7 +72,7 @@ pub fn compute_fields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
monomorphize::field_ty(cx.tcx(), substs, f)
}).collect::<Vec<_>>()
},
ty::TyTuple(fields) => fields.to_vec(),
ty::TyTuple(fields, _) => fields.to_vec(),
ty::TyClosure(def_id, substs) => {
if variant_index > 0 { bug!("{} is a closure, which only has one variant", t);}
substs.upvar_tys(def_id, cx.tcx()).collect()

View file

@ -29,6 +29,7 @@
use rustc::hir::def_id::CrateNum;
use rustc::hir::svh::Svh;
use rustc_back::tempdir::TempDir;
use rustc_back::PanicStrategy;
use rustc_incremental::IncrementalHashesMap;
use std::ascii;
@ -714,6 +715,11 @@ fn link_natively(sess: &Session,
cmd.arg(root.join(obj));
}
if sess.target.target.options.is_like_emscripten &&
sess.panic_strategy() == PanicStrategy::Abort {
cmd.args(&["-s", "DISABLE_EXCEPTION_CATCHING=1"]);
}
{
let mut linker = trans.linker_info.to_linker(&mut cmd, &sess);
link_args(&mut *linker, sess, crate_type, tmpdir,

View file

@ -485,7 +485,7 @@ fn trans_fn_pointer_shim<'a, 'tcx>(
}
};
let sig = tcx.erase_late_bound_regions_and_normalize(sig);
let tuple_input_ty = tcx.intern_tup(sig.inputs());
let tuple_input_ty = tcx.intern_tup(sig.inputs(), false);
let sig = tcx.mk_fn_sig(
[bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(),
sig.output(),

View file

@ -823,7 +823,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
output.push(TransItem::DropGlue(DropGlueKind::Ty(inner_type)));
}
}
ty::TyTuple(args) => {
ty::TyTuple(args, _) => {
for arg in args {
let arg = glue::get_drop_glue_type(scx, arg);
if scx.type_needs_drop(arg) {

View file

@ -93,7 +93,7 @@ pub fn type_pair_fields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
}
}))
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
if tys.len() != 2 {
return None;
}

View file

@ -383,7 +383,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// return type
signature_metadata.push(match signature.output().sty {
ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(),
_ => type_metadata(cx, signature.output(), span)
});
@ -528,7 +528,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ty::TyFloat(_) => {
MetadataCreationResult::new(basic_type_metadata(cx, t), false)
}
ty::TyTuple(ref elements) if elements.is_empty() => {
ty::TyTuple(ref elements, _) if elements.is_empty() => {
MetadataCreationResult::new(basic_type_metadata(cx, t), false)
}
ty::TyArray(typ, len) => {
@ -603,7 +603,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
usage_site_span).finalize(cx)
}
},
ty::TyTuple(ref elements) => {
ty::TyTuple(ref elements, _) => {
prepare_tuple_metadata(cx,
t,
&elements[..],
@ -706,7 +706,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let (name, encoding) = match t.sty {
ty::TyNever => ("!", DW_ATE_unsigned),
ty::TyTuple(ref elements) if elements.is_empty() =>
ty::TyTuple(ref elements, _) if elements.is_empty() =>
("()", DW_ATE_unsigned),
ty::TyBool => ("bool", DW_ATE_boolean),
ty::TyChar => ("char", DW_ATE_unsigned_char),

View file

@ -295,7 +295,7 @@ fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Return type -- llvm::DIBuilder wants this at index 0
signature.push(match sig.output().sty {
ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(),
_ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)
});
@ -311,7 +311,7 @@ fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}
if abi == Abi::RustCall && !sig.inputs().is_empty() {
if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
if let ty::TyTuple(args, _) = sig.inputs()[sig.inputs().len() - 1].sty {
for &argument_type in args {
signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP));
}

View file

@ -48,7 +48,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
push_item_name(cx, def.did, qualified, output);
push_type_params(cx, substs, output);
},
ty::TyTuple(component_types) => {
ty::TyTuple(component_types, _) => {
output.push('(');
for &component_type in component_types {
push_debuginfo_type_name(cx, component_type, true, output);

View file

@ -442,7 +442,7 @@ fn iter_variant_fields<'a, 'tcx>(
cx = tvec::slice_for_each(&cx, ptr.llval, unit_ty, ptr.llextra,
|bb, vv| drop_ty(bb, LvalueRef::new_sized_ty(vv, unit_ty)));
}
ty::TyTuple(ref args) => {
ty::TyTuple(ref args, _) => {
for (i, arg) in args.iter().enumerate() {
let llfld_a = ptr.trans_field_ptr(&cx, i);
drop_ty(&cx, LvalueRef::new_sized_ty(llfld_a, *arg));

View file

@ -695,7 +695,7 @@ fn trans_arguments_untupled(&mut self,
let tuple = self.trans_operand(bcx, operand);
let arg_types = match tuple.ty.sty {
ty::TyTuple(ref tys) => tys,
ty::TyTuple(ref tys, _) => tys,
_ => span_bug!(self.mir.span,
"bad final argument to \"rust-call\" fn {:?}", tuple.ty)
};

View file

@ -735,7 +735,7 @@ fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>,
let rhs = self.const_operand(rhs, span)?;
let ty = lhs.ty;
let val_ty = op.ty(tcx, lhs.ty, rhs.ty);
let binop_ty = tcx.intern_tup(&[val_ty, tcx.types.bool]);
let binop_ty = tcx.intern_tup(&[val_ty, tcx.types.bool], false);
let (lhs, rhs) = (lhs.llval, rhs.llval);
assert!(!ty.is_fp());

View file

@ -384,7 +384,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
// individual LLVM function arguments.
let tupled_arg_tys = match arg_ty.sty {
ty::TyTuple(ref tys) => tys,
ty::TyTuple(ref tys, _) => tys,
_ => bug!("spread argument isn't a tuple?!")
};

View file

@ -402,7 +402,7 @@ pub fn trans_rvalue_operand(&mut self,
lhs.immediate(), rhs.immediate(),
lhs.ty);
let val_ty = op.ty(bcx.tcx(), lhs.ty, rhs.ty);
let operand_ty = bcx.tcx().intern_tup(&[val_ty, bcx.tcx().types.bool]);
let operand_ty = bcx.tcx().intern_tup(&[val_ty, bcx.tcx().types.bool], false);
let operand = OperandRef {
val: result,
ty: operand_ty

View file

@ -409,7 +409,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
self.push_def_path(adt_def.did, output);
self.push_type_params(substs, iter::empty(), output);
},
ty::TyTuple(component_types) => {
ty::TyTuple(component_types, _) => {
output.push('(');
for &component_type in component_types {
self.push_type_name(component_type, output);

View file

@ -74,7 +74,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
Type::array(&llty, size)
}
ty::TyTuple(ref tys) if tys.is_empty() => {
ty::TyTuple(ref tys, _) if tys.is_empty() => {
Type::nil(cx)
}
@ -276,7 +276,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
let sig = cx.tcx().erase_late_bound_regions_and_normalize(&f.sig);
FnType::new(cx, f.abi, &sig, &[]).llvm_type(cx).ptr_to()
}
ty::TyTuple(ref tys) if tys.is_empty() => Type::nil(cx),
ty::TyTuple(ref tys, _) if tys.is_empty() => Type::nil(cx),
ty::TyTuple(..) => {
adt::type_of(cx, t)
}

View file

@ -421,7 +421,7 @@ fn convert_parenthesized_parameters(&self,
span: output_span
};
(self.tcx().mk_ty(ty::TyTuple(inputs)), output_binding)
(self.tcx().mk_ty(ty::TyTuple(inputs, false)), output_binding)
}
/// Instantiates the path for the given trait reference, assuming that it's
@ -1170,7 +1170,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
tcx.types.never
},
hir::TyTup(ref fields) => {
tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)))
tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false)
}
hir::TyBareFn(ref bf) => {
require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);

View file

@ -164,7 +164,7 @@ pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: boo
let mut expected_len = elements.len();
if ddpos.is_some() {
// Require known type only when `..` is present
if let ty::TyTuple(ref tys) =
if let ty::TyTuple(ref tys, _) =
self.structurally_resolved_type(pat.span, expected).sty {
expected_len = tys.len();
}
@ -176,7 +176,7 @@ pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: boo
// from all tuple elements isn't trivial.
TypeVariableOrigin::TypeInference(pat.span)));
let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys));
let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false));
self.demand_eqtype(pat.span, expected, pat_ty);
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat(elem, &element_tys[i]);

View file

@ -89,7 +89,7 @@ fn check_closure(&self,
// Tuple up the arguments and insert the resulting function type into
// the `closures` table.
fn_ty.sig.0 = self.tcx.mk_fn_sig(
iter::once(self.tcx.intern_tup(fn_ty.sig.skip_binder().inputs())),
iter::once(self.tcx.intern_tup(fn_ty.sig.skip_binder().inputs(), false)),
fn_ty.sig.skip_binder().output(),
fn_ty.sig.variadic()
);
@ -218,7 +218,7 @@ fn deduce_sig_from_projection(&self,
arg_param_ty);
let input_tys = match arg_param_ty.sty {
ty::TyTuple(tys) => tys.into_iter(),
ty::TyTuple(tys, _) => tys.into_iter(),
_ => {
return None;
}

View file

@ -489,7 +489,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
Ok(())
}
ty::TyTuple(tys) => {
ty::TyTuple(tys, _) => {
for ty in tys {
iterate_over_potentially_unsafe_regions_in_type(cx, context, ty, depth+1)?
}

View file

@ -87,7 +87,7 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
"cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(ccx, 0)),
param(ccx, 0),
param(ccx, 0)],
tcx.intern_tup(&[param(ccx, 0), tcx.types.bool])),
tcx.intern_tup(&[param(ccx, 0), tcx.types.bool], false)),
"load" => (1, vec![tcx.mk_imm_ptr(param(ccx, 0))],
param(ccx, 0)),
"store" => (1, vec![tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)],
@ -272,7 +272,7 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" =>
(1, vec![param(ccx, 0), param(ccx, 0)],
tcx.intern_tup(&[param(ccx, 0), tcx.types.bool])),
tcx.intern_tup(&[param(ccx, 0), tcx.types.bool], false)),
"unchecked_div" | "unchecked_rem" =>
(1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
@ -420,7 +420,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
match *expected {
Void => match t.sty {
ty::TyTuple(ref v) if v.is_empty() => {},
ty::TyTuple(ref v, _) if v.is_empty() => {},
_ => simple_error(&format!("`{}`", t), "()"),
},
// (The width we pass to LLVM doesn't concern the type checker.)
@ -494,7 +494,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
}
Aggregate(_flatten, ref expected_contents) => {
match t.sty {
ty::TyTuple(contents) => {
ty::TyTuple(contents, _) => {
if contents.len() != expected_contents.len() {
simple_error(&format!("tuple with length {}", contents.len()),
&format!("tuple with length {}", expected_contents.len()));

View file

@ -1947,7 +1947,9 @@ fn check_casts(&self) {
}
/// Apply "fallbacks" to some types
/// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
/// unconstrained types get replaced with ! or () (depending on whether
/// feature(never_type) is enabled), unconstrained ints with i32, and
/// unconstrained floats with f64.
fn default_type_parameters(&self) {
use rustc::ty::error::UnconstrainedNumeric::Neither;
use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
@ -2408,7 +2410,7 @@ fn check_method_argument_types(&self,
let err_inputs = match tuple_arguments {
DontTupleArguments => err_inputs,
TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)],
};
self.check_argument_types(sp, &err_inputs[..], &[], args_no_rcvr,
@ -2505,16 +2507,16 @@ fn parameter_count_error<'tcx>(sess: &Session, sp: Span, expected_count: usize,
let formal_tys = if tuple_arguments == TupleArguments {
let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
match tuple_type.sty {
ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => {
parameter_count_error(tcx.sess, sp_args, arg_types.len(), args.len(),
"E0057", false, def_span);
expected_arg_tys = &[];
self.err_args(args.len())
}
ty::TyTuple(arg_types) => {
ty::TyTuple(arg_types, _) => {
expected_arg_tys = match expected_arg_tys.get(0) {
Some(&ty) => match ty.sty {
ty::TyTuple(ref tys) => &tys,
ty::TyTuple(ref tys, _) => &tys,
_ => &[]
},
None => &[]
@ -3072,7 +3074,7 @@ fn check_tup_field(&self,
}
})
}
ty::TyTuple(ref v) => {
ty::TyTuple(ref v, _) => {
tuple_like = true;
v.get(idx.node).cloned()
}
@ -3864,7 +3866,7 @@ fn check_expr_kind(&self,
hir::ExprTup(ref elts) => {
let flds = expected.only_has_type(self).and_then(|ty| {
match ty.sty {
ty::TyTuple(ref flds) => Some(&flds[..]),
ty::TyTuple(ref flds, _) => Some(&flds[..]),
_ => None
}
});
@ -3882,7 +3884,7 @@ fn check_expr_kind(&self,
};
t
});
let tuple = tcx.mk_tup(elt_ts_iter);
let tuple = tcx.mk_tup(elt_ts_iter, false);
if tuple.references_error() {
tcx.types.err
} else {
@ -3923,7 +3925,7 @@ fn check_expr_kind(&self,
},
base_t);
// Try to give some advice about indexing tuples.
if let ty::TyTuple(_) = base_t.sty {
if let ty::TyTuple(..) = base_t.sty {
let mut needs_note = true;
// If the index is an integer, we can show the actual
// fixed expression:

View file

@ -338,7 +338,7 @@ fn add_constraints_from_ty(&mut self,
self.add_constraints_from_mt(generics, mt, variance);
}
ty::TyTuple(subtys) => {
ty::TyTuple(subtys, _) => {
for &subty in subtys {
self.add_constraints_from_ty(generics, subty, variance);
}

View file

@ -655,7 +655,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
Some(did) if cx.tcx.lang_items.fn_trait_kind(did).is_some() => {
assert_eq!(types.len(), 1);
let inputs = match types[0].sty {
ty::TyTuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
ty::TyTuple(ref tys, _) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => {
return PathParameters::AngleBracketed {
lifetimes: lifetimes,
@ -667,7 +667,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
let output = None;
// FIXME(#20299) return type comes from a projection now
// match types[1].sty {
// ty::TyTuple(ref v) if v.is_empty() => None, // -> ()
// ty::TyTuple(ref v, _) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx))
// };
PathParameters::Parenthesized {
@ -710,7 +710,7 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
// collect any late bound regions
let mut late_bounds = vec![];
for ty_s in self.input_types().skip(1) {
if let ty::TyTuple(ts) = ty_s.sty {
if let ty::TyTuple(ts, _) = ty_s.sty {
for &ty_s in ts {
if let ty::TyRef(ref reg, _) = ty_s.sty {
if let &ty::Region::ReLateBound(..) = *reg {
@ -1895,7 +1895,7 @@ fn clean(&self, cx: &DocContext) -> Type {
Never
}
}
ty::TyTuple(ref t) => Tuple(t.clean(cx)),
ty::TyTuple(ref t, _) => Tuple(t.clean(cx)),
ty::TyProjection(ref data) => data.clean(cx),

View file

@ -193,7 +193,7 @@ pub fn main_args(args: &[String]) -> isize {
nightly_options::check_nightly_options(&matches, &opts());
if matches.opt_present("h") || matches.opt_present("help") {
usage(&args[0]);
usage("rustdoc");
return 0;
} else if matches.opt_present("version") {
rustc_driver::version("rustdoc", &matches);

View file

@ -399,7 +399,7 @@ impl ExactSizeIterator for EscapeDefault {}
#[unstable(feature = "fused", issue = "35602")]
impl FusedIterator for EscapeDefault {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for EscapeDefault {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("EscapeDefault { .. }")

View file

@ -1283,7 +1283,7 @@ fn clone(&self) -> Iter<'a, K, V> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
@ -1318,7 +1318,7 @@ fn clone(&self) -> Keys<'a, K, V> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K: Debug, V: Debug> fmt::Debug for Keys<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
@ -1341,7 +1341,7 @@ fn clone(&self) -> Values<'a, K, V> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K: Debug, V: Debug> fmt::Debug for Values<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
@ -1591,7 +1591,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for IterMut<'a, K, V> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K, V> fmt::Debug for IterMut<'a, K, V>
where K: fmt::Debug,
V: fmt::Debug,
@ -1626,7 +1626,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<K, V> FusedIterator for IntoIter<K, V> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<K: Debug, V: Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
@ -1704,7 +1704,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for ValuesMut<'a, K, V> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K, V> fmt::Debug for ValuesMut<'a, K, V>
where K: fmt::Debug,
V: fmt::Debug,
@ -1739,7 +1739,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K, V> FusedIterator for Drain<'a, K, V> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K, V> fmt::Debug for Drain<'a, K, V>
where K: fmt::Debug,
V: fmt::Debug,
@ -2227,7 +2227,7 @@ fn default() -> RandomState {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for RandomState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("RandomState { .. }")

View file

@ -948,7 +948,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Iter<'a, K> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K: fmt::Debug> fmt::Debug for Iter<'a, K> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
@ -977,7 +977,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<K> FusedIterator for IntoIter<K> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<K: fmt::Debug> fmt::Debug for IntoIter<K> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
@ -1007,7 +1007,7 @@ fn len(&self) -> usize {
#[unstable(feature = "fused", issue = "35602")]
impl<'a, K> FusedIterator for Drain<'a, K> {}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
@ -1050,7 +1050,7 @@ fn size_hint(&self) -> (usize, Option<usize>) {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T, S> fmt::Debug for Intersection<'a, T, S>
where T: fmt::Debug + Eq + Hash,
S: BuildHasher,
@ -1109,7 +1109,7 @@ impl<'a, T, S> FusedIterator for Difference<'a, T, S>
{
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T, S> fmt::Debug for Difference<'a, T, S>
where T: fmt::Debug + Eq + Hash,
S: BuildHasher,
@ -1150,7 +1150,7 @@ impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S>
{
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S>
where T: fmt::Debug + Eq + Hash,
S: BuildHasher,
@ -1176,7 +1176,7 @@ impl<'a, T, S> FusedIterator for Union<'a, T, S>
{
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T, S> fmt::Debug for Union<'a, T, S>
where T: fmt::Debug + Eq + Hash,
S: BuildHasher,

View file

@ -145,7 +145,7 @@ fn next(&mut self) -> Option<(String, String)> {
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Vars {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Vars { .. }")
@ -159,7 +159,7 @@ fn next(&mut self) -> Option<(OsString, OsString)> { self.inner.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for VarsOs {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("VarsOs { .. }")
@ -382,7 +382,7 @@ fn next(&mut self) -> Option<PathBuf> { self.inner.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a> fmt::Debug for SplitPaths<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("SplitPaths { .. }")
@ -665,7 +665,7 @@ fn next_back(&mut self) -> Option<String> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Args {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Args { .. }")
@ -690,7 +690,7 @@ impl DoubleEndedIterator for ArgsOs {
fn next_back(&mut self) -> Option<OsString> { self.inner.next_back() }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ArgsOs {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("ArgsOs { .. }")

View file

@ -869,7 +869,7 @@ pub fn created(&self) -> io::Result<SystemTime> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Metadata")

View file

@ -1450,7 +1450,7 @@ pub struct Chain<T, U> {
done_first: bool,
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<T: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Chain")

View file

@ -282,7 +282,7 @@ pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stdin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Stdin { .. }")
@ -321,7 +321,7 @@ fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
fn consume(&mut self, n: usize) { self.inner.consume(n) }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a> fmt::Debug for StdinLock<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("StdinLock { .. }")
@ -438,7 +438,7 @@ pub fn lock(&self) -> StdoutLock {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stdout {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Stdout { .. }")
@ -470,7 +470,7 @@ fn flush(&mut self) -> io::Result<()> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a> fmt::Debug for StdoutLock<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("StdoutLock { .. }")
@ -573,7 +573,7 @@ pub fn lock(&self) -> StderrLock {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stderr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Stderr { .. }")
@ -605,7 +605,7 @@ fn flush(&mut self) -> io::Result<()> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a> fmt::Debug for StderrLock<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("StderrLock { .. }")

View file

@ -98,7 +98,7 @@ fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
fn consume(&mut self, _n: usize) {}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Empty {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Empty { .. }")
@ -141,7 +141,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Repeat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Repeat { .. }")
@ -180,7 +180,7 @@ fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Sink {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Sink { .. }")

View file

@ -277,6 +277,7 @@
#![feature(oom)]
#![feature(optin_builtin_traits)]
#![feature(panic_unwind)]
#![feature(peek)]
#![feature(placement_in_syntax)]
#![feature(prelude_import)]
#![feature(pub_restricted)]

View file

@ -106,7 +106,10 @@ impl Iterator for LookupHost {
fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
iterator and returning socket \
addresses",
issue = "27705")]
impl fmt::Debug for LookupHost {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("LookupHost { .. }")

View file

@ -296,6 +296,29 @@ pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
self.0.write_timeout()
}
/// Receives data on the socket from the remote adress to which it is
/// connected, without removing that data from the queue. On success,
/// returns the number of bytes peeked.
///
/// Successive calls return the same data. This is accomplished by passing
/// `MSG_PEEK` as a flag to the underlying `recv` system call.
///
/// # Examples
///
/// ```no_run
/// #![feature(peek)]
/// use std::net::TcpStream;
///
/// let stream = TcpStream::connect("127.0.0.1:8000")
/// .expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// let len = stream.peek(&mut buf).expect("peek failed");
/// ```
#[unstable(feature = "peek", issue = "38980")]
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.peek(buf)
}
/// Sets the value of the `TCP_NODELAY` option on this socket.
///
/// If set, this option disables the Nagle algorithm. This means that
@ -1406,4 +1429,35 @@ fn set_nonblocking() {
Err(e) => panic!("unexpected error {}", e),
}
}
#[test]
fn peek() {
each_ip(&mut |addr| {
let (txdone, rxdone) = channel();
let srv = t!(TcpListener::bind(&addr));
let _t = thread::spawn(move|| {
let mut cl = t!(srv.accept()).0;
cl.write(&[1,3,3,7]).unwrap();
t!(rxdone.recv());
});
let mut c = t!(TcpStream::connect(&addr));
let mut b = [0; 10];
for _ in 1..3 {
let len = c.peek(&mut b).unwrap();
assert_eq!(len, 4);
}
let len = c.read(&mut b).unwrap();
assert_eq!(len, 4);
t!(c.set_nonblocking(true));
match c.peek(&mut b) {
Ok(_) => panic!("expected error"),
Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
Err(e) => panic!("unexpected error {}", e),
}
t!(txdone.send(()));
})
}
}

View file

@ -83,6 +83,30 @@ pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.0.recv_from(buf)
}
/// Receives data from the socket, without removing it from the queue.
///
/// Successive calls return the same data. This is accomplished by passing
/// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
///
/// On success, returns the number of bytes peeked and the address from
/// whence the data came.
///
/// # Examples
///
/// ```no_run
/// #![feature(peek)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
/// .expect("Didn't receive data");
/// ```
#[unstable(feature = "peek", issue = "38980")]
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.0.peek_from(buf)
}
/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
@ -579,6 +603,37 @@ pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.recv(buf)
}
/// Receives data on the socket from the remote adress to which it is
/// connected, without removing that data from the queue. On success,
/// returns the number of bytes peeked.
///
/// Successive calls return the same data. This is accomplished by passing
/// `MSG_PEEK` as a flag to the underlying `recv` system call.
///
/// # Errors
///
/// This method will fail if the socket is not connected. The `connect` method
/// will connect this socket to a remote address.
///
/// # Examples
///
/// ```no_run
/// #![feature(peek)]
/// use std::net::UdpSocket;
///
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.connect("127.0.0.1:8080").expect("connect function failed");
/// let mut buf = [0; 10];
/// match socket.peek(&mut buf) {
/// Ok(received) => println!("received {} bytes", received),
/// Err(e) => println!("peek function failed: {:?}", e),
/// }
/// ```
#[unstable(feature = "peek", issue = "38980")]
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.peek(buf)
}
/// Moves this UDP socket into or out of nonblocking mode.
///
/// On Unix this corresponds to calling fcntl, and on Windows this
@ -869,6 +924,48 @@ fn connect_send_recv() {
assert_eq!(b"hello world", &buf[..]);
}
#[test]
fn connect_send_peek_recv() {
each_ip(&mut |addr, _| {
let socket = t!(UdpSocket::bind(&addr));
t!(socket.connect(addr));
t!(socket.send(b"hello world"));
for _ in 1..3 {
let mut buf = [0; 11];
let size = t!(socket.peek(&mut buf));
assert_eq!(b"hello world", &buf[..]);
assert_eq!(size, 11);
}
let mut buf = [0; 11];
let size = t!(socket.recv(&mut buf));
assert_eq!(b"hello world", &buf[..]);
assert_eq!(size, 11);
})
}
#[test]
fn peek_from() {
each_ip(&mut |addr, _| {
let socket = t!(UdpSocket::bind(&addr));
t!(socket.send_to(b"hello world", &addr));
for _ in 1..3 {
let mut buf = [0; 11];
let (size, _) = t!(socket.peek_from(&mut buf));
assert_eq!(b"hello world", &buf[..]);
assert_eq!(size, 11);
}
let mut buf = [0; 11];
let (size, _) = t!(socket.recv_from(&mut buf));
assert_eq!(b"hello world", &buf[..]);
assert_eq!(size, 11);
})
}
#[test]
fn ttl() {
let ttl = 100;

View file

@ -73,7 +73,7 @@ pub enum c_void {
#[doc(hidden)] __variant2,
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for c_void {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("c_void")

View file

@ -297,7 +297,7 @@ extern "rust-call" fn call_once(self, _args: ()) -> R {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("AssertUnwindSafe")

View file

@ -114,7 +114,7 @@ impl IntoInner<imp::Process> for Child {
fn into_inner(self) -> imp::Process { self.handle }
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Child {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Child")
@ -160,7 +160,7 @@ fn from_inner(pipe: AnonPipe) -> ChildStdin {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStdin {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("ChildStdin { .. }")
@ -201,7 +201,7 @@ fn from_inner(pipe: AnonPipe) -> ChildStdout {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStdout {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("ChildStdout { .. }")
@ -242,7 +242,7 @@ fn from_inner(pipe: AnonPipe) -> ChildStderr {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for ChildStderr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("ChildStderr { .. }")
@ -696,7 +696,7 @@ fn from_inner(inner: imp::Stdio) -> Stdio {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Stdio {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Stdio { .. }")
@ -959,10 +959,27 @@ pub fn wait_with_output(mut self) -> io::Result<Output> {
///
/// # Examples
///
/// ```
/// use std::process;
/// Due to this functions behavior regarding destructors, a conventional way
/// to use the function is to extract the actual computation to another
/// function and compute the exit code from its return value:
///
/// process::exit(0);
/// ```
/// use std::io::{self, Write};
///
/// fn run_app() -> Result<(), ()> {
/// // Application logic here
/// Ok(())
/// }
///
/// fn main() {
/// ::std::process::exit(match run_app() {
/// Ok(_) => 0,
/// Err(err) => {
/// writeln!(io::stderr(), "error: {:?}", err).unwrap();
/// 1
/// }
/// });
/// }
/// ```
///
/// Due to [platform-specific behavior], the exit code for this example will be

View file

@ -55,7 +55,7 @@ struct BarrierState {
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BarrierWaitResult(bool);
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Barrier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Barrier { .. }")
@ -110,7 +110,7 @@ pub fn wait(&self) -> BarrierWaitResult {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for BarrierWaitResult {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("BarrierWaitResult")

View file

@ -240,7 +240,7 @@ fn verify(&self, mutex: &sys_mutex::Mutex) {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for Condvar {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Condvar { .. }")

View file

@ -428,7 +428,7 @@ fn drop(&mut self) {
}
}
#[stable(feature = "std_debug", since = "1.15.0")]
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("MutexGuard")

Some files were not shown because too many files have changed in this diff Show more