Skip to content

Rollup of 16 pull requests #59151

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Mar 13, 2019
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
204f087
librustc_interface: Update scoped-tls to 1.0
Xanewok Mar 1, 2019
939a263
Update rand version
JohnTitor Mar 4, 2019
63f60b0
Fix documentation of from_ne_bytes and from_le_bytes
xTibor Mar 7, 2019
0a505a7
Parse lifetimes that start with a number and give specific error
estebank Mar 2, 2019
f690821
review comments
estebank Mar 8, 2019
df4ea90
Use lifetime contravariance to elide more lifetimes in core+alloc+std
scottmcm Mar 10, 2019
d1034c1
Fix incorrect links in librustc_codegen_llvm documentation
nbaksalyar Mar 11, 2019
8b1742e
Fix #54822 and associated faulty tests
kyren Mar 11, 2019
01e2e1f
Remove precompute_in_scope_traits_hashes
Zoxc Mar 10, 2019
749e9d4
added a function for reducing repetition of bit operation
kenta7777 Mar 11, 2019
4c9f7a0
reduced some code repetitions of bit operation
kenta7777 Mar 11, 2019
0ede9e6
replaced some bit operations with truncate
kenta7777 Mar 11, 2019
18b40c6
removed the definition of mask
kenta7777 Mar 11, 2019
95fc3f4
Standardize `Range*` documentation
czipperz Mar 10, 2019
c46f758
Fix RangeBounds documentation to include inclusive operations
czipperz Mar 10, 2019
6b88c90
impl FromIterator for Result: Use assert_eq! instead of assert!
czipperz Mar 12, 2019
365d918
Replace assert with assert_eq for better debugging
ohsayan Mar 12, 2019
2027459
Visit impl Trait for dead_code lint
sanxiyn Mar 12, 2019
7fcdb93
Note that NonNull does not launder shared references for mutation
RalfJung Mar 12, 2019
8ec8639
expand
RalfJung Mar 12, 2019
4632e33
add a useful debug printout
nikomatsakis Mar 12, 2019
261daf2
ignore higher-ranked WF requirements for trait objects
nikomatsakis Mar 12, 2019
8d18e57
Fix the bench_max and bench_max_by_key benchmarks
timvermeulen Mar 12, 2019
b23a047
Remove the projection part of select_fold1
timvermeulen Mar 12, 2019
0de63d9
Fix comment
timvermeulen Mar 12, 2019
1819250
Add tests to ensure that Iterator::min and Iterator::max are stable
timvermeulen Mar 12, 2019
6cc5a3d
Forward `max` and `min` to `max_by` and `min_by` respectively
timvermeulen Mar 12, 2019
aa9bd68
Rename test struct names to something more sensible
kyren Mar 12, 2019
445c4bc
Rollup merge of #58829 - Xanewok:scoped-tls, r=Zoxc
Centril Mar 13, 2019
ad7b650
Rollup merge of #58876 - estebank:numeric-lifetime, r=petrochenkov
Centril Mar 13, 2019
2049d6f
Rollup merge of #58908 - JohnTitor:improve-rand, r=scottmcm
Centril Mar 13, 2019
fc19f0e
Rollup merge of #58998 - xTibor:doc_from_bytes, r=scottmcm
Centril Mar 13, 2019
68abd9a
Rollup merge of #59056 - scottmcm:even-fewer-lifetimes, r=sfackler
Centril Mar 13, 2019
1008150
Rollup merge of #59057 - czipperz:standardize_range_documentation, r=…
Centril Mar 13, 2019
13a8942
Rollup merge of #59080 - nbaksalyar:fix-llvm-codegen-doc, r=frewsxcv
Centril Mar 13, 2019
c0dcfed
Rollup merge of #59083 - kyren:master, r=varkor
Centril Mar 13, 2019
f95bbf3
Rollup merge of #59093 - Zoxc:no-prealloc, r=michaelwoerister
Centril Mar 13, 2019
6c9bdc3
Rollup merge of #59101 - kenta7777:reduce-code-repetition, r=oli-obk
Centril Mar 13, 2019
106159d
Rollup merge of #59121 - czipperz:fix_assert_result_fromiterater, r=C…
Centril Mar 13, 2019
f3dc046
Rollup merge of #59124 - sntdevco:master, r=Centril
Centril Mar 13, 2019
b70a98f
Rollup merge of #59129 - sanxiyn:visit-impl-trait, r=varkor
Centril Mar 13, 2019
3623c1a
Rollup merge of #59130 - RalfJung:non-null, r=rkruppe
Centril Mar 13, 2019
c22566d
Rollup merge of #59132 - nikomatsakis:issue-53548-generator-bound, r=…
Centril Mar 13, 2019
73feddb
Rollup merge of #59138 - timvermeulen:simplify_select_fold1, r=sfackler
Centril Mar 13, 2019
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
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2747,7 +2747,7 @@ version = "0.0.0"
dependencies = [
"graphviz 0.0.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_fs_util 0.0.0",
@@ -2778,7 +2778,7 @@ dependencies = [
"rustc_resolve 0.0.0",
"rustc_traits 0.0.0",
"rustc_typeck 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
8 changes: 4 additions & 4 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
@@ -489,7 +489,7 @@ impl<T: ?Sized> From<Box<T>> for Pin<Box<T>> {
}

#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
impl<T: Copy> From<&[T]> for Box<[T]> {
/// Converts a `&[T]` into a `Box<[T]>`
///
/// This conversion allocates on the heap
@@ -503,15 +503,15 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
///
/// println!("{:?}", boxed_slice);
/// ```
fn from(slice: &'a [T]) -> Box<[T]> {
fn from(slice: &[T]) -> Box<[T]> {
let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() };
boxed.copy_from_slice(slice);
boxed
}
}

#[stable(feature = "box_from_slice", since = "1.17.0")]
impl<'a> From<&'a str> for Box<str> {
impl From<&str> for Box<str> {
/// Converts a `&str` into a `Box<str>`
///
/// This conversion allocates on the heap
@@ -523,7 +523,7 @@ impl<'a> From<&'a str> for Box<str> {
/// println!("{}", boxed);
/// ```
#[inline]
fn from(s: &'a str) -> Box<str> {
fn from(s: &str) -> Box<str> {
unsafe { from_boxed_utf8_unchecked(Box::from(s.as_bytes())) }
}
}
4 changes: 2 additions & 2 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
@@ -1145,15 +1145,15 @@ impl<T> From<T> for Rc<T> {
}

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> {
impl<T: Clone> From<&[T]> for Rc<[T]> {
#[inline]
fn from(v: &[T]) -> Rc<[T]> {
<Self as RcFromSlice<T>>::from_slice(v)
}
}

#[stable(feature = "shared_from_slice", since = "1.21.0")]
impl<'a> From<&'a str> for Rc<str> {
impl From<&str> for Rc<str> {
#[inline]
fn from(v: &str) -> Rc<str> {
let rc = Rc::<[u8]>::from(v.as_bytes());
4 changes: 2 additions & 2 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
@@ -2172,9 +2172,9 @@ impl AsRef<[u8]> for String {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for String {
impl From<&str> for String {
#[inline]
fn from(s: &'a str) -> String {
fn from(s: &str) -> String {
s.to_owned()
}
}
16 changes: 8 additions & 8 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
@@ -2182,25 +2182,25 @@ impl<T> AsMut<[T]> for Vec<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> From<&'a [T]> for Vec<T> {
impl<T: Clone> From<&[T]> for Vec<T> {
#[cfg(not(test))]
fn from(s: &'a [T]) -> Vec<T> {
fn from(s: &[T]) -> Vec<T> {
s.to_vec()
}
#[cfg(test)]
fn from(s: &'a [T]) -> Vec<T> {
fn from(s: &[T]) -> Vec<T> {
crate::slice::to_vec(s)
}
}

#[stable(feature = "vec_from_mut", since = "1.19.0")]
impl<'a, T: Clone> From<&'a mut [T]> for Vec<T> {
impl<T: Clone> From<&mut [T]> for Vec<T> {
#[cfg(not(test))]
fn from(s: &'a mut [T]) -> Vec<T> {
fn from(s: &mut [T]) -> Vec<T> {
s.to_vec()
}
#[cfg(test)]
fn from(s: &'a mut [T]) -> Vec<T> {
fn from(s: &mut [T]) -> Vec<T> {
crate::slice::to_vec(s)
}
}
@@ -2231,8 +2231,8 @@ impl<T> From<Vec<T>> for Box<[T]> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for Vec<u8> {
fn from(s: &'a str) -> Vec<u8> {
impl From<&str> for Vec<u8> {
fn from(s: &str) -> Vec<u8> {
From::from(s.as_bytes())
}
}
2 changes: 1 addition & 1 deletion src/libcore/array.rs
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ macro_rules! array_impls {
}

#[stable(feature = "try_from", since = "1.34.0")]
impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy {
impl<T> TryFrom<&[T]> for [T; $N] where T: Copy {
type Error = TryFromSliceError;

fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
4 changes: 2 additions & 2 deletions src/libcore/benches/iter.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ fn scatter(x: i32) -> i32 { (x * 31) % 127 }
fn bench_max_by_key(b: &mut Bencher) {
b.iter(|| {
let it = 0..100;
it.max_by_key(|&x| scatter(x))
it.map(black_box).max_by_key(|&x| scatter(x))
})
}

@@ -56,7 +56,7 @@ fn bench_max_by_key2(b: &mut Bencher) {
fn bench_max(b: &mut Bencher) {
b.iter(|| {
let it = 0..100;
it.map(scatter).max()
it.map(black_box).map(scatter).max()
})
}

48 changes: 24 additions & 24 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
@@ -1004,26 +1004,26 @@ mod impls {
// & pointers

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: & &B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: & &B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: & &'b B) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: & &B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: & &'b B) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: & &B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: & &B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: & &B) -> bool { PartialOrd::gt(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Ord for &A where A: Ord {
@@ -1036,26 +1036,26 @@ mod impls {
// &mut pointers

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A where A: PartialOrd<B> {
#[inline]
fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &&'b mut B) -> bool { PartialOrd::lt(*self, *other) }
fn lt(&self, other: &&mut B) -> bool { PartialOrd::lt(*self, *other) }
#[inline]
fn le(&self, other: &&'b mut B) -> bool { PartialOrd::le(*self, *other) }
fn le(&self, other: &&mut B) -> bool { PartialOrd::le(*self, *other) }
#[inline]
fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
fn ge(&self, other: &&mut B) -> bool { PartialOrd::ge(*self, *other) }
#[inline]
fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
fn gt(&self, other: &&mut B) -> bool { PartialOrd::gt(*self, *other) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: ?Sized> Ord for &mut A where A: Ord {
@@ -1066,18 +1066,18 @@ mod impls {
impl<A: ?Sized> Eq for &mut A where A: Eq {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&mut B) -> bool { PartialEq::ne(*self, *other) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&B) -> bool { PartialEq::ne(*self, *other) }
}
}
12 changes: 6 additions & 6 deletions src/libcore/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -37,21 +37,21 @@ macro_rules! forward_ref_binop {
}

#[$attr]
impl<'a> $imp<&'a $u> for $t {
impl $imp<&$u> for $t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(self, *other)
}
}

#[$attr]
impl<'a, 'b> $imp<&'a $u> for &'b $t {
impl $imp<&$u> for &$t {
type Output = <$t as $imp<$u>>::Output;

#[inline]
fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
$imp::$method(*self, *other)
}
}
@@ -67,9 +67,9 @@ macro_rules! forward_ref_op_assign {
};
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
#[$attr]
impl<'a> $imp<&'a $u> for $t {
impl $imp<&$u> for $t {
#[inline]
fn $method(&mut self, other: &'a $u) {
fn $method(&mut self, other: &$u) {
$imp::$method(self, *other);
}
}
75 changes: 19 additions & 56 deletions src/libcore/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
@@ -2008,12 +2008,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
select_fold1(self,
|_| (),
// switch to y even if it is only equal, to preserve
// stability.
|_, x, _, y| *x <= *y)
.map(|(_, x)| x)
self.max_by(Ord::cmp)
}

/// Returns the minimum element of an iterator.
@@ -2038,12 +2033,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")]
fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
{
select_fold1(self,
|_| (),
// only switch to y if it is strictly smaller, to
// preserve stability.
|_, x, _, y| *x > *y)
.map(|(_, x)| x)
self.min_by(Ord::cmp)
}

/// Returns the element that gives the maximum value from the
@@ -2062,15 +2052,11 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
fn max_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item) -> B,
{
select_fold1(self,
f,
// switch to y even if it is only equal, to preserve
// stability.
|x_p, _, y_p, _| x_p <= y_p)
.map(|(_, x)| x)
// switch to y even if it is only equal, to preserve stability.
select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p <= y_p).map(|(_, x)| x)
}

/// Returns the element that gives the maximum value with respect to the
@@ -2092,12 +2078,8 @@ pub trait Iterator {
fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
select_fold1(self,
|_| (),
// switch to y even if it is only equal, to preserve
// stability.
|_, x, _, y| Ordering::Greater != compare(x, y))
.map(|(_, x)| x)
// switch to y even if it is only equal, to preserve stability.
select_fold1(self, |x, y| compare(x, y) != Ordering::Greater)
}

/// Returns the element that gives the minimum value from the
@@ -2115,15 +2097,11 @@ pub trait Iterator {
/// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
/// ```
#[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
fn min_by_key<B: Ord, F>(self, mut f: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item) -> B,
{
select_fold1(self,
f,
// only switch to y if it is strictly smaller, to
// preserve stability.
|x_p, _, y_p, _| x_p > y_p)
.map(|(_, x)| x)
// only switch to y if it is strictly smaller, to preserve stability.
select_fold1(self.map(|x| (f(&x), x)), |(x_p, _), (y_p, _)| x_p > y_p).map(|(_, x)| x)
}

/// Returns the element that gives the minimum value with respect to the
@@ -2145,12 +2123,8 @@ pub trait Iterator {
fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
select_fold1(self,
|_| (),
// switch to y even if it is strictly smaller, to
// preserve stability.
|_, x, _, y| Ordering::Greater == compare(x, y))
.map(|(_, x)| x)
// only switch to y if it is strictly smaller, to preserve stability.
select_fold1(self, |x, y| compare(x, y) == Ordering::Greater)
}


@@ -2693,34 +2667,23 @@ pub trait Iterator {
}
}

/// Select an element from an iterator based on the given "projection"
/// and "comparison" function.
/// Select an element from an iterator based on the given "comparison"
/// function.
///
/// This is an idiosyncratic helper to try to factor out the
/// commonalities of {max,min}{,_by}. In particular, this avoids
/// having to implement optimizations several times.
#[inline]
fn select_fold1<I, B, FProj, FCmp>(mut it: I,
mut f_proj: FProj,
mut f_cmp: FCmp) -> Option<(B, I::Item)>
where I: Iterator,
FProj: FnMut(&I::Item) -> B,
FCmp: FnMut(&B, &I::Item, &B, &I::Item) -> bool
fn select_fold1<I, F>(mut it: I, mut f: F) -> Option<I::Item>
where
I: Iterator,
F: FnMut(&I::Item, &I::Item) -> bool,
{
// start with the first element as our selection. This avoids
// having to use `Option`s inside the loop, translating to a
// sizeable performance gain (6x in one case).
it.next().map(|first| {
let first_p = f_proj(&first);

it.fold((first_p, first), |(sel_p, sel), x| {
let x_p = f_proj(&x);
if f_cmp(&sel_p, &sel, &x_p, &x) {
(x_p, x)
} else {
(sel_p, sel)
}
})
it.fold(first, |sel, x| if f(&sel, &x) { x } else { sel })
})
}

16 changes: 8 additions & 8 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
@@ -1979,10 +1979,10 @@ When starting from a slice rather than an array, fallible conversion APIs can be
```
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@@ -2020,10 +2020,10 @@ When starting from a slice rather than an array, fallible conversion APIs can be
```
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@@ -3695,10 +3695,10 @@ When starting from a slice rather than an array, fallible conversion APIs can be
```
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
@@ -3736,10 +3736,10 @@ When starting from a slice rather than an array, fallible conversion APIs can be
```
use std::convert::TryInto;
fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
*input = rest;
", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())
}
```"),
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
70 changes: 43 additions & 27 deletions src/libcore/ops/range.rs
Original file line number Diff line number Diff line change
@@ -26,11 +26,13 @@ use hash::{Hash, Hasher};
/// Used as a [slicing index], `RangeFull` produces the full array as a slice.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]); // RangeFull
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@@ -60,11 +62,13 @@ impl fmt::Debug for RangeFull {
/// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 });
/// assert_eq!(3 + 4 + 5, (3..6).sum());
///
/// let arr = ['a', 'b', 'c', 'd'];
/// assert_eq!(arr[ .. ], ['a', 'b', 'c', 'd']);
/// assert_eq!(arr[ ..3], ['a', 'b', 'c', ]);
/// assert_eq!(arr[1.. ], [ 'b', 'c', 'd']);
/// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]); // Range
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
#[doc(alias = "..")]
#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
@@ -160,11 +164,13 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// assert_eq!((2..), std::ops::RangeFrom { start: 2 });
/// assert_eq!(2 + 3 + 4, (2..).take(3).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]); // RangeFrom
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`Iterator`]: ../iter/trait.IntoIterator.html
@@ -240,11 +246,13 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// elements before the index indicated by `end`.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ .. ], [0,1,2,3]);
/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
/// assert_eq!(arr[1.. ], [ 1,2,3]);
/// assert_eq!(arr[1..3], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]); // RangeTo
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@@ -312,9 +320,13 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5));
/// assert_eq!(3 + 4 + 5, (3..=5).sum());
///
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ..=2], [0,1,2 ]);
/// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]);
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
/// ```
#[doc(alias = "..=")]
#[derive(Clone)] // not Copy -- see #27186
@@ -569,9 +581,13 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// array elements up to and including the index indicated by `end`.
///
/// ```
/// let arr = [0, 1, 2, 3];
/// assert_eq!(arr[ ..=2], [0,1,2 ]); // RangeToInclusive
/// assert_eq!(arr[1..=2], [ 1,2 ]);
/// let arr = [0, 1, 2, 3, 4];
/// assert_eq!(arr[ .. ], [0,1,2,3,4]);
/// assert_eq!(arr[ .. 3], [0,1,2 ]);
/// assert_eq!(arr[ ..=3], [0,1,2,3 ]); // RangeToInclusive
/// assert_eq!(arr[1.. ], [ 1,2,3,4]);
/// assert_eq!(arr[1.. 3], [ 1,2 ]);
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
///
/// [`IntoIterator`]: ../iter/trait.Iterator.html
@@ -676,7 +692,7 @@ pub enum Bound<T> {

#[stable(feature = "collections_range", since = "1.28.0")]
/// `RangeBounds` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
pub trait RangeBounds<T: ?Sized> {
/// Start index bound.
///
26 changes: 18 additions & 8 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
@@ -2837,15 +2837,15 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
}

#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self {
impl<T: ?Sized> From<&mut T> for Unique<T> {
fn from(reference: &mut T) -> Self {
unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
}
}

#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self {
impl<T: ?Sized> From<&T> for Unique<T> {
fn from(reference: &T) -> Self {
unsafe { Unique { pointer: reference as *const T, _marker: PhantomData } }
}
}
@@ -2874,6 +2874,16 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
///
/// Notice that `NonNull<T>` has a `From` instance for `&T`. However, this does
/// not change the fact that mutating through a (pointer derived from a) shared
/// reference is undefined behavior unless the mutation happens inside an
/// [`UnsafeCell<T>`]. The same goes for creating a mutable reference from a shared
/// reference. When using this `From` instance without an `UnsafeCell<T>`,
/// it is your responsibility to ensure that `as_mut` is never called, and `as_ptr`
/// is never used for mutation.
///
/// [`UnsafeCell<T>`]: ../cell/struct.UnsafeCell.html
#[stable(feature = "nonnull", since = "1.25.0")]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
@@ -3049,17 +3059,17 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
}

#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
impl<T: ?Sized> From<&mut T> for NonNull<T> {
#[inline]
fn from(reference: &'a mut T) -> Self {
fn from(reference: &mut T) -> Self {
unsafe { NonNull { pointer: reference as *mut T } }
}
}

#[stable(feature = "nonnull", since = "1.25.0")]
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
impl<T: ?Sized> From<&T> for NonNull<T> {
#[inline]
fn from(reference: &'a T) -> Self {
fn from(reference: &T) -> Self {
unsafe { NonNull { pointer: reference as *const T } }
}
}
2 changes: 1 addition & 1 deletion src/libcore/result.rs
Original file line number Diff line number Diff line change
@@ -1200,7 +1200,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
/// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
/// x.checked_add(1).ok_or("Overflow!")
/// ).collect();
/// assert!(res == Ok(vec![2, 3]));
/// assert_eq!(res, Ok(vec![2, 3]));
/// ```
#[inline]
fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
236 changes: 118 additions & 118 deletions src/libcore/tests/fmt/num.rs
Original file line number Diff line number Diff line change
@@ -3,146 +3,146 @@ fn test_format_int() {
// Formatting integers should select the right implementation based off
// the type of the argument. Also, hex/octal/binary should be defined
// for integers, but they shouldn't emit the negative sign.
assert!(format!("{}", 1isize) == "1");
assert!(format!("{}", 1i8) == "1");
assert!(format!("{}", 1i16) == "1");
assert!(format!("{}", 1i32) == "1");
assert!(format!("{}", 1i64) == "1");
assert!(format!("{}", -1isize) == "-1");
assert!(format!("{}", -1i8) == "-1");
assert!(format!("{}", -1i16) == "-1");
assert!(format!("{}", -1i32) == "-1");
assert!(format!("{}", -1i64) == "-1");
assert!(format!("{:?}", 1isize) == "1");
assert!(format!("{:?}", 1i8) == "1");
assert!(format!("{:?}", 1i16) == "1");
assert!(format!("{:?}", 1i32) == "1");
assert!(format!("{:?}", 1i64) == "1");
assert!(format!("{:b}", 1isize) == "1");
assert!(format!("{:b}", 1i8) == "1");
assert!(format!("{:b}", 1i16) == "1");
assert!(format!("{:b}", 1i32) == "1");
assert!(format!("{:b}", 1i64) == "1");
assert!(format!("{:x}", 1isize) == "1");
assert!(format!("{:x}", 1i8) == "1");
assert!(format!("{:x}", 1i16) == "1");
assert!(format!("{:x}", 1i32) == "1");
assert!(format!("{:x}", 1i64) == "1");
assert!(format!("{:X}", 1isize) == "1");
assert!(format!("{:X}", 1i8) == "1");
assert!(format!("{:X}", 1i16) == "1");
assert!(format!("{:X}", 1i32) == "1");
assert!(format!("{:X}", 1i64) == "1");
assert!(format!("{:o}", 1isize) == "1");
assert!(format!("{:o}", 1i8) == "1");
assert!(format!("{:o}", 1i16) == "1");
assert!(format!("{:o}", 1i32) == "1");
assert!(format!("{:o}", 1i64) == "1");
assert_eq!(format!("{}", 1isize), "1");
assert_eq!(format!("{}", 1i8), "1");
assert_eq!(format!("{}", 1i16), "1");
assert_eq!(format!("{}", 1i32), "1");
assert_eq!(format!("{}", 1i64), "1");
assert_eq!(format!("{}", -1isize), "-1");
assert_eq!(format!("{}", -1i8), "-1");
assert_eq!(format!("{}", -1i16), "-1");
assert_eq!(format!("{}", -1i32), "-1");
assert_eq!(format!("{}", -1i64), "-1");
assert_eq!(format!("{:?}", 1isize), "1");
assert_eq!(format!("{:?}", 1i8), "1");
assert_eq!(format!("{:?}", 1i16), "1");
assert_eq!(format!("{:?}", 1i32), "1");
assert_eq!(format!("{:?}", 1i64), "1");
assert_eq!(format!("{:b}", 1isize), "1");
assert_eq!(format!("{:b}", 1i8), "1");
assert_eq!(format!("{:b}", 1i16), "1");
assert_eq!(format!("{:b}", 1i32), "1");
assert_eq!(format!("{:b}", 1i64), "1");
assert_eq!(format!("{:x}", 1isize), "1");
assert_eq!(format!("{:x}", 1i8), "1");
assert_eq!(format!("{:x}", 1i16), "1");
assert_eq!(format!("{:x}", 1i32), "1");
assert_eq!(format!("{:x}", 1i64), "1");
assert_eq!(format!("{:X}", 1isize), "1");
assert_eq!(format!("{:X}", 1i8), "1");
assert_eq!(format!("{:X}", 1i16), "1");
assert_eq!(format!("{:X}", 1i32), "1");
assert_eq!(format!("{:X}", 1i64), "1");
assert_eq!(format!("{:o}", 1isize), "1");
assert_eq!(format!("{:o}", 1i8), "1");
assert_eq!(format!("{:o}", 1i16), "1");
assert_eq!(format!("{:o}", 1i32), "1");
assert_eq!(format!("{:o}", 1i64), "1");

assert!(format!("{}", 1usize) == "1");
assert!(format!("{}", 1u8) == "1");
assert!(format!("{}", 1u16) == "1");
assert!(format!("{}", 1u32) == "1");
assert!(format!("{}", 1u64) == "1");
assert!(format!("{:?}", 1usize) == "1");
assert!(format!("{:?}", 1u8) == "1");
assert!(format!("{:?}", 1u16) == "1");
assert!(format!("{:?}", 1u32) == "1");
assert!(format!("{:?}", 1u64) == "1");
assert!(format!("{:b}", 1usize) == "1");
assert!(format!("{:b}", 1u8) == "1");
assert!(format!("{:b}", 1u16) == "1");
assert!(format!("{:b}", 1u32) == "1");
assert!(format!("{:b}", 1u64) == "1");
assert!(format!("{:x}", 1usize) == "1");
assert!(format!("{:x}", 1u8) == "1");
assert!(format!("{:x}", 1u16) == "1");
assert!(format!("{:x}", 1u32) == "1");
assert!(format!("{:x}", 1u64) == "1");
assert!(format!("{:X}", 1usize) == "1");
assert!(format!("{:X}", 1u8) == "1");
assert!(format!("{:X}", 1u16) == "1");
assert!(format!("{:X}", 1u32) == "1");
assert!(format!("{:X}", 1u64) == "1");
assert!(format!("{:o}", 1usize) == "1");
assert!(format!("{:o}", 1u8) == "1");
assert!(format!("{:o}", 1u16) == "1");
assert!(format!("{:o}", 1u32) == "1");
assert!(format!("{:o}", 1u64) == "1");
assert_eq!(format!("{}", 1usize), "1");
assert_eq!(format!("{}", 1u8), "1");
assert_eq!(format!("{}", 1u16), "1");
assert_eq!(format!("{}", 1u32), "1");
assert_eq!(format!("{}", 1u64), "1");
assert_eq!(format!("{:?}", 1usize), "1");
assert_eq!(format!("{:?}", 1u8), "1");
assert_eq!(format!("{:?}", 1u16), "1");
assert_eq!(format!("{:?}", 1u32), "1");
assert_eq!(format!("{:?}", 1u64), "1");
assert_eq!(format!("{:b}", 1usize), "1");
assert_eq!(format!("{:b}", 1u8), "1");
assert_eq!(format!("{:b}", 1u16), "1");
assert_eq!(format!("{:b}", 1u32), "1");
assert_eq!(format!("{:b}", 1u64), "1");
assert_eq!(format!("{:x}", 1usize), "1");
assert_eq!(format!("{:x}", 1u8), "1");
assert_eq!(format!("{:x}", 1u16), "1");
assert_eq!(format!("{:x}", 1u32), "1");
assert_eq!(format!("{:x}", 1u64), "1");
assert_eq!(format!("{:X}", 1usize), "1");
assert_eq!(format!("{:X}", 1u8), "1");
assert_eq!(format!("{:X}", 1u16), "1");
assert_eq!(format!("{:X}", 1u32), "1");
assert_eq!(format!("{:X}", 1u64), "1");
assert_eq!(format!("{:o}", 1usize), "1");
assert_eq!(format!("{:o}", 1u8), "1");
assert_eq!(format!("{:o}", 1u16), "1");
assert_eq!(format!("{:o}", 1u32), "1");
assert_eq!(format!("{:o}", 1u64), "1");

// Test a larger number
assert!(format!("{:b}", 55) == "110111");
assert!(format!("{:o}", 55) == "67");
assert!(format!("{}", 55) == "55");
assert!(format!("{:x}", 55) == "37");
assert!(format!("{:X}", 55) == "37");
assert_eq!(format!("{:b}", 55), "110111");
assert_eq!(format!("{:o}", 55), "67");
assert_eq!(format!("{}", 55), "55");
assert_eq!(format!("{:x}", 55), "37");
assert_eq!(format!("{:X}", 55), "37");
}

#[test]
fn test_format_int_zero() {
assert!(format!("{}", 0) == "0");
assert!(format!("{:?}", 0) == "0");
assert!(format!("{:b}", 0) == "0");
assert!(format!("{:o}", 0) == "0");
assert!(format!("{:x}", 0) == "0");
assert!(format!("{:X}", 0) == "0");
assert_eq!(format!("{}", 0), "0");
assert_eq!(format!("{:?}", 0), "0");
assert_eq!(format!("{:b}", 0), "0");
assert_eq!(format!("{:o}", 0), "0");
assert_eq!(format!("{:x}", 0), "0");
assert_eq!(format!("{:X}", 0), "0");

assert!(format!("{}", 0u32) == "0");
assert!(format!("{:?}", 0u32) == "0");
assert!(format!("{:b}", 0u32) == "0");
assert!(format!("{:o}", 0u32) == "0");
assert!(format!("{:x}", 0u32) == "0");
assert!(format!("{:X}", 0u32) == "0");
assert_eq!(format!("{}", 0u32), "0");
assert_eq!(format!("{:?}", 0u32), "0");
assert_eq!(format!("{:b}", 0u32), "0");
assert_eq!(format!("{:o}", 0u32), "0");
assert_eq!(format!("{:x}", 0u32), "0");
assert_eq!(format!("{:X}", 0u32), "0");
}

#[test]
fn test_format_int_flags() {
assert!(format!("{:3}", 1) == " 1");
assert!(format!("{:>3}", 1) == " 1");
assert!(format!("{:>+3}", 1) == " +1");
assert!(format!("{:<3}", 1) == "1 ");
assert!(format!("{:#}", 1) == "1");
assert!(format!("{:#x}", 10) == "0xa");
assert!(format!("{:#X}", 10) == "0xA");
assert!(format!("{:#5x}", 10) == " 0xa");
assert!(format!("{:#o}", 10) == "0o12");
assert!(format!("{:08x}", 10) == "0000000a");
assert!(format!("{:8x}", 10) == " a");
assert!(format!("{:<8x}", 10) == "a ");
assert!(format!("{:>8x}", 10) == " a");
assert!(format!("{:#08x}", 10) == "0x00000a");
assert!(format!("{:08}", -10) == "-0000010");
assert!(format!("{:x}", !0u8) == "ff");
assert!(format!("{:X}", !0u8) == "FF");
assert!(format!("{:b}", !0u8) == "11111111");
assert!(format!("{:o}", !0u8) == "377");
assert!(format!("{:#x}", !0u8) == "0xff");
assert!(format!("{:#X}", !0u8) == "0xFF");
assert!(format!("{:#b}", !0u8) == "0b11111111");
assert!(format!("{:#o}", !0u8) == "0o377");
assert_eq!(format!("{:3}", 1), " 1");
assert_eq!(format!("{:>3}", 1), " 1");
assert_eq!(format!("{:>+3}", 1), " +1");
assert_eq!(format!("{:<3}", 1), "1 ");
assert_eq!(format!("{:#}", 1), "1");
assert_eq!(format!("{:#x}", 10), "0xa");
assert_eq!(format!("{:#X}", 10), "0xA");
assert_eq!(format!("{:#5x}", 10), " 0xa");
assert_eq!(format!("{:#o}", 10), "0o12");
assert_eq!(format!("{:08x}", 10), "0000000a");
assert_eq!(format!("{:8x}", 10), " a");
assert_eq!(format!("{:<8x}", 10), "a ");
assert_eq!(format!("{:>8x}", 10), " a");
assert_eq!(format!("{:#08x}", 10), "0x00000a");
assert_eq!(format!("{:08}", -10), "-0000010");
assert_eq!(format!("{:x}", !0u8), "ff");
assert_eq!(format!("{:X}", !0u8), "FF");
assert_eq!(format!("{:b}", !0u8), "11111111");
assert_eq!(format!("{:o}", !0u8), "377");
assert_eq!(format!("{:#x}", !0u8), "0xff");
assert_eq!(format!("{:#X}", !0u8), "0xFF");
assert_eq!(format!("{:#b}", !0u8), "0b11111111");
assert_eq!(format!("{:#o}", !0u8), "0o377");
}

#[test]
fn test_format_int_sign_padding() {
assert!(format!("{:+5}", 1) == " +1");
assert!(format!("{:+5}", -1) == " -1");
assert!(format!("{:05}", 1) == "00001");
assert!(format!("{:05}", -1) == "-0001");
assert!(format!("{:+05}", 1) == "+0001");
assert!(format!("{:+05}", -1) == "-0001");
assert_eq!(format!("{:+5}", 1), " +1");
assert_eq!(format!("{:+5}", -1), " -1");
assert_eq!(format!("{:05}", 1), "00001");
assert_eq!(format!("{:05}", -1), "-0001");
assert_eq!(format!("{:+05}", 1), "+0001");
assert_eq!(format!("{:+05}", -1), "-0001");
}

#[test]
fn test_format_int_twos_complement() {
use core::{i8, i16, i32, i64};
assert!(format!("{}", i8::MIN) == "-128");
assert!(format!("{}", i16::MIN) == "-32768");
assert!(format!("{}", i32::MIN) == "-2147483648");
assert!(format!("{}", i64::MIN) == "-9223372036854775808");
use core::{i16, i32, i64, i8};
assert_eq!(format!("{}", i8::MIN), "-128");
assert_eq!(format!("{}", i16::MIN), "-32768");
assert_eq!(format!("{}", i32::MIN), "-2147483648");
assert_eq!(format!("{}", i64::MIN), "-9223372036854775808");
}

#[test]
fn test_format_debug_hex() {
assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]");
assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]");
assert_eq!(format!("{:02x?}", b"Foo\0"), "[46, 6f, 6f, 00]");
assert_eq!(format!("{:02X?}", b"Foo\0"), "[46, 6F, 6F, 00]");
}
28 changes: 28 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
@@ -1082,12 +1082,39 @@ fn test_iterator_product_result() {
assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Err(()));
}

/// A wrapper struct that implements `Eq` and `Ord` based on the wrapped
/// integer modulo 3. Used to test that `Iterator::max` and `Iterator::min`
/// return the correct element if some of them are equal.
#[derive(Debug)]
struct Mod3(i32);

impl PartialEq for Mod3 {
fn eq(&self, other: &Self) -> bool {
self.0 % 3 == other.0 % 3
}
}

impl Eq for Mod3 {}

impl PartialOrd for Mod3 {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Mod3 {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
(self.0 % 3).cmp(&(other.0 % 3))
}
}

#[test]
fn test_iterator_max() {
let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
assert_eq!(v[..4].iter().cloned().max(), Some(3));
assert_eq!(v.iter().cloned().max(), Some(10));
assert_eq!(v[..0].iter().cloned().max(), None);
assert_eq!(v.iter().cloned().map(Mod3).max().map(|x| x.0), Some(8));
}

#[test]
@@ -1096,6 +1123,7 @@ fn test_iterator_min() {
assert_eq!(v[..4].iter().cloned().min(), Some(0));
assert_eq!(v.iter().cloned().min(), Some(0));
assert_eq!(v[..0].iter().cloned().min(), None);
assert_eq!(v.iter().cloned().map(Mod3).min().map(|x| x.0), Some(0));
}

#[test]
13 changes: 12 additions & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
// from live codes are live, and everything else is dead.

use crate::hir::Node;
use crate::hir::{self, PatKind};
use crate::hir::{self, PatKind, TyKind};
use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
use crate::hir::itemlikevisit::ItemLikeVisitor;

@@ -282,6 +282,17 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
self.handle_definition(path.def);
intravisit::walk_path(self, path);
}

fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
match ty.node {
TyKind::Def(item_id, _) => {
let item = self.tcx.hir().expect_item(item_id.id);
intravisit::walk_item(self, item);
}
_ => ()
}
intravisit::walk_ty(self, ty);
}
}

fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_, '_, '_>,
2 changes: 2 additions & 0 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
@@ -275,6 +275,8 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
self.selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
}

debug!("process_obligation: obligation = {:?}", obligation);

match obligation.predicate {
ty::Predicate::Trait(ref data) => {
let trait_obligation = obligation.with(data.clone());
10 changes: 0 additions & 10 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
@@ -1443,16 +1443,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

// This method exercises the `in_scope_traits_map` query for all possible
// values so that we have their fingerprints available in the DepGraph.
// This is only required as long as we still use the old dependency tracking
// which needs to have the fingerprints of all input nodes beforehand.
pub fn precompute_in_scope_traits_hashes(self) {
for &def_index in self.trait_map.keys() {
self.in_scope_traits_map(def_index);
}
}

pub fn serialize_query_result_cache<E>(self,
encoder: &mut E)
-> Result<(), E::Error>
3 changes: 1 addition & 2 deletions src/librustc/ty/wf.rs
Original file line number Diff line number Diff line change
@@ -482,8 +482,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
//
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
// am looking forward to the future here.

if !data.has_escaping_bound_vars() {
if !data.has_escaping_bound_vars() && !region.has_escaping_bound_vars() {
let implicit_bounds =
object_region_bounds(self.infcx.tcx, data);

6 changes: 3 additions & 3 deletions src/librustc_codegen_llvm/debuginfo/doc.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
//! # Debug Info Module
//!
//! This module serves the purpose of generating debug symbols. We use LLVM's
//! [source level debugging](http://!llvm.org/docs/SourceLevelDebugging.html)
//! [source level debugging](https://llvm.org/docs/SourceLevelDebugging.html)
//! features for generating the debug information. The general principle is
//! this:
//!
//! Given the right metadata in the LLVM IR, the LLVM code generator is able to
//! create DWARF debug symbols for the given code. The
//! [metadata](http://!llvm.org/docs/LangRef.html#metadata-type) is structured
//! [metadata](https://llvm.org/docs/LangRef.html#metadata-type) is structured
//! much like DWARF *debugging information entries* (DIE), representing type
//! information such as datatype layout, function signatures, block layout,
//! variable location and scope information, etc. It is the purpose of this
//! module to generate correct metadata and insert it into the LLVM IR.
//!
//! As the exact format of metadata trees may change between different LLVM
//! versions, we now use LLVM
//! [DIBuilder](http://!llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html)
//! [DIBuilder](https://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html)
//! to create metadata where possible. This will hopefully ease the adaption of
//! this module to future LLVM versions.
//!
2 changes: 1 addition & 1 deletion src/librustc_incremental/Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ crate-type = ["dylib"]
[dependencies]
graphviz = { path = "../libgraphviz" }
log = "0.4"
rand = "0.5"
rand = "0.6"
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
serialize = { path = "../libserialize" }
1 change: 0 additions & 1 deletion src/librustc_incremental/persist/load.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ pub fn dep_graph_tcx_init<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
}

tcx.allocate_metadata_dep_nodes();
tcx.precompute_in_scope_traits_hashes();
}

type WorkProductMap = FxHashMap<WorkProductId, WorkProduct>;
2 changes: 1 addition & 1 deletion src/librustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ crate-type = ["dylib"]
log = "0.4"
rustc-rayon = "0.1.1"
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
scoped-tls = { version = "0.1.1", features = ["nightly"] }
scoped-tls = "1.0"
syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
5 changes: 3 additions & 2 deletions src/librustc_mir/build/matches/simplify.rs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ use rustc::ty;
use rustc::ty::layout::{Integer, IntegerExt, Size};
use syntax::attr::{SignedInt, UnsignedInt};
use rustc::hir::RangeEnd;
use rustc::mir::interpret::truncate;

use std::mem;

@@ -115,14 +116,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ty::Int(ity) => {
// FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
let max = !0u128 >> (128 - size.bits());
let max = truncate(u128::max_value(), size);
let bias = 1u128 << (size.bits() - 1);
(Some((0, max, size)), bias)
}
ty::Uint(uty) => {
// FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
let max = !0u128 >> (128 - size.bits());
let max = truncate(u128::max_value(), size);
(Some((0, max, size)), 0)
}
_ => (None, 0),
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -917,7 +917,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);

tcx.infer_ctxt().enter(|infcx| {
let param_env = ty::ParamEnv::empty();
let param_env = tcx.param_env(impl_c.def_id);
let inh = Inherited::new(infcx, impl_c.def_id);
let infcx = &inh.infcx;

8 changes: 4 additions & 4 deletions src/libstd/collections/hash/set.rs
Original file line number Diff line number Diff line change
@@ -850,7 +850,7 @@ impl<T, S> Default for HashSet<T, S>
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
where T: Eq + Hash + Clone,
S: BuildHasher + Default
{
@@ -882,7 +882,7 @@ impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
where T: Eq + Hash + Clone,
S: BuildHasher + Default
{
@@ -914,7 +914,7 @@ impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
where T: Eq + Hash + Clone,
S: BuildHasher + Default
{
@@ -946,7 +946,7 @@ impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
where T: Eq + Hash + Clone,
S: BuildHasher + Default
{
8 changes: 4 additions & 4 deletions src/libstd/error.rs
Original file line number Diff line number Diff line change
@@ -337,7 +337,7 @@ impl From<String> for Box<dyn Error> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> {
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
/// # Examples
@@ -351,13 +351,13 @@ impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> {
/// assert!(
/// mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: &'b str) -> Box<dyn Error + Send + Sync + 'a> {
fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
From::from(String::from(err))
}
}

#[stable(feature = "string_box_error", since = "1.6.0")]
impl<'a> From<&'a str> for Box<dyn Error> {
impl From<&str> for Box<dyn Error> {
/// Converts a [`str`] into a box of dyn [`Error`].
///
/// # Examples
@@ -370,7 +370,7 @@ impl<'a> From<&'a str> for Box<dyn Error> {
/// let a_boxed_error = Box::<Error>::from(a_str_error);
/// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
/// ```
fn from(err: &'a str) -> Box<dyn Error> {
fn from(err: &str) -> Box<dyn Error> {
From::from(String::from(err))
}
}
12 changes: 6 additions & 6 deletions src/libstd/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -690,8 +690,8 @@ impl<'a> From<Cow<'a, CStr>> for CString {
}

#[stable(feature = "box_from_c_str", since = "1.17.0")]
impl<'a> From<&'a CStr> for Box<CStr> {
fn from(s: &'a CStr) -> Box<CStr> {
impl From<&CStr> for Box<CStr> {
fn from(s: &CStr) -> Box<CStr> {
let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
}
@@ -767,7 +767,7 @@ impl From<CString> for Arc<CStr> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a CStr> for Arc<CStr> {
impl From<&CStr> for Arc<CStr> {
#[inline]
fn from(s: &CStr) -> Arc<CStr> {
let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul());
@@ -789,7 +789,7 @@ impl From<CString> for Rc<CStr> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a CStr> for Rc<CStr> {
impl From<&CStr> for Rc<CStr> {
#[inline]
fn from(s: &CStr) -> Rc<CStr> {
let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul());
@@ -1268,8 +1268,8 @@ impl ToOwned for CStr {
}

#[stable(feature = "cstring_asref", since = "1.7.0")]
impl<'a> From<&'a CStr> for CString {
fn from(s: &'a CStr) -> CString {
impl From<&CStr> for CString {
fn from(s: &CStr) -> CString {
s.to_owned()
}
}
16 changes: 8 additions & 8 deletions src/libstd/ffi/os_str.rs
Original file line number Diff line number Diff line change
@@ -357,8 +357,8 @@ impl From<String> for OsString {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
fn from(s: &'a T) -> OsString {
impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
fn from(s: &T) -> OsString {
s.as_ref().to_os_string()
}
}
@@ -421,8 +421,8 @@ impl PartialEq<OsString> for str {
}

#[stable(feature = "os_str_str_ref_eq", since = "1.29.0")]
impl<'a> PartialEq<&'a str> for OsString {
fn eq(&self, other: &&'a str) -> bool {
impl PartialEq<&str> for OsString {
fn eq(&self, other: &&str) -> bool {
**self == **other
}
}
@@ -656,8 +656,8 @@ impl OsStr {
}

#[stable(feature = "box_from_os_str", since = "1.17.0")]
impl<'a> From<&'a OsStr> for Box<OsStr> {
fn from(s: &'a OsStr) -> Box<OsStr> {
impl From<&OsStr> for Box<OsStr> {
fn from(s: &OsStr) -> Box<OsStr> {
let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
unsafe { Box::from_raw(rw) }
}
@@ -707,7 +707,7 @@ impl From<OsString> for Arc<OsStr> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a OsStr> for Arc<OsStr> {
impl From<&OsStr> for Arc<OsStr> {
#[inline]
fn from(s: &OsStr) -> Arc<OsStr> {
let arc = s.inner.into_arc();
@@ -729,7 +729,7 @@ impl From<OsString> for Rc<OsStr> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a OsStr> for Rc<OsStr> {
impl From<&OsStr> for Rc<OsStr> {
#[inline]
fn from(s: &OsStr) -> Rc<OsStr> {
let rc = s.inner.into_rc();
12 changes: 6 additions & 6 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
@@ -1456,8 +1456,8 @@ impl PathBuf {
}

#[stable(feature = "box_from_path", since = "1.17.0")]
impl<'a> From<&'a Path> for Box<Path> {
fn from(path: &'a Path) -> Box<Path> {
impl From<&Path> for Box<Path> {
fn from(path: &Path) -> Box<Path> {
let boxed: Box<OsStr> = path.inner.into();
let rw = Box::into_raw(boxed) as *mut Path;
unsafe { Box::from_raw(rw) }
@@ -1494,8 +1494,8 @@ impl Clone for Box<Path> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for PathBuf {
fn from(s: &'a T) -> PathBuf {
impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
fn from(s: &T) -> PathBuf {
PathBuf::from(s.as_ref().to_os_string())
}
}
@@ -1630,7 +1630,7 @@ impl From<PathBuf> for Arc<Path> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a Path> for Arc<Path> {
impl From<&Path> for Arc<Path> {
/// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
#[inline]
fn from(s: &Path) -> Arc<Path> {
@@ -1650,7 +1650,7 @@ impl From<PathBuf> for Rc<Path> {
}

#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl<'a> From<&'a Path> for Rc<Path> {
impl From<&Path> for Rc<Path> {
/// Converts a Path into a Rc by copying the Path data into a new Rc buffer.
#[inline]
fn from(s: &Path) -> Rc<Path> {
4 changes: 2 additions & 2 deletions src/libstd/sys/cloudabi/shims/net.rs
Original file line number Diff line number Diff line change
@@ -297,10 +297,10 @@ impl Iterator for LookupHost {
}
}

impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(_v: &'a str) -> io::Result<LookupHost> {
fn try_from(_v: &str) -> io::Result<LookupHost> {
unsupported()
}
}
2 changes: 1 addition & 1 deletion src/libstd/sys/redox/net/mod.rs
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ impl Iterator for LookupHost {
}
}

impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(s: &str) -> io::Result<LookupHost> {
4 changes: 2 additions & 2 deletions src/libstd/sys/sgx/net.rs
Original file line number Diff line number Diff line change
@@ -420,10 +420,10 @@ impl Iterator for LookupHost {
}
}

impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(v: &'a str) -> io::Result<LookupHost> {
fn try_from(v: &str) -> io::Result<LookupHost> {
LookupHost::new(v.to_owned())
}
}
4 changes: 2 additions & 2 deletions src/libstd/sys/unix/l4re.rs
Original file line number Diff line number Diff line change
@@ -447,10 +447,10 @@ pub mod net {
unsafe impl Send for LookupHost {}


impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(_v: &'a str) -> io::Result<LookupHost> {
fn try_from(_v: &str) -> io::Result<LookupHost> {
unimpl!();
}
}
4 changes: 2 additions & 2 deletions src/libstd/sys/wasm/net.rs
Original file line number Diff line number Diff line change
@@ -298,10 +298,10 @@ impl Iterator for LookupHost {
}
}

impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(_v: &'a str) -> io::Result<LookupHost> {
fn try_from(_v: &str) -> io::Result<LookupHost> {
unsupported()
}
}
2 changes: 1 addition & 1 deletion src/libstd/sys_common/net.rs
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@ impl Drop for LookupHost {
}
}

impl<'a> TryFrom<&'a str> for LookupHost {
impl TryFrom<&str> for LookupHost {
type Error = io::Error;

fn try_from(s: &str) -> io::Result<LookupHost> {
18 changes: 15 additions & 3 deletions src/libsyntax/parse/lexer/mod.rs
Original file line number Diff line number Diff line change
@@ -1423,15 +1423,17 @@ impl<'a> StringReader<'a> {

// If the character is an ident start not followed by another single
// quote, then this is a lifetime name:
if ident_start(Some(c2)) && !self.ch_is('\'') {
if (ident_start(Some(c2)) || c2.is_numeric()) && !self.ch_is('\'') {
while ident_continue(self.ch) {
self.bump();
}
// lifetimes shouldn't end with a single quote
// if we find one, then this is an invalid character literal
if self.ch_is('\'') {
self.err_span_(start_with_quote, self.next_pos,
"character literal may only contain one codepoint");
self.err_span_(
start_with_quote,
self.next_pos,
"character literal may only contain one codepoint");
self.bump();
return Ok(token::Literal(token::Err(Symbol::intern("??")), None))

@@ -1444,6 +1446,15 @@ impl<'a> StringReader<'a> {
self.mk_ident(&format!("'{}", lifetime_name))
});

if c2.is_numeric() {
// this is a recovered lifetime written `'1`, error but accept it
self.err_span_(
start_with_quote,
self.pos,
"lifetimes cannot start with a number",
);
}

return Ok(token::Lifetime(ident));
}

@@ -1873,6 +1884,7 @@ fn is_block_doc_comment(s: &str) -> bool {
res
}

/// Determine whether `c` is a valid start for an ident.
fn ident_start(c: Option<char>) -> bool {
let c = match c {
Some(c) => c,
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ trait Bar: Foo {

impl<T: Foo> Bar for T {
const FROM: &'static str = "foo";
//~^ ERROR the trait bound `T: Foo` is not satisfied [E0277]
//~^ ERROR implemented const `FROM` has an incompatible type for trait [E0326]
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
error[E0277]: the trait bound `T: Foo` is not satisfied
--> $DIR/associated-const-generic-obligations.rs:14:5
error[E0326]: implemented const `FROM` has an incompatible type for trait
--> $DIR/associated-const-generic-obligations.rs:14:17
|
LL | const FROM: Self::Out;
| --------- type in trait
...
LL | const FROM: &'static str = "foo";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T`
| ^^^^^^^^^^^^ expected associated type, found reference
|
= help: consider adding a `where T: Foo` bound
= note: expected type `<T as Foo>::Out`
found type `&'static str`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0326`.
21 changes: 21 additions & 0 deletions src/test/ui/associated-const/associated-const-trait-bound.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// compile-pass

trait ConstDefault {
const DEFAULT: Self;
}

trait Foo: Sized {}

trait FooExt: Foo {
type T: ConstDefault;
}

trait Bar<F: FooExt> {
const T: F::T;
}

impl<F: FooExt> Bar<F> for () {
const T: F::T = <F::T as ConstDefault>::DEFAULT;
}

fn main() {}
20 changes: 20 additions & 0 deletions src/test/ui/generator/issue-53548-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// A variant of #53548 that does not actually require generators,
// but which encountered the same ICE/error. See `issue-53548.rs`
// for details.
//
// compile-pass

use std::cell::RefCell;
use std::rc::Rc;

trait Trait: 'static {}

struct Store<C> {
inner: Rc<RefCell<Option<C>>>,
}

fn main() {
let store = Store::<Box<for<'a> fn(&(dyn Trait + 'a))>> {
inner: Default::default(),
};
}
39 changes: 39 additions & 0 deletions src/test/ui/generator/issue-53548.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Regression test for #53548. The `Box<dyn Trait>` type below is
// expanded to `Box<dyn Trait + 'static>`, but the generator "witness"
// that results is `for<'r> { Box<dyn Trait + 'r> }`. The WF code was
// encountering an ICE (when debug-assertions were enabled) and an
// unexpected compilation error (without debug-asserions) when trying
// to process this `'r` region bound. In particular, to be WF, the
// region bound must meet the requirements of the trait, and hence we
// got `for<'r> { 'r: 'static }`. This would ICE because the `Binder`
// constructor we were using was assering that no higher-ranked
// regions were involved (because the WF code is supposed to skip
// those). The error (if debug-asserions were disabled) came because
// we obviously cannot prove that `'r: 'static` for any region `'r`.
// Pursuant with our "lazy WF" strategy for higher-ranked regions, the
// fix is not to require that `for<'r> { 'r: 'static }` holds (this is
// also analogous to what we would do for higher-ranked regions
// appearing within the trait in other positions).
//
// compile-pass

#![feature(generators)]

use std::cell::RefCell;
use std::rc::Rc;

trait Trait: 'static {}

struct Store<C> {
inner: Rc<RefCell<Option<C>>>,
}

fn main() {
Box::new(static move || {
let store = Store::<Box<dyn Trait>> {
inner: Default::default(),
};
yield ();
});
}

18 changes: 18 additions & 0 deletions src/test/ui/lint/lint-dead-code-impl-trait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![deny(dead_code)]

trait Trait {
type Type;
}

impl Trait for () {
type Type = ();
}

type Used = ();
type Unused = (); //~ ERROR type alias is never used

fn foo() -> impl Trait<Type = Used> {}

fn main() {
foo();
}
14 changes: 14 additions & 0 deletions src/test/ui/lint/lint-dead-code-impl-trait.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: type alias is never used: `Unused`
--> $DIR/lint-dead-code-impl-trait.rs:12:1
|
LL | type Unused = ();
| ^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/lint-dead-code-impl-trait.rs:1:9
|
LL | #![deny(dead_code)]
| ^^^^^^^^^

error: aborting due to previous error

13 changes: 6 additions & 7 deletions src/test/ui/nll/trait-associated-constant.rs
Original file line number Diff line number Diff line change
@@ -9,24 +9,23 @@ trait Anything<'a: 'b, 'b> {
const AC: Option<&'b str>;
}

struct OKStruct { }
struct OKStruct1 { }

impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct {
impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct1 {
const AC: Option<&'b str> = None;
}

struct FailStruct1 { }
struct FailStruct { }

impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 {
impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
const AC: Option<&'c str> = None;
//~^ ERROR: mismatched types
}

struct FailStruct2 { }
struct OKStruct2 { }

impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 {
impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct2 {
const AC: Option<&'a str> = None;
//~^ ERROR: mismatched types
}

fn main() {}
25 changes: 3 additions & 22 deletions src/test/ui/nll/trait-associated-constant.stderr
Original file line number Diff line number Diff line change
@@ -9,33 +9,14 @@ LL | const AC: Option<&'c str> = None;
note: the lifetime 'c as defined on the impl at 20:18...
--> $DIR/trait-associated-constant.rs:20:18
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 {
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 20:14
--> $DIR/trait-associated-constant.rs:20:14
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct1 {
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
| ^^

error[E0308]: mismatched types
--> $DIR/trait-associated-constant.rs:28:5
|
LL | const AC: Option<&'a str> = None;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected type `std::option::Option<&'b str>`
found type `std::option::Option<&'a str>`
note: the lifetime 'a as defined on the impl at 27:6...
--> $DIR/trait-associated-constant.rs:27:6
|
LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 {
| ^^
note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 27:14
--> $DIR/trait-associated-constant.rs:27:14
|
LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 {
| ^^

error: aborting due to 2 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
8 changes: 8 additions & 0 deletions src/test/ui/parser/numeric-lifetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct S<'1> { s: &'1 usize }
//~^ ERROR lifetimes cannot start with a number
//~| ERROR lifetimes cannot start with a number
fn main() {
// verify that the parse error doesn't stop type checking
let x: usize = "";
//~^ ERROR mismatched types
}
24 changes: 24 additions & 0 deletions src/test/ui/parser/numeric-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: lifetimes cannot start with a number
--> $DIR/numeric-lifetime.rs:1:10
|
LL | struct S<'1> { s: &'1 usize }
| ^^

error: lifetimes cannot start with a number
--> $DIR/numeric-lifetime.rs:1:20
|
LL | struct S<'1> { s: &'1 usize }
| ^^

error[E0308]: mismatched types
--> $DIR/numeric-lifetime.rs:6:20
|
LL | let x: usize = "";
| ^^ expected usize, found reference
|
= note: expected type `usize`
found type `&'static str`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.