Skip to content

Commit 6f6ac5e

Browse files
committed
Auto merge of #47984 - kennytm:rollup, r=kennytm
Rollup of 9 pull requests - Successful merges: #47753, #47862, #47877, #47896, #47912, #47944, #47947, #47978, #47958 - Failed merges:
2 parents 3d292b7 + ec010ae commit 6f6ac5e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+534
-271
lines changed

src/Cargo.lock

+92-54
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/doc/book

Submodule book updated 122 files

src/doc/reference

src/doc/unstable-book/src/language-features/match-beginning-vert.md

-23
This file was deleted.

src/libcore/iter/mod.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -2286,16 +2286,7 @@ impl<I> Iterator for Take<I> where I: Iterator{
22862286

22872287
#[inline]
22882288
fn size_hint(&self) -> (usize, Option<usize>) {
2289-
let (lower, upper) = self.iter.size_hint();
2290-
2291-
let lower = cmp::min(lower, self.n);
2292-
2293-
let upper = match upper {
2294-
Some(x) if x < self.n => Some(x),
2295-
_ => Some(self.n)
2296-
};
2297-
2298-
(lower, upper)
2289+
TakeImpl::size_hint(self)
22992290
}
23002291

23012292
#[inline]
@@ -2316,12 +2307,50 @@ impl<I> Iterator for Take<I> where I: Iterator{
23162307
}
23172308
}
23182309

2310+
trait TakeImpl {
2311+
fn size_hint(&self) -> (usize, Option<usize>);
2312+
}
2313+
2314+
impl<I: Iterator> TakeImpl for Take<I> {
2315+
#[inline]
2316+
default fn size_hint(&self) -> (usize, Option<usize>) {
2317+
let (lower, upper) = self.iter.size_hint();
2318+
2319+
let lower = cmp::min(lower, self.n);
2320+
2321+
let upper = match upper {
2322+
Some(x) if x < self.n => Some(x),
2323+
_ => Some(self.n)
2324+
};
2325+
2326+
(lower, upper)
2327+
}
2328+
}
2329+
2330+
impl<I: TrustedLen> TakeImpl for Take<I> {
2331+
#[inline]
2332+
fn size_hint(&self) -> (usize, Option<usize>) {
2333+
let (lower, upper) = self.iter.size_hint();
2334+
match upper {
2335+
None => (self.n, Some(self.n)),
2336+
Some(x) => {
2337+
debug_assert_eq!(x, lower);
2338+
let count = cmp::min(lower, self.n);
2339+
(count, Some(count))
2340+
}
2341+
}
2342+
}
2343+
}
2344+
23192345
#[stable(feature = "rust1", since = "1.0.0")]
23202346
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
23212347

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

2351+
#[unstable(feature = "trusted_len", issue = "37572")]
2352+
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
2353+
23252354
/// An iterator to maintain state while iterating another iterator.
23262355
///
23272356
/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its

src/libcore/iter/range.rs

+3
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
325325
#[unstable(feature = "fused", issue = "35602")]
326326
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
327327

328+
#[unstable(feature = "trusted_len", issue = "37572")]
329+
unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
330+
328331
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
329332
impl<A: Step> Iterator for ops::RangeInclusive<A> {
330333
type Item = A;

src/libcore/iter/sources.rs

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
4444
#[unstable(feature = "fused", issue = "35602")]
4545
impl<A: Clone> FusedIterator for Repeat<A> {}
4646

47+
#[unstable(feature = "trusted_len", issue = "37572")]
48+
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
49+
4750
/// Creates a new iterator that endlessly repeats a single element.
4851
///
4952
/// The `repeat()` function repeats a single value over and over and over and

src/libcore/iter/traits.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,8 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {}
972972
/// The upper bound must only be [`None`] if the actual iterator length is
973973
/// larger than [`usize::MAX`].
974974
///
975-
/// The iterator must produce exactly the number of elements it reported.
975+
/// The iterator must produce exactly the number of elements it reported
976+
/// or diverge before reaching the end.
976977
///
977978
/// # Safety
978979
///

src/libcore/tests/iter.rs

+43
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,29 @@ fn test_range_from_nth() {
13711371
assert_eq!(r, 16..);
13721372
assert_eq!(r.nth(10), Some(26));
13731373
assert_eq!(r, 27..);
1374+
1375+
assert_eq!((0..).size_hint(), (usize::MAX, None));
1376+
}
1377+
1378+
fn is_trusted_len<I: TrustedLen>(_: I) {}
1379+
1380+
#[test]
1381+
fn test_range_from_take() {
1382+
let mut it = (0..).take(3);
1383+
assert_eq!(it.next(), Some(0));
1384+
assert_eq!(it.next(), Some(1));
1385+
assert_eq!(it.next(), Some(2));
1386+
assert_eq!(it.next(), None);
1387+
is_trusted_len((0..).take(3));
1388+
assert_eq!((0..).take(3).size_hint(), (3, Some(3)));
1389+
assert_eq!((0..).take(0).size_hint(), (0, Some(0)));
1390+
assert_eq!((0..).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
1391+
}
1392+
1393+
#[test]
1394+
fn test_range_from_take_collect() {
1395+
let v: Vec<_> = (0..).take(3).collect();
1396+
assert_eq!(v, vec![0, 1, 2]);
13741397
}
13751398

13761399
#[test]
@@ -1465,6 +1488,26 @@ fn test_repeat() {
14651488
assert_eq!(it.next(), Some(42));
14661489
assert_eq!(it.next(), Some(42));
14671490
assert_eq!(it.next(), Some(42));
1491+
assert_eq!(repeat(42).size_hint(), (usize::MAX, None));
1492+
}
1493+
1494+
#[test]
1495+
fn test_repeat_take() {
1496+
let mut it = repeat(42).take(3);
1497+
assert_eq!(it.next(), Some(42));
1498+
assert_eq!(it.next(), Some(42));
1499+
assert_eq!(it.next(), Some(42));
1500+
assert_eq!(it.next(), None);
1501+
is_trusted_len(repeat(42).take(3));
1502+
assert_eq!(repeat(42).take(3).size_hint(), (3, Some(3)));
1503+
assert_eq!(repeat(42).take(0).size_hint(), (0, Some(0)));
1504+
assert_eq!(repeat(42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX)));
1505+
}
1506+
1507+
#[test]
1508+
fn test_repeat_take_collect() {
1509+
let v: Vec<_> = repeat(42).take(3).collect();
1510+
assert_eq!(v, vec![42, 42, 42]);
14681511
}
14691512

14701513
#[test]

src/librustc_lint/unused.rs

+28-9
Original file line numberDiff line numberDiff line change
@@ -302,19 +302,38 @@ impl EarlyLintPass for UnusedParens {
302302
Assign(_, ref value) => (value, "assigned value", false),
303303
AssignOp(.., ref value) => (value, "assigned value", false),
304304
InPlace(_, ref value) => (value, "emplacement value", false),
305-
Call(_, ref args) => {
306-
for arg in args {
307-
self.check_unused_parens_core(cx, arg, "function argument", false)
305+
// either function/method call, or something this lint doesn't care about
306+
ref call_or_other => {
307+
let args_to_check;
308+
let call_kind;
309+
match *call_or_other {
310+
Call(_, ref args) => {
311+
call_kind = "function";
312+
args_to_check = &args[..];
313+
},
314+
MethodCall(_, ref args) => {
315+
call_kind = "method";
316+
// first "argument" is self (which sometimes needs parens)
317+
args_to_check = &args[1..];
318+
}
319+
// actual catch-all arm
320+
_ => { return; }
308321
}
309-
return;
310-
},
311-
MethodCall(_, ref args) => {
312-
for arg in &args[1..] { // first "argument" is self (which sometimes needs parens)
313-
self.check_unused_parens_core(cx, arg, "method argument", false)
322+
// Don't lint if this is a nested macro expansion: otherwise, the lint could
323+
// trigger in situations that macro authors shouldn't have to care about, e.g.,
324+
// when a parenthesized token tree matched in one macro expansion is matched as
325+
// an expression in another and used as a fn/method argument (Issue #47775)
326+
if e.span.ctxt().outer().expn_info()
327+
.map_or(false, |info| info.call_site.ctxt().outer()
328+
.expn_info().is_some()) {
329+
return;
330+
}
331+
let msg = format!("{} argument", call_kind);
332+
for arg in args_to_check {
333+
self.check_unused_parens_core(cx, arg, &msg, false);
314334
}
315335
return;
316336
}
317-
_ => return,
318337
};
319338
self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
320339
}

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
374374
}
375375
};
376376
if let PlaceContext::Copy = context {
377-
let ty = place_ty.to_ty(self.tcx());
378-
if self.cx
379-
.infcx
380-
.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP)
381-
{
382-
span_mirbug!(self, place, "attempted copy of non-Copy type ({:?})", ty);
383-
}
377+
let tcx = self.tcx();
378+
let trait_ref = ty::TraitRef {
379+
def_id: tcx.lang_items().copy_trait().unwrap(),
380+
substs: tcx.mk_substs_trait(place_ty.to_ty(tcx), &[]),
381+
};
382+
383+
// In order to have a Copy operand, the type T of the value must be Copy. Note that we
384+
// prove that T: Copy, rather than using the type_moves_by_default test. This is
385+
// important because type_moves_by_default ignores the resulting region obligations and
386+
// assumes they pass. This can result in bounds from Copy impls being unsoundly ignored
387+
// (e.g., #29149). Note that we decide to use Copy before knowing whether the bounds
388+
// fully apply: in effect, the rule is that if a value of some type could implement
389+
// Copy, then it must.
390+
self.cx.prove_trait_ref(trait_ref, location);
384391
}
385392
place_ty
386393
}

src/librustdoc/clean/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -2447,7 +2447,12 @@ impl Clean<Type> for hir::Ty {
24472447
let def_id = cx.tcx.hir.body_owner_def_id(n);
24482448
let param_env = cx.tcx.param_env(def_id);
24492449
let substs = Substs::identity_for_item(cx.tcx, def_id);
2450-
let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap();
2450+
let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap_or_else(|_| {
2451+
cx.tcx.mk_const(ty::Const {
2452+
val: ConstVal::Unevaluated(def_id, substs),
2453+
ty: cx.tcx.types.usize
2454+
})
2455+
});
24512456
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
24522457
n.to_string()
24532458
} else if let ConstVal::Unevaluated(def_id, _) = n.val {
@@ -2577,7 +2582,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
25772582
let mut n = cx.tcx.lift(&n).unwrap();
25782583
if let ConstVal::Unevaluated(def_id, substs) = n.val {
25792584
let param_env = cx.tcx.param_env(def_id);
2580-
n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap()
2585+
if let Ok(new_n) = cx.tcx.const_eval(param_env.and((def_id, substs))) {
2586+
n = new_n;
2587+
}
25812588
};
25822589
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
25832590
n.to_string()

src/libstd/fs.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -482,20 +482,42 @@ impl File {
482482
self.inner.file_attr().map(Metadata)
483483
}
484484

485-
/// Creates a new independently owned handle to the underlying file.
486-
///
487-
/// The returned `File` is a reference to the same state that this object
488-
/// references. Both handles will read and write with the same cursor
489-
/// position.
485+
/// Create a new `File` instance that shares the same underlying file handle
486+
/// as the existing `File` instance. Reads, writes, and seeks will affect
487+
/// both `File` instances simultaneously.
490488
///
491489
/// # Examples
492490
///
491+
/// Create two handles for a file named `foo.txt`:
492+
///
493493
/// ```no_run
494494
/// use std::fs::File;
495495
///
496496
/// # fn foo() -> std::io::Result<()> {
497-
/// let mut f = File::open("foo.txt")?;
498-
/// let file_copy = f.try_clone()?;
497+
/// let mut file = File::open("foo.txt")?;
498+
/// let file_copy = file.try_clone()?;
499+
/// # Ok(())
500+
/// # }
501+
/// ```
502+
///
503+
/// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create
504+
/// two handles, seek one of them, and read the remaining bytes from the
505+
/// other handle:
506+
///
507+
/// ```no_run
508+
/// use std::fs::File;
509+
/// use std::io::SeekFrom;
510+
/// use std::io::prelude::*;
511+
///
512+
/// # fn foo() -> std::io::Result<()> {
513+
/// let mut file = File::open("foo.txt")?;
514+
/// let mut file_copy = file.try_clone()?;
515+
///
516+
/// file.seek(SeekFrom::Start(3))?;
517+
///
518+
/// let mut contents = vec![];
519+
/// file_copy.read_to_end(&mut contents)?;
520+
/// assert_eq!(contents, b"def\n");
499521
/// # Ok(())
500522
/// # }
501523
/// ```

src/libstd/sys/cloudabi/thread.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,11 @@ impl Drop for Thread {
111111

112112
#[cfg_attr(test, allow(dead_code))]
113113
pub mod guard {
114-
pub unsafe fn current() -> Option<usize> {
114+
pub type Guard = !;
115+
pub unsafe fn current() -> Option<Guard> {
115116
None
116117
}
117-
pub unsafe fn init() -> Option<usize> {
118+
pub unsafe fn init() -> Option<Guard> {
118119
None
119120
}
120121
}

src/libstd/sys/redox/thread.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ impl Thread {
8888
}
8989

9090
pub mod guard {
91-
pub unsafe fn current() -> Option<usize> { None }
92-
pub unsafe fn init() -> Option<usize> { None }
91+
pub type Guard = !;
92+
pub unsafe fn current() -> Option<Guard> { None }
93+
pub unsafe fn init() -> Option<Guard> { None }
9394
}

src/libstd/sys/unix/stack_overflow.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,6 @@ mod imp {
5757
use sys_common::thread_info;
5858

5959

60-
// This is initialized in init() and only read from after
61-
static mut PAGE_SIZE: usize = 0;
62-
6360
#[cfg(any(target_os = "linux", target_os = "android"))]
6461
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
6562
#[repr(C)]
@@ -102,12 +99,12 @@ mod imp {
10299
_data: *mut libc::c_void) {
103100
use sys_common::util::report_overflow;
104101

105-
let guard = thread_info::stack_guard().unwrap_or(0);
102+
let guard = thread_info::stack_guard().unwrap_or(0..0);
106103
let addr = siginfo_si_addr(info);
107104

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

125122
pub unsafe fn init() {
126-
PAGE_SIZE = ::sys::os::page_size();
127-
128123
let mut action: sigaction = mem::zeroed();
129124
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
130125
action.sa_sigaction = signal_handler as sighandler_t;

0 commit comments

Comments
 (0)