Rollup merge of #57798 - hellow554:master, r=davidtwco
Corrected spelling inconsistency
resolves #57773
diff --git a/src/libcore/benches/fmt.rs b/src/libcore/benches/fmt.rs
new file mode 100644
index 0000000..92f10c7
--- /dev/null
+++ b/src/libcore/benches/fmt.rs
@@ -0,0 +1,110 @@
+use std::io::{self, Write as IoWrite};
+use std::fmt::{self, Write as FmtWrite};
+use test::Bencher;
+
+#[bench]
+fn write_vec_value(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = Vec::new();
+ for _ in 0..1000 {
+ mem.write_all("abc".as_bytes()).unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_vec_ref(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = Vec::new();
+ let wr = &mut mem as &mut dyn io::Write;
+ for _ in 0..1000 {
+ wr.write_all("abc".as_bytes()).unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_vec_macro1(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = Vec::new();
+ let wr = &mut mem as &mut dyn io::Write;
+ for _ in 0..1000 {
+ write!(wr, "abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_vec_macro2(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = Vec::new();
+ let wr = &mut mem as &mut dyn io::Write;
+ for _ in 0..1000 {
+ write!(wr, "{}", "abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_vec_macro_debug(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = Vec::new();
+ let wr = &mut mem as &mut dyn io::Write;
+ for _ in 0..1000 {
+ write!(wr, "{:?}", "☃").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_str_value(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = String::new();
+ for _ in 0..1000 {
+ mem.write_str("abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_str_ref(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = String::new();
+ let wr = &mut mem as &mut dyn fmt::Write;
+ for _ in 0..1000 {
+ wr.write_str("abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_str_macro1(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = String::new();
+ for _ in 0..1000 {
+ write!(mem, "abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_str_macro2(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = String::new();
+ let wr = &mut mem as &mut dyn fmt::Write;
+ for _ in 0..1000 {
+ write!(wr, "{}", "abc").unwrap();
+ }
+ });
+}
+
+#[bench]
+fn write_str_macro_debug(bh: &mut Bencher) {
+ bh.iter(|| {
+ let mut mem = String::new();
+ let wr = &mut mem as &mut dyn fmt::Write;
+ for _ in 0..1000 {
+ write!(wr, "{:?}", "☃").unwrap();
+ }
+ });
+}
diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs
index 5b4971c..48572af 100644
--- a/src/libcore/benches/lib.rs
+++ b/src/libcore/benches/lib.rs
@@ -11,3 +11,4 @@
mod num;
mod ops;
mod slice;
+mod fmt;
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 5221d6f..935579f 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1006,28 +1006,30 @@
curarg: args.args.iter(),
};
- let mut pieces = args.pieces.iter();
+ let mut idx = 0;
match args.fmt {
None => {
// We can use default formatting parameters for all arguments.
- for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
+ for (arg, piece) in args.args.iter().zip(args.pieces.iter()) {
formatter.buf.write_str(*piece)?;
(arg.formatter)(arg.value, &mut formatter)?;
+ idx += 1;
}
}
Some(fmt) => {
// Every spec has a corresponding argument that is preceded by
// a string piece.
- for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
+ for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
formatter.buf.write_str(*piece)?;
formatter.run(arg)?;
+ idx += 1;
}
}
}
// There can be only one trailing string piece left.
- if let Some(piece) = pieces.next() {
+ if let Some(piece) = args.pieces.get(idx) {
formatter.buf.write_str(*piece)?;
}
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 6827364..41caa17 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -10,9 +10,9 @@
use str::FromStr;
macro_rules! impl_nonzero_fmt {
- ( ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+ ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
- #[stable(feature = "nonzero", since = "1.28.0")]
+ #[$stability]
impl fmt::$Trait for $Ty {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -31,7 +31,7 @@
}
macro_rules! nonzero_integers {
- ( $( $Ty: ident($Int: ty); )+ ) => {
+ ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
$(
doc_comment! {
concat!("An integer that is known not to equal zero.
@@ -41,10 +41,10 @@
```rust
use std::mem::size_of;
-assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
+assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
- #[stable(feature = "nonzero", since = "1.28.0")]
+ #[$stability]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
@@ -57,14 +57,14 @@
/// # Safety
///
/// The value must not be zero.
- #[stable(feature = "nonzero", since = "1.28.0")]
+ #[$stability]
#[inline]
pub const unsafe fn new_unchecked(n: $Int) -> Self {
$Ty(n)
}
/// Create a non-zero if the given value is not zero.
- #[stable(feature = "nonzero", since = "1.28.0")]
+ #[$stability]
#[inline]
pub fn new(n: $Int) -> Option<Self> {
if n != 0 {
@@ -75,7 +75,7 @@
}
/// Returns the value as a primitive type.
- #[stable(feature = "nonzero", since = "1.28.0")]
+ #[$stability]
#[inline]
pub const fn get(self) -> $Int {
self.0
@@ -91,19 +91,25 @@
}
impl_nonzero_fmt! {
- (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+ #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}
)+
}
}
nonzero_integers! {
- NonZeroU8(u8);
- NonZeroU16(u16);
- NonZeroU32(u32);
- NonZeroU64(u64);
- NonZeroU128(u128);
- NonZeroUsize(usize);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
+ #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
+ #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}
/// Provides intentionally-wrapped arithmetic on `T`.
diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs
index 6cfa367..d4ed861 100644
--- a/src/libcore/ops/index.rs
+++ b/src/libcore/ops/index.rs
@@ -51,21 +51,6 @@
/// ```
#[lang = "index"]
#[rustc_on_unimplemented(
- on(
- _Self="&str",
- note="you can use `.chars().nth()` or `.bytes().nth()`
-see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
- ),
- on(
- _Self="str",
- note="you can use `.chars().nth()` or `.bytes().nth()`
-see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
- ),
- on(
- _Self="std::string::String",
- note="you can use `.chars().nth()` or `.bytes().nth()`
-see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
- ),
message="the type `{Self}` cannot be indexed by `{Idx}`",
label="`{Self}` cannot be indexed by `{Idx}`",
)]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index df4d97e..9f9515e 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -2383,7 +2383,6 @@
}
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
impl<T, I> ops::Index<I> for [T]
where I: SliceIndex<[T]>
{
@@ -2396,7 +2395,6 @@
}
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
impl<T, I> ops::IndexMut<I> for [T]
where I: SliceIndex<[T]>
{
@@ -2447,7 +2445,19 @@
/// A helper trait used for indexing operations.
#[stable(feature = "slice_get_slice", since = "1.28.0")]
-#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
+#[rustc_on_unimplemented(
+ on(
+ T = "str",
+ label = "string indices are ranges of `usize`",
+ ),
+ on(
+ all(any(T = "str", T = "&str", T = "std::string::String"), _Self="{integer}"),
+ note="you can use `.chars().nth()` or `.bytes().nth()`
+see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
+ ),
+ message = "the type `{T}` cannot be indexed by `{Self}`",
+ label = "slice indices are of type `usize` or ranges of `usize`",
+)]
pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// The output type returned by methods.
#[stable(feature = "slice_get_slice", since = "1.28.0")]
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index bdde187..1ee8b77 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1621,190 +1621,26 @@
}
}
- /// Implements substring slicing with syntax `&self[begin .. end]`.
- ///
- /// Returns a slice of the given string from the byte range
- /// [`begin`..`end`).
- ///
- /// This operation is `O(1)`.
- ///
- /// # Panics
- ///
- /// Panics if `begin` or `end` does not point to the starting
- /// byte offset of a character (as defined by `is_char_boundary`).
- /// Requires that `begin <= end` and `end <= len` where `len` is the
- /// length of the string.
- ///
- /// # Examples
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- /// assert_eq!(&s[0 .. 1], "L");
- ///
- /// assert_eq!(&s[1 .. 9], "öwe 老");
- ///
- /// // these will panic:
- /// // byte 2 lies within `ö`:
- /// // &s[2 ..3];
- ///
- /// // byte 8 lies within `老`
- /// // &s[1 .. 8];
- ///
- /// // byte 100 is outside the string
- /// // &s[3 .. 100];
- /// ```
#[stable(feature = "rust1", since = "1.0.0")]
- impl ops::Index<ops::Range<usize>> for str {
- type Output = str;
+ impl<I> ops::Index<I> for str
+ where
+ I: SliceIndex<str>,
+ {
+ type Output = I::Output;
+
#[inline]
- fn index(&self, index: ops::Range<usize>) -> &str {
+ fn index(&self, index: I) -> &I::Output {
index.index(self)
}
}
- /// Implements mutable substring slicing with syntax
- /// `&mut self[begin .. end]`.
- ///
- /// Returns a mutable slice of the given string from the byte range
- /// [`begin`..`end`).
- ///
- /// This operation is `O(1)`.
- ///
- /// # Panics
- ///
- /// Panics if `begin` or `end` does not point to the starting
- /// byte offset of a character (as defined by `is_char_boundary`).
- /// Requires that `begin <= end` and `end <= len` where `len` is the
- /// length of the string.
- #[stable(feature = "derefmut_for_string", since = "1.3.0")]
- impl ops::IndexMut<ops::Range<usize>> for str {
- #[inline]
- fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
- index.index_mut(self)
- }
- }
-
- /// Implements substring slicing with syntax `&self[.. end]`.
- ///
- /// Returns a slice of the string from the beginning to byte offset
- /// `end`.
- ///
- /// Equivalent to `&self[0 .. end]`.
#[stable(feature = "rust1", since = "1.0.0")]
- impl ops::Index<ops::RangeTo<usize>> for str {
- type Output = str;
-
+ impl<I> ops::IndexMut<I> for str
+ where
+ I: SliceIndex<str>,
+ {
#[inline]
- fn index(&self, index: ops::RangeTo<usize>) -> &str {
- index.index(self)
- }
- }
-
- /// Implements mutable substring slicing with syntax `&mut self[.. end]`.
- ///
- /// Returns a mutable slice of the string from the beginning to byte offset
- /// `end`.
- ///
- /// Equivalent to `&mut self[0 .. end]`.
- #[stable(feature = "derefmut_for_string", since = "1.3.0")]
- impl ops::IndexMut<ops::RangeTo<usize>> for str {
- #[inline]
- fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
- index.index_mut(self)
- }
- }
-
- /// Implements substring slicing with syntax `&self[begin ..]`.
- ///
- /// Returns a slice of the string from byte offset `begin`
- /// to the end of the string.
- ///
- /// Equivalent to `&self[begin .. len]`.
- #[stable(feature = "rust1", since = "1.0.0")]
- impl ops::Index<ops::RangeFrom<usize>> for str {
- type Output = str;
-
- #[inline]
- fn index(&self, index: ops::RangeFrom<usize>) -> &str {
- index.index(self)
- }
- }
-
- /// Implements mutable substring slicing with syntax `&mut self[begin ..]`.
- ///
- /// Returns a mutable slice of the string from byte offset `begin`
- /// to the end of the string.
- ///
- /// Equivalent to `&mut self[begin .. len]`.
- #[stable(feature = "derefmut_for_string", since = "1.3.0")]
- impl ops::IndexMut<ops::RangeFrom<usize>> for str {
- #[inline]
- fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
- index.index_mut(self)
- }
- }
-
- /// Implements substring slicing with syntax `&self[..]`.
- ///
- /// Returns a slice of the whole string. This operation can
- /// never panic.
- ///
- /// Equivalent to `&self[0 .. len]`.
- #[stable(feature = "rust1", since = "1.0.0")]
- impl ops::Index<ops::RangeFull> for str {
- type Output = str;
-
- #[inline]
- fn index(&self, _index: ops::RangeFull) -> &str {
- self
- }
- }
-
- /// Implements mutable substring slicing with syntax `&mut self[..]`.
- ///
- /// Returns a mutable slice of the whole string. This operation can
- /// never panic.
- ///
- /// Equivalent to `&mut self[0 .. len]`.
- #[stable(feature = "derefmut_for_string", since = "1.3.0")]
- impl ops::IndexMut<ops::RangeFull> for str {
- #[inline]
- fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
- self
- }
- }
-
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- impl ops::Index<ops::RangeInclusive<usize>> for str {
- type Output = str;
-
- #[inline]
- fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
- index.index(self)
- }
- }
-
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- impl ops::Index<ops::RangeToInclusive<usize>> for str {
- type Output = str;
-
- #[inline]
- fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
- index.index(self)
- }
- }
-
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
- #[inline]
- fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
- index.index_mut(self)
- }
- }
- #[stable(feature = "inclusive_range", since = "1.26.0")]
- impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
- #[inline]
- fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
+ fn index_mut(&mut self, index: I) -> &mut I::Output {
index.index_mut(self)
}
}
@@ -1815,6 +1651,18 @@
panic!("attempted to index str up to maximum usize");
}
+ /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`.
+ ///
+ /// Returns a slice of the whole string, i.e., returns `&self` or `&mut
+ /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
+ /// other indexing operations, this can never panic.
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// Prior to 1.20.0, these indexing operations were still supported by
+ /// direct implementation of `Index` and `IndexMut`.
+ ///
+ /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
impl SliceIndex<str> for ops::RangeFull {
type Output = str;
@@ -1844,6 +1692,41 @@
}
}
+ /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut
+ /// self[begin .. end]`.
+ ///
+ /// Returns a slice of the given string from the byte range
+ /// [`begin`, `end`).
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// Prior to 1.20.0, these indexing operations were still supported by
+ /// direct implementation of `Index` and `IndexMut`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `begin` or `end` does not point to the starting byte offset of
+ /// a character (as defined by `is_char_boundary`), if `begin > end`, or if
+ /// `end > len`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ /// assert_eq!(&s[0 .. 1], "L");
+ ///
+ /// assert_eq!(&s[1 .. 9], "öwe 老");
+ ///
+ /// // these will panic:
+ /// // byte 2 lies within `ö`:
+ /// // &s[2 ..3];
+ ///
+ /// // byte 8 lies within `老`
+ /// // &s[1 .. 8];
+ ///
+ /// // byte 100 is outside the string
+ /// // &s[3 .. 100];
+ /// ```
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
impl SliceIndex<str> for ops::Range<usize> {
type Output = str;
@@ -1898,6 +1781,21 @@
}
}
+ /// Implements substring slicing with syntax `&self[.. end]` or `&mut
+ /// self[.. end]`.
+ ///
+ /// Returns a slice of the given string from the byte range [`0`, `end`).
+ /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// Prior to 1.20.0, these indexing operations were still supported by
+ /// direct implementation of `Index` and `IndexMut`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `end` does not point to the starting byte offset of a
+ /// character (as defined by `is_char_boundary`), or if `end > len`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
impl SliceIndex<str> for ops::RangeTo<usize> {
type Output = str;
@@ -1943,6 +1841,22 @@
}
}
+ /// Implements substring slicing with syntax `&self[begin ..]` or `&mut
+ /// self[begin ..]`.
+ ///
+ /// Returns a slice of the given string from the byte range [`begin`,
+ /// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin ..
+ /// len]`.
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// Prior to 1.20.0, these indexing operations were still supported by
+ /// direct implementation of `Index` and `IndexMut`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `begin` does not point to the starting byte offset of
+ /// a character (as defined by `is_char_boundary`), or if `begin >= len`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
impl SliceIndex<str> for ops::RangeFrom<usize> {
type Output = str;
@@ -1990,6 +1904,22 @@
}
}
+ /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut
+ /// self[begin ..= end]`.
+ ///
+ /// Returns a slice of the given string from the byte range
+ /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut
+ /// self[begin .. end + 1]`, except if `end` has the maximum value for
+ /// `usize`.
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `begin` does not point to the starting byte offset of
+ /// a character (as defined by `is_char_boundary`), if `end` does not point
+ /// to the ending byte offset of a character (`end + 1` is either a starting
+ /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
#[stable(feature = "inclusive_range", since = "1.26.0")]
impl SliceIndex<str> for ops::RangeInclusive<usize> {
type Output = str;
@@ -2023,8 +1953,20 @@
}
}
-
-
+ /// Implements substring slicing with syntax `&self[..= end]` or `&mut
+ /// self[..= end]`.
+ ///
+ /// Returns a slice of the given string from the byte range [0, `end`].
+ /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
+ /// value for `usize`.
+ ///
+ /// This operation is `O(1)`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `end` does not point to the ending byte offset of a character
+ /// (`end + 1` is either a starting byte offset as defined by
+ /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
#[stable(feature = "inclusive_range", since = "1.26.0")]
impl SliceIndex<str> for ops::RangeToInclusive<usize> {
type Output = str;
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index c813bf2..4532568 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -1,4 +1,4 @@
-use core::num::NonZeroU32;
+use core::num::{NonZeroU32, NonZeroI32};
use core::option::Option;
use core::option::Option::{Some, None};
use std::mem::size_of;
@@ -13,6 +13,7 @@
#[test]
fn test_size_nonzero_in_option() {
assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
+ assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
}
#[test]
@@ -118,3 +119,10 @@
let num: u32 = nz.into();
assert_eq!(num, 1u32);
}
+
+#[test]
+fn test_from_signed_nonzero() {
+ let nz = NonZeroI32::new(1).unwrap();
+ let num: i32 = nz.into();
+ assert_eq!(num, 1i32);
+}
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 32ae878..da440cd 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -72,6 +72,15 @@
ArgumentNamed(&'a str),
}
+impl Position<'_> {
+ pub fn index(&self) -> Option<usize> {
+ match self {
+ ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i),
+ _ => None,
+ }
+ }
+}
+
/// Enum of alignments which are supported.
#[derive(Copy, Clone, PartialEq)]
pub enum Alignment {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 367a7ea..1c92e2d 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -471,7 +471,7 @@
}
fn report_similar_impl_candidates(&self,
- mut impl_candidates: Vec<ty::TraitRef<'tcx>>,
+ impl_candidates: Vec<ty::TraitRef<'tcx>>,
err: &mut DiagnosticBuilder<'_>)
{
if impl_candidates.is_empty() {
@@ -497,14 +497,18 @@
});
// Sort impl candidates so that ordering is consistent for UI tests.
- let normalized_impl_candidates = &mut impl_candidates[0..end]
+ let mut normalized_impl_candidates = impl_candidates
.iter()
.map(normalize)
.collect::<Vec<String>>();
+
+ // Sort before taking the `..end` range,
+ // because the ordering of `impl_candidates` may not be deterministic:
+ // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507
normalized_impl_candidates.sort();
err.help(&format!("the following implementations were found:{}{}",
- normalized_impl_candidates.join(""),
+ normalized_impl_candidates[..end].join(""),
if len > 5 {
format!("\nand {} others", len - 4)
} else {
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index f5f4048..105856f 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -72,6 +72,7 @@
ecx.stack.push(interpret::Frame {
block: mir::START_BLOCK,
locals: IndexVec::new(),
+ local_layouts: IndexVec::new(),
instance,
span,
mir,
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 19362b6..b2d3328 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -1,3 +1,4 @@
+use std::cell::Cell;
use std::fmt::Write;
use std::mem;
@@ -76,6 +77,7 @@
/// `None` represents a local that is currently dead, while a live local
/// can either directly contain `Scalar` or refer to some part of an `Allocation`.
pub locals: IndexVec<mir::Local, LocalValue<Tag>>,
+ pub local_layouts: IndexVec<mir::Local, Cell<Option<TyLayout<'tcx>>>>,
////////////////////////////////////////////////////////////////////////////////
// Current position within the function
@@ -290,9 +292,15 @@
frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
local: mir::Local
) -> EvalResult<'tcx, TyLayout<'tcx>> {
- let local_ty = frame.mir.local_decls[local].ty;
- let local_ty = self.monomorphize(local_ty, frame.instance.substs);
- self.layout_of(local_ty)
+ let cell = &frame.local_layouts[local];
+ if cell.get().is_none() {
+ let local_ty = frame.mir.local_decls[local].ty;
+ let local_ty = self.monomorphize(local_ty, frame.instance.substs);
+ let layout = self.layout_of(local_ty)?;
+ cell.set(Some(layout));
+ }
+
+ Ok(cell.get().unwrap())
}
pub fn str_to_immediate(&mut self, s: &str) -> EvalResult<'tcx, Immediate<M::PointerTag>> {
@@ -426,6 +434,7 @@
// empty local array, we fill it in below, after we are inside the stack frame and
// all methods actually know about the frame
locals: IndexVec::new(),
+ local_layouts: IndexVec::from_elem_n(Default::default(), mir.local_decls.len()),
span,
instance,
stmt: 0,
@@ -464,11 +473,11 @@
},
}
// Finally, properly initialize all those that still have the dummy value
- for (local, decl) in locals.iter_mut().zip(mir.local_decls.iter()) {
+ for (idx, local) in locals.iter_enumerated_mut() {
match *local {
LocalValue::Live(_) => {
// This needs to be peoperly initialized.
- let layout = self.layout_of(self.monomorphize(decl.ty, instance.substs))?;
+ let layout = self.layout_of_local(self.frame(), idx)?;
*local = LocalValue::Live(self.uninit_operand(layout)?);
}
LocalValue::Dead => {
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 04e0955..b264848 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -457,36 +457,30 @@
}
/// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local
- ///
- /// When you know the layout of the local in advance, you can pass it as last argument
- pub fn access_local(
+ fn access_local(
&self,
frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
local: mir::Local,
- layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
assert_ne!(local, mir::RETURN_PLACE);
let op = *frame.locals[local].access()?;
- let layout = from_known_layout(layout,
- || self.layout_of_local(frame, local))?;
+ let layout = self.layout_of_local(frame, local)?;
Ok(OpTy { op, layout })
}
// Evaluate a place with the goal of reading from it. This lets us sometimes
- // avoid allocations. If you already know the layout, you can pass it in
- // to avoid looking it up again.
+ // avoid allocations.
fn eval_place_to_op(
&self,
mir_place: &mir::Place<'tcx>,
- layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
let op = match *mir_place {
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
- Local(local) => self.access_local(self.frame(), local, layout)?,
+ Local(local) => self.access_local(self.frame(), local)?,
Projection(ref proj) => {
- let op = self.eval_place_to_op(&proj.base, None)?;
+ let op = self.eval_place_to_op(&proj.base)?;
self.operand_projection(op, &proj.elem)?
}
@@ -510,7 +504,7 @@
// FIXME: do some more logic on `move` to invalidate the old location
Copy(ref place) |
Move(ref place) =>
- self.eval_place_to_op(place, layout)?,
+ self.eval_place_to_op(place)?,
Constant(ref constant) => {
let layout = from_known_layout(layout, || {
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index f9ce7b4..5310526 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -314,13 +314,14 @@
stmt: usize,
}
-impl_stable_hash_for!(impl<'tcx, 'mir: 'tcx> for struct Frame<'mir, 'tcx> {
+impl_stable_hash_for!(impl<'mir, 'tcx: 'mir> for struct Frame<'mir, 'tcx> {
mir,
instance,
span,
return_to_block,
return_place -> (return_place.as_ref().map(|r| &**r)),
locals,
+ local_layouts -> _,
block,
stmt,
extra,
@@ -339,6 +340,7 @@
return_to_block,
return_place,
locals,
+ local_layouts: _,
block,
stmt,
extra: _,
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 987cec6..c34dcbb 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -177,7 +177,10 @@
root_path = page.root_path,
css_class = page.css_class,
logo = if layout.logo.is_empty() {
- String::new()
+ format!("<a href='{}{}/index.html'>\
+ <img src='{static_root_path}rust-logo{suffix}.png' alt='logo' width='100'></a>",
+ static_root_path=static_root_path,
+ suffix=page.resource_suffix)
} else {
format!("<a href='{}{}/index.html'>\
<img src='{}' alt='logo' width='100'></a>",
@@ -188,7 +191,9 @@
description = page.description,
keywords = page.keywords,
favicon = if layout.favicon.is_empty() {
- String::new()
+ format!(r#"<link rel="shortcut icon" href="{static_root_path}favicon{suffix}.ico">"#,
+ static_root_path=static_root_path,
+ suffix=page.resource_suffix)
} else {
format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
},
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ad1659b..86fb514 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -789,6 +789,14 @@
themes.insert(theme.to_owned());
}
+ if (*cx.shared).layout.logo.is_empty() {
+ write(cx.dst.join(&format!("rust-logo{}.png", cx.shared.resource_suffix)),
+ static_files::RUST_LOGO)?;
+ }
+ if (*cx.shared).layout.favicon.is_empty() {
+ write(cx.dst.join(&format!("favicon{}.ico", cx.shared.resource_suffix)),
+ static_files::RUST_FAVICON)?;
+ }
write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)),
static_files::BRUSH_SVG)?;
write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
@@ -2068,8 +2076,6 @@
themes.push(PathBuf::from("settings.css"));
let mut layout = self.shared.layout.clone();
layout.krate = String::new();
- layout.logo = String::new();
- layout.favicon = String::new();
try_err!(layout::render(&mut w, &layout,
&page, &sidebar, &settings,
self.shared.css_file_extension.is_some(),
diff --git a/src/librustdoc/html/static/favicon.ico b/src/librustdoc/html/static/favicon.ico
new file mode 100644
index 0000000..b8ad237
--- /dev/null
+++ b/src/librustdoc/html/static/favicon.ico
Binary files differ
diff --git a/src/librustdoc/html/static/rust-logo.png b/src/librustdoc/html/static/rust-logo.png
new file mode 100644
index 0000000..74b4bd6
--- /dev/null
+++ b/src/librustdoc/html/static/rust-logo.png
Binary files differ
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index f340590..a1d8cfa 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -51,6 +51,11 @@
/// The contents of `LICENSE-MIT.txt`, the text of the MIT License.
pub static LICENSE_MIT: &'static [u8] = include_bytes!("static/LICENSE-MIT.txt");
+/// The contents of `rust-logo.png`, the default icon of the documentation.
+pub static RUST_LOGO: &'static [u8] = include_bytes!("static/rust-logo.png");
+/// The contents of `favicon.ico`, the default favicon of the documentation.
+pub static RUST_FAVICON: &'static [u8] = include_bytes!("static/favicon.ico");
+
/// The built-in themes given to every documentation site.
pub mod themes {
/// The "light" theme, selected by default when no setting is available. Used as the basis for
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index bb1744e..3effe53 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -101,6 +101,7 @@
// Recreate self from the raw pointer.
Some(P { ptr: Box::from_raw(p) })
} else {
+ drop(Box::from_raw(p));
None
}
}
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 3e3bca7..215df42 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -493,7 +493,10 @@
let fill = arg.format.fill.unwrap_or(' ');
- if *arg != simple_arg || fill != ' ' {
+ let pos_simple =
+ arg.position.index() == simple_arg.position.index();
+
+ if !pos_simple || arg.format != simple_arg.format || fill != ' ' {
self.all_pieces_simple = false;
}
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index 140f98b..d6d5ce4 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -8,7 +8,7 @@
<Bar as Foo<i16>>
<Bar as Foo<i32>>
<Bar as Foo<i8>>
- <Bar as Foo<u8>>
+ <Bar as Foo<u16>>
and 2 others
error: aborting due to previous error
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 2346698..3411958 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -40,10 +40,10 @@
| ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool`
|
= help: the following implementations were found:
+ <bool as Foo<bool>>
+ <bool as Foo<i8>>
<bool as Foo<u16>>
<bool as Foo<u32>>
- <bool as Foo<u64>>
- <bool as Foo<u8>>
and 2 others
note: required by `Foo::bar`
--> $DIR/issue-39802-show-5-trait-impls.rs:2:5
diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr
index c8b23d8..4c585a9 100644
--- a/src/test/ui/index-help.stderr
+++ b/src/test/ui/index-help.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not satisfied
+error[E0277]: the type `[{integer}]` cannot be indexed by `i32`
--> $DIR/index-help.rs:3:5
|
LL | x[0i32]; //~ ERROR E0277
diff --git a/src/test/ui/indexing-requires-a-uint.rs b/src/test/ui/indexing-requires-a-uint.rs
index 2db3c58..dbe9b44 100644
--- a/src/test/ui/indexing-requires-a-uint.rs
+++ b/src/test/ui/indexing-requires-a-uint.rs
@@ -3,7 +3,7 @@
fn main() {
fn bar<T>(_: T) {}
- [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied
+ [0][0u8]; //~ ERROR: the type `[{integer}]` cannot be indexed by `u8`
[0][0]; // should infer to be a usize
diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr
index 767f1af..363c3d0 100644
--- a/src/test/ui/indexing-requires-a-uint.stderr
+++ b/src/test/ui/indexing-requires-a-uint.stderr
@@ -1,7 +1,7 @@
-error[E0277]: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied
+error[E0277]: the type `[{integer}]` cannot be indexed by `u8`
--> $DIR/indexing-requires-a-uint.rs:6:5
|
-LL | [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied
+LL | [0][0u8]; //~ ERROR: the type `[{integer}]` cannot be indexed by `u8`
| ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `u8`
diff --git a/src/test/ui/integral-indexing.rs b/src/test/ui/integral-indexing.rs
index 7bdbc45..f076dfc 100644
--- a/src/test/ui/integral-indexing.rs
+++ b/src/test/ui/integral-indexing.rs
@@ -3,14 +3,14 @@
let s: String = "abcdef".to_string();
v[3_usize];
v[3];
- v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
- v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
- v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
- v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
+ v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8`
+ v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8`
+ v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32`
+ v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32`
s.as_bytes()[3_usize];
s.as_bytes()[3];
- s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
- s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
- s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
- s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
+ s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8`
+ s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8`
+ s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32`
+ s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32`
}
diff --git a/src/test/ui/integral-indexing.stderr b/src/test/ui/integral-indexing.stderr
index 7f2dddc..efbad86 100644
--- a/src/test/ui/integral-indexing.stderr
+++ b/src/test/ui/integral-indexing.stderr
@@ -1,70 +1,70 @@
-error[E0277]: the trait bound `u8: std::slice::SliceIndex<[isize]>` is not satisfied
+error[E0277]: the type `[isize]` cannot be indexed by `u8`
--> $DIR/integral-indexing.rs:6:5
|
-LL | v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
+LL | v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8`
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u8`
= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `std::vec::Vec<isize>`
-error[E0277]: the trait bound `i8: std::slice::SliceIndex<[isize]>` is not satisfied
+error[E0277]: the type `[isize]` cannot be indexed by `i8`
--> $DIR/integral-indexing.rs:7:5
|
-LL | v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
+LL | v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8`
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i8`
= note: required because of the requirements on the impl of `std::ops::Index<i8>` for `std::vec::Vec<isize>`
-error[E0277]: the trait bound `u32: std::slice::SliceIndex<[isize]>` is not satisfied
+error[E0277]: the type `[isize]` cannot be indexed by `u32`
--> $DIR/integral-indexing.rs:8:5
|
-LL | v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
+LL | v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32`
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u32`
= note: required because of the requirements on the impl of `std::ops::Index<u32>` for `std::vec::Vec<isize>`
-error[E0277]: the trait bound `i32: std::slice::SliceIndex<[isize]>` is not satisfied
+error[E0277]: the type `[isize]` cannot be indexed by `i32`
--> $DIR/integral-indexing.rs:9:5
|
-LL | v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
+LL | v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32`
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `std::vec::Vec<isize>`
-error[E0277]: the trait bound `u8: std::slice::SliceIndex<[u8]>` is not satisfied
+error[E0277]: the type `[u8]` cannot be indexed by `u8`
--> $DIR/integral-indexing.rs:12:5
|
-LL | s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
+LL | s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8`
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u8`
= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `[u8]`
-error[E0277]: the trait bound `i8: std::slice::SliceIndex<[u8]>` is not satisfied
+error[E0277]: the type `[u8]` cannot be indexed by `i8`
--> $DIR/integral-indexing.rs:13:5
|
-LL | s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
+LL | s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8`
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i8`
= note: required because of the requirements on the impl of `std::ops::Index<i8>` for `[u8]`
-error[E0277]: the trait bound `u32: std::slice::SliceIndex<[u8]>` is not satisfied
+error[E0277]: the type `[u8]` cannot be indexed by `u32`
--> $DIR/integral-indexing.rs:14:5
|
-LL | s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
+LL | s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32`
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u32`
= note: required because of the requirements on the impl of `std::ops::Index<u32>` for `[u8]`
-error[E0277]: the trait bound `i32: std::slice::SliceIndex<[u8]>` is not satisfied
+error[E0277]: the type `[u8]` cannot be indexed by `i32`
--> $DIR/integral-indexing.rs:15:5
|
-LL | s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
+LL | s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32`
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i32`
diff --git a/src/test/ui/issues/issue-54582.rs b/src/test/ui/issues/issue-54582.rs
new file mode 100644
index 0000000..c2dbf36
--- /dev/null
+++ b/src/test/ui/issues/issue-54582.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+pub trait Stage: Sync {}
+
+pub enum Enum {
+ A,
+ B,
+}
+
+impl Stage for Enum {}
+
+pub static ARRAY: [(&Stage, &str); 1] = [
+ (&Enum::A, ""),
+];
+
+fn main() {}
diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr
index 3a32e13..7b45d84 100644
--- a/src/test/ui/on-unimplemented/slice-index.stderr
+++ b/src/test/ui/on-unimplemented/slice-index.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied
+error[E0277]: the type `[i32]` cannot be indexed by `i32`
--> $DIR/slice-index.rs:11:5
|
LL | x[1i32]; //~ ERROR E0277
@@ -7,7 +7,7 @@
= help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`
-error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
+error[E0277]: the type `[i32]` cannot be indexed by `std::ops::RangeTo<i32>`
--> $DIR/slice-index.rs:12:5
|
LL | x[..1i32]; //~ ERROR E0277
diff --git a/src/test/ui/str/str-idx.rs b/src/test/ui/str/str-idx.rs
index 2ea8049..1b32ed5 100644
--- a/src/test/ui/str/str-idx.rs
+++ b/src/test/ui/str/str-idx.rs
@@ -1,4 +1,7 @@
pub fn main() {
let s: &str = "hello";
- let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
+ let _: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
+ let _ = s.get(4); //~ ERROR the type `str` cannot be indexed by `{integer}`
+ let _ = s.get_unchecked(4); //~ ERROR the type `str` cannot be indexed by `{integer}`
+ let _: u8 = s['c']; //~ ERROR the type `str` cannot be indexed by `char`
}
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index 71b1747..99df85d 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -1,13 +1,43 @@
error[E0277]: the type `str` cannot be indexed by `{integer}`
--> $DIR/str-idx.rs:3:17
|
-LL | let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
- | ^^^^ `str` cannot be indexed by `{integer}`
+LL | let _: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
+ | ^^^^ string indices are ranges of `usize`
|
- = help: the trait `std::ops::Index<{integer}>` is not implemented for `str`
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
+ = note: you can use `.chars().nth()` or `.bytes().nth()`
+ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+ = note: required because of the requirements on the impl of `std::ops::Index<{integer}>` for `str`
+
+error[E0277]: the type `str` cannot be indexed by `{integer}`
+ --> $DIR/str-idx.rs:4:15
+ |
+LL | let _ = s.get(4); //~ ERROR the type `str` cannot be indexed by `{integer}`
+ | ^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
= note: you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-error: aborting due to previous error
+error[E0277]: the type `str` cannot be indexed by `{integer}`
+ --> $DIR/str-idx.rs:5:15
+ |
+LL | let _ = s.get_unchecked(4); //~ ERROR the type `str` cannot be indexed by `{integer}`
+ | ^^^^^^^^^^^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
+ = note: you can use `.chars().nth()` or `.bytes().nth()`
+ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+
+error[E0277]: the type `str` cannot be indexed by `char`
+ --> $DIR/str-idx.rs:6:17
+ |
+LL | let _: u8 = s['c']; //~ ERROR the type `str` cannot be indexed by `char`
+ | ^^^^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `char`
+ = note: required because of the requirements on the impl of `std::ops::Index<char>` for `str`
+
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/str/str-mut-idx.rs b/src/test/ui/str/str-mut-idx.rs
index cebbbc3..575a9ea 100644
--- a/src/test/ui/str/str-mut-idx.rs
+++ b/src/test/ui/str/str-mut-idx.rs
@@ -5,7 +5,13 @@
//~^ ERROR the size for values of type
//~| ERROR the size for values of type
s[1usize] = bot();
- //~^ ERROR the type `str` cannot be mutably indexed by `usize`
+ //~^ ERROR the type `str` cannot be indexed by `usize`
+ s.get_mut(1);
+ //~^ ERROR the type `str` cannot be indexed by `{integer}`
+ s.get_unchecked_mut(1);
+ //~^ ERROR the type `str` cannot be indexed by `{integer}`
+ s['c'];
+ //~^ ERROR the type `str` cannot be indexed by `char`
}
pub fn main() {}
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index a1212c5..beb2272 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -22,16 +22,44 @@
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: the left-hand-side of an assignment must have a statically known size
-error[E0277]: the type `str` cannot be mutably indexed by `usize`
+error[E0277]: the type `str` cannot be indexed by `usize`
--> $DIR/str-mut-idx.rs:7:5
|
LL | s[1usize] = bot();
- | ^^^^^^^^^ `str` cannot be mutably indexed by `usize`
+ | ^^^^^^^^^ string indices are ranges of `usize`
|
- = help: the trait `std::ops::IndexMut<usize>` is not implemented for `str`
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `usize`
+ = note: required because of the requirements on the impl of `std::ops::Index<usize>` for `str`
+
+error[E0277]: the type `str` cannot be indexed by `{integer}`
+ --> $DIR/str-mut-idx.rs:9:7
+ |
+LL | s.get_mut(1);
+ | ^^^^^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
= note: you can use `.chars().nth()` or `.bytes().nth()`
see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
-error: aborting due to 3 previous errors
+error[E0277]: the type `str` cannot be indexed by `{integer}`
+ --> $DIR/str-mut-idx.rs:11:7
+ |
+LL | s.get_unchecked_mut(1);
+ | ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
+ = note: you can use `.chars().nth()` or `.bytes().nth()`
+ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
+
+error[E0277]: the type `str` cannot be indexed by `char`
+ --> $DIR/str-mut-idx.rs:13:5
+ |
+LL | s['c'];
+ | ^^^^^^ string indices are ranges of `usize`
+ |
+ = help: the trait `std::slice::SliceIndex<str>` is not implemented for `char`
+ = note: required because of the requirements on the impl of `std::ops::Index<char>` for `str`
+
+error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr
index 202885e..df8e646 100644
--- a/src/test/ui/try-block/try-block-bad-type.stderr
+++ b/src/test/ui/try-block/try-block-bad-type.stderr
@@ -6,10 +6,10 @@
|
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
+ <i32 as std::convert::From<core::num::NonZeroI32>>
<i32 as std::convert::From<i16>>
<i32 as std::convert::From<i8>>
- <i32 as std::convert::From<u16>>
- <i32 as std::convert::From<u8>>
+ and 2 others
= note: required by `std::convert::From::from`
error[E0271]: type mismatch resolving `<std::result::Result<i32, i32> as std::ops::Try>::Ok == &str`
diff --git a/src/tools/miri b/src/tools/miri
index 97f4cff..1cd85d2 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 97f4cff8e904c268569d37922a27835209deff5d
+Subproject commit 1cd85d2a2767b37f9869b719a74e3da99087c31a