Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #47984

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
112feb9
update trpl
steveklabnik Jan 25, 2018
c83566e
update reference
steveklabnik Jan 26, 2018
b9f7564
Do not ignore lifetime bounds in Copy impls
spastorino Jan 30, 2018
a99b5db
stabilize match_beginning_vert
goodmanjonathan Jan 30, 2018
5985b0b
wherein the parens lint keeps its own counsel re args in nested macros
zackmdavis Jan 31, 2018
6284b20
update mdbook to 0.1.2
steveklabnik Jan 25, 2018
e2de8de
Enable stack-probe tests with system LLVM >= 5.0
cuviper Jan 31, 2018
55b54a9
Use a range to identify SIGSEGV in stack guards
cuviper Jan 31, 2018
1fe0a8b
Implement TrustedLen for Take<Repeat> and Take<RangeFrom>
oberien Jan 18, 2018
ba78382
TrustedLen for Repeat / RangeFrom test cases
oberien Feb 2, 2018
45e63ae
Add optimization codegen test
oberien Feb 2, 2018
91e3678
Ignore long CHECK line length
oberien Feb 2, 2018
f56ebc5
Make codegen test more sophisticated
oberien Feb 2, 2018
fa84cc4
Add diverging case to TrustedLen doc
oberien Feb 2, 2018
ee8b4ca
Use CHECK-NEXT for codegen test
oberien Feb 2, 2018
cc68afb
ui tests: diff from old (expected) to new (actual) instead of backwards.
eddyb Feb 3, 2018
6b35d81
Fix const evaluation ICE in rustdoc
GuillaumeGomez Jan 29, 2018
abb162c
add exceptions for new deps
steveklabnik Feb 3, 2018
d597da3
Clarify shared file handler behavior of File::try_clone.
frewsxcv Feb 2, 2018
feeeedc
Rollup merge of #47753 - steveklabnik:update-book, r=alexcrichton
kennytm Feb 3, 2018
867f0b8
Rollup merge of #47862 - GuillaumeGomez:const-evaluation-ice, r=eddyb
kennytm Feb 3, 2018
c2d590f
Rollup merge of #47877 - spastorino:lifetime-bounds-in-copy, r=nikoma…
kennytm Feb 3, 2018
1b92783
Rollup merge of #47896 - zackmdavis:and_the_case_of_the_necessary_unn…
kennytm Feb 3, 2018
eb3b870
Rollup merge of #47912 - cuviper:glibc-stack-guard, r=alexcrichton
kennytm Feb 3, 2018
4655895
Rollup merge of #47944 - oberien:unboundediterator-trustedlen, r=bluss
kennytm Feb 3, 2018
ee3e9ac
Rollup merge of #47947 - goodmanjonathan:stabilize_match_beginning_ve…
kennytm Feb 3, 2018
b1bab59
Rollup merge of #47978 - eddyb:iu, r=kennytm
kennytm Feb 3, 2018
ec010ae
Rollup merge of #47958 - frewsxcv:frewsxcv-try-clone, r=aidanhs
kennytm Feb 3, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 92 additions & 54 deletions src/Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 122 files
2 changes: 1 addition & 1 deletion src/doc/reference

This file was deleted.

49 changes: 39 additions & 10 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2286,16 +2286,7 @@ impl<I> Iterator for Take<I> where I: Iterator{

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.iter.size_hint();

let lower = cmp::min(lower, self.n);

let upper = match upper {
Some(x) if x < self.n => Some(x),
_ => Some(self.n)
};

(lower, upper)
TakeImpl::size_hint(self)
}

#[inline]
Expand All @@ -2316,12 +2307,50 @@ impl<I> Iterator for Take<I> where I: Iterator{
}
}

trait TakeImpl {
fn size_hint(&self) -> (usize, Option<usize>);
}

impl<I: Iterator> TakeImpl for Take<I> {
#[inline]
default fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.iter.size_hint();

let lower = cmp::min(lower, self.n);

let upper = match upper {
Some(x) if x < self.n => Some(x),
_ => Some(self.n)
};

(lower, upper)
}
}

impl<I: TrustedLen> TakeImpl for Take<I> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.iter.size_hint();
match upper {
None => (self.n, Some(self.n)),
Some(x) => {
debug_assert_eq!(x, lower);
let count = cmp::min(lower, self.n);
(count, Some(count))
}
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}

#[unstable(feature = "fused", issue = "35602")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}

/// An iterator to maintain state while iterating another iterator.
///
/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
type Item = A;
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
#[unstable(feature = "fused", issue = "35602")]
impl<A: Clone> FusedIterator for Repeat<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over and over and
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/iter/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,8 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
/// The upper bound must only be [`None`] if the actual iterator length is
/// larger than [`usize::MAX`].
///
/// The iterator must produce exactly the number of elements it reported.
/// The iterator must produce exactly the number of elements it reported
/// or diverge before reaching the end.
///
/// # Safety
///
Expand Down
43 changes: 43 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,29 @@ fn test_range_from_nth() {
assert_eq!(r, 16..);
assert_eq!(r.nth(10), Some(26));
assert_eq!(r, 27..);

assert_eq!((0..).size_hint(), (usize::MAX, None));
}

fn is_trusted_len<I: TrustedLen>(_: I) {}

#[test]
fn test_range_from_take() {
let mut it = (0..).take(3);
assert_eq!(it.next(), Some(0));
assert_eq!(it.next(), Some(1));
assert_eq!(it.next(), Some(2));
assert_eq!(it.next(), None);
is_trusted_len((0..).take(3));
assert_eq!((0..).take(3).size_hint(), (3, Some(3)));
assert_eq!((0..).take(0).size_hint(), (0, Some(0)));
assert_eq!((0..).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
}

#[test]
fn test_range_from_take_collect() {
let v: Vec<_> = (0..).take(3).collect();
assert_eq!(v, vec![0, 1, 2]);
}

#[test]
Expand Down Expand Up @@ -1465,6 +1488,26 @@ fn test_repeat() {
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
assert_eq!(repeat(42).size_hint(), (usize::MAX, None));
}

#[test]
fn test_repeat_take() {
let mut it = repeat(42).take(3);
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), Some(42));
assert_eq!(it.next(), None);
is_trusted_len(repeat(42).take(3));
assert_eq!(repeat(42).take(3).size_hint(), (3, Some(3)));
assert_eq!(repeat(42).take(0).size_hint(), (0, Some(0)));
assert_eq!(repeat(42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
}

#[test]
fn test_repeat_take_collect() {
let v: Vec<_> = repeat(42).take(3).collect();
assert_eq!(v, vec![42, 42, 42]);
}

#[test]
Expand Down
37 changes: 28 additions & 9 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,38 @@ impl EarlyLintPass for UnusedParens {
Assign(_, ref value) => (value, "assigned value", false),
AssignOp(.., ref value) => (value, "assigned value", false),
InPlace(_, ref value) => (value, "emplacement value", false),
Call(_, ref args) => {
for arg in args {
self.check_unused_parens_core(cx, arg, "function argument", false)
// either function/method call, or something this lint doesn't care about
ref call_or_other => {
let args_to_check;
let call_kind;
match *call_or_other {
Call(_, ref args) => {
call_kind = "function";
args_to_check = &args[..];
},
MethodCall(_, ref args) => {
call_kind = "method";
// first "argument" is self (which sometimes needs parens)
args_to_check = &args[1..];
}
// actual catch-all arm
_ => { return; }
}
return;
},
MethodCall(_, ref args) => {
for arg in &args[1..] { // first "argument" is self (which sometimes needs parens)
self.check_unused_parens_core(cx, arg, "method argument", false)
// Don't lint if this is a nested macro expansion: otherwise, the lint could
// trigger in situations that macro authors shouldn't have to care about, e.g.,
// when a parenthesized token tree matched in one macro expansion is matched as
// an expression in another and used as a fn/method argument (Issue #47775)
if e.span.ctxt().outer().expn_info()
.map_or(false, |info| info.call_site.ctxt().outer()
.expn_info().is_some()) {
return;
}
let msg = format!("{} argument", call_kind);
for arg in args_to_check {
self.check_unused_parens_core(cx, arg, &msg, false);
}
return;
}
_ => return,
};
self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
}
Expand Down
21 changes: 14 additions & 7 deletions src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}
};
if let PlaceContext::Copy = context {
let ty = place_ty.to_ty(self.tcx());
if self.cx
.infcx
.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP)
{
span_mirbug!(self, place, "attempted copy of non-Copy type ({:?})", ty);
}
let tcx = self.tcx();
let trait_ref = ty::TraitRef {
def_id: tcx.lang_items().copy_trait().unwrap(),
substs: tcx.mk_substs_trait(place_ty.to_ty(tcx), &[]),
};

// In order to have a Copy operand, the type T of the value must be Copy. Note that we
// prove that T: Copy, rather than using the type_moves_by_default test. This is
// important because type_moves_by_default ignores the resulting region obligations and
// assumes they pass. This can result in bounds from Copy impls being unsoundly ignored
// (e.g., #29149). Note that we decide to use Copy before knowing whether the bounds
// fully apply: in effect, the rule is that if a value of some type could implement
// Copy, then it must.
self.cx.prove_trait_ref(trait_ref, location);
}
place_ty
}
Expand Down
11 changes: 9 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2447,7 +2447,12 @@ impl Clean<Type> for hir::Ty {
let def_id = cx.tcx.hir.body_owner_def_id(n);
let param_env = cx.tcx.param_env(def_id);
let substs = Substs::identity_for_item(cx.tcx, def_id);
let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap();
let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap_or_else(|_| {
cx.tcx.mk_const(ty::Const {
val: ConstVal::Unevaluated(def_id, substs),
ty: cx.tcx.types.usize
})
});
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
n.to_string()
} else if let ConstVal::Unevaluated(def_id, _) = n.val {
Expand Down Expand Up @@ -2577,7 +2582,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
let mut n = cx.tcx.lift(&n).unwrap();
if let ConstVal::Unevaluated(def_id, substs) = n.val {
let param_env = cx.tcx.param_env(def_id);
n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap()
if let Ok(new_n) = cx.tcx.const_eval(param_env.and((def_id, substs))) {
n = new_n;
}
};
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
n.to_string()
Expand Down
36 changes: 29 additions & 7 deletions src/libstd/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,20 +482,42 @@ impl File {
self.inner.file_attr().map(Metadata)
}

/// Creates a new independently owned handle to the underlying file.
///
/// The returned `File` is a reference to the same state that this object
/// references. Both handles will read and write with the same cursor
/// position.
/// Create a new `File` instance that shares the same underlying file handle
/// as the existing `File` instance. Reads, writes, and seeks will affect
/// both `File` instances simultaneously.
///
/// # Examples
///
/// Create two handles for a file named `foo.txt`:
///
/// ```no_run
/// use std::fs::File;
///
/// # fn foo() -> std::io::Result<()> {
/// let mut f = File::open("foo.txt")?;
/// let file_copy = f.try_clone()?;
/// let mut file = File::open("foo.txt")?;
/// let file_copy = file.try_clone()?;
/// # Ok(())
/// # }
/// ```
///
/// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create
/// two handles, seek one of them, and read the remaining bytes from the
/// other handle:
///
/// ```no_run
/// use std::fs::File;
/// use std::io::SeekFrom;
/// use std::io::prelude::*;
///
/// # fn foo() -> std::io::Result<()> {
/// let mut file = File::open("foo.txt")?;
/// let mut file_copy = file.try_clone()?;
///
/// file.seek(SeekFrom::Start(3))?;
///
/// let mut contents = vec![];
/// file_copy.read_to_end(&mut contents)?;
/// assert_eq!(contents, b"def\n");
/// # Ok(())
/// # }
/// ```
Expand Down
5 changes: 3 additions & 2 deletions src/libstd/sys/cloudabi/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@ impl Drop for Thread {

#[cfg_attr(test, allow(dead_code))]
pub mod guard {
pub unsafe fn current() -> Option<usize> {
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> {
None
}
pub unsafe fn init() -> Option<usize> {
pub unsafe fn init() -> Option<Guard> {
None
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/libstd/sys/redox/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl Thread {
}

pub mod guard {
pub unsafe fn current() -> Option<usize> { None }
pub unsafe fn init() -> Option<usize> { None }
pub type Guard = !;
pub unsafe fn current() -> Option<Guard> { None }
pub unsafe fn init() -> Option<Guard> { None }
}
9 changes: 2 additions & 7 deletions src/libstd/sys/unix/stack_overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ mod imp {
use sys_common::thread_info;


// This is initialized in init() and only read from after
static mut PAGE_SIZE: usize = 0;

#[cfg(any(target_os = "linux", target_os = "android"))]
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
#[repr(C)]
Expand Down Expand Up @@ -102,12 +99,12 @@ mod imp {
_data: *mut libc::c_void) {
use sys_common::util::report_overflow;

let guard = thread_info::stack_guard().unwrap_or(0);
let guard = thread_info::stack_guard().unwrap_or(0..0);
let addr = siginfo_si_addr(info);

// If the faulting address is within the guard page, then we print a
// message saying so and abort.
if guard != 0 && guard - PAGE_SIZE <= addr && addr < guard {
if guard.start <= addr && addr < guard.end {
report_overflow();
rtabort!("stack overflow");
} else {
Expand All @@ -123,8 +120,6 @@ mod imp {
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();

pub unsafe fn init() {
PAGE_SIZE = ::sys::os::page_size();

let mut action: sigaction = mem::zeroed();
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
action.sa_sigaction = signal_handler as sighandler_t;
Expand Down
Loading