mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 02:23:20 +00:00
Auto merge of #59151 - Centril:rollup, r=Centril
Rollup of 16 pull requests Successful merges: - #58829 (librustc_interface: Update scoped-tls to 1.0) - #58876 (Parse lifetimes that start with a number and give specific error) - #58908 (Update rand version) - #58998 (Fix documentation of from_ne_bytes and from_le_bytes) - #59056 (Use lifetime contravariance to elide more lifetimes in core+alloc+std) - #59057 (Standardize `Range*` documentation) - #59080 (Fix incorrect links in librustc_codegen_llvm documentation) - #59083 (Fix #54822 and associated faulty tests) - #59093 (Remove precompute_in_scope_traits_hashes) - #59101 (Reduces Code Repetitions like `!n >> amt`) - #59121 (impl FromIterator for Result: Use assert_eq! instead of assert!) - #59124 (Replace assert with assert_eq) - #59129 (Visit impl Trait for dead_code lint) - #59130 (Note that NonNull does not launder shared references for mutation) - #59132 (ignore higher-ranked object bound conditions created by WF) - #59138 (Simplify Iterator::{min, max}) Failed merges: r? @ghost
This commit is contained in:
commit
aa97448caf
@ -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",
|
||||
|
@ -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,7 +503,7 @@ 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
|
||||
@ -511,7 +511,7 @@ impl<'a, T: Copy> From<&'a [T]> for Box<[T]> {
|
||||
}
|
||||
|
||||
#[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())) }
|
||||
}
|
||||
}
|
||||
|
@ -1145,7 +1145,7 @@ 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)
|
||||
@ -1153,7 +1153,7 @@ impl<'a, T: Clone> From<&'a [T]> for Rc<[T]> {
|
||||
}
|
||||
|
||||
#[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());
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 })
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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")]
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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 } }
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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]");
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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<'_, '_, '_>,
|
||||
|
@ -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());
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
//! # 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
|
||||
@ -15,7 +15,7 @@
|
||||
//!
|
||||
//! 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.
|
||||
//!
|
||||
|
@ -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" }
|
||||
|
@ -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>;
|
||||
|
@ -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" }
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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> {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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!();
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -1423,14 +1423,16 @@ 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,
|
||||
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,
|
||||
|
@ -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() {}
|
||||
|
@ -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
src/test/ui/associated-const/associated-const-trait-bound.rs
Normal file
21
src/test/ui/associated-const/associated-const-trait-bound.rs
Normal file
@ -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
src/test/ui/generator/issue-53548-1.rs
Normal file
20
src/test/ui/generator/issue-53548-1.rs
Normal file
@ -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
src/test/ui/generator/issue-53548.rs
Normal file
39
src/test/ui/generator/issue-53548.rs
Normal file
@ -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
src/test/ui/lint/lint-dead-code-impl-trait.rs
Normal file
18
src/test/ui/lint/lint-dead-code-impl-trait.rs
Normal file
@ -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
src/test/ui/lint/lint-dead-code-impl-trait.stderr
Normal file
14
src/test/ui/lint/lint-dead-code-impl-trait.stderr
Normal file
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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
src/test/ui/parser/numeric-lifetime.rs
Normal file
8
src/test/ui/parser/numeric-lifetime.rs
Normal file
@ -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
src/test/ui/parser/numeric-lifetime.stderr
Normal file
24
src/test/ui/parser/numeric-lifetime.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user