Auto merge of #66277 - peter-wilkins:impl-from-wider-non-zeros, r=SimonSapin
From<NonZero*> impls for wider NonZero types
Closes: https://github.com/rust-lang/rust/issues/66291
diff --git a/Cargo.lock b/Cargo.lock
index 5484f24..1a8450e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -570,9 +570,9 @@
[[package]]
name = "compiler_builtins"
-version = "0.1.18"
+version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef1c086a06d6f52f9c0d50cacdc021bfb6034ddeec9fb7e62f099f13f65472f4"
+checksum = "e6f083abf9bb9005a27d2da62706f661245278cb7096da37ab27410eaf60f2c1"
dependencies = [
"cc",
"rustc-std-workspace-core",
@@ -2577,9 +2577,9 @@
[[package]]
name = "polonius-engine"
-version = "0.10.0"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50fa9dbfd0d3d60594da338cfe6f94028433eecae4b11b7e83fd99759227bbfe"
+checksum = "1e478d7c38eb785c6416cbe58df12aa55d7aefa3759b6d3e044b2ed03f423cec"
dependencies = [
"datafrog",
"log",
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
index 934380b..7c56708 160000
--- a/src/doc/rustc-guide
+++ b/src/doc/rustc-guide
@@ -1 +1 @@
-Subproject commit 934380b7cfceaaa4e1b9bb0de4a372f32725520b
+Subproject commit 7c56708aab7986ca390221e8e8902f7de7f9b076
diff --git a/src/liballoc/alloc/tests.rs b/src/liballoc/alloc/tests.rs
index 956298d..c902971 100644
--- a/src/liballoc/alloc/tests.rs
+++ b/src/liballoc/alloc/tests.rs
@@ -22,7 +22,7 @@
}
#[bench]
-#[cfg(not(miri))] // Miri does not support benchmarks
+#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn alloc_owned_small(b: &mut Bencher) {
b.iter(|| {
let _: Box<_> = box 10;
diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs
index 94b92df..1b1d8ea 100644
--- a/src/liballoc/collections/linked_list/tests.rs
+++ b/src/liballoc/collections/linked_list/tests.rs
@@ -182,7 +182,7 @@
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
-#[cfg(not(miri))] // Miri does not support threads
+#[cfg_attr(miri, ignore)] // Miri does not support threads
fn test_send() {
let n = list_from(&[1, 2, 3]);
thread::spawn(move || {
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
index 8dc097c..f2ce5b1 100644
--- a/src/liballoc/collections/vec_deque/tests.rs
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -3,7 +3,7 @@
use ::test;
#[bench]
-#[cfg(not(miri))] // Miri does not support benchmarks
+#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_push_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@@ -16,7 +16,7 @@
}
#[bench]
-#[cfg(not(miri))] // Miri does not support benchmarks
+#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_push_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::with_capacity(101);
b.iter(|| {
@@ -29,7 +29,7 @@
}
#[bench]
-#[cfg(not(miri))] // Miri does not support benchmarks
+#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_pop_back_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
@@ -43,7 +43,7 @@
}
#[bench]
-#[cfg(not(miri))] // Miri does not support benchmarks
+#[cfg_attr(miri, ignore)] // Miri does not support benchmarks
fn bench_pop_front_100(b: &mut test::Bencher) {
let mut deq = VecDeque::<i32>::with_capacity(101);
diff --git a/src/liballoc/sync/tests.rs b/src/liballoc/sync/tests.rs
index 9220f5e..9ddba49 100644
--- a/src/liballoc/sync/tests.rs
+++ b/src/liballoc/sync/tests.rs
@@ -29,7 +29,7 @@
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
-#[cfg(not(miri))] // Miri does not support threads
+#[cfg_attr(miri, ignore)] // Miri does not support threads
fn manually_share_arc() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arc_v = Arc::new(v);
@@ -334,7 +334,7 @@
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
-#[cfg(not(miri))] // Miri does not support threads
+#[cfg_attr(miri, ignore)] // Miri does not support threads
fn test_weak_count_locked() {
let mut a = Arc::new(atomic::AtomicBool::new(false));
let a2 = a.clone();
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index d9707b9..ec45de7 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -388,7 +388,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_sort() {
let mut rng = thread_rng();
@@ -1610,7 +1610,7 @@
let moduli = &[5, 20, 50];
#[cfg(miri)]
- let lens = (1..13);
+ let lens = 1..13;
#[cfg(miri)]
let moduli = &[10];
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index cb73c7c..1b01124 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -166,7 +166,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_unsafe_slice() {
assert_eq!("ab", unsafe {"abc".get_unchecked(0..2)});
assert_eq!("bc", unsafe {"abc".get_unchecked(1..3)});
@@ -483,8 +483,8 @@
}
#[test]
- #[cfg(not(target_os = "emscripten"))] // hits an OOM
- #[cfg(not(miri))] // Miri is too slow
+ #[cfg_attr(target_os = "emscripten", ignore)] // hits an OOM
+ #[cfg_attr(miri, ignore)] // Miri is too slow
fn simple_big() {
fn a_million_letter_x() -> String {
let mut i = 0;
@@ -1069,7 +1069,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_chars_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
@@ -1081,7 +1081,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_chars_rev_decoding() {
let mut bytes = [0; 4];
for c in (0..0x110000).filter_map(std::char::from_u32) {
@@ -1380,7 +1380,6 @@
assert_eq!("not even a boolean".parse::<bool>().ok(), None);
}
-#[cfg(not(miri))] // Miri is too slow
fn check_contains_all_substrings(s: &str) {
assert!(s.contains(""));
for i in 0..s.len() {
@@ -1391,7 +1390,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn strslice_issue_16589() {
assert!("bananas".contains("nana"));
@@ -1408,7 +1407,7 @@
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_strslice_contains() {
let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
check_contains_all_substrings(x);
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 55edf56..fe7b4ff 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -523,7 +523,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
@@ -601,7 +601,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 9ee254f..5e788d6 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -1080,7 +1080,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
@@ -1183,7 +1183,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 5a0162a..ebcc832 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -1100,7 +1100,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve() {
// These are the interesting cases:
// * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM)
@@ -1214,7 +1214,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not support signalling OOM
+#[cfg_attr(miri, ignore)] // Miri does not support signalling OOM
fn test_try_reserve_exact() {
// This is exactly the same as test_try_reserve with the method changed.
// See that test for comments.
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 66d27a2..854942d 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -202,53 +202,18 @@
#[inline]
pub fn alloc_from_iter<I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
assert!(mem::size_of::<T>() != 0);
- let mut iter = iter.into_iter();
- let size_hint = iter.size_hint();
-
- match size_hint {
- (min, Some(max)) if min == max => {
- // We know the exact number of elements the iterator will produce here
- let len = min;
-
- if len == 0 {
- return &mut [];
- }
-
- self.ensure_capacity(len);
-
- let slice = self.ptr.get();
-
- unsafe {
- let mut ptr = self.ptr.get();
- for _ in 0..len {
- // Write into uninitialized memory.
- ptr::write(ptr, iter.next().unwrap());
- // Advance the pointer.
- ptr = ptr.offset(1);
- // Update the pointer per iteration so if `iter.next()` panics
- // we destroy the correct amount
- self.ptr.set(ptr);
- }
- slice::from_raw_parts_mut(slice, len)
- }
- }
- _ => {
- cold_path(move || -> &mut [T] {
- let mut vec: SmallVec<[_; 8]> = iter.collect();
- if vec.is_empty() {
- return &mut [];
- }
- // Move the content to the arena by copying it and then forgetting
- // the content of the SmallVec
- unsafe {
- let len = vec.len();
- let start_ptr = self.alloc_raw_slice(len);
- vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
- vec.set_len(0);
- slice::from_raw_parts_mut(start_ptr, len)
- }
- })
- }
+ let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect();
+ if vec.is_empty() {
+ return &mut [];
+ }
+ // Move the content to the arena by copying it and then forgetting
+ // the content of the SmallVec
+ unsafe {
+ let len = vec.len();
+ let start_ptr = self.alloc_raw_slice(len);
+ vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
+ vec.set_len(0);
+ slice::from_raw_parts_mut(start_ptr, len)
}
}
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 20248f7..f37c57e 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -310,8 +310,7 @@
pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutErr> {
let new_size = self.size().checked_add(next.size())
.ok_or(LayoutErr { private: () })?;
- let layout = Layout::from_size_align(new_size, self.align())?;
- Ok(layout)
+ Layout::from_size_align(new_size, self.align())
}
/// Creates a layout describing the record for a `[T; n]`.
@@ -1143,9 +1142,9 @@
where Self: Sized
{
match Layout::array::<T>(n) {
- Ok(ref layout) if layout.size() > 0 => {
+ Ok(layout) if layout.size() > 0 => {
unsafe {
- self.alloc(layout.clone()).map(|p| p.cast())
+ self.alloc(layout).map(|p| p.cast())
}
}
_ => Err(AllocErr),
@@ -1193,9 +1192,9 @@
where Self: Sized
{
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new)) {
- (Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
+ (Ok(k_old), Ok(k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
debug_assert!(k_old.align() == k_new.align());
- self.realloc(ptr.cast(), k_old.clone(), k_new.size()).map(NonNull::cast)
+ self.realloc(ptr.cast(), k_old, k_new.size()).map(NonNull::cast)
}
_ => {
Err(AllocErr)
@@ -1227,8 +1226,8 @@
where Self: Sized
{
match Layout::array::<T>(n) {
- Ok(ref k) if k.size() > 0 => {
- Ok(self.dealloc(ptr.cast(), k.clone()))
+ Ok(k) if k.size() > 0 => {
+ Ok(self.dealloc(ptr.cast(), k))
}
_ => {
Err(AllocErr)
diff --git a/src/libcore/benches/any.rs b/src/libcore/benches/any.rs
index ceb507a..53099b7 100644
--- a/src/libcore/benches/any.rs
+++ b/src/libcore/benches/any.rs
@@ -1,5 +1,5 @@
use core::any::*;
-use test::{Bencher, black_box};
+use test::{black_box, Bencher};
#[bench]
fn bench_downcast_ref(b: &mut Bencher) {
diff --git a/src/libcore/benches/ascii.rs b/src/libcore/benches/ascii.rs
index e921dd1..76ccd3d 100644
--- a/src/libcore/benches/ascii.rs
+++ b/src/libcore/benches/ascii.rs
@@ -22,17 +22,9 @@
//
// Therefore:
fn branchless_to_ascii_upper_case(byte: u8) -> u8 {
- byte &
- !(
- (
- byte.wrapping_add(0x1f) &
- !byte.wrapping_add(0x05) &
- 0x80
- ) >> 2
- )
+ byte & !((byte.wrapping_add(0x1f) & !byte.wrapping_add(0x05) & 0x80) >> 2)
}
-
macro_rules! benches {
($( fn $name: ident($arg: ident: &mut [u8]) $body: block )+ @iter $( $is_: ident, )+) => {
benches! {@
@@ -254,12 +246,15 @@
}
macro_rules! repeat {
- ($s: expr) => { concat!($s, $s, $s, $s, $s, $s, $s, $s, $s, $s) }
+ ($s: expr) => {
+ concat!($s, $s, $s, $s, $s, $s, $s, $s, $s, $s)
+ };
}
const SHORT: &'static str = "Alice's";
const MEDIUM: &'static str = "Alice's Adventures in Wonderland";
-const LONG: &'static str = repeat!(r#"
+const LONG: &'static str = repeat!(
+ r#"
La Guida di Bragia, a Ballad Opera for the Marionette Theatre (around 1850)
Alice's Adventures in Wonderland (1865)
Phantasmagoria and Other Poems (1869)
@@ -275,8 +270,10 @@
What the Tortoise Said to Achilles (1895)
Three Sunsets and Other Poems (1898)
The Manlet (1903)[106]
-"#);
+"#
+);
+#[rustfmt::skip]
const ASCII_UPPERCASE_MAP: [u8; 256] = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@@ -330,6 +327,7 @@
}
use self::AsciiCharacterClass::*;
+#[rustfmt::skip]
static ASCII_CHARACTER_CLASS: [AsciiCharacterClass; 256] = [
// _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f
C, C, C, C, C, C, C, C, C, Cw,Cw,C, Cw,Cw,C, C, // 0_
diff --git a/src/libcore/benches/char/methods.rs b/src/libcore/benches/char/methods.rs
index af934c1..a9a08a4 100644
--- a/src/libcore/benches/char/methods.rs
+++ b/src/libcore/benches/char/methods.rs
@@ -25,8 +25,13 @@
#[bench]
fn bench_to_digit_radix_var(b: &mut Bencher) {
- b.iter(|| CHARS.iter().cycle()
- .zip(RADIX.iter().cycle())
- .take(10_000)
- .map(|(c, radix)| c.to_digit(*radix)).min())
+ b.iter(|| {
+ CHARS
+ .iter()
+ .cycle()
+ .zip(RADIX.iter().cycle())
+ .take(10_000)
+ .map(|(c, radix)| c.to_digit(*radix))
+ .min()
+ })
}
diff --git a/src/libcore/benches/fmt.rs b/src/libcore/benches/fmt.rs
index 92f10c7..dd72a33 100644
--- a/src/libcore/benches/fmt.rs
+++ b/src/libcore/benches/fmt.rs
@@ -1,5 +1,5 @@
-use std::io::{self, Write as IoWrite};
use std::fmt::{self, Write as FmtWrite};
+use std::io::{self, Write as IoWrite};
use test::Bencher;
#[bench]
diff --git a/src/libcore/benches/hash/sip.rs b/src/libcore/benches/hash/sip.rs
index 5baba42..725c864 100644
--- a/src/libcore/benches/hash/sip.rs
+++ b/src/libcore/benches/hash/sip.rs
@@ -1,7 +1,7 @@
#![allow(deprecated)]
use core::hash::*;
-use test::{Bencher, black_box};
+use test::{black_box, Bencher};
fn hash_bytes<H: Hasher>(mut s: H, x: &[u8]) -> u64 {
Hasher::write(&mut s, x);
@@ -44,11 +44,11 @@
#[bench]
fn bench_long_str(b: &mut Bencher) {
let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
-incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
-exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
-irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
-pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
-officia deserunt mollit anim id est laborum.";
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
+ exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
+ irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
+ pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
+ officia deserunt mollit anim id est laborum.";
b.iter(|| {
assert_eq!(hash(&s), 17717065544121360093);
})
@@ -58,9 +58,7 @@
fn bench_u32(b: &mut Bencher) {
let u = 162629500u32;
let u = black_box(u);
- b.iter(|| {
- hash(&u)
- });
+ b.iter(|| hash(&u));
b.bytes = 8;
}
@@ -70,9 +68,7 @@
let u = black_box(u);
let k1 = black_box(0x1);
let k2 = black_box(0x2);
- b.iter(|| {
- hash_with(SipHasher::new_with_keys(k1, k2), &u)
- });
+ b.iter(|| hash_with(SipHasher::new_with_keys(k1, k2), &u));
b.bytes = 8;
}
@@ -80,62 +76,48 @@
fn bench_u64(b: &mut Bencher) {
let u = 16262950014981195938u64;
let u = black_box(u);
- b.iter(|| {
- hash(&u)
- });
+ b.iter(|| hash(&u));
b.bytes = 8;
}
#[bench]
fn bench_bytes_4(b: &mut Bencher) {
let data = black_box([b' '; 4]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 4;
}
#[bench]
fn bench_bytes_7(b: &mut Bencher) {
let data = black_box([b' '; 7]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 7;
}
#[bench]
fn bench_bytes_8(b: &mut Bencher) {
let data = black_box([b' '; 8]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 8;
}
#[bench]
fn bench_bytes_a_16(b: &mut Bencher) {
let data = black_box([b' '; 16]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 16;
}
#[bench]
fn bench_bytes_b_32(b: &mut Bencher) {
let data = black_box([b' '; 32]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 32;
}
#[bench]
fn bench_bytes_c_128(b: &mut Bencher) {
let data = black_box([b' '; 128]);
- b.iter(|| {
- hash_bytes(SipHasher::default(), &data)
- });
+ b.iter(|| hash_bytes(SipHasher::default(), &data));
b.bytes = 128;
}
diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs
index 7dcfad8..fb6b4b7 100644
--- a/src/libcore/benches/iter.rs
+++ b/src/libcore/benches/iter.rs
@@ -1,5 +1,5 @@
use core::iter::*;
-use test::{Bencher, black_box};
+use test::{black_box, Bencher};
#[bench]
fn bench_rposition(b: &mut Bencher) {
@@ -14,7 +14,11 @@
b.iter(|| {
let it = 0..100;
let mut sum = 0;
- it.skip_while(|&x| { sum += x; sum < 4000 }).all(|_| true);
+ it.skip_while(|&x| {
+ sum += x;
+ sum < 4000
+ })
+ .all(|_| true);
});
}
@@ -29,7 +33,9 @@
});
}
-fn scatter(x: i32) -> i32 { (x * 31) % 127 }
+fn scatter(x: i32) -> i32 {
+ (x * 31) % 127
+}
#[bench]
fn bench_max_by_key(b: &mut Bencher) {
@@ -76,23 +82,21 @@
fn bench_zip_copy(b: &mut Bencher) {
let source = vec![0u8; 16 * 1024];
let mut dst = black_box(vec![0u8; 16 * 1024]);
- b.iter(|| {
- copy_zip(&source, &mut dst)
- })
+ b.iter(|| copy_zip(&source, &mut dst))
}
#[bench]
fn bench_zip_add(b: &mut Bencher) {
let source = vec![1.; 16 * 1024];
let mut dst = vec![0.; 16 * 1024];
- b.iter(|| {
- add_zip(&source, &mut dst)
- });
+ b.iter(|| add_zip(&source, &mut dst));
}
/// `Iterator::for_each` implemented as a plain loop.
-fn for_each_loop<I, F>(iter: I, mut f: F) where
- I: Iterator, F: FnMut(I::Item)
+fn for_each_loop<I, F>(iter: I, mut f: F)
+where
+ I: Iterator,
+ F: FnMut(I::Item),
{
for item in iter {
f(item);
@@ -101,8 +105,10 @@
/// `Iterator::for_each` implemented with `fold` for internal iteration.
/// (except when `by_ref()` effectively disables that optimization.)
-fn for_each_fold<I, F>(iter: I, mut f: F) where
- I: Iterator, F: FnMut(I::Item)
+fn for_each_fold<I, F>(iter: I, mut f: F)
+where
+ I: Iterator,
+ F: FnMut(I::Item),
{
iter.fold((), move |(), item| f(item));
}
@@ -137,25 +143,20 @@
});
}
-
/// Helper to benchmark `sum` for iterators taken by value which
/// can optimize `fold`, and by reference which cannot.
macro_rules! bench_sums {
($bench_sum:ident, $bench_ref_sum:ident, $iter:expr) => {
#[bench]
fn $bench_sum(b: &mut Bencher) {
- b.iter(|| -> i64 {
- $iter.map(black_box).sum()
- });
+ b.iter(|| -> i64 { $iter.map(black_box).sum() });
}
#[bench]
fn $bench_ref_sum(b: &mut Bencher) {
- b.iter(|| -> i64 {
- $iter.map(black_box).by_ref().sum()
- });
+ b.iter(|| -> i64 { $iter.map(black_box).by_ref().sum() });
}
- }
+ };
}
bench_sums! {
@@ -286,7 +287,10 @@
let t: Vec<_> = (0..100_000).collect();
b.iter(|| {
- let s = v.iter().zip(t.iter()).skip(10000)
+ let s = v
+ .iter()
+ .zip(t.iter())
+ .skip(10000)
.take_while(|t| *t.0 < 10100)
.map(|(a, b)| *a + *b)
.sum::<u64>();
@@ -299,7 +303,10 @@
let t: Vec<_> = (0..100_000).collect();
b.iter(|| {
- let s = v.iter().skip(10000).zip(t.iter().skip(10000))
+ let s = v
+ .iter()
+ .skip(10000)
+ .zip(t.iter().skip(10000))
.take_while(|t| *t.0 < 10100)
.map(|(a, b)| *a + *b)
.sum::<u64>();
@@ -309,23 +316,17 @@
#[bench]
fn bench_filter_count(b: &mut Bencher) {
- b.iter(|| {
- (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count()
- })
+ b.iter(|| (0i64..1000000).map(black_box).filter(|x| x % 3 == 0).count())
}
#[bench]
fn bench_filter_ref_count(b: &mut Bencher) {
- b.iter(|| {
- (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count()
- })
+ b.iter(|| (0i64..1000000).map(black_box).by_ref().filter(|x| x % 3 == 0).count())
}
#[bench]
fn bench_filter_chain_count(b: &mut Bencher) {
- b.iter(|| {
- (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count()
- })
+ b.iter(|| (0i64..1000000).chain(0..1000000).map(black_box).filter(|x| x % 3 == 0).count())
}
#[bench]
diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs
index dea2963d..6932c7f 100644
--- a/src/libcore/benches/lib.rs
+++ b/src/libcore/benches/lib.rs
@@ -6,9 +6,9 @@
mod any;
mod ascii;
mod char;
+mod fmt;
mod hash;
mod iter;
mod num;
mod ops;
mod slice;
-mod fmt;
diff --git a/src/libcore/benches/num/flt2dec/mod.rs b/src/libcore/benches/num/flt2dec/mod.rs
index 4153745..b810dd1 100644
--- a/src/libcore/benches/num/flt2dec/mod.rs
+++ b/src/libcore/benches/num/flt2dec/mod.rs
@@ -3,17 +3,17 @@
mod grisu;
}
+use core::num::flt2dec::MAX_SIG_DIGITS;
+use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
use std::f64;
use std::io::Write;
use std::vec::Vec;
use test::Bencher;
-use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
-use core::num::flt2dec::MAX_SIG_DIGITS;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
- full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+ full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}
diff --git a/src/libcore/benches/num/flt2dec/strategy/dragon.rs b/src/libcore/benches/num/flt2dec/strategy/dragon.rs
index 60660b1..4052fec 100644
--- a/src/libcore/benches/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/benches/num/flt2dec/strategy/dragon.rs
@@ -1,6 +1,6 @@
-use std::{i16, f64};
use super::super::*;
use core::num::flt2dec::strategy::dragon::*;
+use std::{f64, i16};
use test::Bencher;
#[bench]
diff --git a/src/libcore/benches/num/flt2dec/strategy/grisu.rs b/src/libcore/benches/num/flt2dec/strategy/grisu.rs
index 841feba..4950747 100644
--- a/src/libcore/benches/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/benches/num/flt2dec/strategy/grisu.rs
@@ -1,12 +1,12 @@
-use std::{i16, f64};
use super::super::*;
use core::num::flt2dec::strategy::grisu::*;
+use std::{f64, i16};
use test::Bencher;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
- full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+ full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}
diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs
index 2dcdf2b..852d4e4 100644
--- a/src/libcore/benches/num/mod.rs
+++ b/src/libcore/benches/num/mod.rs
@@ -1,8 +1,8 @@
-mod flt2dec;
mod dec2flt;
+mod flt2dec;
-use test::Bencher;
use std::str::FromStr;
+use test::Bencher;
const ASCII_NUMBERS: [&str; 19] = [
"0",
@@ -27,7 +27,7 @@
];
macro_rules! from_str_bench {
- ($mac:ident, $t:ty) => (
+ ($mac:ident, $t:ty) => {
#[bench]
fn $mac(b: &mut Bencher) {
b.iter(|| {
@@ -39,11 +39,11 @@
.max()
})
}
- )
+ };
}
macro_rules! from_str_radix_bench {
- ($mac:ident, $t:ty, $radix:expr) => (
+ ($mac:ident, $t:ty, $radix:expr) => {
#[bench]
fn $mac(b: &mut Bencher) {
b.iter(|| {
@@ -55,7 +55,7 @@
.max()
})
}
- )
+ };
}
from_str_bench!(bench_u8_from_str, u8);
diff --git a/src/libcore/benches/ops.rs b/src/libcore/benches/ops.rs
index 80649f3..0a2be8a2 100644
--- a/src/libcore/benches/ops.rs
+++ b/src/libcore/benches/ops.rs
@@ -4,17 +4,16 @@
// Overhead of dtors
struct HasDtor {
- _x: isize
+ _x: isize,
}
impl Drop for HasDtor {
- fn drop(&mut self) {
- }
+ fn drop(&mut self) {}
}
#[bench]
fn alloc_obj_with_dtor(b: &mut Bencher) {
b.iter(|| {
- HasDtor { _x : 10 };
+ HasDtor { _x: 10 };
})
}
diff --git a/src/libcore/benches/slice.rs b/src/libcore/benches/slice.rs
index 711a8df..06b37cb 100644
--- a/src/libcore/benches/slice.rs
+++ b/src/libcore/benches/slice.rs
@@ -8,11 +8,12 @@
}
fn binary_search<F>(b: &mut Bencher, cache: Cache, mapper: F)
- where F: Fn(usize) -> usize
+where
+ F: Fn(usize) -> usize,
{
let size = match cache {
- Cache::L1 => 1000, // 8kb
- Cache::L2 => 10_000, // 80kb
+ Cache::L1 => 1000, // 8kb
+ Cache::L2 => 10_000, // 80kb
Cache::L3 => 1_000_000, // 8Mb
};
let v = (0..size).map(&mapper).collect::<Vec<_>>();
diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs
index 1b3c254..6e0865e 100644
--- a/src/libcore/bool.rs
+++ b/src/libcore/bool.rs
@@ -15,11 +15,7 @@
#[unstable(feature = "bool_to_option", issue = "64260")]
#[inline]
pub fn then_some<T>(self, t: T) -> Option<T> {
- if self {
- Some(t)
- } else {
- None
- }
+ if self { Some(t) } else { None }
}
/// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise.
@@ -35,10 +31,6 @@
#[unstable(feature = "bool_to_option", issue = "64260")]
#[inline]
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
- if self {
- Some(f())
- } else {
- None
- }
+ if self { Some(f()) } else { None }
}
}
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index a295e65..f4fb9ab 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -64,31 +64,27 @@
#[inline]
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
pub fn spin_loop() {
- #[cfg(
- all(
- any(target_arch = "x86", target_arch = "x86_64"),
- target_feature = "sse2"
- )
- )] {
- #[cfg(target_arch = "x86")] {
+ #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
+ {
+ #[cfg(target_arch = "x86")]
+ {
unsafe { crate::arch::x86::_mm_pause() };
}
- #[cfg(target_arch = "x86_64")] {
+ #[cfg(target_arch = "x86_64")]
+ {
unsafe { crate::arch::x86_64::_mm_pause() };
}
}
- #[cfg(
- any(
- target_arch = "aarch64",
- all(target_arch = "arm", target_feature = "v6")
- )
- )] {
- #[cfg(target_arch = "aarch64")] {
+ #[cfg(any(target_arch = "aarch64", all(target_arch = "arm", target_feature = "v6")))]
+ {
+ #[cfg(target_arch = "aarch64")]
+ {
unsafe { crate::arch::aarch64::__yield() };
}
- #[cfg(target_arch = "arm")] {
+ #[cfg(target_arch = "arm")]
+ {
unsafe { crate::arch::arm::__yield() };
}
}
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index d6ae5cf..f21ab8d 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -91,9 +91,9 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
- message="a value of type `{Self}` cannot be built from an iterator \
- over elements of type `{A}`",
- label="value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`",
+ message = "a value of type `{Self}` cannot be built from an iterator \
+ over elements of type `{A}`",
+ label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
)]
pub trait FromIterator<A>: Sized {
/// Creates a value from an iterator.
@@ -116,7 +116,7 @@
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> Self;
+ fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}
/// Conversion into an `Iterator`.
@@ -214,7 +214,7 @@
/// Which kind of iterator are we turning this into?
#[stable(feature = "rust1", since = "1.0.0")]
- type IntoIter: Iterator<Item=Self::Item>;
+ type IntoIter: Iterator<Item = Self::Item>;
/// Creates an iterator from a value.
///
@@ -340,7 +340,7 @@
/// assert_eq!("abcdef", &message);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T);
+ fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);
}
#[stable(feature = "extend_for_unit", since = "1.28.0")]
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 794f77f..5446ce3 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -439,7 +439,10 @@
#[cfg(not(bootstrap))]
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
#[inline]
- pub unsafe fn approx_unchecked_to<Int>(self) -> Int where Self: FloatToInt<Int> {
+ pub unsafe fn approx_unchecked_to<Int>(self) -> Int
+ where
+ Self: FloatToInt<Int>,
+ {
FloatToInt::<Int>::approx_unchecked(self)
}
diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs
index a748ee8..22ba97b 100644
--- a/src/libcore/ops/try.rs
+++ b/src/libcore/ops/try.rs
@@ -5,20 +5,28 @@
/// extracting those success or failure values from an existing instance and
/// creating a new instance from a success or failure value.
#[unstable(feature = "try_trait", issue = "42327")]
-#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
-on(all(
-any(from_method="from_error", from_method="from_ok"),
-from_desugaring="QuestionMark"),
-message="the `?` operator can only be used in {ItemContext} \
- that returns `Result` or `Option` \
- (or another type that implements `{Try}`)",
-label="cannot use the `?` operator in {ItemContext} that returns `{Self}`",
-enclosing_scope="this function should return `Result` or `Option` to accept `?`"),
-on(all(from_method="into_result", from_desugaring="QuestionMark"),
-message="the `?` operator can only be applied to values \
- that implement `{Try}`",
-label="the `?` operator cannot be applied to type `{Self}`")
-))]
+#[cfg_attr(
+ not(bootstrap),
+ rustc_on_unimplemented(
+ on(
+ all(
+ any(from_method = "from_error", from_method = "from_ok"),
+ from_desugaring = "QuestionMark"
+ ),
+ message = "the `?` operator can only be used in {ItemContext} \
+ that returns `Result` or `Option` \
+ (or another type that implements `{Try}`)",
+ label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
+ enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
+ ),
+ on(
+ all(from_method = "into_result", from_desugaring = "QuestionMark"),
+ message = "the `?` operator can only be applied to values \
+ that implement `{Try}`",
+ label = "the `?` operator cannot be applied to type `{Self}`"
+ )
+ )
+)]
#[doc(alias = "?")]
pub trait Try {
/// The type of this value when viewed as successful.
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 5a8d647..4857b11 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -22,10 +22,12 @@
// ignore-tidy-undocumented-unsafe
#![allow(dead_code, missing_docs)]
-#![unstable(feature = "core_panic",
- reason = "internal details of the implementation of the `panic!` \
- and related macros",
- issue = "0")]
+#![unstable(
+ feature = "core_panic",
+ reason = "internal details of the implementation of the `panic!` \
+ and related macros",
+ issue = "0"
+)]
use crate::fmt;
use crate::panic::{Location, PanicInfo};
@@ -33,7 +35,7 @@
#[cold]
// never inline unless panic_immediate_abort to avoid code
// bloat at the call sites as much as possible
-#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[lang = "panic"] // needed by codegen for panic on overflow and other `Assert` MIR terminators
pub fn panic(expr: &str, location: &Location<'_>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
@@ -50,7 +52,7 @@
}
#[cold]
-#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
if cfg!(feature = "panic_immediate_abort") {
@@ -59,13 +61,13 @@
panic_fmt(
format_args!("index out of bounds: the len is {} but the index is {}", len, index),
- location
+ location,
)
}
#[cold]
-#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
-#[cfg_attr( feature="panic_immediate_abort" ,inline)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
if cfg!(feature = "panic_immediate_abort") {
unsafe { super::intrinsics::abort() }
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 88fa718..6a0c5bb 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -376,6 +376,7 @@
use crate::cmp::{self, PartialEq, PartialOrd};
use crate::fmt;
+use crate::hash::{Hash, Hasher};
use crate::marker::{Sized, Unpin};
use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
@@ -390,55 +391,78 @@
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
/// [`pin` module]: ../../std/pin/index.html
//
-// Note: the derives below, and the explicit `PartialEq` and `PartialOrd`
-// implementations, are allowed because they all only use `&P`, so they cannot move
-// the value behind `pointer`.
+// Note: the `Clone` derive below causes unsoundness as it's possible to implement
+// `Clone` for mutable references.
+// See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311> for more details.
#[stable(feature = "pin", since = "1.33.0")]
#[lang = "pin"]
#[fundamental]
#[repr(transparent)]
-#[derive(Copy, Clone, Hash, Eq, Ord)]
+#[derive(Copy, Clone)]
pub struct Pin<P> {
pointer: P,
}
-#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")]
-impl<P, Q> PartialEq<Pin<Q>> for Pin<P>
+// The following implementations aren't derived in order to avoid soundness
+// issues. `&self.pointer` should not be accessible to untrusted trait
+// implementations.
+//
+// See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details.
+
+#[stable(feature = "pin_trait_impls", since = "1.41.0")]
+impl<P: Deref, Q: Deref> PartialEq<Pin<Q>> for Pin<P>
where
- P: PartialEq<Q>,
+ P::Target: PartialEq<Q::Target>,
{
fn eq(&self, other: &Pin<Q>) -> bool {
- self.pointer == other.pointer
+ P::Target::eq(self, other)
}
fn ne(&self, other: &Pin<Q>) -> bool {
- self.pointer != other.pointer
+ P::Target::ne(self, other)
}
}
-#[stable(feature = "pin_partialeq_partialord_impl_applicability", since = "1.34.0")]
-impl<P, Q> PartialOrd<Pin<Q>> for Pin<P>
+#[stable(feature = "pin_trait_impls", since = "1.41.0")]
+impl<P: Deref<Target: Eq>> Eq for Pin<P> {}
+
+#[stable(feature = "pin_trait_impls", since = "1.41.0")]
+impl<P: Deref, Q: Deref> PartialOrd<Pin<Q>> for Pin<P>
where
- P: PartialOrd<Q>,
+ P::Target: PartialOrd<Q::Target>,
{
fn partial_cmp(&self, other: &Pin<Q>) -> Option<cmp::Ordering> {
- self.pointer.partial_cmp(&other.pointer)
+ P::Target::partial_cmp(self, other)
}
fn lt(&self, other: &Pin<Q>) -> bool {
- self.pointer < other.pointer
+ P::Target::lt(self, other)
}
fn le(&self, other: &Pin<Q>) -> bool {
- self.pointer <= other.pointer
+ P::Target::le(self, other)
}
fn gt(&self, other: &Pin<Q>) -> bool {
- self.pointer > other.pointer
+ P::Target::gt(self, other)
}
fn ge(&self, other: &Pin<Q>) -> bool {
- self.pointer >= other.pointer
+ P::Target::ge(self, other)
+ }
+}
+
+#[stable(feature = "pin_trait_impls", since = "1.41.0")]
+impl<P: Deref<Target: Ord>> Ord for Pin<P> {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ P::Target::cmp(self, other)
+ }
+}
+
+#[stable(feature = "pin_trait_impls", since = "1.41.0")]
+impl<P: Deref<Target: Hash>> Hash for Pin<P> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ P::Target::hash(self, state);
}
}
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 1e051db..24ffa34 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -65,15 +65,16 @@
//! [`write_volatile`]: ./fn.write_volatile.html
//! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
+// ignore-tidy-filelength
// ignore-tidy-undocumented-unsafe
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::intrinsics;
+use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::fmt;
use crate::hash;
+use crate::intrinsics;
use crate::mem::{self, MaybeUninit};
-use crate::cmp::Ordering::{self, Less, Equal, Greater};
#[stable(feature = "rust1", since = "1.0.0")]
pub use crate::intrinsics::copy_nonoverlapping;
@@ -197,7 +198,9 @@
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
-pub const fn null<T>() -> *const T { 0 as *const T }
+pub const fn null<T>() -> *const T {
+ 0 as *const T
+}
/// Creates a null mutable raw pointer.
///
@@ -212,7 +215,9 @@
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
-pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
+pub const fn null_mut<T>() -> *mut T {
+ 0 as *mut T
+}
#[repr(C)]
pub(crate) union Repr<T> {
@@ -704,9 +709,7 @@
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn read_unaligned<T>(src: *const T) -> T {
let mut tmp = MaybeUninit::<T>::uninit();
- copy_nonoverlapping(src as *const u8,
- tmp.as_mut_ptr() as *mut u8,
- mem::size_of::<T>());
+ copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
tmp.assume_init()
}
@@ -889,9 +892,7 @@
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
- copy_nonoverlapping(&src as *const T as *const u8,
- dst as *mut u8,
- mem::size_of::<T>());
+ copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
mem::forget(src);
}
@@ -1122,11 +1123,7 @@
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
- if self.is_null() {
- None
- } else {
- Some(&*self)
- }
+ if self.is_null() { None } else { Some(&*self) }
}
/// Calculates the offset from a pointer.
@@ -1182,7 +1179,10 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
+ pub unsafe fn offset(self, count: isize) -> *const T
+ where
+ T: Sized,
+ {
intrinsics::offset(self, count)
}
@@ -1237,10 +1237,11 @@
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
- pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized {
- unsafe {
- intrinsics::arith_offset(self, count)
- }
+ pub fn wrapping_offset(self, count: isize) -> *const T
+ where
+ T: Sized,
+ {
+ unsafe { intrinsics::arith_offset(self, count) }
}
/// Calculates the distance between two pointers. The returned value is in
@@ -1308,7 +1309,10 @@
#[unstable(feature = "ptr_offset_from", issue = "41079")]
#[rustc_const_unstable(feature = "const_ptr_offset_from")]
#[inline]
- pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+ pub const unsafe fn offset_from(self, origin: *const T) -> isize
+ where
+ T: Sized,
+ {
let pointee_size = mem::size_of::<T>();
let ok = 0 < pointee_size && pointee_size <= isize::max_value() as usize;
// assert that the pointee size is valid in a const eval compatible way
@@ -1353,7 +1357,10 @@
/// ```
#[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
#[inline]
- pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+ pub fn wrapping_offset_from(self, origin: *const T) -> isize
+ where
+ T: Sized,
+ {
let pointee_size = mem::size_of::<T>();
assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
@@ -1415,7 +1422,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.offset(count as isize)
}
@@ -1475,7 +1483,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.offset((count as isize).wrapping_neg())
}
@@ -1529,7 +1538,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.wrapping_offset(count as isize)
}
@@ -1583,7 +1593,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.wrapping_offset((count as isize).wrapping_neg())
}
@@ -1597,7 +1608,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read(self)
}
@@ -1615,7 +1627,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read_volatile(self)
}
@@ -1631,7 +1644,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read_unaligned(self)
}
@@ -1647,7 +1661,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy(self, dest, count)
}
@@ -1663,7 +1678,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy_nonoverlapping(self, dest, count)
}
@@ -1708,17 +1724,17 @@
/// # } }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
- pub fn align_offset(self, align: usize) -> usize where T: Sized {
+ pub fn align_offset(self, align: usize) -> usize
+ where
+ T: Sized,
+ {
if !align.is_power_of_two() {
panic!("align_offset: align is not a power-of-two");
}
- unsafe {
- align_offset(self, align)
- }
+ unsafe { align_offset(self, align) }
}
}
-
#[lang = "mut_ptr"]
impl<T: ?Sized> *mut T {
/// Returns `true` if the pointer is null.
@@ -1805,11 +1821,7 @@
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
- if self.is_null() {
- None
- } else {
- Some(&*self)
- }
+ if self.is_null() { None } else { Some(&*self) }
}
/// Calculates the offset from a pointer.
@@ -1865,7 +1877,10 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
+ pub unsafe fn offset(self, count: isize) -> *mut T
+ where
+ T: Sized,
+ {
intrinsics::offset(self, count) as *mut T
}
@@ -1919,10 +1934,11 @@
/// ```
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
- pub fn wrapping_offset(self, count: isize) -> *mut T where T: Sized {
- unsafe {
- intrinsics::arith_offset(self, count) as *mut T
- }
+ pub fn wrapping_offset(self, count: isize) -> *mut T
+ where
+ T: Sized,
+ {
+ unsafe { intrinsics::arith_offset(self, count) as *mut T }
}
/// Returns `None` if the pointer is null, or else returns a mutable
@@ -1967,11 +1983,7 @@
#[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
- if self.is_null() {
- None
- } else {
- Some(&mut *self)
- }
+ if self.is_null() { None } else { Some(&mut *self) }
}
/// Calculates the distance between two pointers. The returned value is in
@@ -2039,7 +2051,10 @@
#[unstable(feature = "ptr_offset_from", issue = "41079")]
#[rustc_const_unstable(feature = "const_ptr_offset_from")]
#[inline]
- pub const unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+ pub const unsafe fn offset_from(self, origin: *const T) -> isize
+ where
+ T: Sized,
+ {
(self as *const T).offset_from(origin)
}
@@ -2079,7 +2094,10 @@
/// ```
#[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
#[inline]
- pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+ pub fn wrapping_offset_from(self, origin: *const T) -> isize
+ where
+ T: Sized,
+ {
(self as *const T).wrapping_offset_from(origin)
}
@@ -2137,7 +2155,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn add(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.offset(count as isize)
}
@@ -2197,7 +2216,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn sub(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.offset((count as isize).wrapping_neg())
}
@@ -2251,7 +2271,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_add(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.wrapping_offset(count as isize)
}
@@ -2305,7 +2326,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub fn wrapping_sub(self, count: usize) -> Self
- where T: Sized,
+ where
+ T: Sized,
{
self.wrapping_offset((count as isize).wrapping_neg())
}
@@ -2319,7 +2341,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read(self)
}
@@ -2337,7 +2360,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_volatile(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read_volatile(self)
}
@@ -2353,7 +2377,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn read_unaligned(self) -> T
- where T: Sized,
+ where
+ T: Sized,
{
read_unaligned(self)
}
@@ -2369,7 +2394,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to(self, dest: *mut T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy(self, dest, count)
}
@@ -2385,7 +2411,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy_nonoverlapping(self, dest, count)
}
@@ -2401,7 +2428,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from(self, src: *const T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy(src, self, count)
}
@@ -2417,7 +2445,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
copy_nonoverlapping(src, self, count)
}
@@ -2442,7 +2471,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write(self, val: T)
- where T: Sized,
+ where
+ T: Sized,
{
write(self, val)
}
@@ -2456,7 +2486,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_bytes(self, val: u8, count: usize)
- where T: Sized,
+ where
+ T: Sized,
{
write_bytes(self, val, count)
}
@@ -2474,7 +2505,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_volatile(self, val: T)
- where T: Sized,
+ where
+ T: Sized,
{
write_volatile(self, val)
}
@@ -2490,7 +2522,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn write_unaligned(self, val: T)
- where T: Sized,
+ where
+ T: Sized,
{
write_unaligned(self, val)
}
@@ -2504,7 +2537,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn replace(self, src: T) -> T
- where T: Sized,
+ where
+ T: Sized,
{
replace(self, src)
}
@@ -2519,7 +2553,8 @@
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[inline]
pub unsafe fn swap(self, with: *mut T)
- where T: Sized,
+ where
+ T: Sized,
{
swap(self, with)
}
@@ -2564,13 +2599,14 @@
/// # } }
/// ```
#[stable(feature = "align_offset", since = "1.36.0")]
- pub fn align_offset(self, align: usize) -> usize where T: Sized {
+ pub fn align_offset(self, align: usize) -> usize
+ where
+ T: Sized,
+ {
if !align.is_power_of_two() {
panic!("align_offset: align is not a power-of-two");
}
- unsafe {
- align_offset(self, align)
- }
+ unsafe { align_offset(self, align) }
}
}
@@ -2588,7 +2624,7 @@
/// than trying to adapt this to accommodate that change.
///
/// Any questions go to @nagisa.
-#[lang="align_offset"]
+#[lang = "align_offset"]
pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
/// Calculate multiplicative modular inverse of `x` modulo `m`.
///
@@ -2628,9 +2664,8 @@
// uses e.g., subtraction `mod n`. It is entirely fine to do them `mod
// usize::max_value()` instead, because we take the result `mod n` at the end
// anyway.
- inverse = inverse.wrapping_mul(
- 2usize.wrapping_sub(x.wrapping_mul(inverse))
- ) & (going_mod - 1);
+ inverse = inverse.wrapping_mul(2usize.wrapping_sub(x.wrapping_mul(inverse)))
+ & (going_mod - 1);
if going_mod > m {
return inverse & (m - 1);
}
@@ -2689,13 +2724,13 @@
usize::max_value()
}
-
-
// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *const T {
#[inline]
- fn eq(&self, other: &*const T) -> bool { *self == *other }
+ fn eq(&self, other: &*const T) -> bool {
+ *self == *other
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2704,7 +2739,9 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> PartialEq for *mut T {
#[inline]
- fn eq(&self, other: &*mut T) -> bool { *self == *other }
+ fn eq(&self, other: &*mut T) -> bool {
+ *self == *other
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2890,7 +2927,7 @@
};
}
-fnptr_impls_args! { }
+fnptr_impls_args! {}
fnptr_impls_args! { A }
fnptr_impls_args! { A, B }
fnptr_impls_args! { A, B, C }
@@ -2927,16 +2964,24 @@
}
#[inline]
- fn lt(&self, other: &*const T) -> bool { *self < *other }
+ fn lt(&self, other: &*const T) -> bool {
+ *self < *other
+ }
#[inline]
- fn le(&self, other: &*const T) -> bool { *self <= *other }
+ fn le(&self, other: &*const T) -> bool {
+ *self <= *other
+ }
#[inline]
- fn gt(&self, other: &*const T) -> bool { *self > *other }
+ fn gt(&self, other: &*const T) -> bool {
+ *self > *other
+ }
#[inline]
- fn ge(&self, other: &*const T) -> bool { *self >= *other }
+ fn ge(&self, other: &*const T) -> bool {
+ *self >= *other
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2961,14 +3006,22 @@
}
#[inline]
- fn lt(&self, other: &*mut T) -> bool { *self < *other }
+ fn lt(&self, other: &*mut T) -> bool {
+ *self < *other
+ }
#[inline]
- fn le(&self, other: &*mut T) -> bool { *self <= *other }
+ fn le(&self, other: &*mut T) -> bool {
+ *self <= *other
+ }
#[inline]
- fn gt(&self, other: &*mut T) -> bool { *self > *other }
+ fn gt(&self, other: &*mut T) -> bool {
+ *self > *other
+ }
#[inline]
- fn ge(&self, other: &*mut T) -> bool { *self >= *other }
+ fn ge(&self, other: &*mut T) -> bool {
+ *self >= *other
+ }
}
diff --git a/src/libcore/tests/any.rs b/src/libcore/tests/any.rs
index 62bebcb..b0dc990 100644
--- a/src/libcore/tests/any.rs
+++ b/src/libcore/tests/any.rs
@@ -24,11 +24,8 @@
#[test]
fn any_owning() {
- let (a, b, c) = (
- box 5_usize as Box<dyn Any>,
- box TEST as Box<dyn Any>,
- box Test as Box<dyn Any>,
- );
+ let (a, b, c) =
+ (box 5_usize as Box<dyn Any>, box TEST as Box<dyn Any>, box Test as Box<dyn Any>);
assert!(a.is::<usize>());
assert!(!b.is::<usize>());
@@ -49,12 +46,12 @@
match a.downcast_ref::<usize>() {
Some(&5) => {}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match a.downcast_ref::<Test>() {
None => {}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
}
@@ -72,7 +69,7 @@
assert_eq!(*x, 5);
*x = 612;
}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<usize>() {
@@ -80,27 +77,27 @@
assert_eq!(*x, 7);
*x = 413;
}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match a_r.downcast_mut::<Test>() {
None => (),
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<Test>() {
None => (),
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match a_r.downcast_mut::<usize>() {
Some(&mut 612) => {}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
match b_r.downcast_mut::<usize>() {
Some(&mut 413) => {}
- x => panic!("Unexpected value {:?}", x)
+ x => panic!("Unexpected value {:?}", x),
}
}
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
index 4f3b79c..c2a816f 100644
--- a/src/libcore/tests/array.rs
+++ b/src/libcore/tests/array.rs
@@ -41,7 +41,6 @@
}
}
-
#[test]
fn iterator_collect() {
let arr = [0, 1, 2, 5, 9];
@@ -150,10 +149,7 @@
#[test]
fn iterator_debug() {
let arr = [0, 1, 2, 5, 9];
- assert_eq!(
- format!("{:?}", IntoIter::new(arr)),
- "IntoIter([0, 1, 2, 5, 9])",
- );
+ assert_eq!(format!("{:?}", IntoIter::new(arr)), "IntoIter([0, 1, 2, 5, 9])",);
}
#[test]
@@ -168,7 +164,7 @@
struct Foo<'a>(&'a Cell<usize>);
impl Drop for Foo<'_> {
- fn drop(&mut self) {
+ fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}
diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs
index 439ed0c..71275d4 100644
--- a/src/libcore/tests/ascii.rs
+++ b/src/libcore/tests/ascii.rs
@@ -22,10 +22,12 @@
assert_eq!("hıKß".to_ascii_uppercase(), "HıKß");
for i in 0..501 {
- let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
- else { i };
- assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
- (from_u32(upper).unwrap()).to_string());
+ let upper =
+ if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } else { i };
+ assert_eq!(
+ (from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
+ (from_u32(upper).unwrap()).to_string()
+ );
}
}
@@ -36,23 +38,23 @@
assert_eq!("HİKß".to_ascii_lowercase(), "hİKß");
for i in 0..501 {
- let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
- else { i };
- assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
- (from_u32(lower).unwrap()).to_string());
+ let lower =
+ if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
+ assert_eq!(
+ (from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
+ (from_u32(lower).unwrap()).to_string()
+ );
}
}
#[test]
fn test_make_ascii_lower_case() {
macro_rules! test {
- ($from: expr, $to: expr) => {
- {
- let mut x = $from;
- x.make_ascii_lowercase();
- assert_eq!(x, $to);
- }
- }
+ ($from: expr, $to: expr) => {{
+ let mut x = $from;
+ x.make_ascii_lowercase();
+ assert_eq!(x, $to);
+ }};
}
test!(b'A', b'a');
test!(b'a', b'a');
@@ -65,17 +67,14 @@
test!("HİKß".to_string(), "hİKß");
}
-
#[test]
fn test_make_ascii_upper_case() {
macro_rules! test {
- ($from: expr, $to: expr) => {
- {
- let mut x = $from;
- x.make_ascii_uppercase();
- assert_eq!(x, $to);
- }
- }
+ ($from: expr, $to: expr) => {{
+ let mut x = $from;
+ x.make_ascii_uppercase();
+ assert_eq!(x, $to);
+ }};
}
test!(b'a', b'A');
test!(b'A', b'A');
@@ -88,7 +87,7 @@
test!("hıKß".to_string(), "HıKß");
let mut x = "Hello".to_string();
- x[..3].make_ascii_uppercase(); // Test IndexMut on String.
+ x[..3].make_ascii_uppercase(); // Test IndexMut on String.
assert_eq!(x, "HELlo")
}
@@ -103,10 +102,13 @@
assert!(!"ß".eq_ignore_ascii_case("s"));
for i in 0..501 {
- let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
- else { i };
- assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
- &from_u32(lower).unwrap().to_string()));
+ let lower =
+ if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } else { i };
+ assert!(
+ (from_u32(i).unwrap())
+ .to_string()
+ .eq_ignore_ascii_case(&from_u32(lower).unwrap().to_string())
+ );
}
}
@@ -158,12 +160,14 @@
#[test]
fn test_is_ascii_alphabetic() {
- assert_all!(is_ascii_alphabetic,
+ assert_all!(
+ is_ascii_alphabetic,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
);
- assert_none!(is_ascii_alphabetic,
+ assert_none!(
+ is_ascii_alphabetic,
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
" \t\n\x0c\r",
@@ -177,11 +181,9 @@
#[test]
fn test_is_ascii_uppercase() {
- assert_all!(is_ascii_uppercase,
- "",
- "ABCDEFGHIJKLMNOQPRSTUVWXYZ",
- );
- assert_none!(is_ascii_uppercase,
+ assert_all!(is_ascii_uppercase, "", "ABCDEFGHIJKLMNOQPRSTUVWXYZ",);
+ assert_none!(
+ is_ascii_uppercase,
"abcdefghijklmnopqrstuvwxyz",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@@ -196,10 +198,9 @@
#[test]
fn test_is_ascii_lowercase() {
- assert_all!(is_ascii_lowercase,
- "abcdefghijklmnopqrstuvwxyz",
- );
- assert_none!(is_ascii_lowercase,
+ assert_all!(is_ascii_lowercase, "abcdefghijklmnopqrstuvwxyz",);
+ assert_none!(
+ is_ascii_lowercase,
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@@ -214,13 +215,15 @@
#[test]
fn test_is_ascii_alphanumeric() {
- assert_all!(is_ascii_alphanumeric,
+ assert_all!(
+ is_ascii_alphanumeric,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
);
- assert_none!(is_ascii_alphanumeric,
+ assert_none!(
+ is_ascii_alphanumeric,
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
" \t\n\x0c\r",
"\x00\x01\x02\x03\x04\x05\x06\x07",
@@ -233,11 +236,9 @@
#[test]
fn test_is_ascii_digit() {
- assert_all!(is_ascii_digit,
- "",
- "0123456789",
- );
- assert_none!(is_ascii_digit,
+ assert_all!(is_ascii_digit, "", "0123456789",);
+ assert_none!(
+ is_ascii_digit,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@@ -252,12 +253,9 @@
#[test]
fn test_is_ascii_hexdigit() {
- assert_all!(is_ascii_hexdigit,
- "",
- "0123456789",
- "abcdefABCDEF",
- );
- assert_none!(is_ascii_hexdigit,
+ assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",);
+ assert_none!(
+ is_ascii_hexdigit,
"ghijklmnopqrstuvwxyz",
"GHIJKLMNOQPRSTUVWXYZ",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
@@ -272,11 +270,9 @@
#[test]
fn test_is_ascii_punctuation() {
- assert_all!(is_ascii_punctuation,
- "",
- "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- );
- assert_none!(is_ascii_punctuation,
+ assert_all!(is_ascii_punctuation, "", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",);
+ assert_none!(
+ is_ascii_punctuation,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
@@ -291,14 +287,16 @@
#[test]
fn test_is_ascii_graphic() {
- assert_all!(is_ascii_graphic,
+ assert_all!(
+ is_ascii_graphic,
"",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
);
- assert_none!(is_ascii_graphic,
+ assert_none!(
+ is_ascii_graphic,
" \t\n\x0c\r",
"\x00\x01\x02\x03\x04\x05\x06\x07",
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@@ -310,11 +308,9 @@
#[test]
fn test_is_ascii_whitespace() {
- assert_all!(is_ascii_whitespace,
- "",
- " \t\n\x0c\r",
- );
- assert_none!(is_ascii_whitespace,
+ assert_all!(is_ascii_whitespace, "", " \t\n\x0c\r",);
+ assert_none!(
+ is_ascii_whitespace,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
@@ -329,7 +325,8 @@
#[test]
fn test_is_ascii_control() {
- assert_all!(is_ascii_control,
+ assert_all!(
+ is_ascii_control,
"",
"\x00\x01\x02\x03\x04\x05\x06\x07",
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
@@ -337,7 +334,8 @@
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
"\x7f",
);
- assert_none!(is_ascii_control,
+ assert_none!(
+ is_ascii_control,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOQPRSTUVWXYZ",
"0123456789",
diff --git a/src/libcore/tests/atomic.rs b/src/libcore/tests/atomic.rs
index 05fe846..acbd913 100644
--- a/src/libcore/tests/atomic.rs
+++ b/src/libcore/tests/atomic.rs
@@ -1,5 +1,5 @@
-use core::sync::atomic::*;
use core::sync::atomic::Ordering::SeqCst;
+use core::sync::atomic::*;
#[test]
fn bool_() {
@@ -15,7 +15,7 @@
fn bool_and() {
let a = AtomicBool::new(true);
assert_eq!(a.fetch_and(false, SeqCst), true);
- assert_eq!(a.load(SeqCst),false);
+ assert_eq!(a.load(SeqCst), false);
}
#[test]
@@ -89,7 +89,7 @@
static S_FALSE: AtomicBool = AtomicBool::new(false);
static S_TRUE: AtomicBool = AtomicBool::new(true);
-static S_INT: AtomicIsize = AtomicIsize::new(0);
+static S_INT: AtomicIsize = AtomicIsize::new(0);
static S_UINT: AtomicUsize = AtomicUsize::new(0);
#[test]
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
index 4dfd884..801b60b 100644
--- a/src/libcore/tests/cell.rs
+++ b/src/libcore/tests/cell.rs
@@ -236,7 +236,7 @@
}
let x = X(RefCell::new((7, 'z')));
{
- let mut d: RefMut<'_ ,u32> = x.accessor();
+ let mut d: RefMut<'_, u32> = x.accessor();
assert_eq!(*d, 7);
*d += 1;
}
@@ -250,7 +250,9 @@
assert_eq!(1, unsafe { *c1.as_ptr() });
let c2: Cell<usize> = Cell::new(0);
- unsafe { *c2.as_ptr() = 1; }
+ unsafe {
+ *c2.as_ptr() = 1;
+ }
assert_eq!(1, c2.get());
let r1: RefCell<usize> = RefCell::new(0);
@@ -258,7 +260,9 @@
assert_eq!(1, unsafe { *r1.as_ptr() });
let r2: RefCell<usize> = RefCell::new(0);
- unsafe { *r2.as_ptr() = 1; }
+ unsafe {
+ *r2.as_ptr() = 1;
+ }
assert_eq!(1, *r2.borrow());
}
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index 57e9f4e..c16f540 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -1,6 +1,6 @@
-use std::{char,str};
use std::convert::TryFrom;
use std::str::FromStr;
+use std::{char, str};
#[test]
fn test_convert() {
@@ -143,13 +143,13 @@
#[test]
fn test_is_numeric() {
- assert!('2'.is_numeric());
- assert!('7'.is_numeric());
- assert!('¾'.is_numeric());
- assert!(!'c'.is_numeric());
- assert!(!'i'.is_numeric());
- assert!(!'z'.is_numeric());
- assert!(!'Q'.is_numeric());
+ assert!('2'.is_numeric());
+ assert!('7'.is_numeric());
+ assert!('¾'.is_numeric());
+ assert!(!'c'.is_numeric());
+ assert!(!'i'.is_numeric());
+ assert!(!'z'.is_numeric());
+ assert!(!'Q'.is_numeric());
}
#[test]
@@ -176,9 +176,9 @@
assert_eq!(string('\u{ff}'), "\u{ff}");
assert_eq!(string('\u{11b}'), "\u{11b}");
assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
- assert_eq!(string('\u{301}'), "\\u{301}"); // combining character
- assert_eq!(string('\u{200b}'),"\\u{200b}"); // zero width space
- assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
+ assert_eq!(string('\u{301}'), "\\u{301}"); // combining character
+ assert_eq!(string('\u{200b}'), "\\u{200b}"); // zero width space
+ assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
}
@@ -272,8 +272,8 @@
fn test_decode_utf16() {
fn check(s: &[u16], expected: &[Result<char, u16>]) {
let v = char::decode_utf16(s.iter().cloned())
- .map(|r| r.map_err(|e| e.unpaired_surrogate()))
- .collect::<Vec<_>>();
+ .map(|r| r.map_err(|e| e.unpaired_surrogate()))
+ .collect::<Vec<_>>();
assert_eq!(v, expected);
}
check(&[0xD800, 0x41, 0x42], &[Err(0xD800), Ok('A'), Ok('B')]);
diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs
index 1000088..ba0220f 100644
--- a/src/libcore/tests/hash/mod.rs
+++ b/src/libcore/tests/hash/mod.rs
@@ -1,7 +1,7 @@
mod sip;
-use std::hash::{Hash, Hasher};
use std::default::Default;
+use std::hash::{Hash, Hasher};
use std::rc::Rc;
struct MyHasher {
@@ -20,10 +20,11 @@
self.hash += *byte as u64;
}
}
- fn finish(&self) -> u64 { self.hash }
+ fn finish(&self) -> u64 {
+ self.hash
+ }
}
-
#[test]
fn test_writer_hasher() {
fn hash<T: Hash>(t: &T) -> u64 {
@@ -52,17 +53,17 @@
assert_eq!(hash(&'a'), 97);
let s: &str = "a";
- assert_eq!(hash(& s), 97 + 0xFF);
+ assert_eq!(hash(&s), 97 + 0xFF);
let s: Box<str> = String::from("a").into_boxed_str();
- assert_eq!(hash(& s), 97 + 0xFF);
+ assert_eq!(hash(&s), 97 + 0xFF);
let s: Rc<&str> = Rc::new("a");
assert_eq!(hash(&s), 97 + 0xFF);
let cs: &[u8] = &[1, 2, 3];
- assert_eq!(hash(& cs), 9);
+ assert_eq!(hash(&cs), 9);
let cs: Box<[u8]> = Box::new([1, 2, 3]);
- assert_eq!(hash(& cs), 9);
+ assert_eq!(hash(&cs), 9);
let cs: Rc<[u8]> = Rc::new([1, 2, 3]);
- assert_eq!(hash(& cs), 9);
+ assert_eq!(hash(&cs), 9);
let ptr = 5_usize as *const i32;
assert_eq!(hash(&ptr), 5);
@@ -70,24 +71,36 @@
let ptr = 5_usize as *mut i32;
assert_eq!(hash(&ptr), 5);
+ if cfg!(miri) { // Miri cannot hash pointers
+ return;
+ }
+
let cs: &mut [u8] = &mut [1, 2, 3];
let ptr = cs.as_ptr();
let slice_ptr = cs as *const [u8];
- #[cfg(not(miri))] // Miri cannot hash pointers
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
let slice_ptr = cs as *mut [u8];
- #[cfg(not(miri))] // Miri cannot hash pointers
assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
}
-struct Custom { hash: u64 }
-struct CustomHasher { output: u64 }
+struct Custom {
+ hash: u64,
+}
+struct CustomHasher {
+ output: u64,
+}
impl Hasher for CustomHasher {
- fn finish(&self) -> u64 { self.output }
- fn write(&mut self, _: &[u8]) { panic!() }
- fn write_u64(&mut self, data: u64) { self.output = data; }
+ fn finish(&self) -> u64 {
+ self.output
+ }
+ fn write(&mut self, _: &[u8]) {
+ panic!()
+ }
+ fn write_u64(&mut self, data: u64) {
+ self.output = data;
+ }
}
impl Default for CustomHasher {
diff --git a/src/libcore/tests/hash/sip.rs b/src/libcore/tests/hash/sip.rs
index b615cfd..0f09554 100644
--- a/src/libcore/tests/hash/sip.rs
+++ b/src/libcore/tests/hash/sip.rs
@@ -2,7 +2,7 @@
use core::hash::{Hash, Hasher};
use core::hash::{SipHasher, SipHasher13};
-use core::{slice, mem};
+use core::{mem, slice};
// Hash just the bytes of the slice, without length prefix
struct Bytes<'a>(&'a [u8]);
@@ -16,25 +16,25 @@
}
macro_rules! u8to64_le {
- ($buf:expr, $i:expr) =>
- ($buf[0+$i] as u64 |
- ($buf[1+$i] as u64) << 8 |
- ($buf[2+$i] as u64) << 16 |
- ($buf[3+$i] as u64) << 24 |
- ($buf[4+$i] as u64) << 32 |
- ($buf[5+$i] as u64) << 40 |
- ($buf[6+$i] as u64) << 48 |
- ($buf[7+$i] as u64) << 56);
- ($buf:expr, $i:expr, $len:expr) =>
- ({
+ ($buf:expr, $i:expr) => {
+ $buf[0 + $i] as u64
+ | ($buf[1 + $i] as u64) << 8
+ | ($buf[2 + $i] as u64) << 16
+ | ($buf[3 + $i] as u64) << 24
+ | ($buf[4 + $i] as u64) << 32
+ | ($buf[5 + $i] as u64) << 40
+ | ($buf[6 + $i] as u64) << 48
+ | ($buf[7 + $i] as u64) << 56
+ };
+ ($buf:expr, $i:expr, $len:expr) => {{
let mut t = 0;
let mut out = 0;
while t < $len {
- out |= ($buf[t+$i] as u64) << t*8;
+ out |= ($buf[t + $i] as u64) << t * 8;
t += 1;
}
out
- });
+ }};
}
fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
@@ -49,71 +49,71 @@
#[test]
#[allow(unused_must_use)]
fn test_siphash_1_3() {
- let vecs : [[u8; 8]; 64] = [
- [ 0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab ],
- [ 0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9 ],
- [ 0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82 ],
- [ 0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b ],
- [ 0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf ],
- [ 0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde ],
- [ 0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5 ],
- [ 0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3 ],
- [ 0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36 ],
- [ 0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25 ],
- [ 0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79 ],
- [ 0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70 ],
- [ 0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78 ],
- [ 0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30 ],
- [ 0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60 ],
- [ 0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3 ],
- [ 0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc ],
- [ 0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c ],
- [ 0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f ],
- [ 0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2 ],
- [ 0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0 ],
- [ 0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9 ],
- [ 0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f ],
- [ 0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52 ],
- [ 0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4 ],
- [ 0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45 ],
- [ 0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a ],
- [ 0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9 ],
- [ 0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb ],
- [ 0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88 ],
- [ 0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54 ],
- [ 0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23 ],
- [ 0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81 ],
- [ 0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d ],
- [ 0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75 ],
- [ 0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce ],
- [ 0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c ],
- [ 0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6 ],
- [ 0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3 ],
- [ 0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62 ],
- [ 0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1 ],
- [ 0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66 ],
- [ 0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65 ],
- [ 0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24 ],
- [ 0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2 ],
- [ 0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2 ],
- [ 0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1 ],
- [ 0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49 ],
- [ 0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f ],
- [ 0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6 ],
- [ 0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e ],
- [ 0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c ],
- [ 0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4 ],
- [ 0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36 ],
- [ 0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31 ],
- [ 0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2 ],
- [ 0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4 ],
- [ 0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23 ],
- [ 0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f ],
- [ 0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8 ],
- [ 0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6 ],
- [ 0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae ],
- [ 0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3 ],
- [ 0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d ]
+ let vecs: [[u8; 8]; 64] = [
+ [0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab],
+ [0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9],
+ [0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82],
+ [0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b],
+ [0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf],
+ [0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde],
+ [0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5],
+ [0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3],
+ [0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36],
+ [0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25],
+ [0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79],
+ [0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70],
+ [0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78],
+ [0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30],
+ [0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60],
+ [0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3],
+ [0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc],
+ [0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c],
+ [0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f],
+ [0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2],
+ [0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0],
+ [0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9],
+ [0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f],
+ [0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52],
+ [0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4],
+ [0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45],
+ [0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a],
+ [0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9],
+ [0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb],
+ [0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88],
+ [0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54],
+ [0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23],
+ [0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81],
+ [0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d],
+ [0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75],
+ [0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce],
+ [0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c],
+ [0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6],
+ [0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3],
+ [0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62],
+ [0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1],
+ [0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66],
+ [0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65],
+ [0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24],
+ [0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2],
+ [0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2],
+ [0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1],
+ [0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49],
+ [0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f],
+ [0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6],
+ [0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e],
+ [0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c],
+ [0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4],
+ [0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36],
+ [0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31],
+ [0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2],
+ [0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4],
+ [0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23],
+ [0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f],
+ [0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8],
+ [0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6],
+ [0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae],
+ [0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3],
+ [0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d],
];
let k0 = 0x_07_06_05_04_03_02_01_00;
@@ -143,71 +143,71 @@
#[test]
#[allow(unused_must_use)]
fn test_siphash_2_4() {
- let vecs : [[u8; 8]; 64] = [
- [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
- [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
- [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
- [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
- [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
- [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
- [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
- [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
- [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
- [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
- [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
- [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
- [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
- [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
- [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
- [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
- [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
- [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
- [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
- [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
- [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
- [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
- [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
- [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
- [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
- [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
- [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
- [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
- [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
- [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
- [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
- [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
- [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
- [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
- [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
- [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
- [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
- [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
- [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
- [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
- [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
- [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
- [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
- [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
- [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
- [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
- [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
- [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
- [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
- [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
- [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
- [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
- [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
- [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
- [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
- [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
- [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
- [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
- [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
- [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
- [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
- [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
- [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
- [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
+ let vecs: [[u8; 8]; 64] = [
+ [0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72],
+ [0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74],
+ [0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d],
+ [0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85],
+ [0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf],
+ [0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18],
+ [0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb],
+ [0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab],
+ [0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93],
+ [0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e],
+ [0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a],
+ [0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4],
+ [0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75],
+ [0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14],
+ [0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7],
+ [0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1],
+ [0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f],
+ [0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69],
+ [0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b],
+ [0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb],
+ [0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe],
+ [0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0],
+ [0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93],
+ [0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8],
+ [0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8],
+ [0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc],
+ [0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17],
+ [0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f],
+ [0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde],
+ [0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6],
+ [0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad],
+ [0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32],
+ [0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71],
+ [0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7],
+ [0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12],
+ [0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15],
+ [0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31],
+ [0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02],
+ [0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca],
+ [0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a],
+ [0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e],
+ [0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad],
+ [0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18],
+ [0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4],
+ [0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9],
+ [0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9],
+ [0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb],
+ [0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0],
+ [0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6],
+ [0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7],
+ [0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee],
+ [0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1],
+ [0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a],
+ [0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81],
+ [0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f],
+ [0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24],
+ [0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7],
+ [0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea],
+ [0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60],
+ [0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66],
+ [0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c],
+ [0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f],
+ [0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5],
+ [0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95],
];
let k0 = 0x_07_06_05_04_03_02_01_00;
@@ -320,8 +320,7 @@
h1.write_u8(0x01u8);
let mut h2 = SipHasher::new();
h2.write(unsafe {
- slice::from_raw_parts(&test_usize as *const _ as *const u8,
- mem::size_of::<usize>())
+ slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::<usize>())
});
h2.write(b"bytes");
h2.write(b"string");
diff --git a/src/libcore/tests/intrinsics.rs b/src/libcore/tests/intrinsics.rs
index 7544c13..fed7c4a 100644
--- a/src/libcore/tests/intrinsics.rs
+++ b/src/libcore/tests/intrinsics.rs
@@ -2,7 +2,8 @@
#[test]
fn test_typeid_sized_types() {
- struct X; struct Y(u32);
+ struct X;
+ struct Y(u32);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
@@ -12,7 +13,8 @@
#[test]
fn test_typeid_unsized_types() {
trait Z {}
- struct X(str); struct Y(dyn Z + 'static);
+ struct X(str);
+ struct Y(dyn Z + 'static);
assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
diff --git a/src/libcore/tests/manually_drop.rs b/src/libcore/tests/manually_drop.rs
index 49a1c18..77a338d 100644
--- a/src/libcore/tests/manually_drop.rs
+++ b/src/libcore/tests/manually_drop.rs
@@ -13,7 +13,7 @@
drop(x);
// also test unsizing
- let x : Box<ManuallyDrop<[TypeWithDrop]>> =
+ let x: Box<ManuallyDrop<[TypeWithDrop]>> =
Box::new(ManuallyDrop::new([TypeWithDrop, TypeWithDrop]));
drop(x);
}
diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs
index f5b2419..59588d9 100644
--- a/src/libcore/tests/mem.rs
+++ b/src/libcore/tests/mem.rs
@@ -96,7 +96,9 @@
#[test]
fn test_transmute() {
- trait Foo { fn dummy(&self) { } }
+ trait Foo {
+ fn dummy(&self) {}
+ }
impl Foo for isize {}
let a = box 100isize as Box<dyn Foo>;
@@ -116,13 +118,13 @@
fn test_discriminant_send_sync() {
enum Regular {
A,
- B(i32)
+ B(i32),
}
enum NotSendSync {
- A(*const i32)
+ A(*const i32),
}
- fn is_send_sync<T: Send + Sync>() { }
+ fn is_send_sync<T: Send + Sync>() {}
is_send_sync::<Discriminant<Regular>>();
is_send_sync::<Discriminant<NotSendSync>>();
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index 77e4846..6c5d198 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -4,9 +4,7 @@
#[test]
fn test_create_nonzero_instance() {
- let _a = unsafe {
- NonZeroU32::new_unchecked(21)
- };
+ let _a = unsafe { NonZeroU32::new_unchecked(21) };
}
#[test]
@@ -17,17 +15,15 @@
#[test]
fn test_match_on_nonzero_option() {
- let a = Some(unsafe {
- NonZeroU32::new_unchecked(42)
- });
+ let a = Some(unsafe { NonZeroU32::new_unchecked(42) });
match a {
Some(val) => assert_eq!(val.get(), 42),
- None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
+ None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
}
match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
Some(val) => assert_eq!(val.get(), 43),
- None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
+ None => panic!("unexpected None while matching on Some(NonZeroU32(_))"),
}
}
@@ -45,7 +41,7 @@
let a = Some(vec![1, 2, 3, 4]);
match a {
Some(v) => assert_eq!(v, [1, 2, 3, 4]),
- None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
+ None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])"),
}
}
@@ -56,7 +52,7 @@
let five = Rc::new(5);
match Some(five) {
Some(r) => assert_eq!(*r, 5),
- None => panic!("unexpected None while matching on Some(Rc::new(5))")
+ None => panic!("unexpected None while matching on Some(Rc::new(5))"),
}
}
@@ -67,7 +63,7 @@
let five = Arc::new(5);
match Some(five) {
Some(a) => assert_eq!(*a, 5),
- None => panic!("unexpected None while matching on Some(Arc::new(5))")
+ None => panic!("unexpected None while matching on Some(Arc::new(5))"),
}
}
@@ -85,7 +81,7 @@
let five = "Five".to_string();
match Some(five) {
Some(s) => assert_eq!(s, "Five"),
- None => panic!("unexpected None while matching on Some(String { ... })")
+ None => panic!("unexpected None while matching on Some(String { ... })"),
}
}
@@ -100,7 +96,9 @@
}
macro_rules! atom {
- ("foo") => { atom::FOO_ATOM }
+ ("foo") => {
+ atom::FOO_ATOM
+ };
}
#[test]
@@ -108,7 +106,7 @@
match atom!("foo") {
// Using as a pattern is supported by the compiler:
atom!("foo") => {}
- _ => panic!("Expected the const item as a pattern to match.")
+ _ => panic!("Expected the const item as a pattern to match."),
}
}
@@ -129,10 +127,7 @@
#[test]
fn test_from_str() {
assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
- assert_eq!(
- "0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
- Some(IntErrorKind::Zero)
- );
+ assert_eq!("0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()), Some(IntErrorKind::Zero));
assert_eq!(
"-1".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
Some(IntErrorKind::InvalidDigit)
diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs
index 50a3ec0..1457064 100644
--- a/src/libcore/tests/num/bignum.rs
+++ b/src/libcore/tests/num/bignum.rs
@@ -70,7 +70,7 @@
fn test_mul_small() {
assert_eq!(*Big::from_small(7).mul_small(5), Big::from_small(35));
assert_eq!(*Big::from_small(0xff).mul_small(0xff), Big::from_u64(0xfe01));
- assert_eq!(*Big::from_u64(0xffffff/13).mul_small(13), Big::from_u64(0xffffff));
+ assert_eq!(*Big::from_u64(0xffffff / 13).mul_small(13), Big::from_u64(0xffffff));
}
#[test]
@@ -134,7 +134,7 @@
assert_eq!(*Big::from_u64(0x123).mul_digits(&[0x56, 0x4]), Big::from_u64(0x4edc2));
assert_eq!(*Big::from_u64(0x12345).mul_digits(&[0x67]), Big::from_u64(0x7530c3));
assert_eq!(*Big::from_small(0x12).mul_digits(&[0x67, 0x45, 0x3]), Big::from_u64(0x3ae13e));
- assert_eq!(*Big::from_u64(0xffffff/13).mul_digits(&[13]), Big::from_u64(0xffffff));
+ assert_eq!(*Big::from_u64(0xffffff / 13).mul_digits(&[13]), Big::from_u64(0xffffff));
assert_eq!(*Big::from_small(13).mul_digits(&[0x3b, 0xb1, 0x13]), Big::from_u64(0xffffff));
}
@@ -156,10 +156,14 @@
assert_eq!(as_val(Big::from_small(0xff).div_rem_small(15)), (Big::from_small(17), 0));
assert_eq!(as_val(Big::from_small(0xff).div_rem_small(16)), (Big::from_small(15), 15));
assert_eq!(as_val(Big::from_small(3).div_rem_small(40)), (Big::from_small(0), 3));
- assert_eq!(as_val(Big::from_u64(0xffffff).div_rem_small(123)),
- (Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8));
- assert_eq!(as_val(Big::from_u64(0x10000).div_rem_small(123)),
- (Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8));
+ assert_eq!(
+ as_val(Big::from_u64(0xffffff).div_rem_small(123)),
+ (Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8)
+ );
+ assert_eq!(
+ as_val(Big::from_u64(0x10000).div_rem_small(123)),
+ (Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8)
+ );
}
#[test]
diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs
index 46eacb4..6bb348f 100644
--- a/src/libcore/tests/num/dec2flt/mod.rs
+++ b/src/libcore/tests/num/dec2flt/mod.rs
@@ -1,6 +1,6 @@
#![allow(overflowing_literals)]
-use std::{i64, f32, f64};
+use std::{f32, f64, i64};
mod parse;
mod rawfp;
@@ -9,7 +9,7 @@
// to be correct) and see if those strings are parsed back to the value of the literal.
// Requires a *polymorphic literal*, i.e., one that can serve as f64 as well as f32.
macro_rules! test_literal {
- ($x: expr) => ({
+ ($x: expr) => {{
let x32: f32 = $x;
let x64: f64 = $x;
let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
@@ -20,7 +20,7 @@
assert_eq!(neg_input.parse(), Ok(-x64));
assert_eq!(neg_input.parse(), Ok(-x32));
}
- })
+ }};
}
#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
@@ -31,7 +31,11 @@
test_literal!(0.1);
test_literal!(12345.);
test_literal!(0.9999999);
- #[cfg(not(miri))] // Miri is too slow
+
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
test_literal!(2.2250738585072014e-308);
}
@@ -53,7 +57,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn subnormals() {
test_literal!(5e-324);
test_literal!(91e-324);
@@ -65,7 +69,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn infinity() {
test_literal!(1e400);
test_literal!(1e309);
@@ -77,9 +81,12 @@
fn zero() {
test_literal!(0.0);
test_literal!(1e-325);
- #[cfg(not(miri))] // Miri is too slow
+
+ if cfg!(miri) { // Miri is too slow
+ return;
+ }
+
test_literal!(1e-326);
- #[cfg(not(miri))] // Miri is too slow
test_literal!(1e-500);
}
diff --git a/src/libcore/tests/num/dec2flt/parse.rs b/src/libcore/tests/num/dec2flt/parse.rs
index 1eac484..bb7e51d 100644
--- a/src/libcore/tests/num/dec2flt/parse.rs
+++ b/src/libcore/tests/num/dec2flt/parse.rs
@@ -1,5 +1,5 @@
-use core::num::dec2flt::parse::{Decimal, parse_decimal};
-use core::num::dec2flt::parse::ParseResult::{Valid, Invalid};
+use core::num::dec2flt::parse::ParseResult::{Invalid, Valid};
+use core::num::dec2flt::parse::{parse_decimal, Decimal};
#[test]
fn missing_pieces() {
diff --git a/src/libcore/tests/num/dec2flt/rawfp.rs b/src/libcore/tests/num/dec2flt/rawfp.rs
index 747c1bf..665fb6b 100644
--- a/src/libcore/tests/num/dec2flt/rawfp.rs
+++ b/src/libcore/tests/num/dec2flt/rawfp.rs
@@ -1,8 +1,8 @@
+use core::num::dec2flt::rawfp::RawFloat;
+use core::num::dec2flt::rawfp::{fp_to_float, next_float, prev_float, round_normal};
+use core::num::diy_float::Fp;
use std::f32;
use std::f64;
-use core::num::diy_float::Fp;
-use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
-use core::num::dec2flt::rawfp::RawFloat;
fn integer_decode(f: f64) -> (u64, i16, i8) {
RawFloat::integer_decode(f)
@@ -53,16 +53,23 @@
assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
}
-const SOME_FLOATS: [f64; 9] =
- [0.1f64, 33.568, 42.1e-5, 777.0e9, 1.1111, 0.347997,
- 9843579834.35892, 12456.0e-150, 54389573.0e-150];
-
+const SOME_FLOATS: [f64; 9] = [
+ 0.1f64,
+ 33.568,
+ 42.1e-5,
+ 777.0e9,
+ 1.1111,
+ 0.347997,
+ 9843579834.35892,
+ 12456.0e-150,
+ 54389573.0e-150,
+];
#[test]
fn human_f64_roundtrip() {
for &x in &SOME_FLOATS {
let (f, e, _) = integer_decode(x);
- let fp = Fp { f: f, e: e};
+ let fp = Fp { f: f, e: e };
assert_eq!(fp_to_float::<f64>(fp), x);
}
}
diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs
index c514517..8ee06d8 100644
--- a/src/libcore/tests/num/flt2dec/estimator.rs
+++ b/src/libcore/tests/num/flt2dec/estimator.rs
@@ -3,14 +3,24 @@
#[test]
fn test_estimate_scaling_factor() {
macro_rules! assert_almost_eq {
- ($actual:expr, $expected:expr) => ({
+ ($actual:expr, $expected:expr) => {{
let actual = $actual;
let expected = $expected;
- println!("{} - {} = {} - {} = {}", stringify!($expected), stringify!($actual),
- expected, actual, expected - actual);
- assert!(expected == actual || expected == actual + 1,
- "expected {}, actual {}", expected, actual);
- })
+ println!(
+ "{} - {} = {} - {} = {}",
+ stringify!($expected),
+ stringify!($actual),
+ expected,
+ actual,
+ expected - actual
+ );
+ assert!(
+ expected == actual || expected == actual + 1,
+ "expected {}, actual {}",
+ expected,
+ actual
+ );
+ }};
}
assert_almost_eq!(estimate_scaling_factor(1, 0), 0);
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index f85369c..2f94ea2 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -256,7 +256,6 @@
check_shortest!(f(minf32) => b"1", -44);
}
-#[cfg(not(miri))] // Miri is too slow
pub fn f32_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf32 = ldexp_f32(1.0, -149);
@@ -362,7 +361,6 @@
check_shortest!(f(minf64) => b"5", -323);
}
-#[cfg(not(miri))] // Miri is too slow
pub fn f64_exact_sanity_test<F>(mut f: F)
where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
let minf64 = ldexp_f64(1.0, -1074);
diff --git a/src/libcore/tests/num/flt2dec/random.rs b/src/libcore/tests/num/flt2dec/random.rs
index d954379..ecdfc4b 100644
--- a/src/libcore/tests/num/flt2dec/random.rs
+++ b/src/libcore/tests/num/flt2dec/random.rs
@@ -3,27 +3,28 @@
use std::i16;
use std::str;
-use core::num::flt2dec::MAX_SIG_DIGITS;
use core::num::flt2dec::strategy::grisu::format_exact_opt;
use core::num::flt2dec::strategy::grisu::format_shortest_opt;
-use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
+use core::num::flt2dec::MAX_SIG_DIGITS;
+use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
-use rand::SeedableRng;
-use rand::rngs::StdRng;
use rand::distributions::{Distribution, Uniform};
+use rand::rngs::StdRng;
+use rand::SeedableRng;
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
match decode(v).1 {
FullDecoded::Finite(decoded) => decoded,
- full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+ full_decoded => panic!("expected finite, got {:?} instead", full_decoded),
}
}
-
fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
- where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
- G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
- V: FnMut(usize) -> Decoded {
+where
+ F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+ G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+ V: FnMut(usize) -> Decoded,
+{
assert!(k <= 1024);
let mut npassed = 0; // f(x) = Some(g(x))
@@ -31,8 +32,14 @@
for i in 0..n {
if (i & 0xfffff) == 0 {
- println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
- i, n, nignored, npassed, i - nignored - npassed);
+ println!(
+ "in progress, {:x}/{:x} (ignored={} passed={} failed={})",
+ i,
+ n,
+ nignored,
+ npassed,
+ i - nignored - npassed
+ );
}
let decoded = v(i);
@@ -43,27 +50,47 @@
if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
npassed += 1;
} else {
- println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
- i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
- str::from_utf8(&buf2[..len2]).unwrap(), e2);
+ println!(
+ "equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
+ i,
+ n,
+ decoded,
+ str::from_utf8(&buf1[..len1]).unwrap(),
+ e1,
+ str::from_utf8(&buf2[..len2]).unwrap(),
+ e2
+ );
}
} else {
nignored += 1;
}
}
- println!("{}({}): done, ignored={} passed={} failed={}",
- func, k, nignored, npassed, n - nignored - npassed);
- assert!(nignored + npassed == n,
- "{}({}): {} out of {} values returns an incorrect value!",
- func, k, n - nignored - npassed, n);
+ println!(
+ "{}({}): done, ignored={} passed={} failed={}",
+ func,
+ k,
+ nignored,
+ npassed,
+ n - nignored - npassed
+ );
+ assert!(
+ nignored + npassed == n,
+ "{}({}): {} out of {} values returns an incorrect value!",
+ func,
+ k,
+ n - nignored - npassed,
+ n
+ );
(npassed, nignored)
}
pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
- where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
- G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+where
+ F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+ G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+{
if cfg!(target_os = "emscripten") {
- return // using rng pulls in i128 support, which doesn't work
+ return; // using rng pulls in i128 support, which doesn't work
}
let mut rng = StdRng::from_entropy();
let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
@@ -74,10 +101,12 @@
}
pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
- where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
- G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+where
+ F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+ G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+{
if cfg!(target_os = "emscripten") {
- return // using rng pulls in i128 support, which doesn't work
+ return; // using rng pulls in i128 support, which doesn't work
}
let mut rng = StdRng::from_entropy();
let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
@@ -88,8 +117,10 @@
}
pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
- where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
- G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+where
+ F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+ G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+{
// we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
// so why not simply testing all of them?
//
@@ -97,12 +128,11 @@
// but with `-C opt-level=3 -C lto` this only takes about an hour or so.
// iterate from 0x0000_0001 to 0x7f7f_ffff, i.e., all finite ranges
- let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
- k, 0x7f7f_ffff, f, g, |i: usize| {
-
- let x = f32::from_bits(i as u32 + 1);
- decode_finite(x)
- });
+ let (npassed, nignored) =
+ iterate("f32_exhaustive_equivalence_test", k, 0x7f7f_ffff, f, g, |i: usize| {
+ let x = f32::from_bits(i as u32 + 1);
+ decode_finite(x)
+ });
assert_eq!((npassed, nignored), (2121451881, 17643158));
}
@@ -118,7 +148,8 @@
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
}
-#[test] #[ignore] // it is too expensive
+#[test]
+#[ignore] // it is too expensive
fn shortest_f32_exhaustive_equivalence_test() {
// it is hard to directly test the optimality of the output, but we can at least test if
// two different algorithms agree to each other.
@@ -131,13 +162,13 @@
f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}
-#[test] #[ignore] // it is too expensive
+#[test]
+#[ignore] // it is too expensive
fn shortest_f64_hard_random_equivalence_test() {
// this again probably has to use appropriate rustc flags.
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
- f64_random_equivalence_test(format_shortest_opt, fallback,
- MAX_SIG_DIGITS, 100_000_000);
+ f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 100_000_000);
}
#[test]
@@ -149,8 +180,12 @@
const N: usize = 3;
for k in 1..21 {
- f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
- |d, buf| fallback(d, buf, i16::MIN), k, N);
+ f32_random_equivalence_test(
+ |d, buf| format_exact_opt(d, buf, i16::MIN),
+ |d, buf| fallback(d, buf, i16::MIN),
+ k,
+ N,
+ );
}
}
@@ -163,7 +198,11 @@
const N: usize = 3;
for k in 1..21 {
- f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
- |d, buf| fallback(d, buf, i16::MIN), k, N);
+ f64_random_equivalence_test(
+ |d, buf| format_exact_opt(d, buf, i16::MIN),
+ |d, buf| fallback(d, buf, i16::MIN),
+ k,
+ N,
+ );
}
}
diff --git a/src/libcore/tests/num/flt2dec/strategy/dragon.rs b/src/libcore/tests/num/flt2dec/strategy/dragon.rs
index 0c545b4..3d985c6 100644
--- a/src/libcore/tests/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/tests/num/flt2dec/strategy/dragon.rs
@@ -22,7 +22,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn exact_sanity_test() {
// This test ends up running what I can only assume is some corner-ish case
// of the `exp2` library function, defined in whatever C runtime we're
diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
index f8bdddf..ff8373c 100644
--- a/src/libcore/tests/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
@@ -6,12 +6,18 @@
assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E);
assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E);
- for e in -1137..961 { // full range for f64
+ for e in -1137..961 {
+ // full range for f64
let low = ALPHA - e - 64;
let high = GAMMA - e - 64;
let (_k, cached) = cached_power(low, high);
- assert!(low <= cached.e && cached.e <= high,
- "cached_power({}, {}) = {:?} is incorrect", low, high, cached);
+ assert!(
+ low <= cached.e && cached.e <= high,
+ "cached_power({}, {}) = {:?} is incorrect",
+ low,
+ high,
+ cached
+ );
}
}
@@ -26,7 +32,6 @@
}
}
-
#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
#[test]
fn shortest_sanity_test() {
@@ -36,7 +41,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn exact_sanity_test() {
// See comments in dragon.rs's exact_sanity_test for why this test is
// ignored on MSVC
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 0475aeb..4a44b5f 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -1,240 +1,241 @@
-macro_rules! int_module { ($T:ident, $T_i:ident) => (
-#[cfg(test)]
-mod tests {
- use core::$T_i::*;
- use core::isize;
- use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
- use core::mem;
+macro_rules! int_module {
+ ($T:ident, $T_i:ident) => {
+ #[cfg(test)]
+ mod tests {
+ use core::isize;
+ use core::mem;
+ use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+ use core::$T_i::*;
- use crate::num;
+ use crate::num;
- #[test]
- fn test_overflows() {
- assert!(MAX > 0);
- assert!(MIN <= 0);
- assert_eq!(MIN + MAX + 1, 0);
- }
+ #[test]
+ fn test_overflows() {
+ assert!(MAX > 0);
+ assert!(MIN <= 0);
+ assert_eq!(MIN + MAX + 1, 0);
+ }
- #[test]
- fn test_num() {
- num::test_num(10 as $T, 2 as $T);
- }
+ #[test]
+ fn test_num() {
+ num::test_num(10 as $T, 2 as $T);
+ }
- #[test]
- fn test_rem_euclid() {
- assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
- }
+ #[test]
+ fn test_rem_euclid() {
+ assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
+ }
- #[test]
- pub fn test_abs() {
- assert_eq!((1 as $T).abs(), 1 as $T);
- assert_eq!((0 as $T).abs(), 0 as $T);
- assert_eq!((-1 as $T).abs(), 1 as $T);
- }
+ #[test]
+ pub fn test_abs() {
+ assert_eq!((1 as $T).abs(), 1 as $T);
+ assert_eq!((0 as $T).abs(), 0 as $T);
+ assert_eq!((-1 as $T).abs(), 1 as $T);
+ }
- #[test]
- fn test_signum() {
- assert_eq!((1 as $T).signum(), 1 as $T);
- assert_eq!((0 as $T).signum(), 0 as $T);
- assert_eq!((-0 as $T).signum(), 0 as $T);
- assert_eq!((-1 as $T).signum(), -1 as $T);
- }
+ #[test]
+ fn test_signum() {
+ assert_eq!((1 as $T).signum(), 1 as $T);
+ assert_eq!((0 as $T).signum(), 0 as $T);
+ assert_eq!((-0 as $T).signum(), 0 as $T);
+ assert_eq!((-1 as $T).signum(), -1 as $T);
+ }
- #[test]
- fn test_is_positive() {
- assert!((1 as $T).is_positive());
- assert!(!(0 as $T).is_positive());
- assert!(!(-0 as $T).is_positive());
- assert!(!(-1 as $T).is_positive());
- }
+ #[test]
+ fn test_is_positive() {
+ assert!((1 as $T).is_positive());
+ assert!(!(0 as $T).is_positive());
+ assert!(!(-0 as $T).is_positive());
+ assert!(!(-1 as $T).is_positive());
+ }
- #[test]
- fn test_is_negative() {
- assert!(!(1 as $T).is_negative());
- assert!(!(0 as $T).is_negative());
- assert!(!(-0 as $T).is_negative());
- assert!((-1 as $T).is_negative());
- }
+ #[test]
+ fn test_is_negative() {
+ assert!(!(1 as $T).is_negative());
+ assert!(!(0 as $T).is_negative());
+ assert!(!(-0 as $T).is_negative());
+ assert!((-1 as $T).is_negative());
+ }
- #[test]
- fn test_bitwise_operators() {
- assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
- assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
- assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
- assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
- assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
- assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
- }
+ #[test]
+ fn test_bitwise_operators() {
+ assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
+ assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
+ assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
+ assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
+ assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
+ assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
+ }
- const A: $T = 0b0101100;
- const B: $T = 0b0100001;
- const C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- const _0: $T = 0;
- const _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
- #[test]
- fn test_count_ones() {
- assert_eq!(A.count_ones(), 3);
- assert_eq!(B.count_ones(), 2);
- assert_eq!(C.count_ones(), 5);
- }
+ #[test]
+ fn test_count_ones() {
+ assert_eq!(A.count_ones(), 3);
+ assert_eq!(B.count_ones(), 2);
+ assert_eq!(C.count_ones(), 5);
+ }
- #[test]
- fn test_count_zeros() {
- let bits = mem::size_of::<$T>() * 8;
- assert_eq!(A.count_zeros(), bits as u32 - 3);
- assert_eq!(B.count_zeros(), bits as u32 - 2);
- assert_eq!(C.count_zeros(), bits as u32 - 5);
- }
+ #[test]
+ fn test_count_zeros() {
+ let bits = mem::size_of::<$T>() * 8;
+ assert_eq!(A.count_zeros(), bits as u32 - 3);
+ assert_eq!(B.count_zeros(), bits as u32 - 2);
+ assert_eq!(C.count_zeros(), bits as u32 - 5);
+ }
- #[test]
- fn test_rotate() {
- assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
- assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
- assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+ #[test]
+ fn test_rotate() {
+ assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+ assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+ assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
- // Rotating these should make no difference
- //
- // We test using 124 bits because to ensure that overlong bit shifts do
- // not cause undefined behaviour. See #10183.
- assert_eq!(_0.rotate_left(124), _0);
- assert_eq!(_1.rotate_left(124), _1);
- assert_eq!(_0.rotate_right(124), _0);
- assert_eq!(_1.rotate_right(124), _1);
+ // Rotating these should make no difference
+ //
+ // We test using 124 bits because to ensure that overlong bit shifts do
+ // not cause undefined behaviour. See #10183.
+ assert_eq!(_0.rotate_left(124), _0);
+ assert_eq!(_1.rotate_left(124), _1);
+ assert_eq!(_0.rotate_right(124), _0);
+ assert_eq!(_1.rotate_right(124), _1);
- // Rotating by 0 should have no effect
- assert_eq!(A.rotate_left(0), A);
- assert_eq!(B.rotate_left(0), B);
- assert_eq!(C.rotate_left(0), C);
- // Rotating by a multiple of word size should also have no effect
- assert_eq!(A.rotate_left(64), A);
- assert_eq!(B.rotate_left(64), B);
- assert_eq!(C.rotate_left(64), C);
- }
+ // Rotating by 0 should have no effect
+ assert_eq!(A.rotate_left(0), A);
+ assert_eq!(B.rotate_left(0), B);
+ assert_eq!(C.rotate_left(0), C);
+ // Rotating by a multiple of word size should also have no effect
+ assert_eq!(A.rotate_left(64), A);
+ assert_eq!(B.rotate_left(64), B);
+ assert_eq!(C.rotate_left(64), C);
+ }
- #[test]
- fn test_swap_bytes() {
- assert_eq!(A.swap_bytes().swap_bytes(), A);
- assert_eq!(B.swap_bytes().swap_bytes(), B);
- assert_eq!(C.swap_bytes().swap_bytes(), C);
+ #[test]
+ fn test_swap_bytes() {
+ assert_eq!(A.swap_bytes().swap_bytes(), A);
+ assert_eq!(B.swap_bytes().swap_bytes(), B);
+ assert_eq!(C.swap_bytes().swap_bytes(), C);
- // Swapping these should make no difference
- assert_eq!(_0.swap_bytes(), _0);
- assert_eq!(_1.swap_bytes(), _1);
- }
+ // Swapping these should make no difference
+ assert_eq!(_0.swap_bytes(), _0);
+ assert_eq!(_1.swap_bytes(), _1);
+ }
- #[test]
- fn test_le() {
- assert_eq!($T::from_le(A.to_le()), A);
- assert_eq!($T::from_le(B.to_le()), B);
- assert_eq!($T::from_le(C.to_le()), C);
- assert_eq!($T::from_le(_0), _0);
- assert_eq!($T::from_le(_1), _1);
- assert_eq!(_0.to_le(), _0);
- assert_eq!(_1.to_le(), _1);
- }
+ #[test]
+ fn test_le() {
+ assert_eq!($T::from_le(A.to_le()), A);
+ assert_eq!($T::from_le(B.to_le()), B);
+ assert_eq!($T::from_le(C.to_le()), C);
+ assert_eq!($T::from_le(_0), _0);
+ assert_eq!($T::from_le(_1), _1);
+ assert_eq!(_0.to_le(), _0);
+ assert_eq!(_1.to_le(), _1);
+ }
- #[test]
- fn test_be() {
- assert_eq!($T::from_be(A.to_be()), A);
- assert_eq!($T::from_be(B.to_be()), B);
- assert_eq!($T::from_be(C.to_be()), C);
- assert_eq!($T::from_be(_0), _0);
- assert_eq!($T::from_be(_1), _1);
- assert_eq!(_0.to_be(), _0);
- assert_eq!(_1.to_be(), _1);
- }
+ #[test]
+ fn test_be() {
+ assert_eq!($T::from_be(A.to_be()), A);
+ assert_eq!($T::from_be(B.to_be()), B);
+ assert_eq!($T::from_be(C.to_be()), C);
+ assert_eq!($T::from_be(_0), _0);
+ assert_eq!($T::from_be(_1), _1);
+ assert_eq!(_0.to_be(), _0);
+ assert_eq!(_1.to_be(), _1);
+ }
- #[test]
- fn test_signed_checked_div() {
- assert_eq!((10 as $T).checked_div(2), Some(5));
- assert_eq!((5 as $T).checked_div(0), None);
- assert_eq!(isize::MIN.checked_div(-1), None);
- }
+ #[test]
+ fn test_signed_checked_div() {
+ assert_eq!((10 as $T).checked_div(2), Some(5));
+ assert_eq!((5 as $T).checked_div(0), None);
+ assert_eq!(isize::MIN.checked_div(-1), None);
+ }
- #[test]
- fn test_saturating_abs() {
- assert_eq!((0 as $T).saturating_abs(), 0);
- assert_eq!((123 as $T).saturating_abs(), 123);
- assert_eq!((-123 as $T).saturating_abs(), 123);
- assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
- assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
- assert_eq!(MAX.saturating_abs(), MAX);
- assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
- assert_eq!((MIN + 1).saturating_abs(), MAX);
- assert_eq!(MIN.saturating_abs(), MAX);
- }
+ #[test]
+ fn test_saturating_abs() {
+ assert_eq!((0 as $T).saturating_abs(), 0);
+ assert_eq!((123 as $T).saturating_abs(), 123);
+ assert_eq!((-123 as $T).saturating_abs(), 123);
+ assert_eq!((MAX - 2).saturating_abs(), MAX - 2);
+ assert_eq!((MAX - 1).saturating_abs(), MAX - 1);
+ assert_eq!(MAX.saturating_abs(), MAX);
+ assert_eq!((MIN + 2).saturating_abs(), MAX - 1);
+ assert_eq!((MIN + 1).saturating_abs(), MAX);
+ assert_eq!(MIN.saturating_abs(), MAX);
+ }
- #[test]
- fn test_saturating_neg() {
- assert_eq!((0 as $T).saturating_neg(), 0);
- assert_eq!((123 as $T).saturating_neg(), -123);
- assert_eq!((-123 as $T).saturating_neg(), 123);
- assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
- assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
- assert_eq!(MAX.saturating_neg(), MIN + 1);
- assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
- assert_eq!((MIN + 1).saturating_neg(), MAX);
- assert_eq!(MIN.saturating_neg(), MAX);
- }
+ #[test]
+ fn test_saturating_neg() {
+ assert_eq!((0 as $T).saturating_neg(), 0);
+ assert_eq!((123 as $T).saturating_neg(), -123);
+ assert_eq!((-123 as $T).saturating_neg(), 123);
+ assert_eq!((MAX - 2).saturating_neg(), MIN + 3);
+ assert_eq!((MAX - 1).saturating_neg(), MIN + 2);
+ assert_eq!(MAX.saturating_neg(), MIN + 1);
+ assert_eq!((MIN + 2).saturating_neg(), MAX - 1);
+ assert_eq!((MIN + 1).saturating_neg(), MAX);
+ assert_eq!(MIN.saturating_neg(), MAX);
+ }
- #[test]
- fn test_from_str() {
- fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
- ::std::str::FromStr::from_str(t).ok()
+ #[test]
+ fn test_from_str() {
+ fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
+ ::std::str::FromStr::from_str(t).ok()
+ }
+ assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+ assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+ assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+ assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
+ assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+ assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
+ assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
+ assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
+ assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
+ assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
+
+ assert_eq!(from_str::<$T>(""), None);
+ assert_eq!(from_str::<$T>(" "), None);
+ assert_eq!(from_str::<$T>("x"), None);
+ }
+
+ #[test]
+ fn test_from_str_radix() {
+ assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+ assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+ assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+ assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
+ assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
+ assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
+ assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+ assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
+
+ assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
+ assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
+ assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
+ assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
+ assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+ assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+ assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
+ assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
+
+ assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
+ assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
+ }
+
+ #[test]
+ fn test_pow() {
+ let mut r = 2 as $T;
+
+ assert_eq!(r.pow(2), 4 as $T);
+ assert_eq!(r.pow(0), 1 as $T);
+ r = -2 as $T;
+ assert_eq!(r.pow(2), 4 as $T);
+ assert_eq!(r.pow(3), -8 as $T);
+ }
}
- assert_eq!(from_str::<$T>("0"), Some(0 as $T));
- assert_eq!(from_str::<$T>("3"), Some(3 as $T));
- assert_eq!(from_str::<$T>("10"), Some(10 as $T));
- assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
- assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
- assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
- assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
- assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
- assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
- assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
-
- assert_eq!(from_str::<$T>(""), None);
- assert_eq!(from_str::<$T>(" "), None);
- assert_eq!(from_str::<$T>("x"), None);
- }
-
- #[test]
- fn test_from_str_radix() {
- assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
- assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
- assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
- assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
- assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
- assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
- assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
- assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
-
- assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
- assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
- assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
- assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
- assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
- assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
- assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
- assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
-
- assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
- assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
- }
-
- #[test]
- fn test_pow() {
- let mut r = 2 as $T;
-
- assert_eq!(r.pow(2), 4 as $T);
- assert_eq!(r.pow(0), 1 as $T);
- r = -2 as $T;
- assert_eq!(r.pow(2), 4 as $T);
- assert_eq!(r.pow(3), -8 as $T);
- }
+ };
}
-
-)}
diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs
index 04ed14f..f94b2f5 100644
--- a/src/libcore/tests/num/uint_macros.rs
+++ b/src/libcore/tests/num/uint_macros.rs
@@ -1,160 +1,162 @@
-macro_rules! uint_module { ($T:ident, $T_i:ident) => (
-#[cfg(test)]
-mod tests {
- use core::$T_i::*;
- use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
- use std::str::FromStr;
- use std::mem;
+macro_rules! uint_module {
+ ($T:ident, $T_i:ident) => {
+ #[cfg(test)]
+ mod tests {
+ use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+ use core::$T_i::*;
+ use std::mem;
+ use std::str::FromStr;
- use crate::num;
+ use crate::num;
- #[test]
- fn test_overflows() {
- assert!(MAX > 0);
- assert!(MIN <= 0);
- assert!((MIN + MAX).wrapping_add(1) == 0);
- }
+ #[test]
+ fn test_overflows() {
+ assert!(MAX > 0);
+ assert!(MIN <= 0);
+ assert!((MIN + MAX).wrapping_add(1) == 0);
+ }
- #[test]
- fn test_num() {
- num::test_num(10 as $T, 2 as $T);
- }
+ #[test]
+ fn test_num() {
+ num::test_num(10 as $T, 2 as $T);
+ }
- #[test]
- fn test_bitwise_operators() {
- assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
- assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
- assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
- assert!(0b1110 as $T == (0b0111 as $T).shl(1));
- assert!(0b0111 as $T == (0b1110 as $T).shr(1));
- assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
- }
+ #[test]
+ fn test_bitwise_operators() {
+ assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+ assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+ assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+ assert!(0b1110 as $T == (0b0111 as $T).shl(1));
+ assert!(0b0111 as $T == (0b1110 as $T).shr(1));
+ assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
+ }
- const A: $T = 0b0101100;
- const B: $T = 0b0100001;
- const C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- const _0: $T = 0;
- const _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
- #[test]
- fn test_count_ones() {
- assert!(A.count_ones() == 3);
- assert!(B.count_ones() == 2);
- assert!(C.count_ones() == 5);
- }
+ #[test]
+ fn test_count_ones() {
+ assert!(A.count_ones() == 3);
+ assert!(B.count_ones() == 2);
+ assert!(C.count_ones() == 5);
+ }
- #[test]
- fn test_count_zeros() {
- let bits = mem::size_of::<$T>() * 8;
- assert!(A.count_zeros() == bits as u32 - 3);
- assert!(B.count_zeros() == bits as u32 - 2);
- assert!(C.count_zeros() == bits as u32 - 5);
- }
+ #[test]
+ fn test_count_zeros() {
+ let bits = mem::size_of::<$T>() * 8;
+ assert!(A.count_zeros() == bits as u32 - 3);
+ assert!(B.count_zeros() == bits as u32 - 2);
+ assert!(C.count_zeros() == bits as u32 - 5);
+ }
- #[test]
- fn test_rotate() {
- assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
- assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
- assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+ #[test]
+ fn test_rotate() {
+ assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+ assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+ assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
- // Rotating these should make no difference
- //
- // We test using 124 bits because to ensure that overlong bit shifts do
- // not cause undefined behaviour. See #10183.
- assert_eq!(_0.rotate_left(124), _0);
- assert_eq!(_1.rotate_left(124), _1);
- assert_eq!(_0.rotate_right(124), _0);
- assert_eq!(_1.rotate_right(124), _1);
+ // Rotating these should make no difference
+ //
+ // We test using 124 bits because to ensure that overlong bit shifts do
+ // not cause undefined behaviour. See #10183.
+ assert_eq!(_0.rotate_left(124), _0);
+ assert_eq!(_1.rotate_left(124), _1);
+ assert_eq!(_0.rotate_right(124), _0);
+ assert_eq!(_1.rotate_right(124), _1);
- // Rotating by 0 should have no effect
- assert_eq!(A.rotate_left(0), A);
- assert_eq!(B.rotate_left(0), B);
- assert_eq!(C.rotate_left(0), C);
- // Rotating by a multiple of word size should also have no effect
- assert_eq!(A.rotate_left(64), A);
- assert_eq!(B.rotate_left(64), B);
- assert_eq!(C.rotate_left(64), C);
- }
+ // Rotating by 0 should have no effect
+ assert_eq!(A.rotate_left(0), A);
+ assert_eq!(B.rotate_left(0), B);
+ assert_eq!(C.rotate_left(0), C);
+ // Rotating by a multiple of word size should also have no effect
+ assert_eq!(A.rotate_left(64), A);
+ assert_eq!(B.rotate_left(64), B);
+ assert_eq!(C.rotate_left(64), C);
+ }
- #[test]
- fn test_swap_bytes() {
- assert_eq!(A.swap_bytes().swap_bytes(), A);
- assert_eq!(B.swap_bytes().swap_bytes(), B);
- assert_eq!(C.swap_bytes().swap_bytes(), C);
+ #[test]
+ fn test_swap_bytes() {
+ assert_eq!(A.swap_bytes().swap_bytes(), A);
+ assert_eq!(B.swap_bytes().swap_bytes(), B);
+ assert_eq!(C.swap_bytes().swap_bytes(), C);
- // Swapping these should make no difference
- assert_eq!(_0.swap_bytes(), _0);
- assert_eq!(_1.swap_bytes(), _1);
- }
+ // Swapping these should make no difference
+ assert_eq!(_0.swap_bytes(), _0);
+ assert_eq!(_1.swap_bytes(), _1);
+ }
- #[test]
- fn test_reverse_bits() {
- assert_eq!(A.reverse_bits().reverse_bits(), A);
- assert_eq!(B.reverse_bits().reverse_bits(), B);
- assert_eq!(C.reverse_bits().reverse_bits(), C);
+ #[test]
+ fn test_reverse_bits() {
+ assert_eq!(A.reverse_bits().reverse_bits(), A);
+ assert_eq!(B.reverse_bits().reverse_bits(), B);
+ assert_eq!(C.reverse_bits().reverse_bits(), C);
- // Swapping these should make no difference
- assert_eq!(_0.reverse_bits(), _0);
- assert_eq!(_1.reverse_bits(), _1);
- }
+ // Swapping these should make no difference
+ assert_eq!(_0.reverse_bits(), _0);
+ assert_eq!(_1.reverse_bits(), _1);
+ }
- #[test]
- fn test_le() {
- assert_eq!($T::from_le(A.to_le()), A);
- assert_eq!($T::from_le(B.to_le()), B);
- assert_eq!($T::from_le(C.to_le()), C);
- assert_eq!($T::from_le(_0), _0);
- assert_eq!($T::from_le(_1), _1);
- assert_eq!(_0.to_le(), _0);
- assert_eq!(_1.to_le(), _1);
- }
+ #[test]
+ fn test_le() {
+ assert_eq!($T::from_le(A.to_le()), A);
+ assert_eq!($T::from_le(B.to_le()), B);
+ assert_eq!($T::from_le(C.to_le()), C);
+ assert_eq!($T::from_le(_0), _0);
+ assert_eq!($T::from_le(_1), _1);
+ assert_eq!(_0.to_le(), _0);
+ assert_eq!(_1.to_le(), _1);
+ }
- #[test]
- fn test_be() {
- assert_eq!($T::from_be(A.to_be()), A);
- assert_eq!($T::from_be(B.to_be()), B);
- assert_eq!($T::from_be(C.to_be()), C);
- assert_eq!($T::from_be(_0), _0);
- assert_eq!($T::from_be(_1), _1);
- assert_eq!(_0.to_be(), _0);
- assert_eq!(_1.to_be(), _1);
- }
+ #[test]
+ fn test_be() {
+ assert_eq!($T::from_be(A.to_be()), A);
+ assert_eq!($T::from_be(B.to_be()), B);
+ assert_eq!($T::from_be(C.to_be()), C);
+ assert_eq!($T::from_be(_0), _0);
+ assert_eq!($T::from_be(_1), _1);
+ assert_eq!(_0.to_be(), _0);
+ assert_eq!(_1.to_be(), _1);
+ }
- #[test]
- fn test_unsigned_checked_div() {
- assert!((10 as $T).checked_div(2) == Some(5));
- assert!((5 as $T).checked_div(0) == None);
- }
+ #[test]
+ fn test_unsigned_checked_div() {
+ assert!((10 as $T).checked_div(2) == Some(5));
+ assert!((5 as $T).checked_div(0) == None);
+ }
- fn from_str<T: FromStr>(t: &str) -> Option<T> {
- FromStr::from_str(t).ok()
- }
+ fn from_str<T: FromStr>(t: &str) -> Option<T> {
+ FromStr::from_str(t).ok()
+ }
- #[test]
- pub fn test_from_str() {
- assert_eq!(from_str::<$T>("0"), Some(0 as $T));
- assert_eq!(from_str::<$T>("3"), Some(3 as $T));
- assert_eq!(from_str::<$T>("10"), Some(10 as $T));
- assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
- assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+ #[test]
+ pub fn test_from_str() {
+ assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+ assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+ assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+ assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
+ assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
- assert_eq!(from_str::<$T>(""), None);
- assert_eq!(from_str::<$T>(" "), None);
- assert_eq!(from_str::<$T>("x"), None);
- }
+ assert_eq!(from_str::<$T>(""), None);
+ assert_eq!(from_str::<$T>(" "), None);
+ assert_eq!(from_str::<$T>("x"), None);
+ }
- #[test]
- pub fn test_parse_bytes() {
- assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
- assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
- assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
- assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
- assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
- assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+ #[test]
+ pub fn test_parse_bytes() {
+ assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+ assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+ assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+ assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
+ assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
+ assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
- assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
- assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
- }
+ assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
+ assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
+ }
+ }
+ };
}
-)}
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 48755ae..43eb498 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -1,4 +1,4 @@
-use core::ops::{Bound, Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
+use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo};
// Test the Range structs without the syntactic sugar.
@@ -59,28 +59,27 @@
assert_eq!(r.next(), None);
}
-
#[test]
fn test_range_is_empty() {
use core::f32::*;
- assert!(!(0.0 .. 10.0).is_empty());
- assert!( (-0.0 .. 0.0).is_empty());
- assert!( (10.0 .. 0.0).is_empty());
+ assert!(!(0.0..10.0).is_empty());
+ assert!((-0.0..0.0).is_empty());
+ assert!((10.0..0.0).is_empty());
- assert!(!(NEG_INFINITY .. INFINITY).is_empty());
- assert!( (EPSILON .. NAN).is_empty());
- assert!( (NAN .. EPSILON).is_empty());
- assert!( (NAN .. NAN).is_empty());
+ assert!(!(NEG_INFINITY..INFINITY).is_empty());
+ assert!((EPSILON..NAN).is_empty());
+ assert!((NAN..EPSILON).is_empty());
+ assert!((NAN..NAN).is_empty());
- assert!(!(0.0 ..= 10.0).is_empty());
- assert!(!(-0.0 ..= 0.0).is_empty());
- assert!( (10.0 ..= 0.0).is_empty());
+ assert!(!(0.0..=10.0).is_empty());
+ assert!(!(-0.0..=0.0).is_empty());
+ assert!((10.0..=0.0).is_empty());
- assert!(!(NEG_INFINITY ..= INFINITY).is_empty());
- assert!( (EPSILON ..= NAN).is_empty());
- assert!( (NAN ..= EPSILON).is_empty());
- assert!( (NAN ..= NAN).is_empty());
+ assert!(!(NEG_INFINITY..=INFINITY).is_empty());
+ assert!((EPSILON..=NAN).is_empty());
+ assert!((NAN..=EPSILON).is_empty());
+ assert!((NAN..=NAN).is_empty());
}
#[test]
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index ff43fc4..fa30816 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -1,8 +1,8 @@
-use core::option::*;
-use core::mem;
-use core::clone::Clone;
use core::array::FixedSizeArray;
+use core::clone::Clone;
+use core::mem;
use core::ops::DerefMut;
+use core::option::*;
#[test]
fn test_get_ptr() {
@@ -28,15 +28,15 @@
#[test]
fn test_get_resource() {
- use std::rc::Rc;
use core::cell::RefCell;
+ use std::rc::Rc;
struct R {
- i: Rc<RefCell<isize>>,
+ i: Rc<RefCell<isize>>,
}
- impl Drop for R {
- fn drop(&mut self) {
+ impl Drop for R {
+ fn drop(&mut self) {
let ii = &*self.i;
let i = *ii.borrow();
*ii.borrow_mut() = i + 1;
@@ -44,9 +44,7 @@
}
fn r(i: Rc<RefCell<isize>>) -> R {
- R {
- i,
- }
+ R { i }
}
let i = Rc::new(RefCell::new(0));
@@ -70,7 +68,8 @@
assert!(y.is_none());
}
-#[test] #[should_panic]
+#[test]
+#[should_panic]
fn test_option_too_much_dance() {
struct A;
let mut y = Some(A);
@@ -210,7 +209,7 @@
fn test_ord() {
let small = Some(1.0f64);
let big = Some(5.0f64);
- let nan = Some(0.0f64/0.0);
+ let nan = Some(0.0f64 / 0.0);
assert!(!(nan < big));
assert!(!(nan > big));
assert!(small < big);
@@ -226,9 +225,7 @@
let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
assert!(v == Some(vec![0, 1, 2]));
- let v: Option<Vec<isize>> = (0..3).map(|x| {
- if x > 1 { None } else { Some(x) }
- }).collect();
+ let v: Option<Vec<isize>> = (0..3).map(|x| if x > 1 { None } else { Some(x) }).collect();
assert!(v == None);
// test that it does not take more elements than it needs
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 1a6be3a..eea736b 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -1,14 +1,14 @@
-use core::ptr::*;
use core::cell::RefCell;
+use core::ptr::*;
#[test]
fn test() {
unsafe {
struct Pair {
fst: isize,
- snd: isize
+ snd: isize,
};
- let mut p = Pair {fst: 10, snd: 20};
+ let mut p = Pair { fst: 10, snd: 20 };
let pptr: *mut Pair = &mut p;
let iptr: *mut isize = pptr as *mut isize;
assert_eq!(*iptr, 10);
@@ -16,7 +16,7 @@
assert_eq!(*iptr, 30);
assert_eq!(p.fst, 30);
- *pptr = Pair {fst: 50, snd: 60};
+ *pptr = Pair { fst: 50, snd: 60 };
assert_eq!(*iptr, 50);
assert_eq!(p.fst, 50);
assert_eq!(p.snd, 60);
@@ -25,17 +25,11 @@
let mut v1 = vec![0u16, 0u16, 0u16];
copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
- assert!((v1[0] == 0u16 &&
- v1[1] == 32001u16 &&
- v1[2] == 0u16));
+ assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
- assert!((v1[0] == 32002u16 &&
- v1[1] == 32001u16 &&
- v1[2] == 0u16));
+ assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
- assert!((v1[0] == 32002u16 &&
- v1[1] == 32001u16 &&
- v1[2] == 32000u16));
+ assert!((v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16));
}
}
@@ -208,7 +202,7 @@
#[test]
fn test_ptr_subtraction() {
unsafe {
- let xs = vec![0,1,2,3,4,5,6,7,8,9];
+ let xs = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let mut idx = 9;
let ptr = xs.as_ptr();
@@ -229,7 +223,7 @@
m_ptr = m_ptr.offset(-1);
}
- assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
+ assert_eq!(xs_mut, [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]);
}
}
@@ -237,7 +231,9 @@
fn test_set_memory() {
let mut xs = [0u8; 20];
let ptr = xs.as_mut_ptr();
- unsafe { write_bytes(ptr, 5u8, xs.len()); }
+ unsafe {
+ write_bytes(ptr, 5u8, xs.len());
+ }
assert!(xs == [5u8; 20]);
}
@@ -257,10 +253,10 @@
#[no_mangle]
pub fn test_variadic_fnptr() {
use core::hash::{Hash, SipHasher};
- extern {
+ extern "C" {
fn test_variadic_fnptr(_: u64, ...) -> f64;
}
- let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
+ let p: unsafe extern "C" fn(u64, ...) -> f64 = test_variadic_fnptr;
let q = p.clone();
assert_eq!(p, q);
assert!(!(p < q));
@@ -285,13 +281,15 @@
{
let c = Dropper(0);
let mut t = Dropper(1);
- unsafe { write_unaligned(&mut t, c); }
+ unsafe {
+ write_unaligned(&mut t, c);
+ }
}
DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
}
#[test]
-#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
+#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn align_offset_zst() {
// For pointers of stride = 0, the pointer is already aligned or it cannot be aligned at
// all, because no amount of elements will align the pointer.
@@ -306,24 +304,29 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
+#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn align_offset_stride1() {
// For pointers of stride = 1, the pointer can always be aligned. The offset is equal to
// number of bytes.
let mut align = 1;
while align < 1024 {
- for ptr in 1..2*align {
+ for ptr in 1..2 * align {
let expected = ptr % align;
let offset = if expected == 0 { 0 } else { align - expected };
- assert_eq!((ptr as *const u8).align_offset(align), offset,
- "ptr = {}, align = {}, size = 1", ptr, align);
+ assert_eq!(
+ (ptr as *const u8).align_offset(align),
+ offset,
+ "ptr = {}, align = {}, size = 1",
+ ptr,
+ align
+ );
}
align = (align + 1).next_power_of_two();
}
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn align_offset_weird_strides() {
#[repr(packed)]
struct A3(u16, u8);
@@ -353,8 +356,14 @@
}
let got = ptr.align_offset(align);
if got != expected {
- eprintln!("aligning {:p} (with stride of {}) to {}, expected {}, got {}", ptr,
- ::std::mem::size_of::<T>(), align, expected, got);
+ eprintln!(
+ "aligning {:p} (with stride of {}) to {}, expected {}, got {}",
+ ptr,
+ ::std::mem::size_of::<T>(),
+ align,
+ expected,
+ got
+ );
return true;
}
return false;
@@ -365,7 +374,7 @@
let mut align = 1;
let mut x = false;
while align < 1024 {
- for ptr in 1usize..4*align {
+ for ptr in 1usize..4 * align {
unsafe {
x |= test_weird_stride::<A3>(ptr as *const A3, align);
x |= test_weird_stride::<A4>(ptr as *const A4, align);
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 6609bc3..cc274b4 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -1,4 +1,4 @@
-use core::result::Result::{Ok, Err};
+use core::result::Result::{Err, Ok};
#[test]
fn test_position() {
@@ -50,8 +50,14 @@
assert_eq!(b.binary_search(&0), Err(0));
assert_eq!(b.binary_search(&1), Ok(0));
assert_eq!(b.binary_search(&2), Err(1));
- assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
- assert!(match b.binary_search(&3) { Ok(1..=3) => true, _ => false });
+ assert!(match b.binary_search(&3) {
+ Ok(1..=3) => true,
+ _ => false,
+ });
+ assert!(match b.binary_search(&3) {
+ Ok(1..=3) => true,
+ _ => false,
+ });
assert_eq!(b.binary_search(&4), Err(4));
assert_eq!(b.binary_search(&5), Err(4));
assert_eq!(b.binary_search(&6), Err(4));
@@ -187,7 +193,8 @@
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
- let res = v1.chunks(2)
+ let res = v1
+ .chunks(2)
.zip(v2.chunks(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@@ -339,7 +346,8 @@
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
- let res = v1.chunks_exact(2)
+ let res = v1
+ .chunks_exact(2)
.zip(v2.chunks_exact(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@@ -482,7 +490,8 @@
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
- let res = v1.rchunks(2)
+ let res = v1
+ .rchunks(2)
.zip(v2.rchunks(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@@ -619,7 +628,8 @@
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
- let res = v1.rchunks_exact(2)
+ let res = v1
+ .rchunks_exact(2)
.zip(v2.rchunks_exact(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@@ -756,7 +766,8 @@
let v1: &[i32] = &[0, 1, 2, 3, 4];
let v2: &[i32] = &[6, 7, 8, 9, 10];
- let res = v1.windows(2)
+ let res = v1
+ .windows(2)
.zip(v2.windows(2))
.map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>())
.collect::<Vec<_>>();
@@ -769,11 +780,11 @@
fn test_iter_ref_consistency() {
use std::fmt::Debug;
- fn test<T : Copy + Debug + PartialEq>(x : T) {
- let v : &[T] = &[x, x, x];
- let v_ptrs : [*const T; 3] = match v {
+ fn test<T: Copy + Debug + PartialEq>(x: T) {
+ let v: &[T] = &[x, x, x];
+ let v_ptrs: [*const T; 3] = match v {
[ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
- _ => unreachable!()
+ _ => unreachable!(),
};
let len = v.len();
@@ -817,19 +828,20 @@
assert_eq!(it.size_hint(), (remaining, Some(remaining)));
let prev = it.next_back().unwrap();
- assert_eq!(prev as *const _, v_ptrs[remaining-1]);
+ assert_eq!(prev as *const _, v_ptrs[remaining - 1]);
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
}
}
- fn test_mut<T : Copy + Debug + PartialEq>(x : T) {
- let v : &mut [T] = &mut [x, x, x];
- let v_ptrs : [*mut T; 3] = match v {
- [ref v1, ref v2, ref v3] =>
- [v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _],
- _ => unreachable!()
+ fn test_mut<T: Copy + Debug + PartialEq>(x: T) {
+ let v: &mut [T] = &mut [x, x, x];
+ let v_ptrs: [*mut T; 3] = match v {
+ [ref v1, ref v2, ref v3] => {
+ [v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _]
+ }
+ _ => unreachable!(),
};
let len = v.len();
@@ -873,7 +885,7 @@
assert_eq!(it.size_hint(), (remaining, Some(remaining)));
let prev = it.next_back().unwrap();
- assert_eq!(prev as *mut _, v_ptrs[remaining-1]);
+ assert_eq!(prev as *mut _, v_ptrs[remaining - 1]);
}
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
@@ -897,8 +909,7 @@
// This checks all six indexing methods, given an input range that
// should succeed. (it is NOT suitable for testing invalid inputs)
macro_rules! assert_range_eq {
- ($arr:expr, $range:expr, $expected:expr)
- => {
+ ($arr:expr, $range:expr, $expected:expr) => {
let mut arr = $arr;
let mut expected = $expected;
{
@@ -909,7 +920,8 @@
assert_eq!(s.get($range), Some(expected), "(in assertion for: get)");
unsafe {
assert_eq!(
- s.get_unchecked($range), expected,
+ s.get_unchecked($range),
+ expected,
"(in assertion for: get_unchecked)",
);
}
@@ -918,22 +930,21 @@
let s: &mut [_] = &mut arr;
let expected: &mut [_] = &mut expected;
+ assert_eq!(&mut s[$range], expected, "(in assertion for: index_mut)",);
assert_eq!(
- &mut s[$range], expected,
- "(in assertion for: index_mut)",
- );
- assert_eq!(
- s.get_mut($range), Some(&mut expected[..]),
+ s.get_mut($range),
+ Some(&mut expected[..]),
"(in assertion for: get_mut)",
);
unsafe {
assert_eq!(
- s.get_unchecked_mut($range), expected,
+ s.get_unchecked_mut($range),
+ expected,
"(in assertion for: get_unchecked_mut)",
);
}
}
- }
+ };
}
// Make sure the macro can actually detect bugs,
@@ -1126,8 +1137,8 @@
#[test]
fn test_iter_folds() {
let a = [1, 2, 3, 4, 5]; // len>4 so the unroll is used
- assert_eq!(a.iter().fold(0, |acc, &x| 2*acc + x), 57);
- assert_eq!(a.iter().rfold(0, |acc, &x| 2*acc + x), 129);
+ assert_eq!(a.iter().fold(0, |acc, &x| 2 * acc + x), 57);
+ assert_eq!(a.iter().rfold(0, |acc, &x| 2 * acc + x), 129);
let fold = |acc: i32, &x| acc.checked_mul(2)?.checked_add(x);
assert_eq!(a.iter().try_fold(0, &fold), Some(57));
assert_eq!(a.iter().try_rfold(0, &fold), Some(129));
@@ -1172,7 +1183,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn brute_force_rotate_test_0() {
// In case of edge cases involving multiple algorithms
let n = 300;
@@ -1214,7 +1225,7 @@
fn sort_unstable() {
use core::cmp::Ordering::{Equal, Greater, Less};
use core::slice::heapsort;
- use rand::{SeedableRng, Rng, rngs::StdRng, seq::SliceRandom};
+ use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};
#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
@@ -1291,12 +1302,12 @@
#[test]
#[cfg(not(target_arch = "wasm32"))]
-#[cfg(not(miri))] // Miri is too slow
+#[cfg_attr(miri, ignore)] // Miri is too slow
fn partition_at_index() {
use core::cmp::Ordering::{Equal, Greater, Less};
use rand::rngs::StdRng;
use rand::seq::SliceRandom;
- use rand::{SeedableRng, Rng};
+ use rand::{Rng, SeedableRng};
let mut rng = StdRng::from_entropy();
@@ -1494,7 +1505,7 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
+#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn test_align_to_simple() {
let bytes = [1u8, 2, 3, 4, 5, 6, 7];
let (prefix, aligned, suffix) = unsafe { bytes.align_to::<u16>() };
@@ -1504,9 +1515,15 @@
let expect2 = [1 | 2 << 8, 3 | 4 << 8, 5 | 6 << 8];
let expect3 = [2 << 8 | 3, 4 << 8 | 5, 6 << 8 | 7];
let expect4 = [2 | 3 << 8, 4 | 5 << 8, 6 | 7 << 8];
- assert!(aligned == expect1 || aligned == expect2 || aligned == expect3 || aligned == expect4,
- "aligned={:?} expected={:?} || {:?} || {:?} || {:?}",
- aligned, expect1, expect2, expect3, expect4);
+ assert!(
+ aligned == expect1 || aligned == expect2 || aligned == expect3 || aligned == expect4,
+ "aligned={:?} expected={:?} || {:?} || {:?} || {:?}",
+ aligned,
+ expect1,
+ expect2,
+ expect3,
+ expect4
+ );
}
#[test]
@@ -1518,12 +1535,22 @@
}
#[test]
-#[cfg(not(miri))] // Miri does not compute a maximal `mid` for `align_offset`
+#[cfg_attr(miri, ignore)] // Miri does not compute a maximal `mid` for `align_offset`
fn test_align_to_non_trivial() {
- #[repr(align(8))] struct U64(u64, u64);
- #[repr(align(8))] struct U64U64U32(u64, u64, u32);
- let data = [U64(1, 2), U64(3, 4), U64(5, 6), U64(7, 8), U64(9, 10), U64(11, 12), U64(13, 14),
- U64(15, 16)];
+ #[repr(align(8))]
+ struct U64(u64, u64);
+ #[repr(align(8))]
+ struct U64U64U32(u64, u64, u32);
+ let data = [
+ U64(1, 2),
+ U64(3, 4),
+ U64(5, 6),
+ U64(7, 8),
+ U64(9, 10),
+ U64(11, 12),
+ U64(13, 14),
+ U64(15, 16),
+ ];
let (prefix, aligned, suffix) = unsafe { data.align_to::<U64U64U32>() };
assert_eq!(aligned.len(), 4);
assert_eq!(prefix.len() + suffix.len(), 2);
@@ -1538,7 +1565,7 @@
let bytes = [1, 2, 3, 4, 5, 6, 7];
type Chunk = u32;
for offset in 0..4 {
- let (_, mid, _) = unsafe { bytes[offset..offset+1].align_to::<Chunk>() };
+ let (_, mid, _) = unsafe { bytes[offset..offset + 1].align_to::<Chunk>() };
assert_eq!(mid.as_ptr() as usize % mem::align_of::<Chunk>(), 0);
}
}
diff --git a/src/libcore/tests/str_lossy.rs b/src/libcore/tests/str_lossy.rs
index f9fd333..d4b47a4 100644
--- a/src/libcore/tests/str_lossy.rs
+++ b/src/libcore/tests/str_lossy.rs
@@ -3,65 +3,65 @@
#[test]
fn chunks() {
let mut iter = Utf8Lossy::from_bytes(b"hello").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "hello", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes("ศไทย中华Việt Nam".as_bytes()).chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "ศไทย中华Việt Nam", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "ศไทย中华Việt Nam", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"Hello\xC2 There\xFF Goodbye").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC2", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xFF", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC2" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xFF" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC0", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xE6\x83", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "Hello", broken: b"\xC0" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: " There", broken: b"\xE6\x83" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: " Goodbye", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"\xF5foo\xF5\x80bar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF5", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF5", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF5" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF5" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"\xF1foo\xF1\x80bar\xF1\x80\x80baz").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF1", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF1\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF1\x80\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF1" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF1\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF1\x80\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"\xF4foo\xF4\x80bar\xF4\xBFbaz").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF4", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF4\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF4", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF4" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xF4\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"\xF4" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "baz", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
let mut iter = Utf8Lossy::from_bytes(b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF0", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo\u{10000}bar", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xF0" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "foo\u{10000}bar", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
// surrogates
let mut iter = Utf8Lossy::from_bytes(b"\xED\xA0\x80foo\xED\xBF\xBFbar").chunks();
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xED", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xA0", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xED", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF", }), iter.next());
- assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"", }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xED" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xA0" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\x80" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "foo", broken: b"\xED" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "", broken: b"\xBF" }), iter.next());
+ assert_eq!(Some(Utf8LossyChunk { valid: "bar", broken: b"" }), iter.next());
assert_eq!(None, iter.next());
}
@@ -69,13 +69,17 @@
fn display() {
assert_eq!(
"Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye",
- &Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string());
+ &Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye").to_string()
+ );
}
#[test]
fn debug() {
assert_eq!(
"\"Hello\\xc0\\x80 There\\xe6\\x83 Goodbye\\u{10d4ea}\"",
- &format!("{:?}", Utf8Lossy::from_bytes(
- b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa")));
+ &format!(
+ "{:?}",
+ Utf8Lossy::from_bytes(b"Hello\xC0\x80 There\xE6\x83 Goodbye\xf4\x8d\x93\xaa")
+ )
+ );
}
diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs
index fac70c4..273f125 100644
--- a/src/libcore/tests/time.rs
+++ b/src/libcore/tests/time.rs
@@ -3,10 +3,11 @@
#[test]
fn creation() {
assert_ne!(Duration::from_secs(1), Duration::from_secs(0));
- assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
- Duration::from_secs(3));
- assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
- Duration::new(4, 10 * 1_000_000));
+ assert_eq!(Duration::from_secs(1) + Duration::from_secs(2), Duration::from_secs(3));
+ assert_eq!(
+ Duration::from_millis(10) + Duration::from_secs(4),
+ Duration::new(4, 10 * 1_000_000)
+ );
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
}
@@ -68,29 +69,25 @@
#[test]
fn add() {
- assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
- Duration::new(0, 1));
- assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
- Duration::new(1, 1));
+ assert_eq!(Duration::new(0, 0) + Duration::new(0, 1), Duration::new(0, 1));
+ assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001), Duration::new(1, 1));
}
#[test]
fn checked_add() {
- assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
- Some(Duration::new(0, 1)));
- assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
- Some(Duration::new(1, 1)));
+ assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
+ assert_eq!(
+ Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
+ Some(Duration::new(1, 1))
+ );
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::core::u64::MAX, 0)), None);
}
#[test]
fn sub() {
- assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
- Duration::new(0, 1));
- assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
- Duration::new(0, 1));
- assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
- Duration::new(0, 999_999_999));
+ assert_eq!(Duration::new(0, 1) - Duration::new(0, 0), Duration::new(0, 1));
+ assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000), Duration::new(0, 1));
+ assert_eq!(Duration::new(1, 0) - Duration::new(0, 1), Duration::new(0, 999_999_999));
}
#[test]
@@ -99,8 +96,7 @@
let one_nano = Duration::new(0, 1);
let one_sec = Duration::new(1, 0);
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
- assert_eq!(one_sec.checked_sub(one_nano),
- Some(Duration::new(0, 999_999_999)));
+ assert_eq!(one_sec.checked_sub(one_nano), Some(Duration::new(0, 999_999_999)));
assert_eq!(zero.checked_sub(one_nano), None);
assert_eq!(zero.checked_sub(one_sec), None);
}
@@ -122,8 +118,7 @@
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
- assert_eq!(Duration::new(0, 500_000_001) * 4000,
- Duration::new(2000, 4000));
+ assert_eq!(Duration::new(0, 500_000_001) * 4000, Duration::new(2000, 4000));
}
#[test]
@@ -131,8 +126,7 @@
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
- assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
- Some(Duration::new(2000, 4000)));
+ assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000), Some(Duration::new(2000, 4000)));
assert_eq!(Duration::new(::core::u64::MAX - 1, 0).checked_mul(2), None);
}
@@ -140,8 +134,7 @@
fn div() {
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
- assert_eq!(Duration::new(99, 999_999_000) / 100,
- Duration::new(0, 999_999_990));
+ assert_eq!(Duration::new(99, 999_999_000) / 100, Duration::new(0, 999_999_990));
}
#[test]
@@ -162,7 +155,7 @@
Duration::new(5, 0),
];
let sum = durations.iter().sum::<Duration>();
- assert_eq!(sum, Duration::new(1+2+5+4, 1_000_000_000 - 5));
+ assert_eq!(sum, Duration::new(1 + 2 + 5 + 4, 1_000_000_000 - 5));
}
#[test]
@@ -286,9 +279,9 @@
#[test]
fn debug_formatting_precision_high() {
- assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs");
+ assert_eq!(format!("{:.5?}", Duration::new(0, 23_678)), "23.67800µs");
- assert_eq!(format!("{:.9?}", Duration::new(1, 000_000_000)), "1.000000000s");
+ assert_eq!(format!("{:.9?}", Duration::new(1, 000_000_000)), "1.000000000s");
assert_eq!(format!("{:.10?}", Duration::new(4, 001_000_000)), "4.0010000000s");
assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s");
}
diff --git a/src/libcore/tests/tuple.rs b/src/libcore/tests/tuple.rs
index c7ed161..3a29146 100644
--- a/src/libcore/tests/tuple.rs
+++ b/src/libcore/tests/tuple.rs
@@ -1,4 +1,4 @@
-use std::cmp::Ordering::{Equal, Less, Greater};
+use std::cmp::Ordering::{Equal, Greater, Less};
use std::f64::NAN;
#[test]
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 791d72d..a4536bb 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -20,7 +20,7 @@
log = { version = "0.4", features = ["release_max_level_info", "std"] }
rustc-rayon = "0.3.0"
rustc-rayon-core = "0.3.0"
-polonius-engine = "0.10.0"
+polonius-engine = "0.11.0"
rustc_apfloat = { path = "../librustc_apfloat" }
rustc_feature = { path = "../librustc_feature" }
rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index a7f5a22..a89bc28 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -278,15 +278,15 @@
/// Returns an iterator over all function arguments.
#[inline]
- pub fn args_iter(&self) -> impl Iterator<Item = Local> {
+ pub fn args_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
- (1..=arg_count).map(Local::new)
+ (1..arg_count + 1).map(Local::new)
}
/// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
/// locals that are neither arguments nor the return place).
#[inline]
- pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> {
+ pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> + ExactSizeIterator {
let arg_count = self.arg_count;
let local_count = self.local_decls.len();
(arg_count + 1..local_count).map(Local::new)
@@ -2380,11 +2380,15 @@
UserTypeProjections { contents: projs.collect() }
}
- pub fn projections_and_spans(&self) -> impl Iterator<Item = &(UserTypeProjection, Span)> {
+ pub fn projections_and_spans(&self)
+ -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator
+ {
self.contents.iter()
}
- pub fn projections(&self) -> impl Iterator<Item = &UserTypeProjection> {
+ pub fn projections(&self)
+ -> impl Iterator<Item = &UserTypeProjection> + ExactSizeIterator
+ {
self.contents.iter().map(|&(ref user_type, _span)| user_type)
}
diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs
index a3926c1..bbf6999 100644
--- a/src/librustc_data_structures/transitive_relation.rs
+++ b/src/librustc_data_structures/transitive_relation.rs
@@ -373,6 +373,14 @@
}
matrix
}
+
+ /// Lists all the base edges in the graph: the initial _non-transitive_ set of element
+ /// relations, which will be later used as the basis for the transitive closure computation.
+ pub fn base_edges(&self) -> impl Iterator<Item=(&T, &T)> {
+ self.edges
+ .iter()
+ .map(move |edge| (&self.elements[edge.source.0], &self.elements[edge.target.0]))
+ }
}
/// Pare down is used as a step in the LUB computation. It edits the
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 4afbb4d..7e3bd98 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -16,7 +16,7 @@
itertools = "0.8"
log = "0.4"
log_settings = "0.1.1"
-polonius-engine = "0.10.0"
+polonius-engine = "0.11.0"
rustc = { path = "../librustc" }
rustc_target = { path = "../librustc_target" }
rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index d14957b..252b31e 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -240,15 +240,17 @@
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id);
let param = generics.type_param(¶m_ty, tcx);
- let generics = tcx.hir().get_generics(self.mir_def_id).unwrap();
- suggest_constraining_type_param(
- generics,
- &mut err,
- ¶m.name.as_str(),
- "Copy",
- tcx.sess.source_map(),
- span,
- );
+ if let Some(generics) =
+ tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id)) {
+ suggest_constraining_type_param(
+ generics,
+ &mut err,
+ ¶m.name.as_str(),
+ "Copy",
+ tcx.sess.source_map(),
+ span,
+ );
+ }
}
let span = if let Some(local) = place.as_local() {
let decl = &self.body.local_decls[local];
diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index ce5d2a1..57c544f 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -3,16 +3,15 @@
//! FIXME: this might be better as a "generic" fixed-point combinator,
//! but is not as ugly as it is right now.
-use rustc::mir::{BasicBlock, Local, Location};
-use rustc::ty::RegionVid;
+use rustc::mir::{BasicBlock, Location};
use rustc_index::bit_set::BitIter;
use crate::borrow_check::location::LocationIndex;
-use polonius_engine::Output;
+use crate::borrow_check::nll::PoloniusOutput;
use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
+use crate::dataflow::move_paths::HasMoveData;
use crate::dataflow::Borrows;
use crate::dataflow::EverInitializedPlaces;
use crate::dataflow::MaybeUninitializedPlaces;
@@ -21,8 +20,6 @@
use std::fmt;
use std::rc::Rc;
-crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
-
crate struct Flows<'b, 'tcx> {
borrows: FlowAtLocation<'tcx, Borrows<'b, 'tcx>>,
pub uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'tcx>>,
diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 13e5769..a16c36d 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -1,6 +1,6 @@
use crate::borrow_check::location::{LocationIndex, LocationTable};
use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
-use polonius_engine::AllFacts as PoloniusAllFacts;
+use polonius_engine::AllFacts as PoloniusFacts;
use polonius_engine::Atom;
use rustc::mir::Local;
use rustc::ty::{RegionVid, TyCtxt};
@@ -11,7 +11,18 @@
use std::io::Write;
use std::path::Path;
-crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
+#[derive(Copy, Clone, Debug)]
+crate struct RustcFacts;
+
+impl polonius_engine::FactTypes for RustcFacts {
+ type Origin = RegionVid;
+ type Loan = BorrowIndex;
+ type Point = LocationIndex;
+ type Variable = Local;
+ type Path = MovePathIndex;
+}
+
+crate type AllFacts = PoloniusFacts<RustcFacts>;
crate trait AllFactsExt {
/// Returns `true` if there is a need to gather `AllFacts` given the
@@ -55,6 +66,7 @@
wr.write_facts_to_path(self.[
borrow_region,
universal_region,
+ placeholder,
cfg_edge,
killed,
outlives,
@@ -69,6 +81,7 @@
initialized_at,
moved_out_at,
path_accessed_at,
+ known_subset,
])
}
Ok(())
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 49a03ce..bbcb823 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -1,10 +1,9 @@
use crate::borrow_check::borrow_set::BorrowSet;
-use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::borrow_check::location::LocationTable;
use crate::borrow_check::nll::facts::AllFactsExt;
use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
use crate::borrow_check::nll::region_infer::values::RegionValueElements;
-use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
+use crate::dataflow::move_paths::{InitLocation, MoveData, InitKind};
use crate::dataflow::FlowAtLocation;
use crate::dataflow::MaybeInitializedPlaces;
use crate::transform::MirSource;
@@ -43,10 +42,12 @@
crate mod type_check;
crate mod region_infer;
-use self::facts::AllFacts;
+use self::facts::{AllFacts, RustcFacts};
use self::region_infer::RegionInferenceContext;
use self::universal_regions::UniversalRegions;
+crate type PoloniusOutput = Output<RustcFacts>;
+
/// Rewrites the regions in the MIR to use NLL variables, also
/// scraping out the set of universal regions (e.g., region parameters)
/// declared on the function. That set will need to be given to
@@ -170,7 +171,7 @@
errors_buffer: &mut Vec<Diagnostic>,
) -> (
RegionInferenceContext<'tcx>,
- Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>>>,
+ Option<Rc<PoloniusOutput>>,
Option<ClosureRegionRequirements<'tcx>>,
) {
let mut all_facts = AllFacts::enabled(infcx.tcx).then_some(AllFacts::default());
@@ -204,6 +205,39 @@
.universal_region
.extend(universal_regions.universal_regions());
populate_polonius_move_facts(all_facts, move_data, location_table, &body);
+
+ // Emit universal regions facts, and their relations, for Polonius.
+ //
+ // 1: universal regions are modeled in Polonius as a pair:
+ // - the universal region vid itself.
+ // - a "placeholder loan" associated to this universal region. Since they don't exist in
+ // the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
+ // added to the existing number of loans, as if they succeeded them in the set.
+ //
+ let borrow_count = borrow_set.borrows.len();
+ debug!(
+ "compute_regions: polonius placeholders, num_universals={}, borrow_count={}",
+ universal_regions.len(),
+ borrow_count
+ );
+
+ for universal_region in universal_regions.universal_regions() {
+ let universal_region_idx = universal_region.index();
+ let placeholder_loan_idx = borrow_count + universal_region_idx;
+ all_facts.placeholder.push((universal_region, placeholder_loan_idx.into()));
+ }
+
+ // 2: the universal region relations `outlives` constraints are emitted as
+ // `known_subset` facts.
+ for (fr1, fr2) in universal_region_relations.known_outlives() {
+ if fr1 != fr2 {
+ debug!(
+ "compute_regions: emitting polonius `known_subset` fr1={:?}, fr2={:?}",
+ fr1, fr2
+ );
+ all_facts.known_subset.push((*fr1, *fr2));
+ }
+ }
}
// Create the region inference context, taking ownership of the
@@ -265,7 +299,7 @@
if infcx.tcx.sess.opts.debugging_opts.polonius {
let algorithm = env::var("POLONIUS_ALGORITHM")
- .unwrap_or_else(|_| String::from("Hybrid"));
+ .unwrap_or_else(|_| String::from("Naive"));
let algorithm = Algorithm::from_str(&algorithm).unwrap();
debug!("compute_regions: using polonius algorithm {:?}", algorithm);
Some(Rc::new(Output::compute(
@@ -279,8 +313,15 @@
});
// Solve the region constraints.
- let closure_region_requirements =
- regioncx.solve(infcx, &body, local_names, upvars, def_id, errors_buffer);
+ let closure_region_requirements = regioncx.solve(
+ infcx,
+ &body,
+ local_names,
+ upvars,
+ def_id,
+ errors_buffer,
+ polonius_output.clone(),
+ );
// Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging.
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 0b3cb29..d62537b 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -44,7 +44,7 @@
use self::values::{LivenessValues, RegionValueElements, RegionValues};
use super::universal_regions::UniversalRegions;
-use super::ToRegionVid;
+use super::{PoloniusOutput, ToRegionVid};
mod dump_mir;
mod graphviz;
@@ -484,6 +484,7 @@
upvars: &[Upvar],
mir_def_id: DefId,
errors_buffer: &mut Vec<Diagnostic>,
+ polonius_output: Option<Rc<PoloniusOutput>>,
) -> Option<ClosureRegionRequirements<'tcx>> {
self.propagate_constraints(body);
@@ -509,16 +510,33 @@
// multiple problems.
let mut region_naming = RegionErrorNamingCtx::new();
- self.check_universal_regions(
- infcx,
- body,
- local_names,
- upvars,
- mir_def_id,
- outlives_requirements.as_mut(),
- errors_buffer,
- &mut region_naming,
- );
+ // In Polonius mode, the errors about missing universal region relations are in the output
+ // and need to be emitted or propagated. Otherwise, we need to check whether the
+ // constraints were too strong, and if so, emit or propagate those errors.
+ if infcx.tcx.sess.opts.debugging_opts.polonius {
+ self.check_polonius_subset_errors(
+ infcx,
+ body,
+ local_names,
+ upvars,
+ mir_def_id,
+ outlives_requirements.as_mut(),
+ errors_buffer,
+ &mut region_naming,
+ polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
+ );
+ } else {
+ self.check_universal_regions(
+ infcx,
+ body,
+ local_names,
+ upvars,
+ mir_def_id,
+ outlives_requirements.as_mut(),
+ errors_buffer,
+ &mut region_naming,
+ );
+ }
self.check_member_constraints(infcx, mir_def_id, errors_buffer);
@@ -1372,6 +1390,114 @@
outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
}
+ /// Checks if Polonius has found any unexpected free region relations.
+ ///
+ /// In Polonius terms, a "subset error" (or "illegal subset relation error") is the equivalent
+ /// of NLL's "checking if any region constraints were too strong": a placeholder origin `'a`
+ /// was unexpectedly found to be a subset of another placeholder origin `'b`, and means in NLL
+ /// terms that the "longer free region" `'a` outlived the "shorter free region" `'b`.
+ ///
+ /// More details can be found in this blog post by Niko:
+ /// http://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/
+ ///
+ /// In the canonical example
+ ///
+ /// fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
+ ///
+ /// returning `x` requires `&'a u32 <: &'b u32` and hence we establish (transitively) a
+ /// constraint that `'a: 'b`. It is an error that we have no evidence that this
+ /// constraint holds.
+ ///
+ /// If `propagated_outlives_requirements` is `Some`, then we will
+ /// push unsatisfied obligations into there. Otherwise, we'll
+ /// report them as errors.
+ fn check_polonius_subset_errors(
+ &self,
+ infcx: &InferCtxt<'_, 'tcx>,
+ body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
+ upvars: &[Upvar],
+ mir_def_id: DefId,
+ mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
+ errors_buffer: &mut Vec<Diagnostic>,
+ region_naming: &mut RegionErrorNamingCtx,
+ polonius_output: Rc<PoloniusOutput>,
+ ) {
+ debug!(
+ "check_polonius_subset_errors: {} subset_errors",
+ polonius_output.subset_errors.len()
+ );
+
+ let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id, local_names);
+
+ // Similarly to `check_universal_regions`: a free region relation, which was not explicitly
+ // declared ("known") was found by Polonius, so emit an error, or propagate the
+ // requirements for our caller into the `propagated_outlives_requirements` vector.
+ //
+ // Polonius doesn't model regions ("origins") as CFG-subsets or durations, but the
+ // `longer_fr` and `shorter_fr` terminology will still be used here, for consistency with
+ // the rest of the NLL infrastructure. The "subset origin" is the "longer free region",
+ // and the "superset origin" is the outlived "shorter free region".
+ //
+ // Note: Polonius will produce a subset error at every point where the unexpected
+ // `longer_fr`'s "placeholder loan" is contained in the `shorter_fr`. This can be helpful
+ // for diagnostics in the future, e.g. to point more precisely at the key locations
+ // requiring this constraint to hold. However, the error and diagnostics code downstream
+ // expects that these errors are not duplicated (and that they are in a certain order).
+ // Otherwise, diagnostics messages such as the ones giving names like `'1` to elided or
+ // anonymous lifetimes for example, could give these names differently, while others like
+ // the outlives suggestions or the debug output from `#[rustc_regions]` would be
+ // duplicated. The polonius subset errors are deduplicated here, while keeping the
+ // CFG-location ordering.
+ let mut subset_errors: Vec<_> = polonius_output
+ .subset_errors
+ .iter()
+ .flat_map(|(_location, subset_errors)| subset_errors.iter())
+ .collect();
+ subset_errors.sort();
+ subset_errors.dedup();
+
+ for (longer_fr, shorter_fr) in subset_errors.into_iter() {
+ debug!("check_polonius_subset_errors: subset_error longer_fr={:?},\
+ shorter_fr={:?}", longer_fr, shorter_fr);
+
+ self.report_or_propagate_universal_region_error(
+ *longer_fr,
+ *shorter_fr,
+ infcx,
+ body,
+ local_names,
+ upvars,
+ mir_def_id,
+ &mut propagated_outlives_requirements,
+ &mut outlives_suggestion,
+ errors_buffer,
+ region_naming,
+ );
+ }
+
+ // Handle the placeholder errors as usual, until the chalk-rustc-polonius triumvirate has
+ // a more complete picture on how to separate this responsibility.
+ for (fr, fr_definition) in self.definitions.iter_enumerated() {
+ match fr_definition.origin {
+ NLLRegionVariableOrigin::FreeRegion => {
+ // handled by polonius above
+ }
+
+ NLLRegionVariableOrigin::Placeholder(placeholder) => {
+ self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
+ }
+
+ NLLRegionVariableOrigin::Existential { .. } => {
+ // nothing to check here
+ }
+ }
+ }
+
+ // Emit outlives suggestions
+ outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
+ }
+
/// Checks the final value for the free region `fr` to see if it
/// grew too large. In particular, examine what `end(X)` points
/// wound up in `fr`'s final value; for each `end(X)` where `X !=
@@ -1471,8 +1597,37 @@
return None;
}
+ self.report_or_propagate_universal_region_error(
+ longer_fr,
+ shorter_fr,
+ infcx,
+ body,
+ local_names,
+ upvars,
+ mir_def_id,
+ propagated_outlives_requirements,
+ outlives_suggestion,
+ errors_buffer,
+ region_naming,
+ )
+ }
+
+ fn report_or_propagate_universal_region_error(
+ &self,
+ longer_fr: RegionVid,
+ shorter_fr: RegionVid,
+ infcx: &InferCtxt<'_, 'tcx>,
+ body: &Body<'tcx>,
+ local_names: &IndexVec<Local, Option<Symbol>>,
+ upvars: &[Upvar],
+ mir_def_id: DefId,
+ propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
+ outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
+ errors_buffer: &mut Vec<Diagnostic>,
+ region_naming: &mut RegionErrorNamingCtx,
+ ) -> Option<ErrorReported> {
debug!(
- "check_universal_region_relation: fr={:?} does not outlive shorter_fr={:?}",
+ "report_or_propagate_universal_region_error: fr={:?} does not outlive shorter_fr={:?}",
longer_fr, shorter_fr,
);
@@ -1481,9 +1636,9 @@
// We'll call it `fr-` -- it's ever so slightly smaller than
// `longer_fr`.
- if let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr)
- {
- debug!("check_universal_region: fr_minus={:?}", fr_minus);
+ if let Some(fr_minus) =
+ self.universal_region_relations.non_local_lower_bound(longer_fr) {
+ debug!("report_or_propagate_universal_region_error: fr_minus={:?}", fr_minus);
let blame_span_category =
self.find_outlives_blame_span(body, longer_fr,
@@ -1492,9 +1647,13 @@
// Grow `shorter_fr` until we find some non-local regions. (We
// always will.) We'll call them `shorter_fr+` -- they're ever
// so slightly larger than `shorter_fr`.
- let shorter_fr_plus =
- self.universal_region_relations.non_local_upper_bounds(&shorter_fr);
- debug!("check_universal_region: shorter_fr_plus={:?}", shorter_fr_plus);
+ let shorter_fr_plus = self
+ .universal_region_relations
+ .non_local_upper_bounds(&shorter_fr);
+ debug!(
+ "report_or_propagate_universal_region_error: shorter_fr_plus={:?}",
+ shorter_fr_plus
+ );
for &&fr in &shorter_fr_plus {
// Push the constraint `fr-: shorter_fr+`
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
diff --git a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
index d18a8e8..8bb6838 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs
@@ -217,6 +217,11 @@
crate fn regions_outlived_by(&self, fr1: RegionVid) -> Vec<&RegionVid> {
self.outlives.reachable_from(&fr1)
}
+
+ /// Returns the _non-transitive_ set of known `outlives` constraints between free regions.
+ crate fn known_outlives(&self) -> impl Iterator<Item=(&RegionVid, &RegionVid)> {
+ self.outlives.base_edges()
+ }
}
struct UniversalRegionRelationsBuilder<'this, 'tcx> {
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 55b9427..33ed69a 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -304,7 +304,9 @@
if !self.stack.is_empty() {
// This should change *something*
debug_assert!(self.cur_frame() != old_stack || self.frame().block != old_bb);
- info!("// {:?}", self.frame().block);
+ if let Some(block) = self.frame().block {
+ info!("// executing {:?}", block);
+ }
}
Ok(())
}
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 29cfee8..202b6ae 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -158,14 +158,14 @@
err.emit();
}
- fn check_decl_no_pat<F: FnMut(Span, bool)>(decl: &FnDecl, mut report_err: F) {
- for arg in &decl.inputs {
- match arg.pat.kind {
+ fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, bool)) {
+ for Param { pat, .. } in &decl.inputs {
+ match pat.kind {
PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) |
PatKind::Wild => {}
PatKind::Ident(BindingMode::ByValue(Mutability::Mutable), _, None) =>
- report_err(arg.pat.span, true),
- _ => report_err(arg.pat.span, false),
+ report_err(pat.span, true),
+ _ => report_err(pat.span, false),
}
}
}
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 04e233c..566ba12 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -12,7 +12,7 @@
use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
use crate::{ModuleOrUniformRoot, ParentScope, PerNS, Resolver, ResolverArenas, ExternPreludeEntry};
use crate::Namespace::{self, TypeNS, ValueNS, MacroNS};
-use crate::{ResolutionError, Determinacy, PathResult, CrateLint};
+use crate::{ResolutionError, VisResolutionError, Determinacy, PathResult, CrateLint};
use rustc::bug;
use rustc::hir::def::{self, *};
@@ -32,8 +32,7 @@
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
use syntax::token::{self, Token};
-use syntax::print::pprust;
-use syntax::{span_err, struct_span_err};
+use syntax::span_err;
use syntax::source_map::{respan, Spanned};
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
@@ -192,14 +191,25 @@
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
+ self.resolve_visibility_speculative(vis, false).unwrap_or_else(|err| {
+ self.r.report_vis_error(err);
+ ty::Visibility::Public
+ })
+ }
+
+ fn resolve_visibility_speculative<'ast>(
+ &mut self,
+ vis: &'ast ast::Visibility,
+ speculative: bool,
+ ) -> Result<ty::Visibility, VisResolutionError<'ast>> {
let parent_scope = &self.parent_scope;
match vis.node {
- ast::VisibilityKind::Public => ty::Visibility::Public,
+ ast::VisibilityKind::Public => Ok(ty::Visibility::Public),
ast::VisibilityKind::Crate(..) => {
- ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
+ Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
}
ast::VisibilityKind::Inherited => {
- ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id)
+ Ok(ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id))
}
ast::VisibilityKind::Restricted { ref path, id, .. } => {
// For visibilities we are not ready to provide correct implementation of "uniform
@@ -209,86 +219,67 @@
let ident = path.segments.get(0).expect("empty path in visibility").ident;
let crate_root = if ident.is_path_segment_keyword() {
None
- } else if ident.span.rust_2018() {
- let msg = "relative paths are not supported in visibilities on 2018 edition";
- self.r.session.struct_span_err(ident.span, msg)
- .span_suggestion(
- path.span,
- "try",
- format!("crate::{}", pprust::path_to_string(&path)),
- Applicability::MaybeIncorrect,
- )
- .emit();
- return ty::Visibility::Public;
- } else {
- let ctxt = ident.span.ctxt();
+ } else if ident.span.rust_2015() {
Some(Segment::from_ident(Ident::new(
- kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ctxt)
+ kw::PathRoot, path.span.shrink_to_lo().with_ctxt(ident.span.ctxt())
)))
+ } else {
+ return Err(VisResolutionError::Relative2018(ident.span, path));
};
let segments = crate_root.into_iter()
.chain(path.segments.iter().map(|seg| seg.into())).collect::<Vec<_>>();
- let expected_found_error = |this: &Self, res: Res| {
- let path_str = Segment::names_to_string(&segments);
- struct_span_err!(this.r.session, path.span, E0577,
- "expected module, found {} `{}`", res.descr(), path_str)
- .span_label(path.span, "not a module").emit();
- };
+ let expected_found_error = |res| Err(VisResolutionError::ExpectedFound(
+ path.span, Segment::names_to_string(&segments), res
+ ));
match self.r.resolve_path(
&segments,
Some(TypeNS),
parent_scope,
- true,
+ !speculative,
path.span,
CrateLint::SimplePath(id),
) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
let res = module.res().expect("visibility resolved to unnamed block");
- self.r.record_partial_res(id, PartialRes::new(res));
+ if !speculative {
+ self.r.record_partial_res(id, PartialRes::new(res));
+ }
if module.is_normal() {
if res == Res::Err {
- ty::Visibility::Public
+ Ok(ty::Visibility::Public)
} else {
let vis = ty::Visibility::Restricted(res.def_id());
if self.r.is_accessible_from(vis, parent_scope.module) {
- vis
+ Ok(vis)
} else {
- struct_span_err!(self.r.session, path.span, E0742,
- "visibilities can only be restricted to ancestor modules")
- .emit();
- ty::Visibility::Public
+ Err(VisResolutionError::AncestorOnly(path.span))
}
}
} else {
- expected_found_error(self, res);
- ty::Visibility::Public
+ expected_found_error(res)
}
}
- PathResult::Module(..) => {
- self.r.session.span_err(path.span, "visibility must resolve to a module");
- ty::Visibility::Public
- }
- PathResult::NonModule(partial_res) => {
- expected_found_error(self, partial_res.base_res());
- ty::Visibility::Public
- }
- PathResult::Failed { span, label, suggestion, .. } => {
- self.r.report_error(
- span, ResolutionError::FailedToResolve { label, suggestion }
- );
- ty::Visibility::Public
- }
- PathResult::Indeterminate => {
- span_err!(self.r.session, path.span, E0578,
- "cannot determine resolution for the visibility");
- ty::Visibility::Public
- }
+ PathResult::Module(..) =>
+ Err(VisResolutionError::ModuleOnly(path.span)),
+ PathResult::NonModule(partial_res) =>
+ expected_found_error(partial_res.base_res()),
+ PathResult::Failed { span, label, suggestion, .. } =>
+ Err(VisResolutionError::FailedToResolve(span, label, suggestion)),
+ PathResult::Indeterminate =>
+ Err(VisResolutionError::Indeterminate(path.span)),
}
}
}
}
+ fn insert_field_names_local(&mut self, def_id: DefId, vdata: &ast::VariantData) {
+ let field_names = vdata.fields().iter().map(|field| {
+ respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
+ }).collect();
+ self.insert_field_names(def_id, field_names);
+ }
+
fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Spanned<Name>>) {
if !field_names.is_empty() {
self.r.field_names.insert(def_id, field_names);
@@ -726,59 +717,52 @@
}
// These items live in both the type and value namespaces.
- ItemKind::Struct(ref struct_def, _) => {
+ ItemKind::Struct(ref vdata, _) => {
// Define a name in the type namespace.
let def_id = self.r.definitions.local_def_id(item.id);
let res = Res::Def(DefKind::Struct, def_id);
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
- let mut ctor_vis = vis;
-
- let has_non_exhaustive = attr::contains_name(&item.attrs, sym::non_exhaustive);
-
- // If the structure is marked as non_exhaustive then lower the visibility
- // to within the crate.
- if has_non_exhaustive && vis == ty::Visibility::Public {
- ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
- }
-
// Record field names for error reporting.
- let field_names = struct_def.fields().iter().map(|field| {
- // NOTE: The field may be an expansion placeholder, but expansion sets correct
- // visibilities for unnamed field placeholders specifically, so the constructor
- // visibility should still be determined correctly.
- let field_vis = self.resolve_visibility(&field.vis);
- if ctor_vis.is_at_least(field_vis, &*self.r) {
- ctor_vis = field_vis;
- }
- respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
- }).collect();
- let item_def_id = self.r.definitions.local_def_id(item.id);
- self.insert_field_names(item_def_id, field_names);
+ self.insert_field_names_local(def_id, vdata);
// If this is a tuple or unit struct, define a name
// in the value namespace as well.
- if let Some(ctor_node_id) = struct_def.ctor_id() {
+ if let Some(ctor_node_id) = vdata.ctor_id() {
+ let mut ctor_vis = vis;
+ // If the structure is marked as non_exhaustive then lower the visibility
+ // to within the crate.
+ if vis == ty::Visibility::Public &&
+ attr::contains_name(&item.attrs, sym::non_exhaustive) {
+ ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
+ }
+ for field in vdata.fields() {
+ // NOTE: The field may be an expansion placeholder, but expansion sets
+ // correct visibilities for unnamed field placeholders specifically, so the
+ // constructor visibility should still be determined correctly.
+ if let Ok(field_vis) =
+ self.resolve_visibility_speculative(&field.vis, true) {
+ if ctor_vis.is_at_least(field_vis, &*self.r) {
+ ctor_vis = field_vis;
+ }
+ }
+ }
let ctor_res = Res::Def(
- DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(struct_def)),
+ DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)),
self.r.definitions.local_def_id(ctor_node_id),
);
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
- self.r.struct_constructors.insert(res.def_id(), (ctor_res, ctor_vis));
+ self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis));
}
}
ItemKind::Union(ref vdata, _) => {
- let res = Res::Def(DefKind::Union, self.r.definitions.local_def_id(item.id));
+ let def_id = self.r.definitions.local_def_id(item.id);
+ let res = Res::Def(DefKind::Union, def_id);
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
// Record field names for error reporting.
- let field_names = vdata.fields().iter().map(|field| {
- self.resolve_visibility(&field.vis);
- respan(field.span, field.ident.map_or(kw::Invalid, |ident| ident.name))
- }).collect();
- let item_def_id = self.r.definitions.local_def_id(item.id);
- self.insert_field_names(item_def_id, field_names);
+ self.insert_field_names_local(def_id, vdata);
}
ItemKind::Impl(.., ref impl_items) => {
@@ -1281,6 +1265,7 @@
if sf.is_placeholder {
self.visit_invoc(sf.id);
} else {
+ self.resolve_visibility(&sf.vis);
visit::walk_struct_field(self, sf);
}
}
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 8dd45f5..f92415f 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -11,6 +11,7 @@
use rustc::util::nodemap::FxHashSet;
use rustc_feature::BUILTIN_ATTRIBUTES;
use syntax::ast::{self, Ident, Path};
+use syntax::print::pprust;
use syntax::source_map::SourceMap;
use syntax::struct_span_err;
use syntax::symbol::{Symbol, kw};
@@ -22,6 +23,7 @@
use crate::path_names_to_string;
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};
+use crate::VisResolutionError;
use rustc_error_codes::*;
@@ -357,6 +359,44 @@
}
}
+ crate fn report_vis_error(&self, vis_resolution_error: VisResolutionError<'_>) {
+ match vis_resolution_error {
+ VisResolutionError::Relative2018(span, path) => {
+ let mut err = self.session.struct_span_err(span,
+ "relative paths are not supported in visibilities on 2018 edition");
+ err.span_suggestion(
+ path.span,
+ "try",
+ format!("crate::{}", pprust::path_to_string(&path)),
+ Applicability::MaybeIncorrect,
+ );
+ err
+ }
+ VisResolutionError::AncestorOnly(span) => {
+ struct_span_err!(self.session, span, E0742,
+ "visibilities can only be restricted to ancestor modules")
+ }
+ VisResolutionError::FailedToResolve(span, label, suggestion) => {
+ self.into_struct_error(
+ span, ResolutionError::FailedToResolve { label, suggestion }
+ )
+ }
+ VisResolutionError::ExpectedFound(span, path_str, res) => {
+ let mut err = struct_span_err!(self.session, span, E0577,
+ "expected module, found {} `{}`", res.descr(), path_str);
+ err.span_label(span, "not a module");
+ err
+ }
+ VisResolutionError::Indeterminate(span) => {
+ struct_span_err!(self.session, span, E0578,
+ "cannot determine resolution for the visibility")
+ }
+ VisResolutionError::ModuleOnly(span) => {
+ self.session.struct_span_err(span, "visibility must resolve to a module")
+ }
+ }.emit()
+ }
+
/// Lookup typo candidate in scope for a macro or import.
fn early_lookup_typo_candidate(
&mut self,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 31f59e4..9db89c8 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -218,6 +218,15 @@
SelfInTyParamDefault,
}
+enum VisResolutionError<'a> {
+ Relative2018(Span, &'a ast::Path),
+ AncestorOnly(Span),
+ FailedToResolve(Span, String, Option<Suggestion>),
+ ExpectedFound(Span, String, Res),
+ Indeterminate(Span),
+ ModuleOnly(Span),
+}
+
// A minimal representation of a path segment. We use this in resolve because
// we synthesize 'path segments' which don't have the rest of an AST or HIR
// `PathSegment`.
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4d8d004..327be40 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -5,12 +5,12 @@
pub mod inline;
pub mod cfg;
-mod simplify;
mod auto_trait;
mod blanket_impl;
+mod simplify;
+pub mod types;
use rustc_index::vec::{IndexVec, Idx};
-use rustc_target::spec::abi::Abi;
use rustc_typeck::hir_ty_to_ty;
use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
use rustc::middle::resolve_lifetime as rl;
@@ -24,46 +24,33 @@
use rustc::ty::subst::{InternalSubsts, SubstsRef, GenericArgKind};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::ty::fold::TypeFolder;
-use rustc::ty::layout::VariantIdx;
use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use syntax::ast::{self, Attribute, AttrStyle, AttrKind, Ident};
+use syntax::ast::{self, Ident};
use syntax::attr;
-use syntax::util::comments;
-use syntax::source_map::DUMMY_SP;
use syntax_pos::symbol::{Symbol, kw, sym};
use syntax_pos::hygiene::MacroKind;
-use syntax_pos::{self, Pos, FileName};
+use syntax_pos::{self, Pos};
use std::collections::hash_map::Entry;
-use std::fmt;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
use std::default::Default;
-use std::{mem, slice, vec};
-use std::num::NonZeroU32;
-use std::iter::FromIterator;
+use std::{mem, vec};
use std::rc::Rc;
-use std::cell::RefCell;
-use std::sync::Arc;
use std::u32;
use crate::core::{self, DocContext, ImplTraitParam};
use crate::doctree;
-use crate::html::render::{cache, ExternalLocation};
-use crate::html::item_type::ItemType;
-
-use self::cfg::Cfg;
use self::auto_trait::AutoTraitFinder;
use self::blanket_impl::BlanketImplFinder;
-pub use self::Type::*;
-pub use self::Mutability::*;
-pub use self::ItemEnum::*;
-pub use self::SelfTy::*;
-pub use self::FunctionRetTy::*;
-pub use self::Visibility::{Public, Inherited};
-
-thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
+pub use self::types::*;
+pub use self::types::Type::*;
+pub use self::types::Mutability::*;
+pub use self::types::ItemEnum::*;
+pub use self::types::SelfTy::*;
+pub use self::types::FunctionRetTy::*;
+pub use self::types::Visibility::{Public, Inherited};
const FN_OUTPUT_NAME: &'static str = "Output";
@@ -122,21 +109,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Crate {
- pub name: String,
- pub version: Option<String>,
- pub src: FileName,
- pub module: Option<Item>,
- pub externs: Vec<(CrateNum, ExternalCrate)>,
- pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
- // These are later on moved into `CACHEKEY`, leaving the map empty.
- // Only here so that they can be filtered through the rustdoc passes.
- pub external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
- pub masked_crates: FxHashSet<CrateNum>,
- pub collapsed: bool,
-}
-
pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
use crate::visit_lib::LibEmbargoVisitor;
@@ -222,15 +194,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct ExternalCrate {
- pub name: String,
- pub src: FileName,
- pub attrs: Attributes,
- pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
- pub keywords: Vec<(DefId, String, Attributes)>,
-}
-
impl Clean<ExternalCrate> for CrateNum {
fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
@@ -351,237 +314,6 @@
}
}
-/// Anything with a source location and set of attributes and, optionally, a
-/// name. That is, anything that can be documented. This doesn't correspond
-/// directly to the AST's concept of an item; it's a strict superset.
-#[derive(Clone)]
-pub struct Item {
- /// Stringified span
- pub source: Span,
- /// Not everything has a name. E.g., impls
- pub name: Option<String>,
- pub attrs: Attributes,
- pub inner: ItemEnum,
- pub visibility: Visibility,
- pub def_id: DefId,
- pub stability: Option<Stability>,
- pub deprecation: Option<Deprecation>,
-}
-
-impl fmt::Debug for Item {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-
- let fake = MAX_DEF_ID.with(|m| m.borrow().get(&self.def_id.krate)
- .map(|id| self.def_id >= *id).unwrap_or(false));
- let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
-
- fmt.debug_struct("Item")
- .field("source", &self.source)
- .field("name", &self.name)
- .field("attrs", &self.attrs)
- .field("inner", &self.inner)
- .field("visibility", &self.visibility)
- .field("def_id", def_id)
- .field("stability", &self.stability)
- .field("deprecation", &self.deprecation)
- .finish()
- }
-}
-
-impl Item {
- /// Finds the `doc` attribute as a NameValue and returns the corresponding
- /// value found.
- pub fn doc_value(&self) -> Option<&str> {
- self.attrs.doc_value()
- }
- /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
- /// with newlines.
- pub fn collapsed_doc_value(&self) -> Option<String> {
- self.attrs.collapsed_doc_value()
- }
-
- pub fn links(&self) -> Vec<(String, String)> {
- self.attrs.links(&self.def_id.krate)
- }
-
- pub fn is_crate(&self) -> bool {
- match self.inner {
- StrippedItem(box ModuleItem(Module { is_crate: true, ..})) |
- ModuleItem(Module { is_crate: true, ..}) => true,
- _ => false,
- }
- }
- pub fn is_mod(&self) -> bool {
- self.type_() == ItemType::Module
- }
- pub fn is_trait(&self) -> bool {
- self.type_() == ItemType::Trait
- }
- pub fn is_struct(&self) -> bool {
- self.type_() == ItemType::Struct
- }
- pub fn is_enum(&self) -> bool {
- self.type_() == ItemType::Enum
- }
- pub fn is_variant(&self) -> bool {
- self.type_() == ItemType::Variant
- }
- pub fn is_associated_type(&self) -> bool {
- self.type_() == ItemType::AssocType
- }
- pub fn is_associated_const(&self) -> bool {
- self.type_() == ItemType::AssocConst
- }
- pub fn is_method(&self) -> bool {
- self.type_() == ItemType::Method
- }
- pub fn is_ty_method(&self) -> bool {
- self.type_() == ItemType::TyMethod
- }
- pub fn is_typedef(&self) -> bool {
- self.type_() == ItemType::Typedef
- }
- pub fn is_primitive(&self) -> bool {
- self.type_() == ItemType::Primitive
- }
- pub fn is_union(&self) -> bool {
- self.type_() == ItemType::Union
- }
- pub fn is_import(&self) -> bool {
- self.type_() == ItemType::Import
- }
- pub fn is_extern_crate(&self) -> bool {
- self.type_() == ItemType::ExternCrate
- }
- pub fn is_keyword(&self) -> bool {
- self.type_() == ItemType::Keyword
- }
-
- pub fn is_stripped(&self) -> bool {
- match self.inner { StrippedItem(..) => true, _ => false }
- }
- pub fn has_stripped_fields(&self) -> Option<bool> {
- match self.inner {
- StructItem(ref _struct) => Some(_struct.fields_stripped),
- UnionItem(ref union) => Some(union.fields_stripped),
- VariantItem(Variant { kind: VariantKind::Struct(ref vstruct)} ) => {
- Some(vstruct.fields_stripped)
- },
- _ => None,
- }
- }
-
- pub fn stability_class(&self) -> Option<String> {
- self.stability.as_ref().and_then(|ref s| {
- let mut classes = Vec::with_capacity(2);
-
- if s.level == stability::Unstable {
- classes.push("unstable");
- }
-
- if s.deprecation.is_some() {
- classes.push("deprecated");
- }
-
- if classes.len() != 0 {
- Some(classes.join(" "))
- } else {
- None
- }
- })
- }
-
- pub fn stable_since(&self) -> Option<&str> {
- self.stability.as_ref().map(|s| &s.since[..])
- }
-
- pub fn is_non_exhaustive(&self) -> bool {
- self.attrs.other_attrs.iter()
- .any(|a| a.check_name(sym::non_exhaustive))
- }
-
- /// Returns a documentation-level item type from the item.
- pub fn type_(&self) -> ItemType {
- ItemType::from(self)
- }
-
- /// Returns the info in the item's `#[deprecated]` or `#[rustc_deprecated]` attributes.
- ///
- /// If the item is not deprecated, returns `None`.
- pub fn deprecation(&self) -> Option<&Deprecation> {
- self.deprecation
- .as_ref()
- .or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
- }
- pub fn is_default(&self) -> bool {
- match self.inner {
- ItemEnum::MethodItem(ref meth) => {
- if let Some(defaultness) = meth.defaultness {
- defaultness.has_value() && !defaultness.is_final()
- } else {
- false
- }
- }
- _ => false,
- }
- }
-}
-
-#[derive(Clone, Debug)]
-pub enum ItemEnum {
- ExternCrateItem(String, Option<String>),
- ImportItem(Import),
- StructItem(Struct),
- UnionItem(Union),
- EnumItem(Enum),
- FunctionItem(Function),
- ModuleItem(Module),
- TypedefItem(Typedef, bool /* is associated type */),
- OpaqueTyItem(OpaqueTy, bool /* is associated type */),
- StaticItem(Static),
- ConstantItem(Constant),
- TraitItem(Trait),
- TraitAliasItem(TraitAlias),
- ImplItem(Impl),
- /// A method signature only. Used for required methods in traits (ie,
- /// non-default-methods).
- TyMethodItem(TyMethod),
- /// A method with a body.
- MethodItem(Method),
- StructFieldItem(Type),
- VariantItem(Variant),
- /// `fn`s from an extern block
- ForeignFunctionItem(Function),
- /// `static`s from an extern block
- ForeignStaticItem(Static),
- /// `type`s from an extern block
- ForeignTypeItem,
- MacroItem(Macro),
- ProcMacroItem(ProcMacro),
- PrimitiveItem(PrimitiveType),
- AssocConstItem(Type, Option<String>),
- AssocTypeItem(Vec<GenericBound>, Option<Type>),
- /// An item that has been stripped by a rustdoc pass
- StrippedItem(Box<ItemEnum>),
- KeywordItem(String),
-}
-
-impl ItemEnum {
- pub fn is_associated(&self) -> bool {
- match *self {
- ItemEnum::TypedefItem(_, _) |
- ItemEnum::AssocTypeItem(_, _) => true,
- _ => false,
- }
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Module {
- pub items: Vec<Item>,
- pub is_crate: bool,
-}
-
impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = if self.name.is_some() {
@@ -645,465 +377,12 @@
}
}
-pub struct ListAttributesIter<'a> {
- attrs: slice::Iter<'a, ast::Attribute>,
- current_list: vec::IntoIter<ast::NestedMetaItem>,
- name: Symbol,
-}
-
-impl<'a> Iterator for ListAttributesIter<'a> {
- type Item = ast::NestedMetaItem;
-
- fn next(&mut self) -> Option<Self::Item> {
- if let Some(nested) = self.current_list.next() {
- return Some(nested);
- }
-
- for attr in &mut self.attrs {
- if let Some(list) = attr.meta_item_list() {
- if attr.check_name(self.name) {
- self.current_list = list.into_iter();
- if let Some(nested) = self.current_list.next() {
- return Some(nested);
- }
- }
- }
- }
-
- None
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- let lower = self.current_list.len();
- (lower, None)
- }
-}
-
-pub trait AttributesExt {
- /// Finds an attribute as List and returns the list of attributes nested inside.
- fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
-}
-
-impl AttributesExt for [ast::Attribute] {
- fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
- ListAttributesIter {
- attrs: self.iter(),
- current_list: Vec::new().into_iter(),
- name,
- }
- }
-}
-
-pub trait NestedAttributesExt {
- /// Returns `true` if the attribute list contains a specific `Word`
- fn has_word(self, word: Symbol) -> bool;
-}
-
-impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
- fn has_word(self, word: Symbol) -> bool {
- self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
- }
-}
-
-/// A portion of documentation, extracted from a `#[doc]` attribute.
-///
-/// Each variant contains the line number within the complete doc-comment where the fragment
-/// starts, as well as the Span where the corresponding doc comment or attribute is located.
-///
-/// Included files are kept separate from inline doc comments so that proper line-number
-/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
-/// kept separate because of issue #42760.
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum DocFragment {
- /// A doc fragment created from a `///` or `//!` doc comment.
- SugaredDoc(usize, syntax_pos::Span, String),
- /// A doc fragment created from a "raw" `#[doc=""]` attribute.
- RawDoc(usize, syntax_pos::Span, String),
- /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
- /// given filename and the file contents.
- Include(usize, syntax_pos::Span, String, String),
-}
-
-impl DocFragment {
- pub fn as_str(&self) -> &str {
- match *self {
- DocFragment::SugaredDoc(_, _, ref s) => &s[..],
- DocFragment::RawDoc(_, _, ref s) => &s[..],
- DocFragment::Include(_, _, _, ref s) => &s[..],
- }
- }
-
- pub fn span(&self) -> syntax_pos::Span {
- match *self {
- DocFragment::SugaredDoc(_, span, _) |
- DocFragment::RawDoc(_, span, _) |
- DocFragment::Include(_, span, _, _) => span,
- }
- }
-}
-
-impl<'a> FromIterator<&'a DocFragment> for String {
- fn from_iter<T>(iter: T) -> Self
- where
- T: IntoIterator<Item = &'a DocFragment>
- {
- iter.into_iter().fold(String::new(), |mut acc, frag| {
- if !acc.is_empty() {
- acc.push('\n');
- }
- match *frag {
- DocFragment::SugaredDoc(_, _, ref docs)
- | DocFragment::RawDoc(_, _, ref docs)
- | DocFragment::Include(_, _, _, ref docs) =>
- acc.push_str(docs),
- }
-
- acc
- })
- }
-}
-
-#[derive(Clone, Debug, Default)]
-pub struct Attributes {
- pub doc_strings: Vec<DocFragment>,
- pub other_attrs: Vec<ast::Attribute>,
- pub cfg: Option<Arc<Cfg>>,
- pub span: Option<syntax_pos::Span>,
- /// map from Rust paths to resolved defs and potential URL fragments
- pub links: Vec<(String, Option<DefId>, Option<String>)>,
- pub inner_docs: bool,
-}
-
-impl Attributes {
- /// Extracts the content from an attribute `#[doc(cfg(content))]`.
- fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
- use syntax::ast::NestedMetaItem::MetaItem;
-
- if let ast::MetaItemKind::List(ref nmis) = mi.kind {
- if nmis.len() == 1 {
- if let MetaItem(ref cfg_mi) = nmis[0] {
- if cfg_mi.check_name(sym::cfg) {
- if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
- if cfg_nmis.len() == 1 {
- if let MetaItem(ref content_mi) = cfg_nmis[0] {
- return Some(content_mi);
- }
- }
- }
- }
- }
- }
- }
-
- None
- }
-
- /// Reads a `MetaItem` from within an attribute, looks for whether it is a
- /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
- /// its expansion.
- fn extract_include(mi: &ast::MetaItem)
- -> Option<(String, String)>
- {
- mi.meta_item_list().and_then(|list| {
- for meta in list {
- if meta.check_name(sym::include) {
- // the actual compiled `#[doc(include="filename")]` gets expanded to
- // `#[doc(include(file="filename", contents="file contents")]` so we need to
- // look for that instead
- return meta.meta_item_list().and_then(|list| {
- let mut filename: Option<String> = None;
- let mut contents: Option<String> = None;
-
- for it in list {
- if it.check_name(sym::file) {
- if let Some(name) = it.value_str() {
- filename = Some(name.to_string());
- }
- } else if it.check_name(sym::contents) {
- if let Some(docs) = it.value_str() {
- contents = Some(docs.to_string());
- }
- }
- }
-
- if let (Some(filename), Some(contents)) = (filename, contents) {
- Some((filename, contents))
- } else {
- None
- }
- });
- }
- }
-
- None
- })
- }
-
- pub fn has_doc_flag(&self, flag: Symbol) -> bool {
- for attr in &self.other_attrs {
- if !attr.check_name(sym::doc) { continue; }
-
- if let Some(items) = attr.meta_item_list() {
- if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
- return true;
- }
- }
- }
-
- false
- }
-
- pub fn from_ast(diagnostic: &::errors::Handler,
- attrs: &[ast::Attribute]) -> Attributes {
- let mut doc_strings = vec![];
- let mut sp = None;
- let mut cfg = Cfg::True;
- let mut doc_line = 0;
-
- /// If `attr` is a doc comment, strips the leading and (if present)
- /// trailing comments symbols, e.g. `///`, `/**`, and `*/`. Otherwise,
- /// returns `attr` unchanged.
- pub fn with_doc_comment_markers_stripped<T>(
- attr: &Attribute,
- f: impl FnOnce(&Attribute) -> T
- ) -> T {
- match attr.kind {
- AttrKind::Normal(_) => {
- f(attr)
- }
- AttrKind::DocComment(comment) => {
- let comment =
- Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str()));
- f(&Attribute {
- kind: AttrKind::DocComment(comment),
- id: attr.id,
- style: attr.style,
- span: attr.span,
- })
- }
- }
- }
-
- let other_attrs = attrs.iter().filter_map(|attr| {
- with_doc_comment_markers_stripped(attr, |attr| {
- if attr.check_name(sym::doc) {
- if let Some(mi) = attr.meta() {
- if let Some(value) = mi.value_str() {
- // Extracted #[doc = "..."]
- let value = value.to_string();
- let line = doc_line;
- doc_line += value.lines().count();
-
- if attr.is_doc_comment() {
- doc_strings.push(DocFragment::SugaredDoc(line, attr.span, value));
- } else {
- doc_strings.push(DocFragment::RawDoc(line, attr.span, value));
- }
-
- if sp.is_none() {
- sp = Some(attr.span);
- }
- return None;
- } else if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
- // Extracted #[doc(cfg(...))]
- match Cfg::parse(cfg_mi) {
- Ok(new_cfg) => cfg &= new_cfg,
- Err(e) => diagnostic.span_err(e.span, e.msg),
- }
- return None;
- } else if let Some((filename, contents)) = Attributes::extract_include(&mi)
- {
- let line = doc_line;
- doc_line += contents.lines().count();
- doc_strings.push(DocFragment::Include(line,
- attr.span,
- filename,
- contents));
- }
- }
- }
- Some(attr.clone())
- })
- }).collect();
-
- // treat #[target_feature(enable = "feat")] attributes as if they were
- // #[doc(cfg(target_feature = "feat"))] attributes as well
- for attr in attrs.lists(sym::target_feature) {
- if attr.check_name(sym::enable) {
- if let Some(feat) = attr.value_str() {
- let meta = attr::mk_name_value_item_str(
- Ident::with_dummy_span(sym::target_feature), feat, DUMMY_SP
- );
- if let Ok(feat_cfg) = Cfg::parse(&meta) {
- cfg &= feat_cfg;
- }
- }
- }
- }
-
- let inner_docs = attrs.iter()
- .filter(|a| a.check_name(sym::doc))
- .next()
- .map_or(true, |a| a.style == AttrStyle::Inner);
-
- Attributes {
- doc_strings,
- other_attrs,
- cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
- span: sp,
- links: vec![],
- inner_docs,
- }
- }
-
- /// Finds the `doc` attribute as a NameValue and returns the corresponding
- /// value found.
- pub fn doc_value(&self) -> Option<&str> {
- self.doc_strings.first().map(|s| s.as_str())
- }
-
- /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
- /// with newlines.
- pub fn collapsed_doc_value(&self) -> Option<String> {
- if !self.doc_strings.is_empty() {
- Some(self.doc_strings.iter().collect())
- } else {
- None
- }
- }
-
- /// Gets links as a vector
- ///
- /// Cache must be populated before call
- pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> {
- use crate::html::format::href;
-
- self.links.iter().filter_map(|&(ref s, did, ref fragment)| {
- match did {
- Some(did) => {
- if let Some((mut href, ..)) = href(did) {
- if let Some(ref fragment) = *fragment {
- href.push_str("#");
- href.push_str(fragment);
- }
- Some((s.clone(), href))
- } else {
- None
- }
- }
- None => {
- if let Some(ref fragment) = *fragment {
- let cache = cache();
- let url = match cache.extern_locations.get(krate) {
- Some(&(_, ref src, ExternalLocation::Local)) =>
- src.to_str().expect("invalid file path"),
- Some(&(_, _, ExternalLocation::Remote(ref s))) => s,
- Some(&(_, _, ExternalLocation::Unknown)) | None =>
- "https://doc.rust-lang.org/nightly",
- };
- // This is a primitive so the url is done "by hand".
- let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
- Some((s.clone(),
- format!("{}{}std/primitive.{}.html{}",
- url,
- if !url.ends_with('/') { "/" } else { "" },
- &fragment[..tail],
- &fragment[tail..])))
- } else {
- panic!("This isn't a primitive?!");
- }
- }
- }
- }).collect()
- }
-}
-
-impl PartialEq for Attributes {
- fn eq(&self, rhs: &Self) -> bool {
- self.doc_strings == rhs.doc_strings &&
- self.cfg == rhs.cfg &&
- self.span == rhs.span &&
- self.links == rhs.links &&
- self.other_attrs.iter().map(|attr| attr.id).eq(rhs.other_attrs.iter().map(|attr| attr.id))
- }
-}
-
-impl Eq for Attributes {}
-
-impl Hash for Attributes {
- fn hash<H: Hasher>(&self, hasher: &mut H) {
- self.doc_strings.hash(hasher);
- self.cfg.hash(hasher);
- self.span.hash(hasher);
- self.links.hash(hasher);
- for attr in &self.other_attrs {
- attr.id.hash(hasher);
- }
- }
-}
-
-impl AttributesExt for Attributes {
- fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
- self.other_attrs.lists(name)
- }
-}
-
impl Clean<Attributes> for [ast::Attribute] {
fn clean(&self, cx: &DocContext<'_>) -> Attributes {
Attributes::from_ast(cx.sess().diagnostic(), self)
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericBound {
- TraitBound(PolyTrait, hir::TraitBoundModifier),
- Outlives(Lifetime),
-}
-
-impl GenericBound {
- fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
- let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
- let empty = cx.tcx.intern_substs(&[]);
- let path = external_path(cx, cx.tcx.item_name(did),
- Some(did), false, vec![], empty);
- inline::record_extern_fqn(cx, did, TypeKind::Trait);
- GenericBound::TraitBound(PolyTrait {
- trait_: ResolvedPath {
- path,
- param_names: None,
- did,
- is_generic: false,
- },
- generic_params: Vec::new(),
- }, hir::TraitBoundModifier::Maybe)
- }
-
- fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
- use rustc::hir::TraitBoundModifier as TBM;
- if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
- if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
- return true;
- }
- }
- false
- }
-
- fn get_poly_trait(&self) -> Option<PolyTrait> {
- if let GenericBound::TraitBound(ref p, _) = *self {
- return Some(p.clone())
- }
- None
- }
-
- fn get_trait_type(&self) -> Option<Type> {
- if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
- Some(trait_.clone())
- } else {
- None
- }
- }
-}
-
impl Clean<GenericBound> for hir::GenericBound {
fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
match *self {
@@ -1237,21 +516,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Lifetime(String);
-
-impl Lifetime {
- pub fn get_ref<'a>(&'a self) -> &'a str {
- let Lifetime(ref s) = *self;
- let s: &'a str = s;
- s
- }
-
- pub fn statik() -> Lifetime {
- Lifetime("'static".to_string())
- }
-}
-
impl Clean<Lifetime> for hir::Lifetime {
fn clean(&self, cx: &DocContext<'_>) -> Lifetime {
if self.hir_id != hir::DUMMY_HIR_ID {
@@ -1332,23 +596,6 @@
}
}
-#[derive(Clone, Debug)]
-pub enum WherePredicate {
- BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
- RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
- EqPredicate { lhs: Type, rhs: Type },
-}
-
-impl WherePredicate {
- pub fn get_bounds(&self) -> Option<&[GenericBound]> {
- match *self {
- WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
- WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
- _ => None,
- }
- }
-}
-
impl Clean<WherePredicate> for hir::WherePredicate {
fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
match *self {
@@ -1470,73 +717,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericParamDefKind {
- Lifetime,
- Type {
- did: DefId,
- bounds: Vec<GenericBound>,
- default: Option<Type>,
- synthetic: Option<hir::SyntheticTyParamKind>,
- },
- Const {
- did: DefId,
- ty: Type,
- },
-}
-
-impl GenericParamDefKind {
- pub fn is_type(&self) -> bool {
- match *self {
- GenericParamDefKind::Type { .. } => true,
- _ => false,
- }
- }
-
- // FIXME(eddyb) this either returns the default of a type parameter, or the
- // type of a `const` parameter. It seems that the intention is to *visit*
- // any embedded types, but `get_type` seems to be the wrong name for that.
- pub fn get_type(&self) -> Option<Type> {
- match self {
- GenericParamDefKind::Type { default, .. } => default.clone(),
- GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
- GenericParamDefKind::Lifetime => None,
- }
- }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct GenericParamDef {
- pub name: String,
-
- pub kind: GenericParamDefKind,
-}
-
-impl GenericParamDef {
- pub fn is_synthetic_type_param(&self) -> bool {
- match self.kind {
- GenericParamDefKind::Lifetime |
- GenericParamDefKind::Const { .. } => false,
- GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
- }
- }
-
- pub fn is_type(&self) -> bool {
- self.kind.is_type()
- }
-
- pub fn get_type(&self) -> Option<Type> {
- self.kind.get_type()
- }
-
- pub fn get_bounds(&self) -> Option<&[GenericBound]> {
- match self.kind {
- GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
- _ => None,
- }
- }
-}
-
impl Clean<GenericParamDef> for ty::GenericParamDef {
fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
let (name, kind) = match self.kind {
@@ -1614,13 +794,6 @@
}
}
-// maybe use a Generic enum and use Vec<Generic>?
-#[derive(Clone, Debug, Default)]
-pub struct Generics {
- pub params: Vec<GenericParamDef>,
- pub where_predicates: Vec<WherePredicate>,
-}
-
impl Clean<Generics> for hir::Generics {
fn clean(&self, cx: &DocContext<'_>) -> Generics {
// Synthetic type-parameters are inserted after normal ones.
@@ -1975,16 +1148,6 @@
(all_types.into_iter().collect(), ret_types)
}
-#[derive(Clone, Debug)]
-pub struct Method {
- pub generics: Generics,
- pub decl: FnDecl,
- pub header: hir::FnHeader,
- pub defaultness: Option<hir::Defaultness>,
- pub all_types: Vec<Type>,
- pub ret_types: Vec<Type>,
-}
-
impl<'a> Clean<Method> for (&'a hir::FnSig, &'a hir::Generics, hir::BodyId,
Option<hir::Defaultness>) {
fn clean(&self, cx: &DocContext<'_>) -> Method {
@@ -2003,24 +1166,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct TyMethod {
- pub header: hir::FnHeader,
- pub decl: FnDecl,
- pub generics: Generics,
- pub all_types: Vec<Type>,
- pub ret_types: Vec<Type>,
-}
-
-#[derive(Clone, Debug)]
-pub struct Function {
- pub decl: FnDecl,
- pub generics: Generics,
- pub header: hir::FnHeader,
- pub all_types: Vec<Type>,
- pub ret_types: Vec<Type>,
-}
-
impl Clean<Item> for doctree::Function<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let (generics, decl) = enter_impl_trait(cx, || {
@@ -2053,49 +1198,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct FnDecl {
- pub inputs: Arguments,
- pub output: FunctionRetTy,
- pub c_variadic: bool,
- pub attrs: Attributes,
-}
-
-impl FnDecl {
- pub fn self_type(&self) -> Option<SelfTy> {
- self.inputs.values.get(0).and_then(|v| v.to_self())
- }
-
- /// Returns the sugared return type for an async function.
- ///
- /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
- /// will return `i32`.
- ///
- /// # Panics
- ///
- /// This function will panic if the return type does not match the expected sugaring for async
- /// functions.
- pub fn sugared_async_return_type(&self) -> FunctionRetTy {
- match &self.output {
- FunctionRetTy::Return(Type::ImplTrait(bounds)) => {
- match &bounds[0] {
- GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
- let bindings = trait_.bindings().unwrap();
- FunctionRetTy::Return(bindings[0].ty().clone())
- }
- _ => panic!("unexpected desugaring of async function"),
- }
- }
- _ => panic!("unexpected desugaring of async function"),
- }
- }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Arguments {
- pub values: Vec<Argument>,
-}
-
impl<'a> Clean<Arguments> for (&'a [hir::Ty], &'a [ast::Ident]) {
fn clean(&self, cx: &DocContext<'_>) -> Arguments {
Arguments {
@@ -2167,42 +1269,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Argument {
- pub type_: Type,
- pub name: String,
-}
-
-#[derive(Clone, PartialEq, Debug)]
-pub enum SelfTy {
- SelfValue,
- SelfBorrowed(Option<Lifetime>, Mutability),
- SelfExplicit(Type),
-}
-
-impl Argument {
- pub fn to_self(&self) -> Option<SelfTy> {
- if self.name != "self" {
- return None;
- }
- if self.type_.is_self_type() {
- return Some(SelfValue);
- }
- match self.type_ {
- BorrowedRef{ref lifetime, mutability, ref type_} if type_.is_self_type() => {
- Some(SelfBorrowed(lifetime.clone(), mutability))
- }
- _ => Some(SelfExplicit(self.type_.clone()))
- }
- }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum FunctionRetTy {
- Return(Type),
- DefaultReturn,
-}
-
impl Clean<FunctionRetTy> for hir::FunctionRetTy {
fn clean(&self, cx: &DocContext<'_>) -> FunctionRetTy {
match *self {
@@ -2212,26 +1278,6 @@
}
}
-impl GetDefId for FunctionRetTy {
- fn def_id(&self) -> Option<DefId> {
- match *self {
- Return(ref ty) => ty.def_id(),
- DefaultReturn => None,
- }
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Trait {
- pub auto: bool,
- pub unsafety: hir::Unsafety,
- pub items: Vec<Item>,
- pub generics: Generics,
- pub bounds: Vec<GenericBound>,
- pub is_spotlight: bool,
- pub is_auto: bool,
-}
-
impl Clean<Item> for doctree::Trait<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
@@ -2257,12 +1303,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct TraitAlias {
- pub generics: Generics,
- pub bounds: Vec<GenericBound>,
-}
-
impl Clean<Item> for doctree::TraitAlias<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
@@ -2541,321 +1581,6 @@
}
}
-/// A trait reference, which may have higher ranked lifetimes.
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct PolyTrait {
- pub trait_: Type,
- pub generic_params: Vec<GenericParamDef>,
-}
-
-/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
-/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
-/// importantly, it does not preserve mutability or boxes.
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum Type {
- /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
- ResolvedPath {
- path: Path,
- param_names: Option<Vec<GenericBound>>,
- did: DefId,
- /// `true` if is a `T::Name` path for associated types.
- is_generic: bool,
- },
- /// For parameterized types, so the consumer of the JSON don't go
- /// looking for types which don't exist anywhere.
- Generic(String),
- /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
- /// arrays, slices, and tuples.
- Primitive(PrimitiveType),
- /// `extern "ABI" fn`
- BareFunction(Box<BareFunctionDecl>),
- Tuple(Vec<Type>),
- Slice(Box<Type>),
- Array(Box<Type>, String),
- Never,
- RawPointer(Mutability, Box<Type>),
- BorrowedRef {
- lifetime: Option<Lifetime>,
- mutability: Mutability,
- type_: Box<Type>,
- },
-
- // `<Type as Trait>::Name`
- QPath {
- name: String,
- self_type: Box<Type>,
- trait_: Box<Type>
- },
-
- // `_`
- Infer,
-
- // `impl TraitA + TraitB + ...`
- ImplTrait(Vec<GenericBound>),
-}
-
-#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
-pub enum PrimitiveType {
- Isize, I8, I16, I32, I64, I128,
- Usize, U8, U16, U32, U64, U128,
- F32, F64,
- Char,
- Bool,
- Str,
- Slice,
- Array,
- Tuple,
- Unit,
- RawPointer,
- Reference,
- Fn,
- Never,
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum TypeKind {
- Enum,
- Function,
- Module,
- Const,
- Static,
- Struct,
- Union,
- Trait,
- Typedef,
- Foreign,
- Macro,
- Attr,
- Derive,
- TraitAlias,
-}
-
-pub trait GetDefId {
- fn def_id(&self) -> Option<DefId>;
-}
-
-impl<T: GetDefId> GetDefId for Option<T> {
- fn def_id(&self) -> Option<DefId> {
- self.as_ref().and_then(|d| d.def_id())
- }
-}
-
-impl Type {
- pub fn primitive_type(&self) -> Option<PrimitiveType> {
- match *self {
- Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
- Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
- Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
- Tuple(ref tys) => if tys.is_empty() {
- Some(PrimitiveType::Unit)
- } else {
- Some(PrimitiveType::Tuple)
- },
- RawPointer(..) => Some(PrimitiveType::RawPointer),
- BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
- BareFunction(..) => Some(PrimitiveType::Fn),
- Never => Some(PrimitiveType::Never),
- _ => None,
- }
- }
-
- pub fn is_generic(&self) -> bool {
- match *self {
- ResolvedPath { is_generic, .. } => is_generic,
- _ => false,
- }
- }
-
- pub fn is_self_type(&self) -> bool {
- match *self {
- Generic(ref name) => name == "Self",
- _ => false
- }
- }
-
- pub fn generics(&self) -> Option<Vec<Type>> {
- match *self {
- ResolvedPath { ref path, .. } => {
- path.segments.last().and_then(|seg| {
- if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
- Some(args.iter().filter_map(|arg| match arg {
- GenericArg::Type(ty) => Some(ty.clone()),
- _ => None,
- }).collect())
- } else {
- None
- }
- })
- }
- _ => None,
- }
- }
-
- pub fn bindings(&self) -> Option<&[TypeBinding]> {
- match *self {
- ResolvedPath { ref path, .. } => {
- path.segments.last().and_then(|seg| {
- if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
- Some(&**bindings)
- } else {
- None
- }
- })
- }
- _ => None
- }
- }
-
- pub fn is_full_generic(&self) -> bool {
- match *self {
- Type::Generic(_) => true,
- _ => false,
- }
- }
-
- pub fn projection(&self) -> Option<(&Type, DefId, &str)> {
- let (self_, trait_, name) = match self {
- QPath { ref self_type, ref trait_, ref name } => {
- (self_type, trait_, name)
- }
- _ => return None,
- };
- let trait_did = match **trait_ {
- ResolvedPath { did, .. } => did,
- _ => return None,
- };
- Some((&self_, trait_did, name))
- }
-
-}
-
-impl GetDefId for Type {
- fn def_id(&self) -> Option<DefId> {
- match *self {
- ResolvedPath { did, .. } => Some(did),
- Primitive(p) => crate::html::render::cache().primitive_locations.get(&p).cloned(),
- BorrowedRef { type_: box Generic(..), .. } =>
- Primitive(PrimitiveType::Reference).def_id(),
- BorrowedRef { ref type_, .. } => type_.def_id(),
- Tuple(ref tys) => if tys.is_empty() {
- Primitive(PrimitiveType::Unit).def_id()
- } else {
- Primitive(PrimitiveType::Tuple).def_id()
- },
- BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
- Never => Primitive(PrimitiveType::Never).def_id(),
- Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
- Array(..) => Primitive(PrimitiveType::Array).def_id(),
- RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
- QPath { ref self_type, .. } => self_type.def_id(),
- _ => None,
- }
- }
-}
-
-impl PrimitiveType {
- fn from_str(s: &str) -> Option<PrimitiveType> {
- match s {
- "isize" => Some(PrimitiveType::Isize),
- "i8" => Some(PrimitiveType::I8),
- "i16" => Some(PrimitiveType::I16),
- "i32" => Some(PrimitiveType::I32),
- "i64" => Some(PrimitiveType::I64),
- "i128" => Some(PrimitiveType::I128),
- "usize" => Some(PrimitiveType::Usize),
- "u8" => Some(PrimitiveType::U8),
- "u16" => Some(PrimitiveType::U16),
- "u32" => Some(PrimitiveType::U32),
- "u64" => Some(PrimitiveType::U64),
- "u128" => Some(PrimitiveType::U128),
- "bool" => Some(PrimitiveType::Bool),
- "char" => Some(PrimitiveType::Char),
- "str" => Some(PrimitiveType::Str),
- "f32" => Some(PrimitiveType::F32),
- "f64" => Some(PrimitiveType::F64),
- "array" => Some(PrimitiveType::Array),
- "slice" => Some(PrimitiveType::Slice),
- "tuple" => Some(PrimitiveType::Tuple),
- "unit" => Some(PrimitiveType::Unit),
- "pointer" => Some(PrimitiveType::RawPointer),
- "reference" => Some(PrimitiveType::Reference),
- "fn" => Some(PrimitiveType::Fn),
- "never" => Some(PrimitiveType::Never),
- _ => None,
- }
- }
-
- pub fn as_str(&self) -> &'static str {
- use self::PrimitiveType::*;
- match *self {
- Isize => "isize",
- I8 => "i8",
- I16 => "i16",
- I32 => "i32",
- I64 => "i64",
- I128 => "i128",
- Usize => "usize",
- U8 => "u8",
- U16 => "u16",
- U32 => "u32",
- U64 => "u64",
- U128 => "u128",
- F32 => "f32",
- F64 => "f64",
- Str => "str",
- Bool => "bool",
- Char => "char",
- Array => "array",
- Slice => "slice",
- Tuple => "tuple",
- Unit => "unit",
- RawPointer => "pointer",
- Reference => "reference",
- Fn => "fn",
- Never => "never",
- }
- }
-
- pub fn to_url_str(&self) -> &'static str {
- self.as_str()
- }
-}
-
-impl From<ast::IntTy> for PrimitiveType {
- fn from(int_ty: ast::IntTy) -> PrimitiveType {
- match int_ty {
- ast::IntTy::Isize => PrimitiveType::Isize,
- ast::IntTy::I8 => PrimitiveType::I8,
- ast::IntTy::I16 => PrimitiveType::I16,
- ast::IntTy::I32 => PrimitiveType::I32,
- ast::IntTy::I64 => PrimitiveType::I64,
- ast::IntTy::I128 => PrimitiveType::I128,
- }
- }
-}
-
-impl From<ast::UintTy> for PrimitiveType {
- fn from(uint_ty: ast::UintTy) -> PrimitiveType {
- match uint_ty {
- ast::UintTy::Usize => PrimitiveType::Usize,
- ast::UintTy::U8 => PrimitiveType::U8,
- ast::UintTy::U16 => PrimitiveType::U16,
- ast::UintTy::U32 => PrimitiveType::U32,
- ast::UintTy::U64 => PrimitiveType::U64,
- ast::UintTy::U128 => PrimitiveType::U128,
- }
- }
-}
-
-impl From<ast::FloatTy> for PrimitiveType {
- fn from(float_ty: ast::FloatTy) -> PrimitiveType {
- match float_ty {
- ast::FloatTy::F32 => PrimitiveType::F32,
- ast::FloatTy::F64 => PrimitiveType::F64,
- }
- }
-}
-
impl Clean<Type> for hir::Ty {
fn clean(&self, cx: &DocContext<'_>) -> Type {
use rustc::hir::*;
@@ -3310,14 +2035,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub enum Visibility {
- Public,
- Inherited,
- Crate,
- Restricted(DefId, Path),
-}
-
impl Clean<Visibility> for hir::Visibility {
fn clean(&self, cx: &DocContext<'_>) -> Visibility {
match self.node {
@@ -3339,22 +2056,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Struct {
- pub struct_type: doctree::StructType,
- pub generics: Generics,
- pub fields: Vec<Item>,
- pub fields_stripped: bool,
-}
-
-#[derive(Clone, Debug)]
-pub struct Union {
- pub struct_type: doctree::StructType,
- pub generics: Generics,
- pub fields: Vec<Item>,
- pub fields_stripped: bool,
-}
-
impl Clean<Item> for doctree::Struct<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3395,16 +2096,6 @@
}
}
-/// This is a more limited form of the standard Struct, different in that
-/// it lacks the things most items have (name, id, parameterization). Found
-/// only as a variant in an enum.
-#[derive(Clone, Debug)]
-pub struct VariantStruct {
- pub struct_type: doctree::StructType,
- pub fields: Vec<Item>,
- pub fields_stripped: bool,
-}
-
impl Clean<VariantStruct> for ::rustc::hir::VariantData {
fn clean(&self, cx: &DocContext<'_>) -> VariantStruct {
VariantStruct {
@@ -3415,13 +2106,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Enum {
- pub variants: IndexVec<VariantIdx, Item>,
- pub generics: Generics,
- pub variants_stripped: bool,
-}
-
impl Clean<Item> for doctree::Enum<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3441,11 +2125,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Variant {
- pub kind: VariantKind,
-}
-
impl Clean<Item> for doctree::Variant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3504,13 +2183,6 @@
}
}
-#[derive(Clone, Debug)]
-pub enum VariantKind {
- CLike,
- Tuple(Vec<Type>),
- Struct(VariantStruct),
-}
-
impl Clean<VariantKind> for hir::VariantData {
fn clean(&self, cx: &DocContext<'_>) -> VariantKind {
match self {
@@ -3522,31 +2194,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Span {
- pub filename: FileName,
- pub loline: usize,
- pub locol: usize,
- pub hiline: usize,
- pub hicol: usize,
- pub original: syntax_pos::Span,
-}
-
-impl Span {
- pub fn empty() -> Span {
- Span {
- filename: FileName::Anon(0),
- loline: 0, locol: 0,
- hiline: 0, hicol: 0,
- original: syntax_pos::DUMMY_SP,
- }
- }
-
- pub fn span(&self) -> syntax_pos::Span {
- self.original
- }
-}
-
impl Clean<Span> for syntax_pos::Span {
fn clean(&self, cx: &DocContext<'_>) -> Span {
if self.is_dummy() {
@@ -3568,19 +2215,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct Path {
- pub global: bool,
- pub res: Res,
- pub segments: Vec<PathSegment>,
-}
-
-impl Path {
- pub fn last_name(&self) -> &str {
- self.segments.last().expect("segments were empty").name.as_str()
- }
-}
-
impl Clean<Path> for hir::Path {
fn clean(&self, cx: &DocContext<'_>) -> Path {
Path {
@@ -3591,25 +2225,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericArg {
- Lifetime(Lifetime),
- Type(Type),
- Const(Constant),
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum GenericArgs {
- AngleBracketed {
- args: Vec<GenericArg>,
- bindings: Vec<TypeBinding>,
- },
- Parenthesized {
- inputs: Vec<Type>,
- output: Option<Type>,
- }
-}
-
impl Clean<GenericArgs> for hir::GenericArgs {
fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
if self.parenthesized {
@@ -3638,12 +2253,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct PathSegment {
- pub name: String,
- pub args: GenericArgs,
-}
-
impl Clean<PathSegment> for hir::PathSegment {
fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
PathSegment {
@@ -3727,12 +2336,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Typedef {
- pub type_: Type,
- pub generics: Generics,
-}
-
impl Clean<Item> for doctree::Typedef<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3751,12 +2354,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct OpaqueTy {
- pub bounds: Vec<GenericBound>,
- pub generics: Generics,
-}
-
impl Clean<Item> for doctree::OpaqueTy<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3775,14 +2372,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct BareFunctionDecl {
- pub unsafety: hir::Unsafety,
- pub generic_params: Vec<GenericParamDef>,
- pub decl: FnDecl,
- pub abi: Abi,
-}
-
impl Clean<BareFunctionDecl> for hir::BareFnTy {
fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
let (generic_params, decl) = enter_impl_trait(cx, || {
@@ -3797,16 +2386,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Static {
- pub type_: Type,
- pub mutability: Mutability,
- /// It's useful to have the value of a static documented, but I have no
- /// desire to represent expressions (that'd basically be all of the AST,
- /// which is huge!). So, have a string.
- pub expr: String,
-}
-
impl Clean<Item> for doctree::Static<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
@@ -3827,12 +2406,6 @@
}
}
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub struct Constant {
- pub type_: Type,
- pub expr: String,
-}
-
impl Clean<Item> for doctree::Constant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -3851,12 +2424,6 @@
}
}
-#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
-pub enum Mutability {
- Mutable,
- Immutable,
-}
-
impl Clean<Mutability> for hir::Mutability {
fn clean(&self, _: &DocContext<'_>) -> Mutability {
match self {
@@ -3866,12 +2433,6 @@
}
}
-#[derive(Clone, PartialEq, Debug)]
-pub enum ImplPolarity {
- Positive,
- Negative,
-}
-
impl Clean<ImplPolarity> for ty::ImplPolarity {
fn clean(&self, _: &DocContext<'_>) -> ImplPolarity {
match self {
@@ -3883,19 +2444,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Impl {
- pub unsafety: hir::Unsafety,
- pub generics: Generics,
- pub provided_trait_methods: FxHashSet<String>,
- pub trait_: Option<Type>,
- pub for_: Type,
- pub items: Vec<Item>,
- pub polarity: Option<ImplPolarity>,
- pub synthetic: bool,
- pub blanket_impl: Option<Type>,
-}
-
pub fn get_auto_trait_and_blanket_impls(
cx: &DocContext<'tcx>,
ty: Ty<'tcx>,
@@ -4115,20 +2663,6 @@
}
}
-#[derive(Clone, Debug)]
-pub enum Import {
- // use source as str;
- Simple(String, ImportSource),
- // use source::*;
- Glob(ImportSource)
-}
-
-#[derive(Clone, Debug)]
-pub struct ImportSource {
- pub path: Path,
- pub did: Option<DefId>,
-}
-
impl Clean<Item> for doctree::ForeignItem<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let inner = match self.kind {
@@ -4340,12 +2874,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Macro {
- pub source: String,
- pub imported_from: Option<String>,
-}
-
impl Clean<Item> for doctree::Macro<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = self.name.clean(cx);
@@ -4369,12 +2897,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct ProcMacro {
- pub kind: MacroKind,
- pub helpers: Vec<String>,
-}
-
impl Clean<Item> for doctree::ProcMacro<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
@@ -4393,22 +2915,6 @@
}
}
-#[derive(Clone, Debug)]
-pub struct Stability {
- pub level: stability::StabilityLevel,
- pub feature: Option<String>,
- pub since: String,
- pub deprecation: Option<Deprecation>,
- pub unstable_reason: Option<String>,
- pub issue: Option<NonZeroU32>,
-}
-
-#[derive(Clone, Debug)]
-pub struct Deprecation {
- pub since: Option<String>,
- pub note: Option<String>,
-}
-
impl Clean<Stability> for attr::Stability {
fn clean(&self, _: &DocContext<'_>) -> Stability {
Stability {
@@ -4451,33 +2957,6 @@
}
}
-/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
-/// `A: Send + Sync` in `Foo<A: Send + Sync>`).
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub struct TypeBinding {
- pub name: String,
- pub kind: TypeBindingKind,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum TypeBindingKind {
- Equality {
- ty: Type,
- },
- Constraint {
- bounds: Vec<GenericBound>,
- },
-}
-
-impl TypeBinding {
- pub fn ty(&self) -> &Type {
- match self.kind {
- TypeBindingKind::Equality { ref ty } => ty,
- _ => panic!("expected equality type binding for parenthesized generic args"),
- }
- }
-}
-
impl Clean<TypeBinding> for hir::TypeBinding {
fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
TypeBinding {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
new file mode 100644
index 0000000..bd3f2a3
--- /dev/null
+++ b/src/librustdoc/clean/types.rs
@@ -0,0 +1,1545 @@
+use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::default::Default;
+use std::{slice, vec};
+use std::num::NonZeroU32;
+use std::iter::FromIterator;
+use std::rc::Rc;
+use std::cell::RefCell;
+use std::sync::Arc;
+
+use rustc::middle::lang_items;
+use rustc::middle::stability;
+use rustc::hir;
+use rustc::hir::def::Res;
+use rustc::hir::def_id::{CrateNum, DefId};
+use rustc::ty::layout::VariantIdx;
+use rustc::util::nodemap::{FxHashMap, FxHashSet};
+use rustc_index::vec::IndexVec;
+use rustc_target::spec::abi::Abi;
+use syntax::ast::{self, Attribute, AttrStyle, AttrKind, Ident};
+use syntax::attr;
+use syntax::util::comments;
+use syntax::source_map::DUMMY_SP;
+use syntax_pos::hygiene::MacroKind;
+use syntax_pos::symbol::{Symbol, sym};
+use syntax_pos::{self, FileName};
+
+use crate::core::DocContext;
+use crate::clean::cfg::Cfg;
+use crate::clean::inline;
+use crate::clean::external_path;
+use crate::clean::types::Type::{QPath, ResolvedPath};
+use crate::doctree;
+use crate::html::item_type::ItemType;
+use crate::html::render::{cache, ExternalLocation};
+
+use self::Type::*;
+use self::ItemEnum::*;
+use self::SelfTy::*;
+use self::FunctionRetTy::*;
+
+thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = Default::default());
+
+#[derive(Clone, Debug)]
+pub struct Crate {
+ pub name: String,
+ pub version: Option<String>,
+ pub src: FileName,
+ pub module: Option<Item>,
+ pub externs: Vec<(CrateNum, ExternalCrate)>,
+ pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
+ // These are later on moved into `CACHEKEY`, leaving the map empty.
+ // Only here so that they can be filtered through the rustdoc passes.
+ pub external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>,
+ pub masked_crates: FxHashSet<CrateNum>,
+ pub collapsed: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct ExternalCrate {
+ pub name: String,
+ pub src: FileName,
+ pub attrs: Attributes,
+ pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
+ pub keywords: Vec<(DefId, String, Attributes)>,
+}
+
+/// Anything with a source location and set of attributes and, optionally, a
+/// name. That is, anything that can be documented. This doesn't correspond
+/// directly to the AST's concept of an item; it's a strict superset.
+#[derive(Clone)]
+pub struct Item {
+ /// Stringified span
+ pub source: Span,
+ /// Not everything has a name. E.g., impls
+ pub name: Option<String>,
+ pub attrs: Attributes,
+ pub inner: ItemEnum,
+ pub visibility: Visibility,
+ pub def_id: DefId,
+ pub stability: Option<Stability>,
+ pub deprecation: Option<Deprecation>,
+}
+
+impl fmt::Debug for Item {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let fake = MAX_DEF_ID.with(|m| m.borrow().get(&self.def_id.krate)
+ .map(|id| self.def_id >= *id).unwrap_or(false));
+ let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
+
+ fmt.debug_struct("Item")
+ .field("source", &self.source)
+ .field("name", &self.name)
+ .field("attrs", &self.attrs)
+ .field("inner", &self.inner)
+ .field("visibility", &self.visibility)
+ .field("def_id", def_id)
+ .field("stability", &self.stability)
+ .field("deprecation", &self.deprecation)
+ .finish()
+ }
+}
+
+impl Item {
+ /// Finds the `doc` attribute as a NameValue and returns the corresponding
+ /// value found.
+ pub fn doc_value(&self) -> Option<&str> {
+ self.attrs.doc_value()
+ }
+
+ /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
+ /// with newlines.
+ pub fn collapsed_doc_value(&self) -> Option<String> {
+ self.attrs.collapsed_doc_value()
+ }
+
+ pub fn links(&self) -> Vec<(String, String)> {
+ self.attrs.links(&self.def_id.krate)
+ }
+
+ pub fn is_crate(&self) -> bool {
+ match self.inner {
+ StrippedItem(box ModuleItem(Module { is_crate: true, ..})) |
+ ModuleItem(Module { is_crate: true, ..}) => true,
+ _ => false,
+ }
+ }
+ pub fn is_mod(&self) -> bool {
+ self.type_() == ItemType::Module
+ }
+ pub fn is_trait(&self) -> bool {
+ self.type_() == ItemType::Trait
+ }
+ pub fn is_struct(&self) -> bool {
+ self.type_() == ItemType::Struct
+ }
+ pub fn is_enum(&self) -> bool {
+ self.type_() == ItemType::Enum
+ }
+ pub fn is_variant(&self) -> bool {
+ self.type_() == ItemType::Variant
+ }
+ pub fn is_associated_type(&self) -> bool {
+ self.type_() == ItemType::AssocType
+ }
+ pub fn is_associated_const(&self) -> bool {
+ self.type_() == ItemType::AssocConst
+ }
+ pub fn is_method(&self) -> bool {
+ self.type_() == ItemType::Method
+ }
+ pub fn is_ty_method(&self) -> bool {
+ self.type_() == ItemType::TyMethod
+ }
+ pub fn is_typedef(&self) -> bool {
+ self.type_() == ItemType::Typedef
+ }
+ pub fn is_primitive(&self) -> bool {
+ self.type_() == ItemType::Primitive
+ }
+ pub fn is_union(&self) -> bool {
+ self.type_() == ItemType::Union
+ }
+ pub fn is_import(&self) -> bool {
+ self.type_() == ItemType::Import
+ }
+ pub fn is_extern_crate(&self) -> bool {
+ self.type_() == ItemType::ExternCrate
+ }
+ pub fn is_keyword(&self) -> bool {
+ self.type_() == ItemType::Keyword
+ }
+ pub fn is_stripped(&self) -> bool {
+ match self.inner { StrippedItem(..) => true, _ => false }
+ }
+ pub fn has_stripped_fields(&self) -> Option<bool> {
+ match self.inner {
+ StructItem(ref _struct) => Some(_struct.fields_stripped),
+ UnionItem(ref union) => Some(union.fields_stripped),
+ VariantItem(Variant { kind: VariantKind::Struct(ref vstruct)} ) => {
+ Some(vstruct.fields_stripped)
+ },
+ _ => None,
+ }
+ }
+
+ pub fn stability_class(&self) -> Option<String> {
+ self.stability.as_ref().and_then(|ref s| {
+ let mut classes = Vec::with_capacity(2);
+
+ if s.level == stability::Unstable {
+ classes.push("unstable");
+ }
+
+ if s.deprecation.is_some() {
+ classes.push("deprecated");
+ }
+
+ if classes.len() != 0 {
+ Some(classes.join(" "))
+ } else {
+ None
+ }
+ })
+ }
+
+ pub fn stable_since(&self) -> Option<&str> {
+ self.stability.as_ref().map(|s| &s.since[..])
+ }
+
+ pub fn is_non_exhaustive(&self) -> bool {
+ self.attrs.other_attrs.iter()
+ .any(|a| a.check_name(sym::non_exhaustive))
+ }
+
+ /// Returns a documentation-level item type from the item.
+ pub fn type_(&self) -> ItemType {
+ ItemType::from(self)
+ }
+
+ /// Returns the info in the item's `#[deprecated]` or `#[rustc_deprecated]` attributes.
+ ///
+ /// If the item is not deprecated, returns `None`.
+ pub fn deprecation(&self) -> Option<&Deprecation> {
+ self.deprecation
+ .as_ref()
+ .or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
+ }
+ pub fn is_default(&self) -> bool {
+ match self.inner {
+ ItemEnum::MethodItem(ref meth) => {
+ if let Some(defaultness) = meth.defaultness {
+ defaultness.has_value() && !defaultness.is_final()
+ } else {
+ false
+ }
+ }
+ _ => false,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub enum ItemEnum {
+ ExternCrateItem(String, Option<String>),
+ ImportItem(Import),
+ StructItem(Struct),
+ UnionItem(Union),
+ EnumItem(Enum),
+ FunctionItem(Function),
+ ModuleItem(Module),
+ TypedefItem(Typedef, bool /* is associated type */),
+ OpaqueTyItem(OpaqueTy, bool /* is associated type */),
+ StaticItem(Static),
+ ConstantItem(Constant),
+ TraitItem(Trait),
+ TraitAliasItem(TraitAlias),
+ ImplItem(Impl),
+ /// A method signature only. Used for required methods in traits (ie,
+ /// non-default-methods).
+ TyMethodItem(TyMethod),
+ /// A method with a body.
+ MethodItem(Method),
+ StructFieldItem(Type),
+ VariantItem(Variant),
+ /// `fn`s from an extern block
+ ForeignFunctionItem(Function),
+ /// `static`s from an extern block
+ ForeignStaticItem(Static),
+ /// `type`s from an extern block
+ ForeignTypeItem,
+ MacroItem(Macro),
+ ProcMacroItem(ProcMacro),
+ PrimitiveItem(PrimitiveType),
+ AssocConstItem(Type, Option<String>),
+ AssocTypeItem(Vec<GenericBound>, Option<Type>),
+ /// An item that has been stripped by a rustdoc pass
+ StrippedItem(Box<ItemEnum>),
+ KeywordItem(String),
+}
+
+impl ItemEnum {
+ pub fn is_associated(&self) -> bool {
+ match *self {
+ ItemEnum::TypedefItem(_, _) |
+ ItemEnum::AssocTypeItem(_, _) => true,
+ _ => false,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct Module {
+ pub items: Vec<Item>,
+ pub is_crate: bool,
+}
+
+pub struct ListAttributesIter<'a> {
+ attrs: slice::Iter<'a, ast::Attribute>,
+ current_list: vec::IntoIter<ast::NestedMetaItem>,
+ name: Symbol,
+}
+
+impl<'a> Iterator for ListAttributesIter<'a> {
+ type Item = ast::NestedMetaItem;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(nested) = self.current_list.next() {
+ return Some(nested);
+ }
+
+ for attr in &mut self.attrs {
+ if let Some(list) = attr.meta_item_list() {
+ if attr.check_name(self.name) {
+ self.current_list = list.into_iter();
+ if let Some(nested) = self.current_list.next() {
+ return Some(nested);
+ }
+ }
+ }
+ }
+
+ None
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let lower = self.current_list.len();
+ (lower, None)
+ }
+}
+
+pub trait AttributesExt {
+ /// Finds an attribute as List and returns the list of attributes nested inside.
+ fn lists(&self, name: Symbol) -> ListAttributesIter<'_>;
+}
+
+impl AttributesExt for [ast::Attribute] {
+ fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
+ ListAttributesIter {
+ attrs: self.iter(),
+ current_list: Vec::new().into_iter(),
+ name,
+ }
+ }
+}
+
+pub trait NestedAttributesExt {
+ /// Returns `true` if the attribute list contains a specific `Word`
+ fn has_word(self, word: Symbol) -> bool;
+}
+
+impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
+ fn has_word(self, word: Symbol) -> bool {
+ self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
+ }
+}
+
+/// A portion of documentation, extracted from a `#[doc]` attribute.
+///
+/// Each variant contains the line number within the complete doc-comment where the fragment
+/// starts, as well as the Span where the corresponding doc comment or attribute is located.
+///
+/// Included files are kept separate from inline doc comments so that proper line-number
+/// information can be given when a doctest fails. Sugared doc comments and "raw" doc comments are
+/// kept separate because of issue #42760.
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum DocFragment {
+ /// A doc fragment created from a `///` or `//!` doc comment.
+ SugaredDoc(usize, syntax_pos::Span, String),
+ /// A doc fragment created from a "raw" `#[doc=""]` attribute.
+ RawDoc(usize, syntax_pos::Span, String),
+ /// A doc fragment created from a `#[doc(include="filename")]` attribute. Contains both the
+ /// given filename and the file contents.
+ Include(usize, syntax_pos::Span, String, String),
+}
+
+impl DocFragment {
+ pub fn as_str(&self) -> &str {
+ match *self {
+ DocFragment::SugaredDoc(_, _, ref s) => &s[..],
+ DocFragment::RawDoc(_, _, ref s) => &s[..],
+ DocFragment::Include(_, _, _, ref s) => &s[..],
+ }
+ }
+
+ pub fn span(&self) -> syntax_pos::Span {
+ match *self {
+ DocFragment::SugaredDoc(_, span, _) |
+ DocFragment::RawDoc(_, span, _) |
+ DocFragment::Include(_, span, _, _) => span,
+ }
+ }
+}
+
+impl<'a> FromIterator<&'a DocFragment> for String {
+ fn from_iter<T>(iter: T) -> Self
+ where
+ T: IntoIterator<Item = &'a DocFragment>
+ {
+ iter.into_iter().fold(String::new(), |mut acc, frag| {
+ if !acc.is_empty() {
+ acc.push('\n');
+ }
+ match *frag {
+ DocFragment::SugaredDoc(_, _, ref docs)
+ | DocFragment::RawDoc(_, _, ref docs)
+ | DocFragment::Include(_, _, _, ref docs) =>
+ acc.push_str(docs),
+ }
+
+ acc
+ })
+ }
+}
+
+#[derive(Clone, Debug, Default)]
+pub struct Attributes {
+ pub doc_strings: Vec<DocFragment>,
+ pub other_attrs: Vec<ast::Attribute>,
+ pub cfg: Option<Arc<Cfg>>,
+ pub span: Option<syntax_pos::Span>,
+ /// map from Rust paths to resolved defs and potential URL fragments
+ pub links: Vec<(String, Option<DefId>, Option<String>)>,
+ pub inner_docs: bool,
+}
+
+impl Attributes {
+ /// Extracts the content from an attribute `#[doc(cfg(content))]`.
+ pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
+ use syntax::ast::NestedMetaItem::MetaItem;
+
+ if let ast::MetaItemKind::List(ref nmis) = mi.kind {
+ if nmis.len() == 1 {
+ if let MetaItem(ref cfg_mi) = nmis[0] {
+ if cfg_mi.check_name(sym::cfg) {
+ if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.kind {
+ if cfg_nmis.len() == 1 {
+ if let MetaItem(ref content_mi) = cfg_nmis[0] {
+ return Some(content_mi);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ None
+ }
+
+ /// Reads a `MetaItem` from within an attribute, looks for whether it is a
+ /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
+ /// its expansion.
+ pub fn extract_include(mi: &ast::MetaItem) -> Option<(String, String)> {
+ mi.meta_item_list().and_then(|list| {
+ for meta in list {
+ if meta.check_name(sym::include) {
+ // the actual compiled `#[doc(include="filename")]` gets expanded to
+ // `#[doc(include(file="filename", contents="file contents")]` so we need to
+ // look for that instead
+ return meta.meta_item_list().and_then(|list| {
+ let mut filename: Option<String> = None;
+ let mut contents: Option<String> = None;
+
+ for it in list {
+ if it.check_name(sym::file) {
+ if let Some(name) = it.value_str() {
+ filename = Some(name.to_string());
+ }
+ } else if it.check_name(sym::contents) {
+ if let Some(docs) = it.value_str() {
+ contents = Some(docs.to_string());
+ }
+ }
+ }
+
+ if let (Some(filename), Some(contents)) = (filename, contents) {
+ Some((filename, contents))
+ } else {
+ None
+ }
+ });
+ }
+ }
+
+ None
+ })
+ }
+
+ pub fn has_doc_flag(&self, flag: Symbol) -> bool {
+ for attr in &self.other_attrs {
+ if !attr.check_name(sym::doc) { continue; }
+
+ if let Some(items) = attr.meta_item_list() {
+ if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
+ return true;
+ }
+ }
+ }
+
+ false
+ }
+
+ pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes {
+ let mut doc_strings = vec![];
+ let mut sp = None;
+ let mut cfg = Cfg::True;
+ let mut doc_line = 0;
+
+ /// If `attr` is a doc comment, strips the leading and (if present)
+ /// trailing comments symbols, e.g. `///`, `/**`, and `*/`. Otherwise,
+ /// returns `attr` unchanged.
+ pub fn with_doc_comment_markers_stripped<T>(
+ attr: &Attribute,
+ f: impl FnOnce(&Attribute) -> T,
+ ) -> T {
+ match attr.kind {
+ AttrKind::Normal(_) => {
+ f(attr)
+ }
+ AttrKind::DocComment(comment) => {
+ let comment =
+ Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str()));
+ f(&Attribute {
+ kind: AttrKind::DocComment(comment),
+ id: attr.id,
+ style: attr.style,
+ span: attr.span,
+ })
+ }
+ }
+ }
+
+ let other_attrs = attrs.iter().filter_map(|attr| {
+ with_doc_comment_markers_stripped(attr, |attr| {
+ if attr.check_name(sym::doc) {
+ if let Some(mi) = attr.meta() {
+ if let Some(value) = mi.value_str() {
+ // Extracted #[doc = "..."]
+ let value = value.to_string();
+ let line = doc_line;
+ doc_line += value.lines().count();
+
+ if attr.is_doc_comment() {
+ doc_strings.push(DocFragment::SugaredDoc(line, attr.span, value));
+ } else {
+ doc_strings.push(DocFragment::RawDoc(line, attr.span, value));
+ }
+
+ if sp.is_none() {
+ sp = Some(attr.span);
+ }
+ return None;
+ } else if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
+ // Extracted #[doc(cfg(...))]
+ match Cfg::parse(cfg_mi) {
+ Ok(new_cfg) => cfg &= new_cfg,
+ Err(e) => diagnostic.span_err(e.span, e.msg),
+ }
+ return None;
+ } else if let Some((filename, contents)) = Attributes::extract_include(&mi)
+ {
+ let line = doc_line;
+ doc_line += contents.lines().count();
+ doc_strings.push(DocFragment::Include(line,
+ attr.span,
+ filename,
+ contents));
+ }
+ }
+ }
+ Some(attr.clone())
+ })
+ }).collect();
+
+ // treat #[target_feature(enable = "feat")] attributes as if they were
+ // #[doc(cfg(target_feature = "feat"))] attributes as well
+ for attr in attrs.lists(sym::target_feature) {
+ if attr.check_name(sym::enable) {
+ if let Some(feat) = attr.value_str() {
+ let meta = attr::mk_name_value_item_str(
+ Ident::with_dummy_span(sym::target_feature), feat, DUMMY_SP
+ );
+ if let Ok(feat_cfg) = Cfg::parse(&meta) {
+ cfg &= feat_cfg;
+ }
+ }
+ }
+ }
+
+ let inner_docs = attrs.iter()
+ .filter(|a| a.check_name(sym::doc))
+ .next()
+ .map_or(true, |a| a.style == AttrStyle::Inner);
+
+ Attributes {
+ doc_strings,
+ other_attrs,
+ cfg: if cfg == Cfg::True { None } else { Some(Arc::new(cfg)) },
+ span: sp,
+ links: vec![],
+ inner_docs,
+ }
+ }
+
+ /// Finds the `doc` attribute as a NameValue and returns the corresponding
+ /// value found.
+ pub fn doc_value(&self) -> Option<&str> {
+ self.doc_strings.first().map(|s| s.as_str())
+ }
+
+ /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
+ /// with newlines.
+ pub fn collapsed_doc_value(&self) -> Option<String> {
+ if !self.doc_strings.is_empty() {
+ Some(self.doc_strings.iter().collect())
+ } else {
+ None
+ }
+ }
+
+ /// Gets links as a vector
+ ///
+ /// Cache must be populated before call
+ pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> {
+ use crate::html::format::href;
+
+ self.links.iter().filter_map(|&(ref s, did, ref fragment)| {
+ match did {
+ Some(did) => {
+ if let Some((mut href, ..)) = href(did) {
+ if let Some(ref fragment) = *fragment {
+ href.push_str("#");
+ href.push_str(fragment);
+ }
+ Some((s.clone(), href))
+ } else {
+ None
+ }
+ }
+ None => {
+ if let Some(ref fragment) = *fragment {
+ let cache = cache();
+ let url = match cache.extern_locations.get(krate) {
+ Some(&(_, ref src, ExternalLocation::Local)) =>
+ src.to_str().expect("invalid file path"),
+ Some(&(_, _, ExternalLocation::Remote(ref s))) => s,
+ Some(&(_, _, ExternalLocation::Unknown)) | None =>
+ "https://doc.rust-lang.org/nightly",
+ };
+ // This is a primitive so the url is done "by hand".
+ let tail = fragment.find('#').unwrap_or_else(|| fragment.len());
+ Some((s.clone(),
+ format!("{}{}std/primitive.{}.html{}",
+ url,
+ if !url.ends_with('/') { "/" } else { "" },
+ &fragment[..tail],
+ &fragment[tail..])))
+ } else {
+ panic!("This isn't a primitive?!");
+ }
+ }
+ }
+ }).collect()
+ }
+}
+
+impl PartialEq for Attributes {
+ fn eq(&self, rhs: &Self) -> bool {
+ self.doc_strings == rhs.doc_strings &&
+ self.cfg == rhs.cfg &&
+ self.span == rhs.span &&
+ self.links == rhs.links &&
+ self.other_attrs.iter().map(|attr| attr.id).eq(rhs.other_attrs.iter().map(|attr| attr.id))
+ }
+}
+
+impl Eq for Attributes {}
+
+impl Hash for Attributes {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.doc_strings.hash(hasher);
+ self.cfg.hash(hasher);
+ self.span.hash(hasher);
+ self.links.hash(hasher);
+ for attr in &self.other_attrs {
+ attr.id.hash(hasher);
+ }
+ }
+}
+
+impl AttributesExt for Attributes {
+ fn lists(&self, name: Symbol) -> ListAttributesIter<'_> {
+ self.other_attrs.lists(name)
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum GenericBound {
+ TraitBound(PolyTrait, hir::TraitBoundModifier),
+ Outlives(Lifetime),
+}
+
+impl GenericBound {
+ pub fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
+ let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
+ let empty = cx.tcx.intern_substs(&[]);
+ let path = external_path(cx, cx.tcx.item_name(did),
+ Some(did), false, vec![], empty);
+ inline::record_extern_fqn(cx, did, TypeKind::Trait);
+ GenericBound::TraitBound(PolyTrait {
+ trait_: ResolvedPath {
+ path,
+ param_names: None,
+ did,
+ is_generic: false,
+ },
+ generic_params: Vec::new(),
+ }, hir::TraitBoundModifier::Maybe)
+ }
+
+ pub fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
+ use rustc::hir::TraitBoundModifier as TBM;
+ if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
+ if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
+ return true;
+ }
+ }
+ false
+ }
+
+ pub fn get_poly_trait(&self) -> Option<PolyTrait> {
+ if let GenericBound::TraitBound(ref p, _) = *self {
+ return Some(p.clone())
+ }
+ None
+ }
+
+ pub fn get_trait_type(&self) -> Option<Type> {
+ if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
+ Some(trait_.clone())
+ } else {
+ None
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct Lifetime(pub String);
+
+impl Lifetime {
+ pub fn get_ref<'a>(&'a self) -> &'a str {
+ let Lifetime(ref s) = *self;
+ let s: &'a str = s;
+ s
+ }
+
+ pub fn statik() -> Lifetime {
+ Lifetime("'static".to_string())
+ }
+}
+
+#[derive(Clone, Debug)]
+pub enum WherePredicate {
+ BoundPredicate { ty: Type, bounds: Vec<GenericBound> },
+ RegionPredicate { lifetime: Lifetime, bounds: Vec<GenericBound> },
+ EqPredicate { lhs: Type, rhs: Type },
+}
+
+impl WherePredicate {
+ pub fn get_bounds(&self) -> Option<&[GenericBound]> {
+ match *self {
+ WherePredicate::BoundPredicate { ref bounds, .. } => Some(bounds),
+ WherePredicate::RegionPredicate { ref bounds, .. } => Some(bounds),
+ _ => None,
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum GenericParamDefKind {
+ Lifetime,
+ Type {
+ did: DefId,
+ bounds: Vec<GenericBound>,
+ default: Option<Type>,
+ synthetic: Option<hir::SyntheticTyParamKind>,
+ },
+ Const {
+ did: DefId,
+ ty: Type,
+ },
+}
+
+impl GenericParamDefKind {
+ pub fn is_type(&self) -> bool {
+ match *self {
+ GenericParamDefKind::Type { .. } => true,
+ _ => false,
+ }
+ }
+
+ // FIXME(eddyb) this either returns the default of a type parameter, or the
+ // type of a `const` parameter. It seems that the intention is to *visit*
+ // any embedded types, but `get_type` seems to be the wrong name for that.
+ pub fn get_type(&self) -> Option<Type> {
+ match self {
+ GenericParamDefKind::Type { default, .. } => default.clone(),
+ GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
+ GenericParamDefKind::Lifetime => None,
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct GenericParamDef {
+ pub name: String,
+ pub kind: GenericParamDefKind,
+}
+
+impl GenericParamDef {
+ pub fn is_synthetic_type_param(&self) -> bool {
+ match self.kind {
+ GenericParamDefKind::Lifetime |
+ GenericParamDefKind::Const { .. } => false,
+ GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
+ }
+ }
+
+ pub fn is_type(&self) -> bool {
+ self.kind.is_type()
+ }
+
+ pub fn get_type(&self) -> Option<Type> {
+ self.kind.get_type()
+ }
+
+ pub fn get_bounds(&self) -> Option<&[GenericBound]> {
+ match self.kind {
+ GenericParamDefKind::Type { ref bounds, .. } => Some(bounds),
+ _ => None,
+ }
+ }
+}
+
+// maybe use a Generic enum and use Vec<Generic>?
+#[derive(Clone, Debug, Default)]
+pub struct Generics {
+ pub params: Vec<GenericParamDef>,
+ pub where_predicates: Vec<WherePredicate>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Method {
+ pub generics: Generics,
+ pub decl: FnDecl,
+ pub header: hir::FnHeader,
+ pub defaultness: Option<hir::Defaultness>,
+ pub all_types: Vec<Type>,
+ pub ret_types: Vec<Type>,
+}
+
+#[derive(Clone, Debug)]
+pub struct TyMethod {
+ pub header: hir::FnHeader,
+ pub decl: FnDecl,
+ pub generics: Generics,
+ pub all_types: Vec<Type>,
+ pub ret_types: Vec<Type>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Function {
+ pub decl: FnDecl,
+ pub generics: Generics,
+ pub header: hir::FnHeader,
+ pub all_types: Vec<Type>,
+ pub ret_types: Vec<Type>,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct FnDecl {
+ pub inputs: Arguments,
+ pub output: FunctionRetTy,
+ pub c_variadic: bool,
+ pub attrs: Attributes,
+}
+
+impl FnDecl {
+ pub fn self_type(&self) -> Option<SelfTy> {
+ self.inputs.values.get(0).and_then(|v| v.to_self())
+ }
+
+ /// Returns the sugared return type for an async function.
+ ///
+ /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
+ /// will return `i32`.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the return type does not match the expected sugaring for async
+ /// functions.
+ pub fn sugared_async_return_type(&self) -> FunctionRetTy {
+ match &self.output {
+ FunctionRetTy::Return(Type::ImplTrait(bounds)) => {
+ match &bounds[0] {
+ GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
+ let bindings = trait_.bindings().unwrap();
+ FunctionRetTy::Return(bindings[0].ty().clone())
+ }
+ _ => panic!("unexpected desugaring of async function"),
+ }
+ }
+ _ => panic!("unexpected desugaring of async function"),
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct Arguments {
+ pub values: Vec<Argument>,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct Argument {
+ pub type_: Type,
+ pub name: String,
+}
+
+#[derive(Clone, PartialEq, Debug)]
+pub enum SelfTy {
+ SelfValue,
+ SelfBorrowed(Option<Lifetime>, Mutability),
+ SelfExplicit(Type),
+}
+
+impl Argument {
+ pub fn to_self(&self) -> Option<SelfTy> {
+ if self.name != "self" {
+ return None;
+ }
+ if self.type_.is_self_type() {
+ return Some(SelfValue);
+ }
+ match self.type_ {
+ BorrowedRef{ref lifetime, mutability, ref type_} if type_.is_self_type() => {
+ Some(SelfBorrowed(lifetime.clone(), mutability))
+ }
+ _ => Some(SelfExplicit(self.type_.clone()))
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum FunctionRetTy {
+ Return(Type),
+ DefaultReturn,
+}
+
+impl GetDefId for FunctionRetTy {
+ fn def_id(&self) -> Option<DefId> {
+ match *self {
+ Return(ref ty) => ty.def_id(),
+ DefaultReturn => None,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct Trait {
+ pub auto: bool,
+ pub unsafety: hir::Unsafety,
+ pub items: Vec<Item>,
+ pub generics: Generics,
+ pub bounds: Vec<GenericBound>,
+ pub is_spotlight: bool,
+ pub is_auto: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct TraitAlias {
+ pub generics: Generics,
+ pub bounds: Vec<GenericBound>,
+}
+
+/// A trait reference, which may have higher ranked lifetimes.
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct PolyTrait {
+ pub trait_: Type,
+ pub generic_params: Vec<GenericParamDef>,
+}
+
+/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
+/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
+/// importantly, it does not preserve mutability or boxes.
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum Type {
+ /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
+ ResolvedPath {
+ path: Path,
+ param_names: Option<Vec<GenericBound>>,
+ did: DefId,
+ /// `true` if is a `T::Name` path for associated types.
+ is_generic: bool,
+ },
+ /// For parameterized types, so the consumer of the JSON don't go
+ /// looking for types which don't exist anywhere.
+ Generic(String),
+ /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
+ /// arrays, slices, and tuples.
+ Primitive(PrimitiveType),
+ /// `extern "ABI" fn`
+ BareFunction(Box<BareFunctionDecl>),
+ Tuple(Vec<Type>),
+ Slice(Box<Type>),
+ Array(Box<Type>, String),
+ Never,
+ RawPointer(Mutability, Box<Type>),
+ BorrowedRef {
+ lifetime: Option<Lifetime>,
+ mutability: Mutability,
+ type_: Box<Type>,
+ },
+
+ // `<Type as Trait>::Name`
+ QPath {
+ name: String,
+ self_type: Box<Type>,
+ trait_: Box<Type>
+ },
+
+ // `_`
+ Infer,
+
+ // `impl TraitA + TraitB + ...`
+ ImplTrait(Vec<GenericBound>),
+}
+
+#[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
+pub enum PrimitiveType {
+ Isize, I8, I16, I32, I64, I128,
+ Usize, U8, U16, U32, U64, U128,
+ F32, F64,
+ Char,
+ Bool,
+ Str,
+ Slice,
+ Array,
+ Tuple,
+ Unit,
+ RawPointer,
+ Reference,
+ Fn,
+ Never,
+}
+
+#[derive(Clone, Copy, Debug)]
+pub enum TypeKind {
+ Enum,
+ Function,
+ Module,
+ Const,
+ Static,
+ Struct,
+ Union,
+ Trait,
+ Typedef,
+ Foreign,
+ Macro,
+ Attr,
+ Derive,
+ TraitAlias,
+}
+
+pub trait GetDefId {
+ fn def_id(&self) -> Option<DefId>;
+}
+
+impl<T: GetDefId> GetDefId for Option<T> {
+ fn def_id(&self) -> Option<DefId> {
+ self.as_ref().and_then(|d| d.def_id())
+ }
+}
+
+impl Type {
+ pub fn primitive_type(&self) -> Option<PrimitiveType> {
+ match *self {
+ Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
+ Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
+ Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
+ Tuple(ref tys) => if tys.is_empty() {
+ Some(PrimitiveType::Unit)
+ } else {
+ Some(PrimitiveType::Tuple)
+ },
+ RawPointer(..) => Some(PrimitiveType::RawPointer),
+ BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
+ BareFunction(..) => Some(PrimitiveType::Fn),
+ Never => Some(PrimitiveType::Never),
+ _ => None,
+ }
+ }
+
+ pub fn is_generic(&self) -> bool {
+ match *self {
+ ResolvedPath { is_generic, .. } => is_generic,
+ _ => false,
+ }
+ }
+
+ pub fn is_self_type(&self) -> bool {
+ match *self {
+ Generic(ref name) => name == "Self",
+ _ => false
+ }
+ }
+
+ pub fn generics(&self) -> Option<Vec<Type>> {
+ match *self {
+ ResolvedPath { ref path, .. } => {
+ path.segments.last().and_then(|seg| {
+ if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+ Some(args.iter().filter_map(|arg| match arg {
+ GenericArg::Type(ty) => Some(ty.clone()),
+ _ => None,
+ }).collect())
+ } else {
+ None
+ }
+ })
+ }
+ _ => None,
+ }
+ }
+
+ pub fn bindings(&self) -> Option<&[TypeBinding]> {
+ match *self {
+ ResolvedPath { ref path, .. } => {
+ path.segments.last().and_then(|seg| {
+ if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
+ Some(&**bindings)
+ } else {
+ None
+ }
+ })
+ }
+ _ => None
+ }
+ }
+
+ pub fn is_full_generic(&self) -> bool {
+ match *self {
+ Type::Generic(_) => true,
+ _ => false,
+ }
+ }
+
+ pub fn projection(&self) -> Option<(&Type, DefId, &str)> {
+ let (self_, trait_, name) = match self {
+ QPath { ref self_type, ref trait_, ref name } => {
+ (self_type, trait_, name)
+ }
+ _ => return None,
+ };
+ let trait_did = match **trait_ {
+ ResolvedPath { did, .. } => did,
+ _ => return None,
+ };
+ Some((&self_, trait_did, name))
+ }
+
+}
+
+impl GetDefId for Type {
+ fn def_id(&self) -> Option<DefId> {
+ match *self {
+ ResolvedPath { did, .. } => Some(did),
+ Primitive(p) => crate::html::render::cache().primitive_locations.get(&p).cloned(),
+ BorrowedRef { type_: box Generic(..), .. } =>
+ Primitive(PrimitiveType::Reference).def_id(),
+ BorrowedRef { ref type_, .. } => type_.def_id(),
+ Tuple(ref tys) => if tys.is_empty() {
+ Primitive(PrimitiveType::Unit).def_id()
+ } else {
+ Primitive(PrimitiveType::Tuple).def_id()
+ },
+ BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
+ Never => Primitive(PrimitiveType::Never).def_id(),
+ Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
+ Array(..) => Primitive(PrimitiveType::Array).def_id(),
+ RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
+ QPath { ref self_type, .. } => self_type.def_id(),
+ _ => None,
+ }
+ }
+}
+
+impl PrimitiveType {
+ pub fn from_str(s: &str) -> Option<PrimitiveType> {
+ match s {
+ "isize" => Some(PrimitiveType::Isize),
+ "i8" => Some(PrimitiveType::I8),
+ "i16" => Some(PrimitiveType::I16),
+ "i32" => Some(PrimitiveType::I32),
+ "i64" => Some(PrimitiveType::I64),
+ "i128" => Some(PrimitiveType::I128),
+ "usize" => Some(PrimitiveType::Usize),
+ "u8" => Some(PrimitiveType::U8),
+ "u16" => Some(PrimitiveType::U16),
+ "u32" => Some(PrimitiveType::U32),
+ "u64" => Some(PrimitiveType::U64),
+ "u128" => Some(PrimitiveType::U128),
+ "bool" => Some(PrimitiveType::Bool),
+ "char" => Some(PrimitiveType::Char),
+ "str" => Some(PrimitiveType::Str),
+ "f32" => Some(PrimitiveType::F32),
+ "f64" => Some(PrimitiveType::F64),
+ "array" => Some(PrimitiveType::Array),
+ "slice" => Some(PrimitiveType::Slice),
+ "tuple" => Some(PrimitiveType::Tuple),
+ "unit" => Some(PrimitiveType::Unit),
+ "pointer" => Some(PrimitiveType::RawPointer),
+ "reference" => Some(PrimitiveType::Reference),
+ "fn" => Some(PrimitiveType::Fn),
+ "never" => Some(PrimitiveType::Never),
+ _ => None,
+ }
+ }
+
+ pub fn as_str(&self) -> &'static str {
+ use self::PrimitiveType::*;
+ match *self {
+ Isize => "isize",
+ I8 => "i8",
+ I16 => "i16",
+ I32 => "i32",
+ I64 => "i64",
+ I128 => "i128",
+ Usize => "usize",
+ U8 => "u8",
+ U16 => "u16",
+ U32 => "u32",
+ U64 => "u64",
+ U128 => "u128",
+ F32 => "f32",
+ F64 => "f64",
+ Str => "str",
+ Bool => "bool",
+ Char => "char",
+ Array => "array",
+ Slice => "slice",
+ Tuple => "tuple",
+ Unit => "unit",
+ RawPointer => "pointer",
+ Reference => "reference",
+ Fn => "fn",
+ Never => "never",
+ }
+ }
+
+ pub fn to_url_str(&self) -> &'static str {
+ self.as_str()
+ }
+}
+
+impl From<ast::IntTy> for PrimitiveType {
+ fn from(int_ty: ast::IntTy) -> PrimitiveType {
+ match int_ty {
+ ast::IntTy::Isize => PrimitiveType::Isize,
+ ast::IntTy::I8 => PrimitiveType::I8,
+ ast::IntTy::I16 => PrimitiveType::I16,
+ ast::IntTy::I32 => PrimitiveType::I32,
+ ast::IntTy::I64 => PrimitiveType::I64,
+ ast::IntTy::I128 => PrimitiveType::I128,
+ }
+ }
+}
+
+impl From<ast::UintTy> for PrimitiveType {
+ fn from(uint_ty: ast::UintTy) -> PrimitiveType {
+ match uint_ty {
+ ast::UintTy::Usize => PrimitiveType::Usize,
+ ast::UintTy::U8 => PrimitiveType::U8,
+ ast::UintTy::U16 => PrimitiveType::U16,
+ ast::UintTy::U32 => PrimitiveType::U32,
+ ast::UintTy::U64 => PrimitiveType::U64,
+ ast::UintTy::U128 => PrimitiveType::U128,
+ }
+ }
+}
+
+impl From<ast::FloatTy> for PrimitiveType {
+ fn from(float_ty: ast::FloatTy) -> PrimitiveType {
+ match float_ty {
+ ast::FloatTy::F32 => PrimitiveType::F32,
+ ast::FloatTy::F64 => PrimitiveType::F64,
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum Visibility {
+ Public,
+ Inherited,
+ Crate,
+ Restricted(DefId, Path),
+}
+
+#[derive(Clone, Debug)]
+pub struct Struct {
+ pub struct_type: doctree::StructType,
+ pub generics: Generics,
+ pub fields: Vec<Item>,
+ pub fields_stripped: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct Union {
+ pub struct_type: doctree::StructType,
+ pub generics: Generics,
+ pub fields: Vec<Item>,
+ pub fields_stripped: bool,
+}
+
+/// This is a more limited form of the standard Struct, different in that
+/// it lacks the things most items have (name, id, parameterization). Found
+/// only as a variant in an enum.
+#[derive(Clone, Debug)]
+pub struct VariantStruct {
+ pub struct_type: doctree::StructType,
+ pub fields: Vec<Item>,
+ pub fields_stripped: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct Enum {
+ pub variants: IndexVec<VariantIdx, Item>,
+ pub generics: Generics,
+ pub variants_stripped: bool,
+}
+
+#[derive(Clone, Debug)]
+pub struct Variant {
+ pub kind: VariantKind,
+}
+
+#[derive(Clone, Debug)]
+pub enum VariantKind {
+ CLike,
+ Tuple(Vec<Type>),
+ Struct(VariantStruct),
+}
+
+#[derive(Clone, Debug)]
+pub struct Span {
+ pub filename: FileName,
+ pub loline: usize,
+ pub locol: usize,
+ pub hiline: usize,
+ pub hicol: usize,
+ pub original: syntax_pos::Span,
+}
+
+impl Span {
+ pub fn empty() -> Span {
+ Span {
+ filename: FileName::Anon(0),
+ loline: 0, locol: 0,
+ hiline: 0, hicol: 0,
+ original: syntax_pos::DUMMY_SP,
+ }
+ }
+
+ pub fn span(&self) -> syntax_pos::Span {
+ self.original
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct Path {
+ pub global: bool,
+ pub res: Res,
+ pub segments: Vec<PathSegment>,
+}
+
+impl Path {
+ pub fn last_name(&self) -> &str {
+ self.segments.last().expect("segments were empty").name.as_str()
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum GenericArg {
+ Lifetime(Lifetime),
+ Type(Type),
+ Const(Constant),
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum GenericArgs {
+ AngleBracketed {
+ args: Vec<GenericArg>,
+ bindings: Vec<TypeBinding>,
+ },
+ Parenthesized {
+ inputs: Vec<Type>,
+ output: Option<Type>,
+ }
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct PathSegment {
+ pub name: String,
+ pub args: GenericArgs,
+}
+
+#[derive(Clone, Debug)]
+pub struct Typedef {
+ pub type_: Type,
+ pub generics: Generics,
+}
+
+#[derive(Clone, Debug)]
+pub struct OpaqueTy {
+ pub bounds: Vec<GenericBound>,
+ pub generics: Generics,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct BareFunctionDecl {
+ pub unsafety: hir::Unsafety,
+ pub generic_params: Vec<GenericParamDef>,
+ pub decl: FnDecl,
+ pub abi: Abi,
+}
+
+#[derive(Clone, Debug)]
+pub struct Static {
+ pub type_: Type,
+ pub mutability: Mutability,
+ /// It's useful to have the value of a static documented, but I have no
+ /// desire to represent expressions (that'd basically be all of the AST,
+ /// which is huge!). So, have a string.
+ pub expr: String,
+}
+
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub struct Constant {
+ pub type_: Type,
+ pub expr: String,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
+pub enum Mutability {
+ Mutable,
+ Immutable,
+}
+
+#[derive(Clone, PartialEq, Debug)]
+pub enum ImplPolarity {
+ Positive,
+ Negative,
+}
+
+#[derive(Clone, Debug)]
+pub struct Impl {
+ pub unsafety: hir::Unsafety,
+ pub generics: Generics,
+ pub provided_trait_methods: FxHashSet<String>,
+ pub trait_: Option<Type>,
+ pub for_: Type,
+ pub items: Vec<Item>,
+ pub polarity: Option<ImplPolarity>,
+ pub synthetic: bool,
+ pub blanket_impl: Option<Type>,
+}
+
+#[derive(Clone, Debug)]
+pub enum Import {
+ // use source as str;
+ Simple(String, ImportSource),
+ // use source::*;
+ Glob(ImportSource)
+}
+
+#[derive(Clone, Debug)]
+pub struct ImportSource {
+ pub path: Path,
+ pub did: Option<DefId>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Macro {
+ pub source: String,
+ pub imported_from: Option<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct ProcMacro {
+ pub kind: MacroKind,
+ pub helpers: Vec<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Stability {
+ pub level: stability::StabilityLevel,
+ pub feature: Option<String>,
+ pub since: String,
+ pub deprecation: Option<Deprecation>,
+ pub unstable_reason: Option<String>,
+ pub issue: Option<NonZeroU32>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Deprecation {
+ pub since: Option<String>,
+ pub note: Option<String>,
+}
+
+/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
+/// `A: Send + Sync` in `Foo<A: Send + Sync>`).
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub struct TypeBinding {
+ pub name: String,
+ pub kind: TypeBindingKind,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
+pub enum TypeBindingKind {
+ Equality {
+ ty: Type,
+ },
+ Constraint {
+ bounds: Vec<GenericBound>,
+ },
+}
+
+impl TypeBinding {
+ pub fn ty(&self) -> &Type {
+ match self.kind {
+ TypeBindingKind::Equality { ref ty } => ty,
+ _ => panic!("expected equality type binding for parenthesized generic args"),
+ }
+ }
+}
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 6cf062d..b9cede7 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -495,11 +495,13 @@
///
/// let os_str = OsStr::new("foo");
/// ```
+ #[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
s.as_ref()
}
+ #[inline]
fn from_inner(inner: &Slice) -> &OsStr {
unsafe { &*(inner as *const Slice as *const OsStr) }
}
@@ -658,6 +660,7 @@
///
/// Note: it is *crucial* that this API is private, to avoid
/// revealing the internal, platform-specific encodings.
+ #[inline]
fn bytes(&self) -> &[u8] {
unsafe { &*(&self.inner as *const _ as *const [u8]) }
}
@@ -797,6 +800,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
+ #[inline]
fn eq(&self, other: &OsStr) -> bool {
self.bytes().eq(other.bytes())
}
@@ -804,6 +808,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
+ #[inline]
fn eq(&self, other: &str) -> bool {
*self == *OsStr::new(other)
}
@@ -811,6 +816,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
+ #[inline]
fn eq(&self, other: &OsStr) -> bool {
*other == *OsStr::new(self)
}
@@ -944,6 +950,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
+ #[inline]
fn as_ref(&self) -> &OsStr {
OsStr::from_inner(Slice::from_str(self))
}
@@ -951,6 +958,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
+ #[inline]
fn as_ref(&self) -> &OsStr {
(&**self).as_ref()
}
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index e451e0c..ef260f9 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -128,6 +128,7 @@
}
impl Slice {
+ #[inline]
pub fn from_str(s: &str) -> &Slice {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}
diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs
index a2608ad..eb8a881 100644
--- a/src/libstd/sys_common/os_str_bytes.rs
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -139,10 +139,12 @@
}
impl Slice {
+ #[inline]
fn from_u8_slice(s: &[u8]) -> &Slice {
unsafe { mem::transmute(s) }
}
+ #[inline]
pub fn from_str(s: &str) -> &Slice {
Slice::from_u8_slice(s.as_bytes())
}
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index b2e8d85..f0c5fb3 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1518,6 +1518,7 @@
crate fn print_variant(&mut self, v: &ast::Variant) {
self.head("");
+ self.print_visibility(&v.vis);
let generics = ast::Generics::default();
self.print_struct(&v.data, &generics, v.ident, v.span, false);
match v.disr_expr {
diff --git a/src/test/pretty/enum-variant-vis.rs b/src/test/pretty/enum-variant-vis.rs
new file mode 100644
index 0000000..a3e8178
--- /dev/null
+++ b/src/test/pretty/enum-variant-vis.rs
@@ -0,0 +1,8 @@
+// pp-exact
+
+// Check that the visibility is printed on an enum variant.
+
+fn main() { }
+
+#[cfg(FALSE)]
+enum Foo { pub V, }
diff --git a/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs
new file mode 100644
index 0000000..c8c2702
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs
@@ -0,0 +1,15 @@
+// edition:2018
+
+struct Ia<S>(S);
+
+impl<S> Ia<S> {
+ fn partial(_: S) {}
+ fn full(self) {}
+
+ async fn crash(self) {
+ Self::partial(self.0);
+ Self::full(self); //~ ERROR use of moved value: `self`
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr
new file mode 100644
index 0000000..9177b83
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `self`
+ --> $DIR/issue-66958-non-copy-infered-type-arg.rs:11:20
+ |
+LL | Self::partial(self.0);
+ | ------ value moved here
+LL | Self::full(self);
+ | ^^^^ value used here after partial move
+ |
+ = note: move occurs because `self.0` has type `S`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/attributes/field-attributes-vis-unresolved.rs b/src/test/ui/attributes/field-attributes-vis-unresolved.rs
new file mode 100644
index 0000000..d1bd2a1
--- /dev/null
+++ b/src/test/ui/attributes/field-attributes-vis-unresolved.rs
@@ -0,0 +1,25 @@
+// Non-builtin attributes do not mess with field visibility resolution (issue #67006).
+
+mod internal {
+ struct S {
+ #[rustfmt::skip]
+ pub(in crate::internal) field: u8 // OK
+ }
+
+ struct Z(
+ #[rustfmt::skip]
+ pub(in crate::internal) u8 // OK
+ );
+}
+
+struct S {
+ #[rustfmt::skip]
+ pub(in nonexistent) field: u8 //~ ERROR failed to resolve
+}
+
+struct Z(
+ #[rustfmt::skip]
+ pub(in nonexistent) u8 //~ ERROR failed to resolve
+);
+
+fn main() {}
diff --git a/src/test/ui/attributes/field-attributes-vis-unresolved.stderr b/src/test/ui/attributes/field-attributes-vis-unresolved.stderr
new file mode 100644
index 0000000..41c3cea
--- /dev/null
+++ b/src/test/ui/attributes/field-attributes-vis-unresolved.stderr
@@ -0,0 +1,15 @@
+error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
+ --> $DIR/field-attributes-vis-unresolved.rs:17:12
+ |
+LL | pub(in nonexistent) field: u8
+ | ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+
+error[E0433]: failed to resolve: maybe a missing crate `nonexistent`?
+ --> $DIR/field-attributes-vis-unresolved.rs:22:12
+ |
+LL | pub(in nonexistent) u8
+ | ^^^^^^^^^^^ maybe a missing crate `nonexistent`?
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr
new file mode 100644
index 0000000..2a7461f
--- /dev/null
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.polonius.stderr
@@ -0,0 +1,56 @@
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/expect-region-supply-region.rs:18:9
+ |
+LL | let mut f: Option<&u32> = None;
+ | ----- `f` is declared here, outside of the closure body
+LL | closure_expecting_bound(|x| {
+ | - `x` is a reference that is only valid in the closure body
+LL | f = Some(x);
+ | ^^^^^^^^^^^ `x` escapes the closure body here
+
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/expect-region-supply-region.rs:28:9
+ |
+LL | let mut f: Option<&u32> = None;
+ | ----- `f` is declared here, outside of the closure body
+LL | closure_expecting_bound(|x: &u32| {
+ | - `x` is a reference that is only valid in the closure body
+LL | f = Some(x);
+ | ^^^^^^^^^^^ `x` escapes the closure body here
+
+error: lifetime may not live long enough
+ --> $DIR/expect-region-supply-region.rs:37:30
+ |
+LL | fn expect_bound_supply_named<'x>() {
+ | -- lifetime `'x` defined here
+...
+LL | closure_expecting_bound(|x: &'x u32| {
+ | ^ - let's call the lifetime of this reference `'1`
+ | |
+ | requires that `'1` must outlive `'x`
+
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/expect-region-supply-region.rs:42:9
+ |
+LL | let mut f: Option<&u32> = None;
+ | ----- `f` is declared here, outside of the closure body
+...
+LL | closure_expecting_bound(|x: &'x u32| {
+ | - `x` is a reference that is only valid in the closure body
+...
+LL | f = Some(x);
+ | ^^^^^^^^^^^ `x` escapes the closure body here
+
+error: lifetime may not live long enough
+ --> $DIR/expect-region-supply-region.rs:37:30
+ |
+LL | fn expect_bound_supply_named<'x>() {
+ | -- lifetime `'x` defined here
+...
+LL | closure_expecting_bound(|x: &'x u32| {
+ | ^ requires that `'x` must outlive `'static`
+ |
+ = help: consider replacing `'x` with `'static`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/closures/issue-67123.rs b/src/test/ui/closures/issue-67123.rs
new file mode 100644
index 0000000..014c530
--- /dev/null
+++ b/src/test/ui/closures/issue-67123.rs
@@ -0,0 +1,5 @@
+fn foo<T>(t: T) {
+ || { t; t; }; //~ ERROR: use of moved value
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/issue-67123.stderr b/src/test/ui/closures/issue-67123.stderr
new file mode 100644
index 0000000..b2e875b
--- /dev/null
+++ b/src/test/ui/closures/issue-67123.stderr
@@ -0,0 +1,15 @@
+error[E0382]: use of moved value: `t`
+ --> $DIR/issue-67123.rs:2:13
+ |
+LL | fn foo<T>(t: T) {
+ | - help: consider restricting this bound: `T: Copy`
+LL | || { t; t; };
+ | - ^ value used here after move
+ | |
+ | value moved here
+ |
+ = note: move occurs because `t` has type `T`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
new file mode 100644
index 0000000..558d643
--- /dev/null
+++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.polonius.stderr
@@ -0,0 +1,68 @@
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:22:1
+ |
+LL | / fn no_hrtb<'b,T>(mut t: T)
+LL | | where T : Bar<&'b isize>
+LL | | {
+LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
+LL | | // `&mut T : Bar<&'b isize>`.
+LL | | no_hrtb(&mut t);
+ | | --------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = note: `#[warn(unconditional_recursion)]` on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:30:1
+ |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where T : for<'b> Bar<&'b isize>
+LL | | {
+LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
+... |
+LL | | bar_hrtb(&mut t);
+ | | ---------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:39:1
+ |
+LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T)
+LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
+LL | | {
+LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
+... |
+LL | | foo_hrtb_bar_not(&mut t);
+ | | ------------------------ recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: higher-ranked subtype error
+ --> $DIR/hrtb-perfect-forwarding.rs:46:5
+ |
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:49:1
+ |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
+LL | | {
+LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`.
+LL | | foo_hrtb_bar_hrtb(&mut t);
+ | | ------------------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr
new file mode 100644
index 0000000..72e8fa3
--- /dev/null
+++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.polonius.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/error-handling.rs:13:56
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
+ | -- -- lifetime `'b` defined here ^^^^^^^^^ opaque type requires that `'a` must outlive `'b`
+ | |
+ | lifetime `'a` defined here
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.rs b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.rs
new file mode 100644
index 0000000..a496e58
--- /dev/null
+++ b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.rs
@@ -0,0 +1,27 @@
+// Pin's PartialEq implementation allowed to access the pointer allowing for
+// unsoundness by using Rc::get_mut to move value within Rc.
+// See https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73 for more details.
+
+use std::ops::Deref;
+use std::pin::Pin;
+use std::rc::Rc;
+
+struct Apple;
+
+impl Deref for Apple {
+ type Target = Apple;
+ fn deref(&self) -> &Apple {
+ &Apple
+ }
+}
+
+impl PartialEq<Rc<Apple>> for Apple {
+ fn eq(&self, _rc: &Rc<Apple>) -> bool {
+ unreachable!()
+ }
+}
+
+fn main() {
+ let _ = Pin::new(Apple) == Rc::pin(Apple);
+ //~^ ERROR type mismatch resolving
+}
diff --git a/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
new file mode 100644
index 0000000..3330d60
--- /dev/null
+++ b/src/test/ui/issues/issue-67039-unsound-pin-partialeq.stderr
@@ -0,0 +1,13 @@
+error[E0271]: type mismatch resolving `<std::rc::Rc<Apple> as std::ops::Deref>::Target == std::rc::Rc<Apple>`
+ --> $DIR/issue-67039-unsound-pin-partialeq.rs:25:29
+ |
+LL | let _ = Pin::new(Apple) == Rc::pin(Apple);
+ | ^^ expected struct `Apple`, found struct `std::rc::Rc`
+ |
+ = note: expected type `Apple`
+ found struct `std::rc::Rc<Apple>`
+ = note: required because of the requirements on the impl of `std::cmp::PartialEq<std::pin::Pin<std::rc::Rc<Apple>>>` for `std::pin::Pin<Apple>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr b/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr
new file mode 100644
index 0000000..8157446
--- /dev/null
+++ b/src/test/ui/nll/outlives-suggestion-simple.polonius.stderr
@@ -0,0 +1,121 @@
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:6:5
+ |
+LL | fn foo1<'a, 'b>(x: &'a usize) -> &'b usize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x
+ | ^ returning this value requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:10:5
+ |
+LL | fn foo2<'a>(x: &'a usize) -> &'static usize {
+ | -- lifetime `'a` defined here
+LL | x
+ | ^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:14:5
+ |
+LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | (x, y)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:14:5
+ |
+LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | (x, y)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:22:5
+ |
+LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (x, x)
+ | ^^^^^^ returning this value requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:22:5
+ |
+LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (x, x)
+ | ^^^^^^ returning this value requires that `'a` must outlive `'c`
+ |
+ = help: consider adding the following bound: `'a: 'c`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:31:9
+ |
+LL | pub fn foo<'a>(x: &'a usize) -> Self {
+ | -- lifetime `'a` defined here
+LL | Foo { x }
+ | ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:41:9
+ |
+LL | impl<'a> Bar<'a> {
+ | -- lifetime `'a` defined here
+LL | pub fn get<'b>(&self) -> &'b usize {
+ | -- lifetime `'b` defined here
+LL | self.x
+ | ^^^^^^ returning this value requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/outlives-suggestion-simple.rs:52:9
+ |
+LL | impl<'a> Baz<'a> {
+ | -- lifetime `'a` defined here
+LL | fn get<'b>(&'b self) -> &'a i32 {
+ | -- lifetime `'b` defined here
+LL | self.x
+ | ^^^^^^ returning this value requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/outlives-suggestion-simple.rs:73:9
+ |
+LL | fn get_bar(&self) -> Bar2 {
+ | -----
+ | |
+ | `self` is declared here, outside of the function body
+ | `self` is a reference that is only valid in the function body
+LL | Bar2::new(&self)
+ | ^^^^^^^^^^^^^^^^ `self` escapes the function body here
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/nll/polonius/subset-relations.rs b/src/test/ui/nll/polonius/subset-relations.rs
new file mode 100644
index 0000000..3f6f67e
--- /dev/null
+++ b/src/test/ui/nll/polonius/subset-relations.rs
@@ -0,0 +1,30 @@
+// Checks that Polonius can compute cases of universal regions errors:
+// "illegal subset relation errors", cases where analysis finds that
+// two free regions outlive each other, without any evidence that this
+// relation holds.
+
+// ignore-compare-mode-nll
+// compile-flags: -Z borrowck=mir -Zpolonius
+
+// returning `y` requires that `'b: 'a`, but it's not known to be true
+fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
+ y //~ ERROR
+}
+
+// `'b: 'a` is explicitly declared
+fn valid_subset<'a, 'b: 'a>(x: &'a u32, y: &'b u32) -> &'a u32 {
+ y
+}
+
+// because of `x`, it is implied that `'b: 'a` holds
+fn implied_bounds_subset<'a, 'b>(x: &'a &'b mut u32) -> &'a u32 {
+ x
+}
+
+// `'b: 'a` is declared, and `'a: 'c` is known via implied bounds:
+// `'b: 'c` is therefore known to hold transitively
+fn transitively_valid_subset<'a, 'b: 'a, 'c>(x: &'c &'a u32, y: &'b u32) -> &'c u32 {
+ y
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/polonius/subset-relations.stderr b/src/test/ui/nll/polonius/subset-relations.stderr
new file mode 100644
index 0000000..6364510
--- /dev/null
+++ b/src/test/ui/nll/polonius/subset-relations.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/subset-relations.rs:11:5
+ |
+LL | fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | y
+ | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr b/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr
new file mode 100644
index 0000000..d5bcdf6
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/closure-substs.polonius.stderr
@@ -0,0 +1,60 @@
+error: lifetime may not live long enough
+ --> $DIR/closure-substs.rs:8:16
+ |
+LL | fn foo<'a>() {
+ | -- lifetime `'a` defined here
+...
+LL | return x;
+ | ^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/closure-substs.rs:15:16
+ |
+LL | |x: &i32| -> &'static i32 {
+ | - let's call the lifetime of this reference `'1`
+LL | return x;
+ | ^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/closure-substs.rs:15:16
+ |
+LL | |x: &i32| -> &'static i32 {
+ | - ------------ return type of closure is &'2 i32
+ | |
+ | let's call the lifetime of this reference `'1`
+LL | return x;
+ | ^ returning this value requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+ --> $DIR/closure-substs.rs:22:9
+ |
+LL | fn bar<'a>() {
+ | -- lifetime `'a` defined here
+...
+LL | b(x);
+ | ^^^^ argument requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/closure-substs.rs:29:9
+ |
+LL | |x: &i32, b: fn(&'static i32)| {
+ | - `x` is a reference that is only valid in the closure body
+LL | b(x);
+ | ^^^^ `x` escapes the closure body here
+
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/closure-substs.rs:29:9
+ |
+LL | |x: &i32, b: fn(&'static i32)| {
+ | - - `b` is declared here, outside of the closure body
+ | |
+ | `x` is a reference that is only valid in the closure body
+LL | b(x);
+ | ^^^^ `x` escapes the closure body here
+
+error: aborting due to 6 previous errors
+